def __init__(self, health_resource: HealthOrManaResource, mana_resource: HealthOrManaResource, consumable_inventory: ConsumableInventory, abilities: List[AbilityType], item_inventory: ItemInventory, new_level_abilities: Dict[int, AbilityType], hero_id: HeroId, armor: int, base_dodge_chance: float, level_bonus: PlayerLevelBonus, talents_config: TalentsConfig, base_block_chance: float): self.health_resource: HealthOrManaResource = health_resource self.mana_resource: HealthOrManaResource = mana_resource self.consumable_inventory = consumable_inventory self.abilities: List[AbilityType] = abilities self._ability_cooldowns_remaining: Dict[AbilityType, int] = { ability_type: 0 for ability_type in abilities } self.active_buffs: List[BuffWithDuration] = [] self.is_invisible = False self.stun_status = StunStatus() self.item_inventory = item_inventory self.life_steal_ratio: float = 0 self.exp = 0 self.level = 1 self.max_exp_in_this_level = 50 self.new_level_abilities: Dict[int, AbilityType] = new_level_abilities self.money = 0 self.base_physical_damage_modifier: float = 1 # only affected by level. [Changes multiplicatively] self.physical_damage_modifier_bonus: float = 0 # affected by items. [Change it additively] self.base_magic_damage_modifier: float = 1 # only affected by level. [Changes multiplicatively] self.magic_damage_modifier_bonus: float = 0 # affected by items. [Change it additively] self.hero_id: HeroId = hero_id self.base_armor: float = armor # depends on which hero is being played # TODO add method for getting effective value self.armor_bonus: int = 0 # affected by items/buffs. [Change it additively] self.base_dodge_chance: float = base_dodge_chance # depends on which hero is being used self.dodge_chance_bonus: float = 0 # affected by items/buffs. [Change it additively] self.level_bonus = level_bonus self._talents_state: TalentsState = TalentsState(talents_config) self._upgrades: List[Any] = [] self.base_block_chance: float = base_block_chance # depends on which hero is being used self.block_chance_bonus: float = 0 # affected by items/buffs. [Change it additively] self.block_damage_reduction: int = 0 self.talents_were_updated = Observable() self.stats_were_updated = Observable() self.exp_was_updated = Observable() self.money_was_updated = Observable() self.abilities_were_updated = Observable() self.cooldowns_were_updated = Observable() self.buffs_were_updated = Observable() self.has_finished_main_quest = False
def __init__(self, pygame_screen, camera_size: Tuple[int, int], screen_size: Tuple[int, int], images_by_ui_sprite: Dict[UiIconSprite, Any], big_images_by_ui_sprite: Dict[UiIconSprite, Any], images_by_portrait_sprite: Dict[PortraitIconSprite, Any], ability_key_labels: List[str]): # INIT PYGAME FONTS pygame.font.init() # SETUP FUNDAMENTALS self.screen_render = DrawableArea(pygame_screen) self.ui_render = DrawableArea(pygame_screen, self._translate_ui_position_to_screen) self.ui_screen_area = Rect(0, camera_size[1], screen_size[0], screen_size[1] - camera_size[1]) self.camera_size = camera_size self.screen_size = screen_size self.ability_key_labels = ability_key_labels # FONTS self.font_splash_screen = pygame.font.Font( DIR_FONTS + 'Arial Rounded Bold.ttf', 64) self.font_ui_stat_bar_numbers = pygame.font.Font( DIR_FONTS + 'Monaco.dfont', 12) self.font_ui_money = pygame.font.Font(DIR_FONTS + 'Monaco.dfont', 12) self.font_tooltip_details = pygame.font.Font( DIR_FONTS + 'Monaco.dfont', 12) self.font_buttons = pygame.font.Font(DIR_FONTS + 'Monaco.dfont', 12) self.font_stats = pygame.font.Font(DIR_FONTS + 'Monaco.dfont', 9) self.font_buff_texts = pygame.font.Font(DIR_FONTS + 'Monaco.dfont', 12) self.font_message = pygame.font.Font(DIR_FONTS + 'Monaco.dfont', 14) self.font_debug_info = pygame.font.Font(DIR_FONTS + 'Monaco.dfont', 12) self.font_ui_icon_keys = pygame.font.Font( DIR_FONTS + 'Courier New Bold.ttf', 12) self.font_level = pygame.font.Font(DIR_FONTS + 'Courier New Bold.ttf', 11) # IMAGES self.images_by_ui_sprite = images_by_ui_sprite self.big_images_by_ui_sprite = big_images_by_ui_sprite self.images_by_portrait_sprite = images_by_portrait_sprite self.images_by_item_category = { ItemEquipmentCategory.HEAD: self.images_by_ui_sprite[UiIconSprite.INVENTORY_TEMPLATE_HELMET], ItemEquipmentCategory.CHEST: self.images_by_ui_sprite[UiIconSprite.INVENTORY_TEMPLATE_CHEST], ItemEquipmentCategory.MAIN_HAND: self.images_by_ui_sprite[UiIconSprite.INVENTORY_TEMPLATE_MAINHAND], ItemEquipmentCategory.OFF_HAND: self.images_by_ui_sprite[UiIconSprite.INVENTORY_TEMPLATE_OFFHAND], ItemEquipmentCategory.NECK: self.images_by_ui_sprite[UiIconSprite.INVENTORY_TEMPLATE_NECK], ItemEquipmentCategory.RING: self.images_by_ui_sprite[UiIconSprite.INVENTORY_TEMPLATE_RING], } # UI COMPONENTS self.ability_icons_row: Rect = Rect(0, 0, 0, 0) self.ability_icons: List[AbilityIcon] = [] self.consumable_icons_row: Rect = Rect(0, 0, 0, 0) self.consumable_icons: List[ConsumableIcon] = [] self.inventory_icons_rect: Rect = Rect(0, 0, 0, 0) self.inventory_icons: List[ItemIcon] = [] self.exp_bar = ExpBar(self.ui_render, Rect(135, 8, 300, 2), self.font_level) self.minimap = Minimap(self.ui_render, Rect(475, 52, 80, 80), Rect(0, 0, 1, 1), (0, 0)) self.buffs = Buffs(self.ui_render, self.font_buff_texts, (10, -35)) self.money_text = Text(self.ui_render, self.font_ui_money, (24, 150), "NO MONEY") self.talents_window: TalentsWindow = None self.quests_window: QuestsWindow = None self.message = Message(self.screen_render, self.font_message, self.ui_screen_area.w // 2, self.ui_screen_area.y - 30) self.paused_splash_screen = PausedSplashScreen( self.screen_render, self.font_splash_screen, Rect(0, 0, self.screen_size[0], self.screen_size[1])) self.controls_window = ControlsWindow(self.ui_render, self.font_tooltip_details, self.font_stats) # SETUP UI COMPONENTS self._setup_ability_icons() self._setup_consumable_icons() self._setup_inventory_icons() self._setup_health_and_mana_bars() self._setup_stats_window() self._setup_talents_window(TalentsState(TalentsConfig({}))) self._setup_quests_window() self._setup_toggle_buttons() self._setup_portrait() self._setup_dialog() # QUICKLY CHANGING STATE self.hovered_component = None self.fps_string = "" self.game_mode_string = "" self.enabled_toggle: ToggleButton = None self.item_slot_being_dragged: ItemIcon = None self.consumable_slot_being_dragged: ConsumableIcon = None self.is_mouse_hovering_ui = False self.mouse_screen_position = (0, 0) self.dialog_state = DialogState() self._ticks_since_last_consumable_action = 0 self._ticks_since_last_ability_action = 0 self.highlighted_consumable_action: Optional[int] = None self.highlighted_ability_action: Optional[AbilityType] = None self.manually_highlighted_inventory_item: Optional[ ItemId] = None # used for dialog self.info_message = InfoMessage()
def on_talents_updated(self, talents_state: TalentsState): self._setup_talents_window(talents_state) if talents_state.has_unpicked_talents( ) and not self.talents_toggle.is_open: self.talents_toggle.highlighted = True
def __init__(self, health_resource: HealthOrManaResource, mana_resource: HealthOrManaResource, consumable_inventory: ConsumableInventory, abilities: List[AbilityType], item_inventory: ItemInventory, new_level_abilities: Dict[int, AbilityType], hero_id: HeroId, armor: int, base_dodge_chance: float, level_bonus: PlayerLevelBonus, talents_config: TalentsConfig, base_block_chance: float, base_magic_resist_chance: float, enabled_portals: Dict[PortalId, Sprite]): self.health_resource: HealthOrManaResource = health_resource self.mana_resource: HealthOrManaResource = mana_resource self.consumable_inventory = consumable_inventory self.abilities: List[AbilityType] = abilities self._active_item_ability: Optional[AbilityType] = None self._ability_cooldowns_remaining: Dict[AbilityType, int] = { ability_type: 0 for ability_type in abilities } self.active_buffs: List[BuffWithDuration] = [] self.is_invisible = False self.stun_status = StunStatus() self.item_inventory = item_inventory self.life_steal_ratio: float = 0 self.exp = 0 self.level = 1 self.max_exp_in_this_level = 50 self.new_level_abilities: Dict[int, AbilityType] = new_level_abilities self.money = 0 self.base_physical_damage_modifier: float = 1 # only affected by level. [Changes multiplicatively] self.physical_damage_modifier_bonus: float = 0 # affected by items. [Change it additively] self.base_magic_damage_modifier: float = 1 # only affected by level. [Changes multiplicatively] self.magic_damage_modifier_bonus: float = 0 # affected by items. [Change it additively] self.hero_id: HeroId = hero_id self.base_armor: float = armor # depends on which hero is being played self.armor_bonus: int = 0 # affected by items/buffs. [Change it additively] self.base_dodge_chance: float = base_dodge_chance # depends on which hero is being used self.dodge_chance_bonus: float = 0 # affected by items/buffs. [Change it additively] self.level_bonus = level_bonus self._talents_state: TalentsState = TalentsState(talents_config) self._upgrades: List[Any] = [] self.base_block_chance: float = base_block_chance # depends on which hero is being used self.block_chance_bonus: float = 0 # affected by items/buffs. [Change it additively] self.block_damage_reduction: int = 0 self.base_magic_resist_chance: float = base_magic_resist_chance self.magic_resist_chance_bonus: float = 0 # affected by items/buffs. [Change it additively] self.base_movement_impairing_resist_chance: float = 0 self.movement_impairing_resist_chance_bonus: float = 0 # affected by items/buffs. [Change it additively] self.talents_were_updated = Observable() self.stats_were_updated = Observable() self.exp_was_updated = Observable() self.money_was_updated = Observable() self.cooldowns_were_updated = Observable() self.buffs_were_updated = Observable() self.quests_were_updated = Observable() self.completed_quests: List[Quest] = [] self.active_quests: List[Quest] = [] self.increased_loot_money_chance = 0 self.increased_loot_rare_or_unique_chance = 0 self.life_on_kill: int = 0 # affected by items/buffs. [Change it additively] self.mana_on_kill: int = 0 # affected by items/buffs. [Change it additively] self.dungeon_difficulty_level = 1 self.enabled_portals = enabled_portals # Part of playerState so that we can save it in save file easily