예제 #1
0
    def __init__(self, prop: str, world: "World") -> None:
        name = f"Has property '{prop}' ?"
        image = np.array(load_or_create_image(world, prop))
        super().__init__(name=name, image=image)

        self.world = world
        self.prop = prop
예제 #2
0
    def __init__(self, zone: "Zone", world: "World") -> None:
        name = f"Is in {zone}?"
        image = np.array(load_or_create_image(world, zone))
        super().__init__(name=name, image=image)

        self.world = world
        self.zone = zone
        self.slot = self.world.zone_id_to_slot[zone.zone_id]
예제 #3
0
 def _add_property_needed(self, graph: OptionGraph, prop: str) -> HasProperty:
     has_prop = HasProperty(prop, world=self.world)
     graph.add_node(has_prop)
     image = np.array(load_or_create_image(self.world, prop))
     get_prop = Option(f"Get {prop}", image=image)
     graph.add_node(get_prop)
     graph.add_edge(has_prop, get_prop, index=int(False))
     return has_prop
예제 #4
0
 def _add_zone_option(self, graph: OptionGraph, zone_id: int) -> IsInZone:
     zone = self.world.zone_from_id[zone_id]
     is_in_zone = IsInZone(zone, self.world)
     graph.add_node(is_in_zone)
     image = np.array(load_or_create_image(self.world, zone))
     reach_zone = Option(f"Reach {zone}", image=image)
     graph.add_node(reach_zone)
     graph.add_edge(is_in_zone, reach_zone, index=int(False))
     return is_in_zone
예제 #5
0
 def _add_crafting_option(
     self, graph: OptionGraph, item_id: int, quantity: int
 ) -> HasItem:
     item = self.world.item_from_id[item_id]
     has_item = HasItem(item=item, world=self.world, quantity=quantity)
     graph.add_node(has_item)
     image = np.array(load_or_create_image(self.world, item))
     get_item = Option(f"Get {item}", image=image)
     graph.add_node(get_item)
     graph.add_edge(has_item, get_item, index=int(False))
     return has_item
예제 #6
0
    def __init__(self, recipe: "Recipe", world: "World") -> None:
        name = f"Craft {recipe}"

        if recipe.outputs is not None:
            obj = recipe.outputs[0]
        else:
            obj = list(recipe.added_properties.keys())[0]

        image = np.array(load_or_create_image(world, obj))
        action = world.action("craft", recipe.recipe_id)
        super().__init__(action, name=name, image=image)
        self.recipe = recipe
예제 #7
0
    def __init__(self,
                 item: "Item",
                 world: "World",
                 quantity: int = 1) -> None:
        name = f"Has {quantity} {item}?"
        conditon_text = f"{quantity}" if quantity > 1 else ""
        image = load_or_create_image(world, item, text=conditon_text)
        super().__init__(name=name, image=np.array(image))

        self.world = world
        self.item = item
        self.quantity = quantity
        self.slot = self.world.item_id_to_slot[item.item_id]
예제 #8
0
 def __init__(self, zone: "Zone", world: "World") -> None:
     name = f"Move to {zone}"
     image = np.array(load_or_create_image(world, zone))
     action = world.action("move", zone.zone_id)
     super().__init__(action, name=name, image=image)
     self.zone = zone
예제 #9
0
 def __init__(self, item: "Item", world: "World") -> None:
     name = f"Search {item}"
     image = np.array(load_or_create_image(world, item))
     action = world.action("get", item.item_id)
     super().__init__(action, name=name, image=image)
     self.item = item
예제 #10
0
    def get_requirements_graph(self) -> nx.DiGraph:
        """Build the world requirements graph.

        Returns:
            The world requirements graph as a networkx DiGraph.

        """
        graph = nx.DiGraph()

        # Add items nodes
        for i, item in enumerate(self.items):

            color = "blue"
            if item in self.foundable_items:
                color = "green"
            elif isinstance(item, Tool):
                color = "cyan"

            graph.add_node(
                item.item_id,
                type="item",
                color=color,
                image=np.array(load_or_create_image(self, item)),
                item_id=item.item_id,
                label=item.name.capitalize(),
            )

        # Add properties nodes
        for i, prop in enumerate(self.zone_properties):
            graph.add_node(
                prop,
                type="zone_property",
                color="orange",
                prop_id=i,
                image=np.array(load_or_create_image(self, prop)),
                label=prop.capitalize(),
            )

        # Add recipes edges
        def _add_crafts(in_nodes, out_node):
            for index, node in enumerate(in_nodes):
                graph.add_edge(
                    node,
                    out_node,
                    type="craft",
                    color=[1, 0, 0, 1],
                    index=index + 1,
                )

        for recipe in self.recipes:

            in_items_ids = []
            if recipe.inputs is not None:
                in_items_ids = [stack.item_id for stack in recipe.inputs]

            out_items_ids = []
            if recipe.outputs is not None:
                out_items_ids = [stack.item_id for stack in recipe.outputs]

            in_props = (list(recipe.needed_properties.keys())
                        if recipe.needed_properties is not None else [])
            out_props = (list(recipe.added_properties.keys())
                         if recipe.needed_properties is not None else [])

            for out_item in out_items_ids:
                _add_crafts(in_items_ids + in_props, out_item)

            for out_prop in out_props:
                _add_crafts(in_items_ids + in_props, out_prop)

        # Add required_tools and drops edges
        for foundable_item in self.foundable_items:

            need_tool = (foundable_item.required_tools is not None
                         and None not in foundable_item.required_tools)
            if need_tool:
                for tool in foundable_item.required_tools:
                    graph.add_edge(
                        tool.item_id,
                        foundable_item.item_id,
                        type="tool_requirement",
                        color=[0, 1, 1, 1],
                        index=0,
                    )

            if hasattr(foundable_item, "items_dropped"):
                for dropped_item in foundable_item.items_dropped:
                    if dropped_item != foundable_item:
                        graph.add_edge(
                            foundable_item.item_id,
                            dropped_item.item_id,
                            type="drop",
                            color=[0, 1, 0, 1],
                            index=0,
                        )
        return graph
예제 #11
0
def make_menus(world: "World", window_shape: tuple):
    """Build menus for user interface.

    Args:
        world: The current world.
        window_shape: Shape of the window containing menus.

    """
    def add_button(
        menu: Menu,
        id_to_action: Dict[str, Any],
        image: Image,
        scaling: float,
        text_width: int,
        action_type,
        identificator,
        padding,
    ):
        buffered = BytesIO()
        image.save(buffered, format="PNG")
        buffered.seek(0)
        image = BaseImage(buffered).scale(scaling, scaling)

        button = menu.add.button(
            " " * text_width,
            lambda *args: args,
            action_type,
            identificator,
            padding=padding,
        )

        decorator = button.get_decorator()
        decorator.add_baseimage(0, 0, image, centered=True)
        id_to_action[button.get_id()] = (action_type, identificator)

    id_to_action = {}

    # Item Menu
    items_menu_height = int(0.75 * window_shape[1])
    items_menu_width = int(0.15 * window_shape[0])

    items_menu = Menu(
        title="Search",
        height=items_menu_height,
        width=items_menu_width,
        keyboard_enabled=False,
        joystick_enabled=False,
        position=(0, 0),
        overflow=(False, True),
        theme=THEME_BLUE,
    )

    for item in world.searchable_items:
        add_button(
            items_menu,
            id_to_action,
            image=load_or_create_image(world, item),
            scaling=0.5,
            text_width=8,
            action_type="get",
            identificator=item.item_id,
            padding=(12, 0, 12, 0),
        )

    # Recipes Menu
    recipes_menu_height = window_shape[1] - items_menu_height
    recipes_menu_width = window_shape[0]

    recipes_menu = Menu(
        title="Craft",
        height=recipes_menu_height,
        width=recipes_menu_width,
        keyboard_enabled=False,
        joystick_enabled=False,
        rows=1,
        columns=world.n_recipes,
        position=(0, 100),
        overflow=(True, False),
        column_max_width=int(0.08 * window_shape[0]),
        theme=THEME_ORANGE,
    )

    for recipe in world.recipes:
        add_button(
            recipes_menu,
            id_to_action,
            image=load_or_create_image(world, recipe),
            scaling=0.5,
            text_width=8,
            action_type="craft",
            identificator=recipe.recipe_id,
            padding=(16, 0, 16, 0),
        )

    # Zones Menu
    zones_menu_height = items_menu_height
    zones_menu_width = int(0.20 * window_shape[0])

    zones_menu = Menu(
        title="Move",
        height=zones_menu_height,
        width=zones_menu_width,
        keyboard_enabled=False,
        joystick_enabled=False,
        position=(100, 0),
        overflow=(False, True),
        theme=THEME_GREEN,
    )

    for zone in world.zones:
        add_button(
            zones_menu,
            id_to_action,
            image=load_or_create_image(world, zone),
            scaling=0.2,
            text_width=19,
            action_type="move",
            identificator=zone.zone_id,
            padding=(26, 0, 26, 0),
        )

    return (items_menu, recipes_menu, zones_menu), id_to_action
예제 #12
0
 def _load_image(self, item_id) -> "Surface":
     image = load_or_create_image(self.world,
                                  self.world.item_from_id[item_id])
     image = pilImageToSurface(image)
     return scale(image, self.shape, 0.09)
예제 #13
0
 def _load_property_image(self, prop: str):
     image = load_or_create_image(self.world, prop)
     image = pilImageToSurface(image)
     return scale(image, self.shape, 0.2)
예제 #14
0
 def _load_zone_image(self, zone_id, window_shape):
     image = load_or_create_image(self.world,
                                  self.world.zone_from_id[zone_id])
     image = pilImageToSurface(image)
     return scale(image, window_shape, 0.25)