class Healer( base.Monster ): name = "Healer" statline = { stats.STRENGTH: 12, stats.TOUGHNESS: 16, stats.REFLEXES: 12, \ stats.INTELLIGENCE: 14, stats.PIETY: 18, stats.CHARISMA: 18 } SPRITENAME = "monster_spellcasters.png" FRAME = 16 TEMPLATES = () MOVE_POINTS = 10 HABITAT = ( context.HAB_EVERY, context.HAB_BUILDING, context.SET_EVERY, context.DES_CIVILIZED, context.DES_SOLAR, context.DES_WATER, context.MTY_BOSS, context.MTY_HUMANOID, context.MTY_PRIEST, context.GEN_KINGDOM ) ENC_LEVEL = 10 TREASURE = treasuretype.HighItems( ( items.potions.PotionOfHealing, items.scrolls.Rank4Scroll, items.scrolls.Rank5Scroll ) ) COMBAT_AI = aibrain.BasicTechnicalAI() COMPANIONS = (NoviceWarrior,NovicePriest,Warrior) ATTACK = items.Attack( (3,6,0), element = stats.RESIST_SOLAR, hit_anim=animobs.YellowExplosion ) TECHNIQUES = ( spells.priestspells.SMITE, spells.solarspells.MASS_CURE, spells.solarspells.MAXIMUM_CURE, invocations.MPInvocation( "Repent", effects.TargetIsAlly( on_true = ( effects.Enchant( enchantments.BlessingEn, anim=animobs.GreenSparkle ), effects.TargetIsDamaged( on_true= ( effects.HealthRestore( dice=(3,12,12) ), )) ), on_false=( effects.TargetIsEnemy( on_true = ( effects.HealthDamage( (3,12,0), stat_bonus=stats.CHARISMA, element=stats.RESIST_WATER, anim=animobs.Bubbles ), )), )), shot_anim=animobs.BlueComet, com_tar=targetarea.Blast(radius=3), ai_tar=invocations.TargetEnemy(), mp_cost=12 ) ) def init_monster( self ): self.levels.append( base.Spellcaster( 6, self ) ) self.levels.append( base.Defender( 4, self ) )
class YoungCaveDragon(base.Monster): name = "Young Cave Dragon" statline = { stats.STRENGTH: 11, stats.TOUGHNESS: 13, stats.REFLEXES: 10, \ stats.INTELLIGENCE: 10, stats.PIETY: 11, stats.CHARISMA: 10, stats.RESIST_POISON: 100 } SPRITENAME = "monster_dragons.png" FRAME = 2 TEMPLATES = (stats.DRAGON, ) MOVE_POINTS = 8 VOICE = dialogue.voice.DRACONIAN HABITAT = (context.HAB_EVERY, context.SET_EVERY, context.HAB_CAVE, context.MAP_DUNGEON, context.MTY_DRAGON, context.MTY_BOSS, context.DES_EARTH, context.GEN_DRAGON) ENC_LEVEL = 4 COMBAT_AI = aibrain.BruiserAI() TREASURE = treasuretype.DragonHoard() ATTACK = items.Attack((3, 4, 0), element=stats.RESIST_SLASHING) TECHNIQUES = (invocations.MPInvocation( "Toxic Breath", effects.OpposedRoll(def_stat=stats.TOUGHNESS, anim=animobs.PoisonCloud, on_success=(effects.Paralyze(max_duration=3), )), com_tar=targetarea.Cone(reach=4), ai_tar=invocations.TargetEnemy(), mp_cost=4), ) def init_monster(self): self.levels.append(base.Terror(4, self))
class IceDragon(base.Monster): name = "Ice Dragon" statline = { stats.STRENGTH: 17, stats.TOUGHNESS: 15, stats.REFLEXES: 10, \ stats.INTELLIGENCE: 10, stats.PIETY: 11, stats.CHARISMA: 10, stats.RESIST_COLD: 100 } SPRITENAME = "monster_dragons.png" FRAME = 17 TEMPLATES = (stats.DRAGON, ) MOVE_POINTS = 10 VOICE = dialogue.voice.DRACONIAN HABITAT = (context.HAB_EVERY, context.SET_EVERY, context.MTY_DRAGON, context.DES_ICE, context.GEN_DRAGON, context.MTY_BOSS) ENC_LEVEL = 9 TREASURE = treasuretype.DragonHoard() ATTACK = items.Attack((3, 8, 0), element=stats.RESIST_SLASHING) TECHNIQUES = (invocations.MPInvocation( "Frost Breath", effects.OpposedRoll(att_stat=stats.REFLEXES, def_stat=stats.REFLEXES, on_success=(effects.HealthDamage( (4, 8, 0), stat_bonus=stats.TOUGHNESS, element=stats.RESIST_COLD, anim=animobs.SnowCloud), ), on_failure=(effects.HealthDamage( (2, 8, 0), stat_bonus=None, element=stats.RESIST_COLD, anim=animobs.SnowCloud), )), com_tar=targetarea.Cone(reach=5), ai_tar=invocations.TargetEnemy(), mp_cost=16), ) def init_monster(self): self.levels.append(base.Terror(13, self))
class ShieldOfBashing(Enhancer): NAMEPAT = "{0} of Bashing" DESCPAT = "{0} It may be used to bash enemies, doing 2d6 damage and potentially stunning them." PLUSRANK = 2 AFFECTS = (SHIELD, ) TECH = (invocations.MPInvocation( "Shield Bash", effects.PhysicalAttackRoll( att_stat=stats.STRENGTH, on_success=( effects.HealthDamage((2, 6, 0), stat_bonus=stats.STRENGTH, element=stats.RESIST_CRUSHING, stat_mod=2, anim=animobs.RedBoom), effects.OpposedRoll( att_skill=stats.PHYSICAL_ATTACK, def_stat=stats.TOUGHNESS, on_success=(effects.Paralyze(max_duration=3), )), ), on_failure=(effects.NoEffect(anim=animobs.SmallBoom), )), com_tar=targetarea.SingleTarget(reach=1), ai_tar=invocations.TargetEnemy(), mp_cost=3), ) TYPE = ET_SECONDARY
class FireBat(base.Monster): name = "Fire Bat" statline = { stats.STRENGTH: 12, stats.TOUGHNESS: 12, stats.REFLEXES: 14, \ stats.INTELLIGENCE: 2, stats.PIETY: 9, stats.CHARISMA: 3, } SPRITENAME = "monster_animals.png" FRAME = 26 TEMPLATES = (stats.FIRE, ) MOVE_POINTS = 14 VOICE = None HABITAT = (context.HAB_CAVE, context.SET_EVERY, context.DES_FIRE, context.DES_LUNAR, context.MTY_BEAST) ENC_LEVEL = 4 ATTACK = items.Attack((2, 4, 0), element=stats.RESIST_PIERCING, extra_effect=effects.OpposedRoll( att_stat=stats.TOUGHNESS, att_modifier=-10, on_success=( effects.HealthDamage( (1, 6, 0), stat_bonus=None, element=stats.RESIST_FIRE, anim=animobs.OrangeExplosion), effects.Enchant(enchantments.BurnLowEn), ))) TECHNIQUES = (invocations.MPInvocation( "Fire Breath", effects.OpposedRoll(att_skill=stats.PHYSICAL_ATTACK, att_stat=stats.REFLEXES, att_modifier=-10, def_stat=stats.REFLEXES, on_success=( effects.HealthDamage( (1, 8, 0), stat_bonus=None, element=stats.RESIST_FIRE, anim=animobs.OrangeExplosion), effects.Enchant(enchantments.BurnLowEn), ), on_failure=(effects.HealthDamage( (1, 8, 0), stat_bonus=None, element=stats.RESIST_FIRE, anim=animobs.OrangeExplosion), )), com_tar=targetarea.SingleTarget(), shot_anim=animobs.Fireball, ai_tar=invocations.TargetEnemy(), mp_cost=3), ) def init_monster(self): self.levels.append(base.Beast(3, self))
class GreatCaveWyrm(base.Monster): name = "Great Cave Wyrm" statline = { stats.STRENGTH: 27, stats.TOUGHNESS: 21, stats.REFLEXES: 10, \ stats.INTELLIGENCE: 16, stats.PIETY: 17, stats.CHARISMA: 16, stats.PHYSICAL_ATTACK: 20, stats.RESIST_POISON: 100 } SPRITENAME = "monster_dragons.png" FRAME = 42 TEMPLATES = (stats.DRAGON, ) MOVE_POINTS = 10 VOICE = dialogue.voice.DRACONIAN HABITAT = (context.HAB_EVERY, context.SET_EVERY, context.HAB_CAVE, context.MAP_DUNGEON, context.MTY_LEADER, context.MTY_DRAGON, context.MTY_BOSS, context.DES_EARTH, context.GEN_DRAGON) ENC_LEVEL = 20 COMBAT_AI = aibrain.BruiserAI() TREASURE = treasuretype.DragonHoard() LONER = True COMPANIONS = ( OldCaveDragon, AncientCaveDragon, ) ATTACK = items.Attack((7, 8, 0), element=stats.RESIST_SLASHING, extra_effect=abilities.POISON_ATTACK_2d6) TECHNIQUES = (invocations.MPInvocation( "Toxic Breath", effects.OpposedRoll(def_stat=stats.TOUGHNESS, anim=None, on_success=( effects.HealthDamage( (9, 6, 0), stat_bonus=None, element=stats.RESIST_POISON, anim=animobs.PoisonCloud), effects.Paralyze(max_duration=3), effects.Enchant(enchantments.PoisonClassic, anim=animobs.DeathSparkle), ), on_failure=(effects.HealthDamage( (3, 9, 0), stat_bonus=None, element=stats.RESIST_POISON, anim=animobs.PoisonCloud), )), com_tar=targetarea.Cone(reach=8), ai_tar=invocations.TargetEnemy(), mp_cost=38), ) def init_monster(self): self.levels.append(base.Terror(28, self))
class FireWeasel(base.Monster): name = "Fire Weasel" statline = { stats.STRENGTH: 12, stats.TOUGHNESS: 12, stats.REFLEXES: 15, \ stats.INTELLIGENCE: 3, stats.PIETY: 14, stats.CHARISMA: 9 } SPRITENAME = "monster_animals.png" FRAME = 29 TEMPLATES = (stats.FIRE, ) MOVE_POINTS = 10 VOICE = None HABITAT = (context.HAB_EVERY, context.SET_EVERY, context.MAP_WILDERNESS, context.DES_FIRE, context.MTY_BEAST, context.MTY_CREATURE, context.MTY_BOSS, context.GEN_NATURE) ENC_LEVEL = 4 ATTACK = items.Attack((1, 6, 0), element=stats.RESIST_PIERCING, extra_effect=effects.OpposedRoll( att_stat=None, att_modifier=5, on_success=( effects.HealthDamage( (1, 6, 0), stat_bonus=None, element=stats.RESIST_FIRE, anim=animobs.RedCloud), effects.Enchant(enchantments.BurnLowEn), ))) TECHNIQUES = (invocations.MPInvocation( "Fire Breath", effects.OpposedRoll(att_skill=stats.PHYSICAL_ATTACK, att_stat=stats.REFLEXES, def_stat=stats.REFLEXES, on_success=(effects.HealthDamage( (1, 6, 0), stat_bonus=stats.TOUGHNESS, element=stats.RESIST_FIRE, anim=animobs.RedCloud), ), on_failure=(effects.HealthDamage( (1, 3, 0), stat_bonus=None, element=stats.RESIST_FIRE, anim=animobs.RedCloud), )), com_tar=targetarea.Cone(reach=4), ai_tar=invocations.TargetEnemy(), mp_cost=3), ) def init_monster(self): self.levels.append(base.Beast(4, self))
class Ankheg(base.Monster): # OGL monster http://www.d20srd.org/srd/monsters/ankheg.htm name = "Ankheg" statline = { stats.STRENGTH: 21, stats.TOUGHNESS: 17, stats.REFLEXES: 10, \ stats.INTELLIGENCE: 1, stats.PIETY: 13, stats.CHARISMA: 6, stats.STEALTH: 30 } SPRITENAME = "monster_bugs.png" FRAME = 40 TEMPLATES = (stats.BUG, ) MOVE_POINTS = 10 VOICE = None TREASURE = treasuretype.Swallowed(swag_chance=35) HABITAT = (context.HAB_CAVE, context.HAB_TUNNELS, context.SET_EVERY, context.DES_EARTH, context.MTY_BOSS, context.MTY_BEAST, context.MTY_CREATURE, context.GEN_NATURE) ENC_LEVEL = 5 ATTACK = items.Attack((2, 6, 3), element=stats.RESIST_SLASHING, extra_effect=effects.HealthDamage( (1, 6, 0), stat_bonus=None, element=stats.RESIST_ACID, anim=animobs.GreenExplosion)) TECHNIQUES = (invocations.MPInvocation( "Acid Breath", effects.OpposedRoll(att_skill=stats.PHYSICAL_ATTACK, att_stat=stats.REFLEXES, def_stat=stats.REFLEXES, on_success=(effects.HealthDamage( (4, 4, 0), stat_bonus=None, element=stats.RESIST_ACID, anim=animobs.GreenExplosion), ), on_failure=(effects.HealthDamage( (1, 8, 0), stat_bonus=None, element=stats.RESIST_ACID, anim=animobs.GreenExplosion), )), com_tar=targetarea.Line(reach=5), ai_tar=invocations.TargetEnemy(), mp_cost=10), ) def init_monster(self): self.levels.append(base.Defender(2, self)) self.levels.append(base.Beast(2, self))
class Belker(base.Monster): name = "Belker" statline = { stats.STRENGTH: 14, stats.TOUGHNESS: 13, stats.REFLEXES: 21, \ stats.INTELLIGENCE: 6, stats.PIETY: 11, stats.CHARISMA: 11 } SPRITENAME = "monster_e_air.png" FRAME = 10 TEMPLATES = (stats.ELEMENTAL, stats.AIR, stats.INCORPOREAL) MOVE_POINTS = 12 VOICE = None HABITAT = (context.HAB_EVERY, context.SET_EVERY, context.DES_AIR, context.DES_LUNAR, context.MTY_ELEMENTAL) ENC_LEVEL = 8 ATTACK = items.Attack((2, 4, 0), element=stats.RESIST_WIND) TECHNIQUES = (invocations.MPInvocation( "Smoke Claw", effects.OpposedRoll( att_stat=stats.STRENGTH, def_stat=stats.TOUGHNESS, on_success=( effects.HealthDamage((2, 4, 0), stat_bonus=stats.STRENGTH, element=stats.RESIST_WIND, anim=animobs.RedBoom), effects.TargetIs(effects.ALIVE, on_true=( effects.HealthDamage( (3, 4, 0), stat_bonus=None, element=None, anim=animobs.BloodSplat), effects.Enchant(enchantments.Bleeding), )), ), on_failure=(effects.HealthDamage((2, 4, 0), stat_bonus=None, element=stats.RESIST_WIND, anim=animobs.RedBoom), )), mp_cost=5, com_tar=targetarea.SingleTarget(reach=1), ai_tar=invocations.TargetEnemy()), ) def init_monster(self): self.levels.append(base.Humanoid(8, self))
class AnimatedCandlestick(base.Monster): name = "Candlestick" statline = { stats.STRENGTH: 12, stats.TOUGHNESS: 12, stats.REFLEXES: 12, \ stats.INTELLIGENCE: 12, stats.PIETY: 12, stats.CHARISMA: 12 } SPRITENAME = "monster_constructs.png" FRAME = 19 TEMPLATES = (stats.CONSTRUCT, ) MOVE_POINTS = 10 VOICE = None HABITAT = (context.HAB_BUILDING, context.SET_EVERY, context.MTY_CONSTRUCT, context.DES_FIRE) ENC_LEVEL = 7 COMBAT_AI = aibrain.SteadyAI() ATTACK = items.Attack( (2, 6, 0), element=stats.RESIST_PIERCING, extra_effect=effects.OpposedRoll(att_modifier=-10, on_success=(effects.Enchant( enchantments.BurnLowEn, anim=animobs.RedCloud), ))) TECHNIQUES = (invocations.MPInvocation( "Fireball", effects.OpposedRoll(def_stat=stats.REFLEXES, on_success=(effects.HealthDamage( (1, 10, 0), stat_bonus=None, element=stats.RESIST_FIRE, anim=animobs.RedCloud), ), on_failure=(effects.HealthDamage( (1, 6, 0), stat_bonus=None, element=stats.RESIST_FIRE, anim=animobs.RedCloud), )), com_tar=targetarea.SingleTarget(), ai_tar=invocations.TargetEnemy(), shot_anim=animobs.Fireball, mp_cost=5), ) def init_monster(self): self.levels.append(base.Beast(7, self))
class Scarab(base.Monster): name = "Scarab" statline = { stats.STRENGTH: 13, stats.TOUGHNESS: 16, stats.REFLEXES: 14, \ stats.INTELLIGENCE: 1, stats.PIETY: 12, stats.CHARISMA: 1, stats.RESIST_SOLAR: 50 } SPRITENAME = "monster_bugs.png" FRAME = 5 TEMPLATES = (stats.BUG, ) MOVE_POINTS = 8 VOICE = None HABITAT = (context.HAB_TUNNELS, context.HAB_DESERT, context.SET_EVERY, context.DES_SOLAR, context.MTY_BEAST, context.MTY_CREATURE) ENC_LEVEL = 7 TECHNIQUES = (invocations.MPInvocation( "Draining Breath", effects.TargetIsEnemy( on_true=(effects.OpposedRoll( att_skill=stats.PHYSICAL_ATTACK, att_stat=stats.REFLEXES, def_stat=stats.REFLEXES, on_success=(effects.HealthDamage( (1, 8, 0), stat_bonus=stats.TOUGHNESS, element=stats.RESIST_FIRE, anim=animobs.PurpleExplosion), ), on_failure=(effects.HealthDamage( (1, 4, 0), stat_bonus=None, element=stats.RESIST_FIRE, anim=animobs.PurpleExplosion), )), ), on_false=(effects.NoEffect(anim=animobs.PurpleExplosion), )), com_tar=targetarea.Cone(reach=4), ai_tar=invocations.TargetEnemy(), mp_cost=3), ) ATTACK = items.Attack((1, 6, 0), element=stats.RESIST_PIERCING, extra_effect=abilities.POISON_ATTACK_2d6) def init_monster(self): self.levels.append(base.Beast(7, self))
class EarthElemental(base.Monster): name = "Earth Elemental" statline = { stats.STRENGTH: 25, stats.TOUGHNESS: 35, stats.REFLEXES: 10, \ stats.INTELLIGENCE: 12, stats.PIETY: 12, stats.CHARISMA: 12, stats.RESIST_ACID: 100 } SPRITENAME = "monster_e_earth.png" FRAME = 1 TEMPLATES = (stats.ELEMENTAL, stats.EARTH) MOVE_POINTS = 6 HABITAT = (context.HAB_EVERY, context.SET_EVERY, context.DES_EARTH, context.MTY_ELEMENTAL, context.GEN_TERRAN, context.SUMMON_ELEMENTAL) ENC_LEVEL = 12 ATTACK = items.Attack((3, 10, 0), element=stats.RESIST_CRUSHING) TECHNIQUES = (invocations.MPInvocation( "Earthquake", effects.TargetIsEnemy(anim=animobs.EarthBoom, on_true=(effects.OpposedRoll( def_stat=stats.REFLEXES, on_success=(effects.HealthDamage( (5, 6, 0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_CRUSHING, anim=animobs.RedBoom), ), on_failure=(effects.HealthDamage( (1, 12, 0), stat_bonus=None, element=stats.RESIST_CRUSHING, anim=animobs.RedBoom), )), )), mp_cost=15, com_tar=targetarea.SelfCentered(radius=8, delay_from=-1, exclude_middle=True), ai_tar=invocations.TargetEnemy()), ) def init_monster(self): self.levels.append(base.Beast(12, self))
class AncientSkyDragon(base.Monster): name = "Ancient Sky Dragon" statline = { stats.STRENGTH: 27, stats.TOUGHNESS: 21, stats.REFLEXES: 10, \ stats.INTELLIGENCE: 18, stats.PIETY: 19, stats.CHARISMA: 18, stats.RESIST_LIGHTNING: 100 } SPRITENAME = "monster_dragons.png" FRAME = 38 TEMPLATES = (stats.DRAGON, ) MOVE_POINTS = 10 VOICE = dialogue.voice.DRACONIAN HABITAT = (context.HAB_EVERY, context.HAB_DESERT, context.SET_EVERY, context.MAP_WILDERNESS, context.MTY_BOSS, context.MTY_DRAGON, context.DES_AIR, context.GEN_DRAGON) ENC_LEVEL = 17 COMBAT_AI = aibrain.ArcherAI(approach_allies=0) TREASURE = treasuretype.DragonHoard() LONER = True COMPANIONS = (YoungSkyDragon, ) ATTACK = items.Attack((4, 8, 0), element=stats.RESIST_SLASHING) TECHNIQUES = (invocations.MPInvocation( "Lightning Breath", effects.OpposedRoll(att_stat=stats.REFLEXES, def_stat=stats.REFLEXES, on_success=(effects.HealthDamage( (14, 4, 0), stat_bonus=stats.TOUGHNESS, element=stats.RESIST_LIGHTNING, anim=animobs.Spark), ), on_failure=(effects.HealthDamage( (7, 4, 0), stat_bonus=None, element=stats.RESIST_LIGHTNING, anim=animobs.Spark), )), com_tar=targetarea.Line(reach=9), ai_tar=invocations.TargetEnemy(), mp_cost=32), ) def init_monster(self): self.levels.append(base.Terror(23, self))
class LightningBug(base.Monster): name = "Lightning Bug" statline = { stats.STRENGTH: 10, stats.TOUGHNESS: 13, stats.REFLEXES: 12, \ stats.INTELLIGENCE: 1, stats.PIETY: 12, stats.CHARISMA: 1, \ stats.RESIST_LIGHTNING: 150 } SPRITENAME = "monster_bugs.png" FRAME = 13 TEMPLATES = (stats.BUG, ) MOVE_POINTS = 14 VOICE = None HABITAT = (context.HAB_FOREST, context.HAB_CAVE, context.SET_EVERY, context.DES_AIR, context.MTY_BEAST, context.MTY_CREATURE, context.GEN_NATURE) ENC_LEVEL = 5 ATTACK = items.Attack((1, 6, 0), element=stats.RESIST_PIERCING) TECHNIQUES = (invocations.MPInvocation( "Zap", effects.OpposedRoll(att_skill=stats.PHYSICAL_ATTACK, att_stat=stats.REFLEXES, def_stat=stats.REFLEXES, on_success=(effects.HealthDamage( (2, 6, 0), stat_bonus=stats.TOUGHNESS, element=stats.RESIST_LIGHTNING, anim=animobs.Spark), ), on_failure=(effects.HealthDamage( (1, 6, 0), stat_bonus=None, element=stats.RESIST_LIGHTNING, anim=animobs.Spark), )), com_tar=targetarea.Line(reach=6), ai_tar=invocations.TargetEnemy(), mp_cost=5), ) def init_monster(self): self.levels.append(base.Beast(4, self))
class FireScorpion(base.Monster): name = "Fire Scorpion" statline = { stats.STRENGTH: 19, stats.TOUGHNESS: 13, stats.REFLEXES: 18, \ stats.INTELLIGENCE: 4, stats.PIETY: 12, stats.CHARISMA: 1 } SPRITENAME = "monster_bugs.png" FRAME = 16 TEMPLATES = (stats.BUG, stats.FIRE) MOVE_POINTS = 10 VOICE = None HABITAT = (context.HAB_CAVE, context.HAB_DESERT, context.SET_EVERY, context.DES_FIRE, context.MTY_BEAST, context.MTY_BOSS, context.MTY_CREATURE, context.GEN_NATURE) ENC_LEVEL = 8 TECHNIQUES = (invocations.MPInvocation( "Flamethrower", effects.OpposedRoll(att_stat=stats.REFLEXES, on_success=( effects.HealthDamage( (2, 6, 0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_FIRE, anim=animobs.Ignite), effects.Enchant(enchantments.BurnLowEn), ), on_failure=(effects.HealthDamage( (2, 6, 0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_FIRE, anim=animobs.Ignite), )), com_tar=targetarea.Line(reach=6), ai_tar=invocations.TargetEnemy(), mp_cost=12), ) ATTACK = items.Attack((2, 8, 0), element=stats.RESIST_PIERCING, extra_effect=abilities.POISON_ATTACK_1d8) def init_monster(self): self.levels.append(base.Beast(8, self))
class AncientSwampDragon(base.Monster): name = "Ancient Swamp Dragon" statline = { stats.STRENGTH: 29, stats.TOUGHNESS: 21, stats.REFLEXES: 10, \ stats.INTELLIGENCE: 12, stats.PIETY: 13, stats.CHARISMA: 12, stats.RESIST_ACID: 100 } SPRITENAME = "monster_dragons.png" FRAME = 30 TEMPLATES = (stats.DRAGON, ) MOVE_POINTS = 10 VOICE = dialogue.voice.DRACONIAN HABITAT = (context.HAB_EVERY, context.SET_EVERY, context.MTY_LEADER, context.MTY_DRAGON, context.MTY_BOSS, context.DES_EARTH, context.DES_WATER, context.GEN_DRAGON) ENC_LEVEL = 16 TREASURE = treasuretype.DragonHoard() LONER = True COMPANIONS = (OldSwampDragon, ) ATTACK = items.Attack((3, 12, 0), element=stats.RESIST_SLASHING) TECHNIQUES = (invocations.MPInvocation( "Acid Breath", effects.OpposedRoll(att_stat=stats.REFLEXES, def_stat=stats.REFLEXES, on_success=(effects.HealthDamage( (8, 6, 0), stat_bonus=stats.TOUGHNESS, element=stats.RESIST_ACID, anim=animobs.GreenExplosion), ), on_failure=(effects.HealthDamage( (4, 6, 0), stat_bonus=None, element=stats.RESIST_ACID, anim=animobs.GreenExplosion), )), com_tar=targetarea.Line(reach=10), ai_tar=invocations.TargetEnemy(), mp_cost=20), ) def init_monster(self): self.levels.append(base.Terror(24, self))
class DragonTurtle(base.Monster): name = "Dragon Turtle" statline = { stats.STRENGTH: 28, stats.TOUGHNESS: 36, stats.REFLEXES: 10, \ stats.INTELLIGENCE: 6, stats.PIETY: 14, stats.CHARISMA: 6, \ stats.RESIST_WATER: 50 } SPRITENAME = "monster_animals.png" FRAME = 34 TEMPLATES = (stats.REPTILE, stats.DRAGON, stats.WATER) MOVE_POINTS = 6 VOICE = None TREASURE = treasuretype.Swallowed() HABITAT = (context.HAB_EVERY, context.SET_EVERY, context.DES_WATER, context.MTY_BEAST, context.MTY_CREATURE, context.MTY_BOSS, context.GEN_NATURE, context.GEN_DRAGON) ENC_LEVEL = 18 ATTACK = items.Attack((4, 6, 0), element=stats.RESIST_CRUSHING) TECHNIQUES = (invocations.MPInvocation( "Steam Breath", effects.OpposedRoll(att_skill=stats.PHYSICAL_ATTACK, att_stat=stats.REFLEXES, def_stat=stats.REFLEXES, on_success=(effects.HealthDamage( (10, 10, 0), stat_bonus=None, element=stats.RESIST_FIRE, anim=animobs.Steam), ), on_failure=(effects.HealthDamage( (2, 20, 0), stat_bonus=None, element=stats.RESIST_FIRE, anim=animobs.Steam), )), com_tar=targetarea.Cone(reach=8), ai_tar=invocations.TargetEnemy(), mp_cost=15), ) def init_monster(self): self.levels.append(base.Beast(18, self))
class Beastman(base.Monster): name = "Beastman" statline = { stats.STRENGTH: 12, stats.TOUGHNESS: 14, stats.REFLEXES: 14, \ stats.INTELLIGENCE: 9, stats.PIETY: 6, stats.CHARISMA: 8 } SPRITENAME = "monster_chaos.png" FRAME = 3 TEMPLATES = () MOVE_POINTS = 12 TREASURE = treasuretype.Standard() HABITAT = (context.HAB_EVERY, context.SET_EVERY, context.MAP_WILDERNESS, context.DES_LUNAR, context.MTY_HUMANOID, context.MTY_FIGHTER, context.GEN_CHAOS) ENC_LEVEL = 4 COMPANIONS = (Hooligan, ) TECHNIQUES = (invocations.MPInvocation( "Headbutt", effects.PhysicalAttackRoll( att_stat=stats.STRENGTH, on_success=( effects.HealthDamage((1, 10, 0), stat_bonus=stats.STRENGTH, element=stats.RESIST_CRUSHING, stat_mod=2, anim=animobs.RedBoom), effects.OpposedRoll( att_skill=stats.PHYSICAL_ATTACK, def_stat=stats.TOUGHNESS, on_success=(effects.Paralyze(max_duration=3), )), ), on_failure=(effects.NoEffect(anim=animobs.SmallBoom), )), com_tar=targetarea.SingleTarget(reach=1), ai_tar=invocations.TargetEnemy(), mp_cost=5), ) ATTACK = items.Attack((1, 8, 0), element=stats.RESIST_SLASHING) def init_monster(self): self.levels.append(base.Humanoid(4, self))
class CreepingCoins(base.Monster): name = "Creeping Coins" statline = { stats.STRENGTH: 12, stats.TOUGHNESS: 12, stats.REFLEXES: 12, \ stats.INTELLIGENCE: 1, stats.PIETY: 10, stats.CHARISMA: 1, \ stats.RESIST_COLD: 155 } SPRITENAME = "monster_constructs.png" FRAME = 18 TEMPLATES = (stats.CONSTRUCT, ) MOVE_POINTS = 6 VOICE = None HABITAT = (context.HAB_CAVE, context.SET_RENFAN, context.MTY_CONSTRUCT, context.DES_ICE) ENC_LEVEL = 7 TREASURE = treasuretype.High() COMBAT_AI = aibrain.SteadyAI() ATTACK = items.Attack((2, 6, 0), element=stats.RESIST_CRUSHING) TECHNIQUES = (invocations.MPInvocation( "Cold Blast", effects.OpposedRoll(att_modifier=10, def_stat=stats.REFLEXES, on_success=(effects.HealthDamage( (1, 10, 0), stat_bonus=None, element=stats.RESIST_COLD, anim=animobs.SnowCloud), ), on_failure=(effects.HealthDamage( (1, 6, 0), stat_bonus=None, element=stats.RESIST_COLD, anim=animobs.SnowCloud), )), com_tar=targetarea.Cone(reach=5), ai_tar=invocations.TargetEnemy(), mp_cost=1), ) def init_monster(self): self.levels.append(base.Defender(6, self))
class WaterElemental( base.Monster ): name = "Water Elemental" statline = { stats.STRENGTH: 25, stats.TOUGHNESS: 25, stats.REFLEXES: 20, \ stats.INTELLIGENCE: 12, stats.PIETY: 12, stats.CHARISMA: 12, stats.RESIST_WATER: 100 } SPRITENAME = "monster_e_water.png" FRAME = 0 TEMPLATES = (stats.ELEMENTAL,stats.WATER) MOVE_POINTS = 20 HABITAT = ( context.HAB_EVERY, context.SET_EVERY, context.DES_WATER, context.SUMMON_ELEMENTAL ) ENC_LEVEL = 12 ATTACK = items.Attack( (1,10,0), element = stats.RESIST_CRUSHING, extra_effect = effects.HealthDamage( (1,10,0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_WATER, anim=animobs.Spiral ) ) TECHNIQUES = ( invocations.MPInvocation( "Tidal Wave", effects.OpposedRoll( def_stat=stats.REFLEXES, on_success = ( effects.HealthDamage( (3,8,0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_WATER, anim=animobs.Bubbles ) ,), on_failure = ( effects.HealthDamage( (1,12,0), stat_bonus=None, element=stats.RESIST_WATER, anim=animobs.Bubbles ) ,) ), mp_cost=10, com_tar=targetarea.Cone(), ai_tar=invocations.TargetEnemy() ), ) def init_monster( self ): self.levels.append( base.Beast( 12, self ) )
class Roc(base.Monster): name = "Roc" statline = { stats.STRENGTH: 35, stats.TOUGHNESS: 24, stats.REFLEXES: 18, \ stats.INTELLIGENCE: 2, stats.PIETY: 13, stats.CHARISMA: 12 } SPRITENAME = "monster_animals.png" FRAME = 30 TEMPLATES = () MOVE_POINTS = 16 VOICE = None TREASURE = treasuretype.Swallowed() HABITAT = (context.HAB_FOREST, context.HAB_DESERT, context.SET_EVERY, context.MAP_WILDERNESS, context.MTY_BEAST, context.MTY_CREATURE, context.GEN_NATURE, context.DES_AIR, context.DES_SOLAR) ENC_LEVEL = 14 ATTACK = items.Attack((3, 8, 0), element=stats.RESIST_PIERCING) TECHNIQUES = (invocations.MPInvocation( "Wing Sweep", effects.OpposedRoll(att_skill=stats.PHYSICAL_ATTACK, att_stat=stats.REFLEXES, def_stat=stats.REFLEXES, on_success=(effects.HealthDamage( (3, 6, 0), stat_bonus=stats.TOUGHNESS, element=stats.RESIST_WIND, anim=animobs.Spiral), ), on_failure=(effects.HealthDamage( (1, 8, 0), stat_bonus=None, element=stats.RESIST_WIND, anim=animobs.Spiral), )), com_tar=targetarea.Cone(reach=4), ai_tar=invocations.TargetEnemy(), mp_cost=10), ) def init_monster(self): self.levels.append(base.Beast(14, self))
class FireGlove(Enhancer): NAMEPAT = "{0} of Fire" DESCPAT = "{0} The user may project an arc of fire from the fingertips." PLUSRANK = 4 AFFECTS = (GLOVE, GAUNTLET) BONUSES_PER_RANK = stats.StatMod({stats.RESIST_FIRE: 15}) TYPE = ET_PRIMARY TECH = (invocations.Invocation("Flamethrower", effects.OpposedRoll( att_skill=stats.PHYSICAL_ATTACK, att_stat=stats.REFLEXES, def_stat=stats.REFLEXES, on_success=(effects.HealthDamage( (2, 5, 0), stat_bonus=stats.TOUGHNESS, element=stats.RESIST_FIRE, anim=animobs.RedCloud), ), on_failure=(effects.HealthDamage( (1, 6, 0), stat_bonus=None, element=stats.RESIST_FIRE, anim=animobs.RedCloud), )), com_tar=targetarea.Cone(reach=4), ai_tar=invocations.TargetEnemy()), )
class LivingStatue(base.Monster): name = "Living Statue" statline = { stats.STRENGTH: 14, stats.TOUGHNESS: 13, stats.REFLEXES: 10, \ stats.INTELLIGENCE: 10, stats.PIETY: 10, stats.CHARISMA: 1, \ stats.RESIST_FIRE: 155 } SPRITENAME = "monster_constructs.png" FRAME = 13 TEMPLATES = (stats.CONSTRUCT, ) MOVE_POINTS = 10 VOICE = None HABITAT = (context.HAB_BUILDING, context.HAB_TUNNELS, context.SET_EVERY, context.MTY_CONSTRUCT, context.DES_FIRE, context.DES_SOLAR) ENC_LEVEL = 8 TREASURE = treasuretype.Low() COMBAT_AI = aibrain.SteadyAI() ATTACK = items.Attack((1, 6, 0), element=stats.RESIST_SLASHING) TECHNIQUES = (invocations.MPInvocation( "Magma Blast", effects.OpposedRoll(att_modifier=10, def_stat=stats.REFLEXES, on_success=(effects.HealthDamage( (2, 8, 0), stat_bonus=None, element=stats.RESIST_FIRE, anim=animobs.OrangeExplosion), ), on_failure=(effects.HealthDamage( (1, 6, 0), stat_bonus=None, element=stats.RESIST_FIRE, anim=animobs.OrangeExplosion), )), com_tar=targetarea.Line(), ai_tar=invocations.TargetEnemy(), mp_cost=1), ) def init_monster(self): self.levels.append(base.Defender(7, self))
class YoungForestDragon(base.Monster): name = "Young Forest Dragon" statline = { stats.STRENGTH: 15, stats.TOUGHNESS: 16, stats.REFLEXES: 15, \ stats.INTELLIGENCE: 12, stats.PIETY: 12, stats.CHARISMA: 12, stats.RESIST_POISON: 100 } SPRITENAME = "monster_dragons.png" FRAME = 4 TEMPLATES = (stats.DRAGON, ) MOVE_POINTS = 8 VOICE = dialogue.voice.DRACONIAN HABITAT = (context.HAB_EVERY, context.SET_EVERY, context.HAB_FOREST, context.MAP_WILDERNESS, context.MTY_DRAGON, context.GEN_NATURE, context.GEN_DRAGON, context.MTY_BOSS) ENC_LEVEL = 6 TREASURE = treasuretype.DragonHoard() ATTACK = items.Attack((1, 12, 0), element=stats.RESIST_SLASHING) TECHNIQUES = (invocations.MPInvocation( "Poison Breath", effects.OpposedRoll(def_stat=stats.TOUGHNESS, on_success=(effects.HealthDamage( (3, 6, 0), stat_bonus=stats.TOUGHNESS, element=stats.RESIST_POISON, anim=animobs.PoisonCloud), ), on_failure=(effects.HealthDamage( (1, 10, 0), stat_bonus=None, element=stats.RESIST_POISON, anim=animobs.PoisonCloud), )), com_tar=targetarea.Blast(radius=1), ai_tar=invocations.TargetEnemy(), mp_cost=9, shot_anim=animobs.GreenComet), ) def init_monster(self): self.levels.append(base.Terror(7, self))
SUNRAY = Spell("Sunray", "This attack does 3d6 solar damage when it hits.", effects.OpposedRoll( att_modifier=10, on_success=(effects.HealthDamage( (3, 6, 0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_SOLAR, anim=animobs.YellowExplosion), ), on_failure=(effects.NoEffect(anim=animobs.SmallBoom), )), rank=3, gems={SOLAR: 2}, com_tar=targetarea.SingleTarget(), shot_anim=animobs.YellowVortex, ai_tar=invocations.TargetEnemy()) CURE_POISON = Spell( "Cure Poison", "This spell will remove all poisoning from a single party member.", effects.TidyEnchantments(enchantments.POISON, anim=animobs.YellowSparkle), rank=3, gems={SOLAR: 1}, com_tar=targetarea.SingleTarget(reach=1), exp_tar=targetarea.SinglePartyMember(), mpfudge=-1) # CIRCLE 4 MAJOR_CURE = Spell("Major Cure", "This spell will heal one nearby ally for 15-36 damage.",
class Cockatrice( base.Monster ): name = "Cockatrice" statline = { stats.STRENGTH: 8, stats.TOUGHNESS: 8, stats.REFLEXES: 15, \ stats.INTELLIGENCE: 1, stats.PIETY: 10, stats.CHARISMA: 4 } SPRITENAME = "monster_default.png" FRAME = 21 TEMPLATES = () MOVE_POINTS = 10 VOICE = None HABITAT = ( context.HAB_EVERY, context.SET_EVERY, context.SET_RENFAN, context.DES_AIR, context.DES_EARTH, context.MTY_BEAST, context.MTY_BOSS ) ENC_LEVEL = 4 COMPANIONS = (animals.Chicken,) ATTACK = items.Attack( (1,6,0), element = stats.RESIST_PIERCING, skill_mod=stats.REFLEXES ) TECHNIQUES = ( invocations.MPInvocation( "Death Gaze", effects.OpposedRoll( att_stat=stats.PIETY, att_modifier=-10, on_success = ( effects.InstaKill( anim=animobs.CriticalHit ) ,), on_failure = ( effects.NoEffect( anim=animobs.SmallBoom ) ,) ), com_tar=targetarea.SingleTarget(reach=4), shot_anim=animobs.PurpleVortex, ai_tar=invocations.TargetEnemy(), mp_cost=4 ), ) def init_monster( self ): self.levels.append( base.Beast( 3, self ) )
class Medusa( base.Monster ): name = "Medusa" statline = { stats.STRENGTH: 10, stats.TOUGHNESS: 12, stats.REFLEXES: 15, \ stats.INTELLIGENCE: 12, stats.PIETY: 13, stats.CHARISMA: 15 } SPRITENAME = "monster_default.png" FRAME = 30 TEMPLATES = () MOVE_POINTS = 10 VOICE = dialogue.voice.GREEK HABITAT = ( context.HAB_EVERY, context.SET_EVERY, context.MTY_HUMANOID ) ENC_LEVEL = 9 COMBAT_AI = aibrain.ArcherAI(approach_allies=0,technique_chance=75) ATTACK = items.Attack( (1,6,0), element = stats.RESIST_PIERCING, extra_effect=abilities.POISON_ATTACK_2d6 ) TECHNIQUES = ( invocations.MPInvocation( "Death Gaze", effects.OpposedRoll( att_stat=stats.PIETY, att_modifier=-10, on_success = ( effects.InstaKill( anim=animobs.CriticalHit ) ,), on_failure = ( effects.NoEffect( anim=animobs.SmallBoom ) ,) ), com_tar=targetarea.SingleTarget(reach=6), shot_anim=animobs.PurpleVortex, ai_tar=invocations.TargetEnemy(), mp_cost=9 ), abilities.LONGBOW ) def init_monster( self ): self.levels.append( base.Humanoid( 6, self ) )
class Manticore( base.Monster ): name = "Manticore" statline = { stats.STRENGTH: 20, stats.TOUGHNESS: 19, stats.REFLEXES: 15, \ stats.INTELLIGENCE: 7, stats.PIETY: 12, stats.CHARISMA: 9 } SPRITENAME = "monster_default.png" FRAME = 26 TEMPLATES = () MOVE_POINTS = 12 HABITAT = ( context.HAB_EVERY, context.SET_EVERY, context.MAP_WILDERNESS, context.MTY_BEAST, context.MTY_BOSS ) ENC_LEVEL = 7 COMBAT_AI = aibrain.ArcherAI() TREASURE = treasuretype.Standard() ATTACK = items.Attack( (2,4,0), element = stats.RESIST_PIERCING, extra_effect=abilities.POISON_ATTACK ) TECHNIQUES = (invocations.MPInvocation( "Tail Spikes", effects.NoEffect( children=( effects.PhysicalAttackRoll( att_stat=stats.REFLEXES, att_modifier=5, on_success = ( effects.HealthDamage( (1,8,0), stat_bonus=stats.STRENGTH, element=stats.RESIST_PIERCING, anim=animobs.RedBoom ), ), on_failure = ( effects.NoEffect( anim=animobs.SmallBoom ), )), effects.PhysicalAttackRoll( att_stat=stats.REFLEXES, att_modifier=5, on_success = ( effects.HealthDamage( (1,8,0), stat_bonus=stats.STRENGTH, element=stats.RESIST_PIERCING, anim=animobs.RedBoom ), ), on_failure = ( effects.NoEffect( anim=animobs.SmallBoom ), ) ), effects.PhysicalAttackRoll( att_stat=stats.REFLEXES, att_modifier=5, on_success = ( effects.HealthDamage( (1,8,0), stat_bonus=stats.STRENGTH, element=stats.RESIST_PIERCING, anim=animobs.RedBoom ), ), on_failure = ( effects.NoEffect( anim=animobs.SmallBoom ), ) ), effects.PhysicalAttackRoll( att_stat=stats.REFLEXES, att_modifier=5, on_success = ( effects.HealthDamage( (1,8,0), stat_bonus=stats.STRENGTH, element=stats.RESIST_PIERCING, anim=animobs.RedBoom ), ), on_failure = ( effects.NoEffect( anim=animobs.SmallBoom ), ) ), ),), mp_cost=10, com_tar=targetarea.SingleTarget(reach=9), shot_anim=animobs.GoldStone, ai_tar=invocations.TargetEnemy() ), ) def init_monster( self ): self.levels.append( base.Beast( 6, self ) )
class Basilisk( base.Monster ): name = "Basilisk" statline = { stats.STRENGTH: 15, stats.TOUGHNESS: 15, stats.REFLEXES: 8, \ stats.INTELLIGENCE: 2, stats.PIETY: 12, stats.CHARISMA: 11 } SPRITENAME = "monster_default.png" FRAME = 39 TEMPLATES = (stats.REPTILE,) MOVE_POINTS = 8 VOICE = None HABITAT = ( context.HAB_EVERY, context.SET_EVERY, context.MTY_BEAST, context.MTY_BOSS ) ENC_LEVEL = 6 ATTACK = items.Attack( (1,8,0), element = stats.RESIST_PIERCING ) TECHNIQUES = ( invocations.MPInvocation( "Death Gaze", effects.OpposedRoll( att_stat=stats.PIETY, att_modifier=-10, on_success = ( effects.InstaKill( anim=animobs.CriticalHit ) ,), on_failure = ( effects.NoEffect( anim=animobs.SmallBoom ) ,) ), com_tar=targetarea.SingleTarget(reach=4), shot_anim=animobs.PurpleVortex, ai_tar=invocations.TargetEnemy(), mp_cost=6 ), ) def init_monster( self ): self.levels.append( base.Beast( 6, self ) )
stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_ACID, anim=animobs.GreenExplosion), effects.OpposedRoll(def_stat=stats.TOUGHNESS, on_success=(effects.Enchant( enchantments.ArmorDamage, anim=animobs.OrangeSparkle), ))), on_failure=(effects.HealthDamage((1, 5, 0), stat_bonus=None, element=stats.RESIST_ACID, anim=animobs.GreenExplosion), )), rank=2, gems={EARTH: 1}, com_tar=targetarea.SingleTarget(), shot_anim=animobs.GreenSpray, ai_tar=invocations.TargetEnemy()) BEASTLY_MIGHT = Spell( "Beastly Might", "Imbues a single ally with supernatural strength, giving +4 strength, +4 toughness, and +5% to attack.", effects.Enchant(enchantments.BeastlyMightEn, anim=animobs.OrangeSparkle), rank=2, gems={EARTH: 1}, com_tar=targetarea.SingleTarget(), ai_tar=invocations.TargetAllyWithoutEnchantment( enchantments.BeastlyMightEn)) # CIRCLE 3 SHAPE_FLESH = Spell( "Shape Flesh",