def complete_quest_option(quest: Quest, boss_npc_type: NpcType, quest_item_type: ItemType,
                          reward_item_id: Callable[[GameState], Optional[ItemId]]) -> DialogOptionData:
    return DialogOptionData(
        summary="QUEST: \"%s\"" % quest.name,
        action_text="give",
        action=CompleteQuestNpcAction(quest, boss_npc_type, quest_item_type, reward_item_id),
        ui_icon_sprite=get_item_data_by_type(quest_item_type).icon_sprite,
        detail_header=get_item_data_by_type(quest_item_type).base_name,
        detail_body="...")
Exemple #2
0
 def generate_loot(self) -> List[LootEntry]:
     loot = list(self.guaranteed_drops)
     if random.random() <= self.item_drop_chance:
         item_level = random.choices(self.item_levels,
                                     weights=self.item_level_weights)[0]
         item_type = random.choice(self.item_types_by_level[item_level])
         # TODO control drop rate of uniques vs rares
         is_unique = get_item_data_by_type(item_type).is_unique
         if not is_unique and random.random() <= self.item_rare_chance:
             # TODO determine suffix based on level!
             suffix_id = random.choice(
                 [suffix_id for suffix_id in ItemSuffixId])
             loot.append(SuffixedItemLootEntry(item_type, suffix_id))
         else:
             loot.append(ItemLootEntry(item_type))
     if random.random() <= self.consumable_drop_chance:
         # Warp stone doesn't have a level, but should be dropped across all levels
         if random.random() < 0.15:
             consumable_type = ConsumableType.WARP_STONE
         else:
             consumable_level = random.choices(
                 self.consumable_levels,
                 weights=self.consumable_level_weights)[0]
             consumable_type = random.choice(
                 self.consumable_types_by_level[consumable_level])
         loot.append(ConsumableLootEntry(consumable_type))
     if random.random() <= self.money_drop_chance:
         amount = random.randint(1, self.level)
         loot.append(MoneyLootEntry(amount))
     return loot
def create_item_on_ground(item_id: ItemId, pos: Tuple[int,
                                                      int]) -> ItemOnGround:
    item_type = item_id.item_type
    entity = WorldEntity(pos, ITEM_ENTITY_SIZE,
                         get_item_data_by_type(item_type).entity_sprite)
    entity.view_z = 1  # It should be rendered below all other entities
    return ItemOnGround(entity, item_id)
Exemple #4
0
def _item_types_for_monster_level(monster_level: int, unique: bool) -> Dict[int, List[ItemType]]:
    d = {}
    for level in range(max(monster_level - 3, 1), monster_level + 3):
        items = [item for item in get_items_with_level(level) if get_item_data_by_type(item).is_unique == unique]
        if items:
            d[level] = items
    return d
def give_quest_option(quest: Quest, quest_intro: str, boss_npc_type: NpcType,
                      quest_item_type: ItemType) -> DialogOptionData:
    return DialogOptionData(
        summary="QUEST: \"%s\"" % quest.name,
        action_text="accept quest",
        action=GiveQuestNpcAction(quest, boss_npc_type, quest_item_type),
        ui_icon_sprite=get_item_data_by_type(quest_item_type).icon_sprite,
        detail_header=quest.name,
        detail_body=quest_intro)
 def try_add_item_to_inventory(self, item_id: ItemId) -> bool:
     item_effect = create_item_effect(item_id)
     item_type = item_id.item_type
     item_equipment_category = get_item_data_by_type(
         item_type).item_equipment_category
     event = self.game_state.player_state.item_inventory.try_add_item(
         item_id, item_effect, item_equipment_category)
     if event is not None:
         self._handle_item_equip_event(event)
     return event is not None
Exemple #7
0
def try_add_item_to_inventory(game_state: GameState, item_id: ItemId) -> bool:
    item_effect = create_item_effect(item_id)
    item_type = item_id.item_type
    item_equipment_category = get_item_data_by_type(
        item_type).item_equipment_category
    result = game_state.player_state.item_inventory.try_add_item(
        item_id, item_effect, item_equipment_category)
    if result:
        if isinstance(result, ItemWasActivated):
            item_effect.apply_start_effect(game_state)
    return result is not None
Exemple #8
0
def _allowed_drop_inside_dungeon(loot_entry: LootEntry):
    if isinstance(loot_entry, ItemLootEntry):
        if get_item_data_by_type(
                loot_entry.item_type
        ).item_equipment_category == ItemEquipmentCategory.QUEST:
            # Player has probably completed the quest anyway and there may be several bosses inside the dungeon, so the
            # ground can get quite crowded
            return False
    if isinstance(loot_entry, ConsumableLootEntry):
        if loot_entry.consumable_type == ConsumableType.WARP_STONE:
            # Warp stones can't be used inside dungeons, and bosses are guaranteed to drop them
            return False
    return True
Exemple #9
0
def sell_item_option(item_id: ItemId, price: int, detail_body: str):
    item_type = item_id.item_type
    name_formatter = "{:<13}"
    cost_formatter = "[{} gold]"
    sell_prompt = "> "
    data = get_item_data_by_type(item_type)
    item_name = build_item_name(item_id)
    icon_sprite = data.icon_sprite
    return DialogOptionData(
        sell_prompt + name_formatter.format(item_name) +
        cost_formatter.format(price), "sell",
        BuyItemNpcAction(item_id, price, item_name.lower()), icon_sprite,
        item_name, detail_body)
Exemple #10
0
def buy_item_option(item_id: ItemId, cost: int):
    item_type = item_id.item_type
    data = get_item_data_by_type(item_type)
    name_formatter = "{:<25}"
    buy_prompt = "> "
    cost_formatter = "[{} gold]"
    item_name = build_item_name(item_id)
    icon_sprite = data.icon_sprite
    description_lines = create_item_description(item_id)
    return DialogOptionData(
        buy_prompt + name_formatter.format(item_name) +
        cost_formatter.format(cost), "buy",
        SellItemNpcAction(cost, item_id, item_name.lower()), icon_sprite,
        item_name, ", ".join([line.text for line in description_lines]))
Exemple #11
0
def print_loot():
    for level in range(1, 10):
        consumable_types = get_consumables_with_level(level)
        item_types = get_items_with_level(level)
        if not consumable_types and not item_types:
            continue
        print("LEVEL " + str(level))
        print("- - - - -")
        for c_type in consumable_types:
            print("{:<25}".format(c_type.name) + str(CONSUMABLES[c_type].description))
        for i_type in item_types:
            data = get_item_data_by_type(i_type)
            description_lines = [line.text for line in create_item_description(randomized_item_id(i_type))]
            print("{:<25}".format(data.base_name) + ", ".join(description_lines))
        print("")
Exemple #12
0
    def on_inventory_updated(self, item_slots: List[ItemInventorySlot]):
        for i in range(len(item_slots)):
            icon = self.inventory_icons[i]
            slot = item_slots[i]
            item_id = slot.get_item_id() if not slot.is_empty() else None
            slot_equipment_category = slot.enforced_equipment_category
            image = None
            tooltip = None
            if item_id:
                item_type = item_id.item_type
                data = get_item_data_by_type(item_type)
                image = self.images_by_ui_sprite[data.icon_sprite]
                category_name = None
                if data.item_equipment_category:
                    category_name = ITEM_EQUIPMENT_CATEGORY_NAMES[
                        data.item_equipment_category]
                description_lines = create_item_description(item_id)
                item_name = item_id.name
                is_rare = bool(item_id.affix_stats)
                is_unique = data.is_unique
                tooltip = TooltipGraphics.create_for_item(self.ui_render,
                                                          item_name,
                                                          category_name,
                                                          icon.rect.topleft,
                                                          description_lines,
                                                          is_rare=is_rare,
                                                          is_unique=is_unique)
            elif slot_equipment_category:
                image = self.images_by_item_category[slot_equipment_category]
                category_name = ITEM_EQUIPMENT_CATEGORY_NAMES[
                    slot_equipment_category]
                tooltip_details = [
                    DetailLine("[" + category_name + "]"),
                    DetailLine(
                        "You have nothing equipped. Drag an item here to equip it!"
                    )
                ]
                tooltip = TooltipGraphics(self.ui_render,
                                          COLOR_WHITE,
                                          "...",
                                          tooltip_details,
                                          bottom_left=icon.rect.topleft)

            icon.image = image
            icon.tooltip = tooltip
            icon.slot_equipment_category = slot_equipment_category
            icon.item_id = item_id
Exemple #13
0
    def render(self):

        self.screen_render.rect(
            COLOR_BORDER, Rect(0, 0, self.camera_size[0], self.camera_size[1]),
            1)
        self.screen_render.rect_filled(
            (20, 10, 0),
            Rect(0, self.camera_size[1], self.screen_size[0],
                 self.screen_size[1] - self.camera_size[1]))

        # CONSUMABLES
        self.ui_render.rect_filled((60, 60, 80), self.consumable_icons_row)
        for icon in self.consumable_icons:
            # TODO treat this as state and update it elsewhere
            recently_clicked = icon.slot_number == self.highlighted_consumable_action
            icon.render(recently_clicked)

        # ABILITIES
        self.ui_render.rect_filled((60, 60, 80), self.ability_icons_row)
        for icon in self.ability_icons:
            ability_type = icon.ability_type
            # TODO treat this as state and update it elsewhere
            if ability_type:
                recently_clicked = ability_type == self.highlighted_ability_action
                icon.render(recently_clicked)

        # ITEMS
        self.ui_render.rect_filled((60, 60, 80), self.inventory_icons_rect)
        for icon in self.inventory_icons:
            # TODO treat this as state and update it elsewhere
            highlighted = False
            if self.item_slot_being_dragged and self.item_slot_being_dragged.item_id:
                item_type = self.item_slot_being_dragged.item_id.item_type
                item_data = get_item_data_by_type(item_type)
                highlighted = item_data.item_equipment_category \
                              and icon.slot_equipment_category == item_data.item_equipment_category
            if self.manually_highlighted_inventory_item and self.manually_highlighted_inventory_item == icon.item_id:
                highlighted = True
            icon.render(highlighted)

        # MINIMAP
        self.minimap.render()

        simple_components = [
            self.exp_bar, self.portrait, self.healthbar, self.manabar,
            self.money_text, self.buffs, self.sound_checkbox, self.save_button,
            self.fullscreen_checkbox, self.stats_window, self.talents_window,
            self.quests_window, self.controls_window
        ] + self.toggle_buttons

        for component in simple_components:
            component.render()

        self.screen_render.rect(COLOR_BORDER, self.ui_screen_area, 1)

        self.screen_render.rect_transparent(Rect(1, 1, 70, 20), 100,
                                            COLOR_BLACK)
        self.screen_render.text(self.font_debug_info,
                                "fps: " + self.fps_string, (6, 4))
        if self.game_mode_string:
            self.screen_render.rect_transparent(Rect(1, 23, 70, 20), 100,
                                                COLOR_BLACK)
            self.screen_render.text(self.font_debug_info,
                                    self.game_mode_string, (6, 26))

        self.message.render(self.info_message.message)

        # TODO Bring back relative render position for dragged entities
        if self.item_slot_being_dragged:
            self._render_item_being_dragged(
                self.item_slot_being_dragged.item_id,
                self.mouse_screen_position,
                (UI_ICON_SIZE[0] // 2, (UI_ICON_SIZE[1] // 2)))
        elif self.consumable_slot_being_dragged:
            self._render_consumable_being_dragged(
                self.consumable_slot_being_dragged.consumable_types[0],
                self.mouse_screen_position,
                (UI_ICON_SIZE[0] // 2, (UI_ICON_SIZE[1] // 2)))

        self.dialog.render()

        if self.hovered_component and self.hovered_component.tooltip and not self.item_slot_being_dragged \
                and not self.consumable_slot_being_dragged:
            tooltip: TooltipGraphics = self.hovered_component.tooltip
            tooltip.render()

        self.paused_splash_screen.render()