def register_skeleton_mage_enemy(): x = 3 indices_by_dir = { Direction.DOWN: [(x, 0), (x + 1, 0), (x + 2, 0), (x + 1, 0)], Direction.LEFT: [(x, 1), (x + 1, 1), (x + 2, 1), (x + 1, 1)], Direction.RIGHT: [(x, 2), (x + 1, 2), (x + 2, 2), (x + 1, 2)], Direction.UP: [(x, 3), (x + 1, 3), (x + 2, 3), (x + 1, 3)] } register_basic_enemy( npc_type=NpcType.SKELETON_MAGE, npc_data=NpcData.enemy(sprite=Sprite.ENEMY_SKELETON_MAGE, size=(32, 32), max_health=50, health_regen=0, speed=0.05, exp_reward=25, enemy_loot_table=LootTableId.LEVEL_4, death_sound_id=SoundId.DEATH_SKELETON_MAGE), mind_constructor=NpcMind, spritesheet_path="resources/graphics/monsters_spritesheet.png", original_sprite_size=(32, 32), scaled_sprite_size=(48, 48), spritesheet_indices=indices_by_dir, sprite_position_relative_to_entity=(-8, -16)) register_projectile_controller(PROJECTILE_TYPE, ProjectileController)
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_necromancer_enemy(): indices_by_dir = { Direction.DOWN: [(x, 0) for x in range(9, 12)], Direction.LEFT: [(x, 1) for x in range(9, 12)], Direction.RIGHT: [(x, 2) for x in range(9, 12)], Direction.UP: [(x, 3) for x in range(9, 12)] } register_basic_enemy( npc_type=NpcType.NECROMANCER, npc_data=NpcData.enemy(sprite=Sprite.ENEMY_NECROMANCER, size=(36, 36), max_health=60, health_regen=0, speed=0.02, exp_reward=29, enemy_loot_table=LootTableId.LEVEL_5, death_sound_id=SoundId.DEATH_NECRO), mind_constructor=NpcMind, spritesheet_path="resources/graphics/enemy_sprite_sheet_3.png", original_sprite_size=(32, 32), scaled_sprite_size=(48, 64), spritesheet_indices=indices_by_dir, sprite_position_relative_to_entity=(-6, -28)) register_projectile_controller(PROJECTILE_TYPE, ProjectileController)
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_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_skeleton_boss_enemy(): x = 6 y = 0 indices_by_dir = { Direction.DOWN: [(x + i, y + 0) for i in range(3)], Direction.LEFT: [(x + i, y + 1) for i in range(3)], Direction.RIGHT: [(x + i, y + 2) for i in range(3)], Direction.UP: [(x + i, y + 3) for i in range(3)] } register_basic_enemy( npc_type=NpcType.SKELETON_BOSS, npc_data=NpcData.enemy( sprite=Sprite.ENEMY_SKELETON_BOSS, size=(32, 32), max_health=120, health_regen=3, speed=0.07, exp_reward=60, enemy_loot_table=LootTableId.BOSS_SKELETON, death_sound_id=SoundId.DEATH_BOSS, is_boss=True), mind_constructor=NpcMind, spritesheet_path="resources/graphics/enemy_sprite_sheet.png", original_sprite_size=(32, 32), scaled_sprite_size=(52, 56), spritesheet_indices=indices_by_dir, sprite_position_relative_to_entity=(-10, -24) ) register_projectile_controller(PROJECTILE_TYPE, ProjectileController) register_buff_effect(BUFF_STUNNED, StunnedFromFiring)
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_arcane_fire_ability(): register_ability_effect(AbilityType.ARCANE_FIRE, _apply_channel_attack) description = "Channel for " + "{:.1f}".format(CHANNEL_DURATION / 1000) + \ "s, firing piercing missiles in front of you dealing up to " + str(MAX_TOTAL_DAMAGE) + \ " magic damage to enemies." ability_data = AbilityData("Arcane Fire", UiIconSprite.ABILITY_ARCANE_FIRE, ARCANE_FIRE_MANA_COST, ARCANE_FIRE_COOLDOWN, description, SoundId.ABILITY_ARCANE_FIRE) register_ability_data(AbilityType.ARCANE_FIRE, ability_data) register_ui_icon_sprite_path(UiIconSprite.ABILITY_ARCANE_FIRE, "resources/graphics/magic_missile.png") register_buff_effect(BuffType.CHANNELING_ARCANE_FIRE, Channeling) register_entity_sprite_initializer( Sprite.PROJECTILE_PLAYER_ARCANE_FIRE, SpriteInitializer("resources/graphics/magic_missile.png", PROJECTILE_SIZE)) register_projectile_controller(ProjectileType.PLAYER_ARCANE_FIRE, ProjectileController) register_buff_as_channeling(BuffType.CHANNELING_ARCANE_FIRE) register_hero_upgrade_effect(HeroUpgradeId.ABILITY_ARCANE_FIRE_COOLDOWN, _upgrade_arcane_fire_cooldown_and_mana_cost)
def register_goblin_warlock_enemy(): enemy_size = (24, 24) enemy_sprite = Sprite.ENEMY_GOBLIN_WARLOCK npc_type = NpcType.GOBLIN_WARLOCK health = 21 exp_reward = 14 npc_data = NpcData.enemy(enemy_sprite, enemy_size, health, 0, 0.032, exp_reward, LootTableId.LEVEL_4, SoundId.DEATH_GOBLIN) register_npc_data(npc_type, npc_data) register_npc_behavior(npc_type, NpcMind) enemy_sprite_sheet = SpriteSheet( "resources/graphics/enemy_sprite_sheet_2.png") enemy_original_sprite_size = (32, 32) enemy_scaled_sprite_size = (48, 48) enemy_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(enemy_sprite, enemy_sprite_sheet, enemy_original_sprite_size, enemy_scaled_sprite_size, enemy_indices_by_dir, (-12, -24)) register_projectile_controller(PROJECTILE_TYPE, ProjectileController) projectile_sprite_sheet = SpriteSheet( "resources/graphics/goblin_fireball_entity.png") projectile_original_sprite_size = (132, 156) projectile_scaled_sprite_size = (20, 20) projectile_indices_by_dir = { Direction.DOWN: [(0, 0), (1, 0), (2, 0), (3, 0)] } projectile_sprite = Sprite.PROJECTILE_ENEMY_GOBLIN_WARLOCK register_entity_sprite_map(projectile_sprite, projectile_sprite_sheet, projectile_original_sprite_size, projectile_scaled_sprite_size, projectile_indices_by_dir, (0, 0)) register_buff_effect(BUFF_TYPE, Burnt) register_buff_text(BUFF_TYPE, "Burnt")
def register_necromancer_enemy(): size = (36, 36) health = 40 exp_reward = 29 npc_data = NpcData.enemy(SPRITE, size, health, 0, 0.02, exp_reward, LOOT_TABLE_4, SoundId.DEATH_NECRO) register_npc_data(ENEMY_TYPE, npc_data) register_npc_behavior(ENEMY_TYPE, NpcMind) enemy_sprite_sheet = SpriteSheet("resources/graphics/enemy_sprite_sheet_3.png") enemy_original_sprite_size = (32, 32) enemy_scaled_sprite_size = (48, 64) enemy_indices_by_dir = { Direction.DOWN: [(x, 0) for x in range(9, 12)], Direction.LEFT: [(x, 1) for x in range(9, 12)], Direction.RIGHT: [(x, 2) for x in range(9, 12)], Direction.UP: [(x, 3) for x in range(9, 12)] } register_entity_sprite_map(SPRITE, enemy_sprite_sheet, enemy_original_sprite_size, enemy_scaled_sprite_size, enemy_indices_by_dir, (-6, -28)) register_projectile_controller(PROJECTILE_TYPE, ProjectileController)
def register_goblin_warlock_enemy(): enemy_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_basic_enemy( npc_type=NpcType.GOBLIN_WARLOCK, npc_data=NpcData.enemy( sprite=Sprite.ENEMY_GOBLIN_WARLOCK, size=(24, 24), max_health=21, health_regen=0, speed=0.032, exp_reward=14, enemy_loot_table=LootTableId.LEVEL_4, death_sound_id=SoundId.DEATH_GOBLIN), mind_constructor=NpcMind, spritesheet_path="resources/graphics/enemy_sprite_sheet_2.png", original_sprite_size=(32, 32), scaled_sprite_size=(48, 48), spritesheet_indices=enemy_indices_by_dir, sprite_position_relative_to_entity=(-12, -24) ) register_projectile_controller(PROJECTILE_TYPE, ProjectileController) projectile_sprite_sheet = SpriteSheet("resources/graphics/goblin_fireball_entity.png") projectile_original_sprite_size = (132, 156) projectile_scaled_sprite_size = (20, 20) projectile_indices_by_dir = { Direction.DOWN: [(0, 0), (1, 0), (2, 0), (3, 0)] } projectile_sprite = Sprite.PROJECTILE_ENEMY_GOBLIN_WARLOCK register_entity_sprite_map(projectile_sprite, projectile_sprite_sheet, projectile_original_sprite_size, projectile_scaled_sprite_size, projectile_indices_by_dir, (0, 0)) register_buff_effect(BUFF_TYPE, Burnt) register_buff_text(BUFF_TYPE, "Burnt")