def register_skeleton_mage_enemy(): size = ( 32, 32 ) # Must not align perfectly with grid cell size (pathfinding issues) sprite = Sprite.ENEMY_SKELETON_MAGE npc_type = NpcType.SKELETON_MAGE movement_speed = 0.05 health = 50 exp_reward = 25 npc_data = NpcData.enemy(sprite, size, health, 0, movement_speed, exp_reward, LootTableId.LEVEL_4, SoundId.DEATH_SKELETON_MAGE) register_npc_data(npc_type, npc_data) register_npc_behavior(npc_type, NpcMind) sprite_sheet = SpriteSheet("resources/graphics/monsters_spritesheet.png") original_sprite_size = (32, 32) scaled_sprite_size = (48, 48) sheet_x = 3 indices_by_dir = { Direction.DOWN: [(sheet_x, 0), (sheet_x + 1, 0), (sheet_x + 2, 0), (sheet_x + 1, 0)], Direction.LEFT: [(sheet_x, 1), (sheet_x + 1, 1), (sheet_x + 2, 1), (sheet_x + 1, 1)], Direction.RIGHT: [(sheet_x, 2), (sheet_x + 1, 2), (sheet_x + 2, 2), (sheet_x + 1, 2)], Direction.UP: [(sheet_x, 3), (sheet_x + 1, 3), (sheet_x + 2, 3), (sheet_x + 1, 3)] } register_entity_sprite_map(sprite, sprite_sheet, original_sprite_size, scaled_sprite_size, indices_by_dir, (-8, -16)) register_projectile_controller(PROJECTILE_TYPE, ProjectileController)
def register_fireball_ability(): register_ability_effect(AbilityType.FIREBALL, _apply_ability) description = "Shoot a fireball, dealing " + str(MIN_DMG) + "-" + str(MAX_DMG) + \ " magic damage to the first enemy that it hits." ability_data = AbilityData("Fireball", UiIconSprite.ABILITY_FIREBALL, FIREBALL_MANA_COST, Millis(500), description, SoundId.ABILITY_FIREBALL) register_ability_data(AbilityType.FIREBALL, ability_data) register_ui_icon_sprite_path(UiIconSprite.ABILITY_FIREBALL, "resources/graphics/icon_fireball.png") register_projectile_controller(ProjectileType.PLAYER_FIREBALL, ProjectileController) sprite_sheet = SpriteSheet( "resources/graphics/projectile_player_fireball.png") original_sprite_size = (64, 64) indices_by_dir = { Direction.LEFT: [(x, 0) for x in range(8)], Direction.UP: [(x, 2) for x in range(8)], Direction.RIGHT: [(x, 4) for x in range(8)], Direction.DOWN: [(x, 6) for x in range(8)] } scaled_sprite_size = (48, 48) register_entity_sprite_map(Sprite.PROJECTILE_PLAYER_FIREBALL, sprite_sheet, original_sprite_size, scaled_sprite_size, indices_by_dir, (-9, -9)) register_buff_effect(BUFF_TYPE, BurntByFireball) register_hero_upgrade_effect(HeroUpgradeId.ABILITY_FIREBALL_MANA_COST, _upgrade_fireball_mana_cost)
def register_goblin_warrior_enemy(): size = (32, 32) # Must not align perfectly with grid cell size (pathfinding issues) sprite = Sprite.ENEMY_GOBLIN_WARRIOR npc_type = NpcType.GOBLIN_WARRIOR movement_speed = 0.09 health = 100 exp_reward = 50 loot_table = LootTable( [ LootGroup(2, [LootEntry.item(ItemType.FROG), LootEntry.consumable(ConsumableType.WARP_STONE)], 1), LootGroup(1, LOOT_ITEMS_3 + LOOT_ITEMS_4, 1), LootGroup(1, [LootEntry.money(2), LootEntry.money(3), LootEntry.money(5)], 0.7) ] ) npc_data = NpcData.enemy(sprite, size, health, 0, movement_speed, exp_reward, loot_table, SoundId.DEATH_BOSS, is_boss=True) register_npc_data(npc_type, npc_data) register_npc_behavior(npc_type, NpcMind) sprite_sheet = SpriteSheet("resources/graphics/enemy_sprite_sheet_2.png") original_sprite_size = (32, 32) scaled_sprite_size = (52, 52) sprite_sheet_x = 3 sprite_sheet_y = 4 indices_by_dir = { Direction.DOWN: [(sprite_sheet_x + i, sprite_sheet_y + 0) for i in range(3)], Direction.LEFT: [(sprite_sheet_x + i, sprite_sheet_y + 1) for i in range(3)], Direction.RIGHT: [(sprite_sheet_x + i, sprite_sheet_y + 2) for i in range(3)], Direction.UP: [(sprite_sheet_x + i, sprite_sheet_y + 3) for i in range(3)] } register_entity_sprite_map(sprite, sprite_sheet, original_sprite_size, scaled_sprite_size, indices_by_dir, (-10, -20))
def register_ninja_npc(): size = ( 30, 30 ) # Must not align perfectly with grid cell size (pathfinding issues) sprite = Sprite.NEUTRAL_NPC_NINJA movement_speed = 0.03 register_npc_data(NPC_TYPE, NpcData.neutral(sprite, size, movement_speed)) register_npc_behavior(NPC_TYPE, NpcMind) _register_dialog() sprite_sheet = SpriteSheet("resources/graphics/enemy_sprite_sheet_3.png") original_sprite_size = (32, 32) scaled_sprite_size = (48, 48) x = 6 indices_by_dir = { Direction.DOWN: [(x, 0), (x + 1, 0), (x + 2, 0)], Direction.LEFT: [(x, 1), (x + 1, 1), (x + 2, 1)], Direction.RIGHT: [(x, 2), (x + 1, 2), (x + 2, 2)], Direction.UP: [(x, 3), (x + 1, 3), (x + 2, 3)] } register_entity_sprite_map(sprite, sprite_sheet, original_sprite_size, scaled_sprite_size, indices_by_dir, (-8, -16)) register_portrait_icon_sprite_path( PORTRAIT_ICON_SPRITE, 'resources/graphics/ninja_portrait.png')
def register_frog_npc(): size = ( 30, 30 ) # Must not align perfectly with grid cell size (pathfinding issues) sprite = Sprite.NEUTRAL_NPC_FROG movement_speed = 0.03 register_npc_data(NPC_TYPE, NpcData.neutral(sprite, size, movement_speed)) register_npc_behavior(NPC_TYPE, NpcMind) _register_dialog() sprite_sheet = SpriteSheet( "resources/graphics/characters_midona_spritesheet.png") original_sprite_size = (32, 32) scaled_sprite_size = (48, 48) x = 6 y = 0 indices_by_dir = { Direction.DOWN: [(x, y), (x + 1, y), (x + 2, y)], Direction.LEFT: [(x, y + 1), (x + 1, y + 1), (x + 2, y + 1)], Direction.RIGHT: [(x, y + 2), (x + 1, y + 2), (x + 2, y + 2)], Direction.UP: [(x, y + 3), (x + 1, y + 3), (x + 2, y + 3)] } register_entity_sprite_map(sprite, sprite_sheet, original_sprite_size, scaled_sprite_size, indices_by_dir, (-9, -18)) register_portrait_icon_sprite_path( UI_ICON_SPRITE, 'resources/graphics/portrait_frog_npc.png')
def register_warrior_king_enemy(): size = ( 32, 32 ) # Must not align perfectly with grid cell size (pathfinding issues) sprite = Sprite.ENEMY_WARRIOR_KING npc_type = NpcType.WARRIOR_KING movement_speed = 0.13 health = 240 exp_reward = 90 npc_data = NpcData.enemy(sprite, size, health, 0, movement_speed, exp_reward, LootTableId.BOSS_WARRIOR_KING, SoundId.DEATH_BOSS, is_boss=True) register_npc_data(npc_type, npc_data) register_npc_behavior(npc_type, NpcMind) sprite_sheet = SpriteSheet("resources/graphics/enemy_sprite_sheet_3.png") original_sprite_size = (32, 32) scaled_sprite_size = (54, 60) x = 9 indices_by_dir = { Direction.DOWN: [(x, 4), (x + 1, 4), (x + 2, 4)], Direction.LEFT: [(x, 5), (x + 1, 5), (x + 2, 5)], Direction.RIGHT: [(x, 6), (x + 1, 6), (x + 2, 6)], Direction.UP: [(x, 7), (x + 1, 7), (x + 2, 7)] } register_entity_sprite_map(sprite, sprite_sheet, original_sprite_size, scaled_sprite_size, indices_by_dir, (-11, -23))
def _register_engangling_roots_effect_decoration(): sprite_sheet = SpriteSheet("resources/graphics/entangling_roots.png") original_sprite_size = (130, 114) indices_by_dir = {Direction.DOWN: [(0, 0)]} register_entity_sprite_map(Sprite.DECORATION_ENTANGLING_ROOTS_EFFECT, sprite_sheet, original_sprite_size, ENTANGLING_ROOTS_SIZE, indices_by_dir, (0, 0))
def register_entangling_roots_ability(): register_ability_effect(ABILITY_TYPE, _apply_ability) description = "Stun an enemy and deal " + str(DEBUFF_TOTAL_DAMAGE) + " magic damage over " + \ "{:.0f}".format(DEBUFF_DURATION / 1000) + "s." mana_cost = 22 ability_data = AbilityData("Entangling roots", ICON_SPRITE, mana_cost, ENTANGLING_ROOTS_COOLDOWN, description, SoundId.ABILITY_ENTANGLING_ROOTS) register_ability_data(ABILITY_TYPE, ability_data) register_ui_icon_sprite_path( ICON_SPRITE, "resources/graphics/ability_icon_entangling_roots.png") register_projectile_controller(PROJECTILE_TYPE, ProjectileController) sprite_sheet = SpriteSheet( "resources/graphics/projectile_entangling_roots.png") original_sprite_size = (165, 214) indices_by_dir = {Direction.LEFT: [(x, 0) for x in range(9)]} register_entity_sprite_map(PROJECTILE_SPRITE, sprite_sheet, original_sprite_size, PROJECTILE_SIZE, indices_by_dir, (0, 0)) register_buff_effect(BUFF_TYPE, Rooted) _register_engangling_roots_effect_decoration() register_hero_upgrade_effect( HeroUpgradeId.ABILITY_ENTANGLING_ROOTS_COOLDOWN, _upgrade_entangling_roots_cooldown)
def register_warrior_king_enemy(): size = (32, 32) # Must not align perfectly with grid cell size (pathfinding issues) sprite = Sprite.ENEMY_WARRIOR_KING npc_type = NpcType.WARRIOR_KING movement_speed = 0.13 health = 190 exp_reward = 75 loot_table = LootTable( [ LootGroup.single(LootEntry.consumable(ConsumableType.WARP_STONE), 1), LootGroup(1, LOOT_ITEMS_4, 1), LootGroup.single(LootEntry.item(ItemType.KEY), 1), ] ) npc_data = NpcData.enemy(sprite, size, health, 0, movement_speed, exp_reward, loot_table, SoundId.DEATH_BOSS) register_npc_data(npc_type, npc_data) register_npc_behavior(npc_type, NpcMind) sprite_sheet = SpriteSheet("resources/graphics/enemy_sprite_sheet_3.png") original_sprite_size = (32, 32) scaled_sprite_size = (54, 60) x = 9 indices_by_dir = { Direction.DOWN: [(x, 4), (x + 1, 4), (x + 2, 4)], Direction.LEFT: [(x, 5), (x + 1, 5), (x + 2, 5)], Direction.RIGHT: [(x, 6), (x + 1, 6), (x + 2, 6)], Direction.UP: [(x, 7), (x + 1, 7), (x + 2, 7)] } register_entity_sprite_map(sprite, sprite_sheet, original_sprite_size, scaled_sprite_size, indices_by_dir, (-11, -23))
def register_warpstone_merchant_npc(): size = ( 30, 30 ) # Must not align perfectly with grid cell size (pathfinding issues) sprite = Sprite.NEUTRAL_WARPSTONE_MERCHANT npc_type = NpcType.NEUTRAL_WARPSTONE_MERCHANT ui_icon_sprite = PortraitIconSprite.WARPSTONE_MERCHANT movement_speed = 0.03 register_npc_data(npc_type, NpcData.neutral(sprite, size, movement_speed)) register_npc_behavior(npc_type, NpcMind) introduction = "Hah! I managed to infuse the statues' teleporting powers into these stones. " \ "You can carry them with you and use them any time you want to return to this place!" dialog_options = [ buy_consumable_option(ConsumableType.WARP_STONE, 2), DialogOptionData("\"Good bye\"", "cancel", None) ] dialog_data = DialogData(ui_icon_sprite, introduction, dialog_options) register_npc_dialog_data(npc_type, dialog_data) sprite_sheet = SpriteSheet("resources/graphics/manga_spritesheet.png") original_sprite_size = (32, 32) scaled_sprite_size = (48, 48) x = 0 y = 0 indices_by_dir = { Direction.DOWN: [(x, y), (x + 1, y), (x + 2, y)], Direction.LEFT: [(x, y + 1), (x + 1, y + 1), (x + 2, y + 1)], Direction.RIGHT: [(x, y + 2), (x + 1, y + 2), (x + 2, y + 2)], Direction.UP: [(x, y + 3), (x + 1, y + 3), (x + 2, y + 3)] } register_entity_sprite_map(sprite, sprite_sheet, original_sprite_size, scaled_sprite_size, indices_by_dir, (-8, -16)) register_portrait_icon_sprite_path( ui_icon_sprite, 'resources/graphics/portrait_warpstone_merchant_npc.png')
def register_hero_mage(): sprite = Sprite.HERO_MAGE portrait_icon_sprite = PortraitIconSprite.HERO_MAGE player_sprite_sheet = SpriteSheet("resources/graphics/player.gif") original_sprite_size = (32, 48) scaled_sprite_size = (60, 60) indices_by_dir = { Direction.DOWN: [(0, 0), (1, 0), (2, 0), (3, 0)], Direction.LEFT: [(0, 1), (1, 1), (2, 1), (3, 1)], Direction.RIGHT: [(0, 2), (1, 2), (2, 2), (3, 2)], Direction.UP: [(0, 3), (1, 3), (2, 3), (3, 3)] } sprite_position_relative_to_entity = (-15, -30) register_entity_sprite_map(sprite, player_sprite_sheet, original_sprite_size, scaled_sprite_size, indices_by_dir, sprite_position_relative_to_entity) register_portrait_icon_sprite_path( portrait_icon_sprite, 'resources/graphics/player_portrait.gif') entity_speed = 0.105 description = "A ranged spellcaster that is explosive but fragile, the mage can take down " \ "large groups of enemies effectively, as long as she can keep her distance..." hero_data = HeroData(sprite, portrait_icon_sprite, _get_initial_player_state_mage(), entity_speed, PLAYER_ENTITY_SIZE, description) register_hero_data(HERO_ID, hero_data) register_ui_icon_sprite_path(UiIconSprite.TALENT_LIGHT_FOOTED, "resources/graphics/boots_of_haste.png")
def register_mummy_enemy(): size = ( 30, 30 ) # Must not align perfectly with grid cell size (pathfinding issues) sprite = Sprite.ENEMY_MUMMY npc_type = NpcType.MUMMY movement_speed = 0.06 health = 20 health_regen = 2 exp_reward = 15 npc_data = NpcData.enemy(sprite, size, health, health_regen, movement_speed, exp_reward, LOOT_TABLE_3, SoundId.DEATH_ZOMBIE) register_npc_data(npc_type, npc_data) register_npc_behavior(npc_type, NpcMind) sprite_sheet = SpriteSheet("resources/graphics/enemy_sprite_sheet_2.png") original_sprite_size = (32, 32) scaled_sprite_size = (48, 48) indices_by_dir = { Direction.DOWN: [(6, 4), (7, 4), (8, 4)], Direction.LEFT: [(6, 5), (7, 5), (8, 5)], Direction.RIGHT: [(6, 6), (7, 6), (8, 6)], Direction.UP: [(6, 7), (7, 7), (8, 7)] } register_entity_sprite_map(sprite, sprite_sheet, original_sprite_size, scaled_sprite_size, indices_by_dir, (-9, -18))
def register_whirlwind_ability(): ability_type = AbilityType.WHIRLWIND ui_icon_sprite = UiIconSprite.ABILITY_WHIRLWIND mana_cost = 13 cooldown = Millis(750) register_ability_effect(ability_type, _apply_ability) description = "Summon a whirlwind that deals up to " + str(PROJECTILE_MAX_TOTAL_DAMAGE) + \ " magic damage to enemies in its path." ability_data = AbilityData("Whirlwind", ui_icon_sprite, mana_cost, cooldown, description, SoundId.ABILITY_WHIRLWIND) register_ability_data(ability_type, ability_data) register_ui_icon_sprite_path(ui_icon_sprite, "resources/graphics/whirlwind.png") sprite_sheet = SpriteSheet( "resources/graphics/ability_whirlwind_transparent_spritemap.png") original_sprite_size = (94, 111) scaled_sprite_size = (140, 140) indices_by_dir = {Direction.DOWN: [(0, 0), (1, 0), (2, 0), (1, 0)]} register_entity_sprite_map(PROJECTILE_SPRITE, sprite_sheet, original_sprite_size, scaled_sprite_size, indices_by_dir, (-8, -50)) register_projectile_controller(PROJECTILE_TYPE, ProjectileController) register_buff_effect(BUFF_TYPE, Stunned)
def register_goblin_spearman_enemy(): size = ( 24, 24 ) # Must not align perfectly with grid cell size (pathfinding issues) sprite = Sprite.ENEMY_GOBLIN_SPEARMAN npc_type = NpcType.GOBLIN_SPEARMAN movement_speed = 0.08 health = 21 exp_reward = 14 register_npc_data( npc_type, NpcData.enemy(sprite, size, health, 0, movement_speed, exp_reward, LootTableId.LEVEL_3, SoundId.DEATH_GOBLIN)) register_npc_behavior(npc_type, NpcMind) sprite_sheet = SpriteSheet("resources/graphics/enemy_sprite_sheet_2.png") original_sprite_size = (32, 32) scaled_sprite_size = (48, 48) sprite_sheet_x = 9 sprite_sheet_y = 0 indices_by_dir = { Direction.DOWN: [(sprite_sheet_x + i, sprite_sheet_y + 0) for i in range(3)], Direction.LEFT: [(sprite_sheet_x + i, sprite_sheet_y + 1) for i in range(3)], Direction.RIGHT: [(sprite_sheet_x + i, sprite_sheet_y + 2) for i in range(3)], Direction.UP: [(sprite_sheet_x + i, sprite_sheet_y + 3) for i in range(3)] } register_entity_sprite_map(sprite, sprite_sheet, original_sprite_size, scaled_sprite_size, indices_by_dir, (-12, -24))
def register_ice_witch_enemy(): size = ( 32, 32 ) # Must not align perfectly with grid cell size (pathfinding issues) sprite = Sprite.ENEMY_ICE_WITCH npc_type = NpcType.ICE_WITCH movement_speed = 0.07 health = 50 exp_reward = 40 npc_data = NpcData.enemy(sprite, size, health, 0, movement_speed, exp_reward, LootTableId.LEVEL_6, SoundId.DEATH_ICE_WITCH) register_npc_data(npc_type, npc_data) register_npc_behavior(npc_type, NpcMind) sprite_sheet = SpriteSheet("resources/graphics/enemy_ice_witch.png") original_sprite_size = (32, 32) scaled_sprite_size = (48, 48) sheet_x = 0 indices_by_dir = { Direction.DOWN: [(sheet_x, 0), (sheet_x + 1, 0), (sheet_x + 2, 0), (sheet_x + 1, 0)], Direction.LEFT: [(sheet_x, 1), (sheet_x + 1, 1), (sheet_x + 2, 1), (sheet_x + 1, 1)], Direction.RIGHT: [(sheet_x, 2), (sheet_x + 1, 2), (sheet_x + 2, 2), (sheet_x + 1, 2)], Direction.UP: [(sheet_x, 3), (sheet_x + 1, 3), (sheet_x + 2, 3), (sheet_x + 1, 3)] } register_entity_sprite_map(sprite, sprite_sheet, original_sprite_size, scaled_sprite_size, indices_by_dir, (-8, -16)) register_buff_effect(SLOW_BUFF_TYPE, SlowedByIceWitch) register_buff_text(SLOW_BUFF_TYPE, "Frozen")
def register_hero_warrior(): sprite = Sprite.HERO_WARRIOR portrait_icon_sprite = PortraitIconSprite.HERO_WARRIOR player_sprite_sheet = SpriteSheet( "resources/graphics/enemy_sprite_sheet_3.png") original_sprite_size = (32, 32) scaled_sprite_size = (48, 48) x = 6 indices_by_dir = { Direction.DOWN: [(x + i, 4) for i in range(3)], Direction.LEFT: [(x + i, 5) for i in range(3)], Direction.RIGHT: [(x + i, 6) for i in range(3)], Direction.UP: [(x + i, 7) for i in range(3)] } sprite_position_relative_to_entity = (-8, -16) register_entity_sprite_map(sprite, player_sprite_sheet, original_sprite_size, scaled_sprite_size, indices_by_dir, sprite_position_relative_to_entity) register_portrait_icon_sprite_path( portrait_icon_sprite, 'resources/graphics/portrait_warrior_hero.png') entity_speed = 0.105 description = "A sturdy melee fighter, the warrior can stand his ground against any foe, and thrives when there " \ "are enemies all around." hero_data = HeroData(sprite, portrait_icon_sprite, _get_initial_player_state_warrior(), entity_speed, PLAYER_ENTITY_SIZE, description) register_hero_data(HERO_ID, hero_data) register_hero_upgrade_effect(HeroUpgradeId.WARRIOR_RETRIBUTION, _apply_retribution_talent) register_buff_effect(BUFF_RETRIBUTION, BuffedFromRetribution) register_buff_text(BUFF_RETRIBUTION, "Retribution")
def register_veteran_enemy(): size = ( 32, 32 ) # Must not align perfectly with grid cell size (pathfinding issues) sprite = Sprite.ENEMY_VETERAN npc_type = NpcType.VETERAN movement_speed = 0.08 health = 60 exp_reward = 35 npc_data = NpcData.enemy(sprite, size, health, 0, movement_speed, exp_reward, LOOT_TABLE_4, SoundId.DEATH_HUMAN) register_npc_data(npc_type, npc_data) register_npc_behavior(npc_type, NpcMind) sprite_sheet = SpriteSheet("resources/graphics/enemy_veteran.png") original_sprite_size = (32, 32) scaled_sprite_size = (48, 48) sheet_x = 0 indices_by_dir = { Direction.DOWN: [(sheet_x, 0), (sheet_x + 1, 0), (sheet_x + 2, 0), (sheet_x + 1, 0)], Direction.LEFT: [(sheet_x, 1), (sheet_x + 1, 1), (sheet_x + 2, 1), (sheet_x + 1, 1)], Direction.RIGHT: [(sheet_x, 2), (sheet_x + 1, 2), (sheet_x + 2, 2), (sheet_x + 1, 2)], Direction.UP: [(sheet_x, 3), (sheet_x + 1, 3), (sheet_x + 2, 3), (sheet_x + 1, 3)] } register_entity_sprite_map(sprite, sprite_sheet, original_sprite_size, scaled_sprite_size, indices_by_dir, (-8, -16))
def register_dark_reaper_enemy(): size = ( 50, 50 ) # Must not align perfectly with grid cell size (pathfinding issues) sprite = Sprite.ENEMY_DARK_REAPER npc_type = NpcType.DARK_REAPER movement_speed = 0.04 health = 80 loot = LootTableId.LEVEL_1 register_npc_data( npc_type, NpcData.enemy(sprite, size, health, 0, movement_speed, 40, loot)) register_npc_behavior(npc_type, NpcMind) sprite_sheet = SpriteSheet("resources/graphics/enemy_sprite_sheet.png") original_sprite_size = (32, 32) scaled_sprite_size = (50, 50) indices_by_dir = { Direction.DOWN: [(9, 0), (10, 0), (11, 0)], Direction.LEFT: [(9, 1), (10, 1), (11, 1)], Direction.RIGHT: [(9, 2), (10, 2), (11, 2)], Direction.UP: [(9, 3), (10, 3), (11, 3)] } register_entity_sprite_map(sprite, sprite_sheet, original_sprite_size, scaled_sprite_size, indices_by_dir, (0, 0)) register_buff_effect(BUFF_TYPE_INVULN, Invuln)
def register_hero_god(): sprite = Sprite.HERO_GOD portrait_icon_sprite = PortraitIconSprite.HERO_GOD player_sprite_sheet = SpriteSheet("resources/graphics/player.gif") original_sprite_size = (32, 48) scaled_sprite_size = (60, 60) indices_by_dir = { Direction.DOWN: [(0, 0), (1, 0), (2, 0), (3, 0)], Direction.LEFT: [(0, 1), (1, 1), (2, 1), (3, 1)], Direction.RIGHT: [(0, 2), (1, 2), (2, 2), (3, 2)], Direction.UP: [(0, 3), (1, 3), (2, 3), (3, 3)] } sprite_position_relative_to_entity = (-15, -30) register_entity_sprite_map(sprite, player_sprite_sheet, original_sprite_size, scaled_sprite_size, indices_by_dir, sprite_position_relative_to_entity) register_portrait_icon_sprite_path( portrait_icon_sprite, 'resources/graphics/player_portrait.gif') entity_speed = 0.5 hero_data = HeroData(sprite, portrait_icon_sprite, _get_initial_player_state_god(), entity_speed, PLAYER_ENTITY_SIZE, "God mode...") register_hero_data(HERO_ID, hero_data) _register_kill_everything_ability()
def register_sorcerer_npc(): size = (30, 30) # Must not align perfectly with grid cell size (pathfinding issues) sprite = Sprite.NEUTRAL_NPC_SORCERER portrait_icon_sprite = PortraitIconSprite.SORCERER npc_type = NpcType.NEUTRAL_SORCERER movement_speed = 0.03 register_npc_data(npc_type, NpcData.neutral(sprite, size, movement_speed)) register_npc_behavior(npc_type, NpcMind) dialog_options = [ buy_consumable_option(ConsumableType.HEALTH, 5), buy_consumable_option(ConsumableType.MANA, 5), buy_consumable_option(ConsumableType.SPEED, 5), buy_consumable_option(ConsumableType.POWER, 10), DialogOptionData("\"Good bye\"", "cancel", None)] dialog_text_body = "Greetings. I am glad to see that you have made it this far! However, great danger lies ahead... " \ "Here, see if any of these potions are of interest to you." dialog_data = DialogData(portrait_icon_sprite, dialog_text_body, dialog_options) register_npc_dialog_data(npc_type, dialog_data) sprite_sheet = SpriteSheet("resources/graphics/enemy_sprite_sheet_3.png") original_sprite_size = (32, 32) scaled_sprite_size = (48, 48) x = 3 indices_by_dir = { Direction.DOWN: [(x, 4), (x + 1, 4), (x + 2, 4)], Direction.LEFT: [(x, 5), (x + 1, 5), (x + 2, 5)], Direction.RIGHT: [(x, 6), (x + 1, 6), (x + 2, 6)], Direction.UP: [(x, 7), (x + 1, 7), (x + 2, 7)] } register_entity_sprite_map(sprite, sprite_sheet, original_sprite_size, scaled_sprite_size, indices_by_dir, (-8, -16)) register_portrait_icon_sprite_path(portrait_icon_sprite, 'resources/graphics/portrait_sorcerer_npc.png')
def register_dwarf_npc(): size = ( 30, 30 ) # Must not align perfectly with grid cell size (pathfinding issues) sprite = Sprite.NEUTRAL_NPC_DWARF npc_type = NpcType.NEUTRAL_DWARF movement_speed = 0.03 register_npc_data(npc_type, NpcData.neutral(sprite, size, movement_speed)) register_npc_behavior(npc_type, NpcMind) introduction = "Hello there. I'm always looking for treasure. If you find any, we might be able to strike a deal!" dialog_options = [ sell_item_option( ItemType.GOLD_NUGGET, 20, "I'll give you good money for a nugget of pure gold!"), sell_item_option(ItemType.SAPHIRE, 30, "If you find a saphire I can make you real rich!"), DialogOptionData("\"Good bye\"", "cancel", None) ] dialog_data = DialogData(PortraitIconSprite.VIKING, introduction, dialog_options) register_npc_dialog_data(npc_type, dialog_data) sprite_sheet = SpriteSheet("resources/graphics/enemy_sprite_sheet.png") original_sprite_size = (32, 32) scaled_sprite_size = (48, 48) indices_by_dir = { Direction.DOWN: [(0, 4), (1, 4), (2, 4)], Direction.LEFT: [(0, 5), (1, 5), (2, 5)], Direction.RIGHT: [(0, 6), (1, 6), (2, 6)], Direction.UP: [(0, 7), (1, 7), (2, 7)] } register_entity_sprite_map(sprite, sprite_sheet, original_sprite_size, scaled_sprite_size, indices_by_dir, (-8, -16)) register_portrait_icon_sprite_path( PortraitIconSprite.VIKING, 'resources/graphics/viking_portrait.png')
def register_zombie_enemy(): size = ( 30, 30 ) # Must not align perfectly with grid cell size (pathfinding issues) sprite = Sprite.ENEMY_ZOMBIE npc_type = NpcType.ZOMBIE movement_speed = 0.03 health = 15 exp_reward = 10 npc_data = NpcData.enemy(sprite, size, health, 0, movement_speed, exp_reward, LootTableId.LEVEL_3, SoundId.DEATH_ZOMBIE) register_npc_data(npc_type, npc_data) register_npc_behavior(npc_type, NpcMind) sprite_sheet = SpriteSheet("resources/graphics/enemy_sprite_sheet_2.png") original_sprite_size = (32, 32) scaled_sprite_size = (48, 48) indices_by_dir = { Direction.DOWN: [(0, 0), (1, 0), (2, 0)], Direction.LEFT: [(0, 1), (1, 1), (2, 1)], Direction.RIGHT: [(0, 2), (1, 2), (2, 2)], Direction.UP: [(0, 3), (1, 3), (2, 3)] } register_entity_sprite_map(sprite, sprite_sheet, original_sprite_size, scaled_sprite_size, indices_by_dir, (-9, -18))
def register_rat_2_enemy(): size = ( 40, 40 ) # Must not align perfectly with grid cell size (pathfinding issues) sprite = Sprite.ENEMY_RAT_2 npc_type = NpcType.RAT_2 movement_speed = 0.08 health = 11 exp_reward = 8 npc_data = NpcData.enemy(sprite, size, health, 0, movement_speed, exp_reward, LootTableId.LEVEL_2, SoundId.DEATH_RAT) register_npc_data(npc_type, npc_data) register_npc_behavior(npc_type, NpcMind) sprite_sheet = SpriteSheet("resources/graphics/gray_rat.png") original_sprite_size = (32, 32) scaled_sprite_size = (50, 50) indices_by_dir = { Direction.DOWN: [(0, 0), (1, 0), (2, 0)], Direction.LEFT: [(0, 1), (1, 1), (2, 1)], Direction.RIGHT: [(0, 2), (1, 2), (2, 2)], Direction.UP: [(0, 3), (1, 3), (2, 3)] } register_entity_sprite_map(sprite, sprite_sheet, original_sprite_size, scaled_sprite_size, indices_by_dir, (-5, -5))
def _register_altar(): sprite = Sprite.WALL_ALTAR sprite_sheet = SpriteSheet("resources/graphics/wall_altar.png") original_sprite_size = (88, 38) scaled_sprite_size = (100, 50) indices_by_dir = {Direction.DOWN: [(0, 0)]} register_entity_sprite_map(sprite, sprite_sheet, original_sprite_size, scaled_sprite_size, indices_by_dir, (0, -13)) register_wall_data(WallType.ALTAR, WallData(sprite, (100, 25))) # table is roughly 13px tall
def _register_plant_decoration(): sprite_sheet = SpriteSheet("resources/graphics/human_tileset.png") original_sprite_size = (32, 32) scaled_sprite_size = (50, 50) indices_by_dir = {Direction.DOWN: [(12, 1)]} register_entity_sprite_map(Sprite.DECORATION_PLANT, sprite_sheet, original_sprite_size, scaled_sprite_size, indices_by_dir, (0, 0))
def register_chest_entity(): sprite = Sprite.CHEST sprite_sheet = SpriteSheet("resources/graphics/human_tileset.png") original_sprite_size = (32, 64) scaled_sprite_size = (50, 75) indices_by_dir = {Direction.DOWN: [(9, 3)]} register_entity_sprite_map(sprite, sprite_sheet, original_sprite_size, scaled_sprite_size, indices_by_dir, (-6, -33))
def register_shrines(): sprite_sheet = SpriteSheet("resources/graphics/human_tileset.png") original_sprite_size = (32, 64) scaled_sprite_size = (50, 100) register_entity_sprite_map(Sprite.SHRINE, sprite_sheet, original_sprite_size, scaled_sprite_size, {Direction.DOWN: [(14, 3)]}, (-7, -54)) _register_buffs()
def _register_statue(): sprite = Sprite.WALL_STATUE sprite_sheet = SpriteSheet("resources/graphics/human_tileset.png") original_sprite_size = (32, 64) scaled_sprite_size = (50, 100) indices_by_dir = {Direction.DOWN: [(13, 3)]} register_entity_sprite_map(sprite, sprite_sheet, original_sprite_size, scaled_sprite_size, indices_by_dir, (-4, -54)) register_wall_data(WallType.STATUE, WallData(sprite, (42, 46)))
def _register_chair(): sprite = Sprite.WALL_CHAIR sprite_sheet = SpriteSheet("resources/graphics/human_tileset.png") original_sprite_size = (32, 32) scaled_sprite_size = (50, 50) indices_by_dir = {Direction.DOWN: [(7, 0)]} register_entity_sprite_map(sprite, sprite_sheet, original_sprite_size, scaled_sprite_size, indices_by_dir, (0, 0)) register_wall_data(WallType.WALL_CHAIR, WallData(sprite, (50, 50)))
def _register_wall(): size = (25, 25) sprite = Sprite.WALL sprite_sheet = SpriteSheet("resources/graphics/stone_tile.png") original_sprite_size = (410, 404) scaled_sprite_size = (size[0] - 1, size[1] - 1) indices_by_dir = {Direction.DOWN: [(0, 0)]} register_entity_sprite_map(sprite, sprite_sheet, original_sprite_size, scaled_sprite_size, indices_by_dir, (1, 1)) register_wall_data(WallType.WALL, WallData(sprite, size))