class Avoral(base.Monster): name = "Avoral" statline = { stats.STRENGTH: 15, stats.TOUGHNESS: 20, stats.REFLEXES: 23, \ stats.INTELLIGENCE: 15, stats.PIETY: 16, stats.CHARISMA: 16, \ stats.AWARENESS: 65, stats.MAGIC_DEFENSE: 25 } SPRITENAME = "monster_celestial.png" FRAME = 12 TEMPLATES = (stats.CELESTIAL, stats.AIR) MOVE_POINTS = 16 HABITAT = (context.SET_EVERY, context.DES_SOLAR, context.DES_AIR, context.MTY_HUMANOID, context.MTY_CELESTIAL) ENC_LEVEL = 12 COMBAT_AI = aibrain.ArcherAI() TREASURE = treasuretype.Standard() TECHNIQUES = (invocations.Invocation("Avoral Missile", effects.HealthDamage( (1, 8, 0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_LUNAR, anim=animobs.PurpleExplosion), com_tar=targetarea.SingleTarget(), shot_anim=animobs.WizardMissile, ai_tar=invocations.TargetEnemy()), invocations.Invocation( "Hold Person", effects.OpposedRoll( att_modifier=20, on_success=(effects.Paralyze(max_duration=3), ), on_failure=(effects.NoEffect( anim=animobs.SmallBoom), )), com_tar=targetarea.SingleTarget(), shot_anim=animobs.BlueComet, ai_tar=invocations.TargetMobileEnemy()), invocations.MPInvocation( "Thunder Strike", effects.OpposedRoll(on_success=(effects.HealthDamage( (3, 6, 0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_LIGHTNING, anim=animobs.Spark), ), on_failure=(effects.HealthDamage( (1, 8, 0), stat_bonus=None, element=stats.RESIST_LIGHTNING, anim=animobs.Spark), )), mp_cost=16, com_tar=targetarea.Line(), ai_tar=invocations.TargetEnemy())) ATTACK = items.Attack((2, 8, 0), element=stats.RESIST_SLASHING) def init_monster(self): self.levels.append(base.Terror(7, self))
class Bodak( base.Monster ): name = "Bodak" statline = { stats.STRENGTH: 13, stats.TOUGHNESS: 12, stats.REFLEXES: 15, \ stats.INTELLIGENCE: 6, stats.PIETY: 12, stats.CHARISMA: 12, stats.RESIST_ACID: 75, stats.RESIST_LIGHTNING: 155 } SPRITENAME = "monster_undead.png" FRAME = 0 TEMPLATES = (stats.UNDEAD,stats.DEMON) MOVE_POINTS = 8 VOICE = None HABITAT = ( context.HAB_EVERY, context.SET_EVERY, context.MTY_UNDEAD, context.MTY_BOSS, context.DES_LUNAR, context.GEN_UNDEAD ) ENC_LEVEL = 10 TREASURE = None ATTACK = items.Attack( (1,8,0), element = stats.RESIST_CRUSHING) TECHNIQUES = ( invocations.MPInvocation( "Death Gaze", effects.OpposedRoll( att_stat=stats.CHARISMA, 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=10 ),) def init_monster( self ): self.levels.append( base.Terror( 9, self ) )
class Spark(base.Monster): name = "Spark" statline = { stats.STRENGTH: 13, stats.TOUGHNESS: 8, stats.REFLEXES: 14, \ stats.INTELLIGENCE: 12, stats.PIETY: 6, stats.CHARISMA: 14, stats.RESIST_PIERCING: 50, stats.RESIST_CRUSHING: 50, stats.RESIST_SLASHING: 50 } SPRITENAME = "monster_by_Joe.png" FRAME = 4 TEMPLATES = (stats.ELEMENTAL, stats.FIRE) MOVE_POINTS = 12 HABITAT = (context.HAB_BUILDING, context.SET_EVERY, context.GEN_IGNAN, context.DES_FIRE, context.DES_SOLAR, context.MTY_ELEMENTAL, context.MTY_CELESTIAL) ENC_LEVEL = 3 COMBAT_AI = aibrain.ArcherAI(approach_allies=0, technique_chance=75) ATTACK = items.Attack((1, 6, 0), element=stats.RESIST_SOLAR, hit_anim=animobs.OrangeExplosion, extra_effect=abilities.BURN_ATTACK) TECHNIQUES = (invocations.Invocation( "Fire Bolt", effects.OpposedRoll( att_modifier=10, att_stat=stats.REFLEXES, def_stat=stats.REFLEXES, on_success=(effects.HealthDamage((1, 6, 0), stat_bonus=None, element=stats.RESIST_FIRE, anim=animobs.OrangeExplosion), ), on_failure=(effects.NoEffect(anim=animobs.SmallBoom), )), com_tar=targetarea.SingleTarget(reach=5), shot_anim=animobs.FireBolt, ai_tar=invocations.TargetEnemy()), ) def init_monster(self): self.levels.append(base.Spellcaster(3, self))
class Unicorn(base.Monster): name = "Unicorn" statline = { stats.STRENGTH: 16, stats.TOUGHNESS: 18, stats.REFLEXES: 16, \ stats.INTELLIGENCE: 16, stats.PIETY: 20, stats.CHARISMA: 18, \ stats.RESIST_LUNAR: 100, stats.MAGIC_DEFENSE: 25 } SPRITENAME = "monster_animals.png" FRAME = 31 TEMPLATES = () MOVE_POINTS = 12 VOICE = None HABITAT = (context.HAB_FOREST, context.SET_EVERY, context.DES_SOLAR, context.MTY_BEAST, context.MTY_CREATURE, context.MTY_LEADER, context.MTY_BOSS, context.GEN_NATURE) ENC_LEVEL = 13 ATTACK = items.Attack((3, 6, 0), element=stats.RESIST_PIERCING) TECHNIQUES = (invocations.MPInvocation( "Radiance", effects.HealthRestore(dice=(5, 8, 20)), mp_cost=7, com_tar=targetarea.SingleTarget(reach=10), ai_tar=invocations.TargetWoundedAlly(), exp_tar=targetarea.SinglePartyMember(), shot_anim=animobs.YellowVortex), ) def init_monster(self): self.levels.append(base.Defender(12, self))
class SkeletonHunter( base.Monster ): name = "Skeleton Hunter" statline = { stats.STRENGTH: 14, stats.TOUGHNESS: 12, stats.REFLEXES: 16, \ stats.INTELLIGENCE: 12, stats.PIETY: 12, stats.CHARISMA: 10, stats.NATURAL_DEFENSE: 10, stats.PHYSICAL_ATTACK: 5 } SPRITENAME = "monster_skeletons.png" FRAME = 9 TEMPLATES = (stats.UNDEAD,stats.BONE) MOVE_POINTS = 8 VOICE = None HABITAT = ( context.HAB_EVERY, context.SET_EVERY, context.SET_RENFAN, context.MTY_UNDEAD, context.MTY_HUMANOID, context.MTY_FIGHTER, context.MTY_BOSS, context.DES_EARTH, context.GEN_UNDEAD ) ENC_LEVEL = 6 TREASURE = treasuretype.High((items.BOW,items.ARROW,items.ARROW)) LONER = True COMPANIONS = (Shade,Ghast,SkeletonMage,SkeletonFighter,SkeletonThief,SkeletalHound) COMBAT_AI = aibrain.SteadyAI() ATTACK = items.Attack( (2,6,0), element = stats.RESIST_CRUSHING ) TECHNIQUES = ( invocations.Invocation( "Arrow", effects.PhysicalAttackRoll( att_stat=stats.REFLEXES, on_success = ( effects.HealthDamage( (1,8,0), stat_bonus=None, element=stats.RESIST_PIERCING, anim=animobs.RedBoom ), effects.TargetIs( effects.ANIMAL, on_true=( effects.PercentRoll( roll_skill=stats.MAGIC_ATTACK, roll_stat=None, roll_modifier=-5, target_affects=True, on_success=( effects.InstaKill( anim=animobs.CriticalHit ) ,) ) ,) ) ), on_failure = ( effects.NoEffect( anim=animobs.SmallBoom ) ,) ), com_tar=targetarea.SingleTarget(reach=8), shot_anim=animobs.Arrow, ai_tar=invocations.TargetEnemy() ), ) def init_monster( self ): self.levels.append( base.Humanoid( 5, self ) )
class OgreLeader( base.Monster ): name = "Ogre Leader" statline = { stats.STRENGTH: 18, stats.TOUGHNESS: 18, stats.REFLEXES: 10, \ stats.INTELLIGENCE: 10, stats.PIETY: 10, stats.CHARISMA: 5 } SPRITENAME = "monster_giants.png" FRAME = 4 TEMPLATES = () MOVE_POINTS = 10 HABITAT = ( context.HAB_EVERY, context.HAB_FOREST, context.SET_EVERY, context.SET_RENFAN, context.MTY_HUMANOID, context.MTY_BOSS, context.MTY_LEADER, context.GEN_GIANT ) ENC_LEVEL = 8 TREASURE = treasuretype.High() LONER = True TECHNIQUES = ( invocations.Invocation( "Rock", effects.PhysicalAttackRoll( att_stat=stats.REFLEXES, on_success = ( effects.HealthDamage( (1,10,2), stat_bonus=None, element=stats.RESIST_CRUSHING, anim=animobs.RedBoom ) ,), on_failure = ( effects.NoEffect( anim=animobs.SmallBoom ) ,) ), com_tar=targetarea.SingleTarget(reach=6), shot_anim=animobs.SlingStone, ai_tar=invocations.TargetEnemy() ), ) COMPANIONS = ( Ogre, OgreChamp, OgreShaman ) ATTACK = items.Attack( (4,4,0), element = stats.RESIST_CRUSHING ) def init_monster( self ): self.levels.append( base.Leader( 9, self ) )
class CloudGiant( base.Monster ): name = "Cloud Giant" statline = { stats.STRENGTH: 31, stats.TOUGHNESS: 21, stats.REFLEXES: 9, \ stats.INTELLIGENCE: 10, stats.PIETY: 14, stats.CHARISMA: 11 } SPRITENAME = "monster_giants.png" FRAME = 11 TEMPLATES = (stats.FIRE,) MOVE_POINTS = 14 HABITAT = ( context.HAB_EVERY, context.SET_EVERY, context.DES_FIRE, context.MTY_HUMANOID, context.MTY_FIGHTER, context.GEN_GIANT ) ENC_LEVEL = 13 TREASURE = treasuretype.HighItems() ATTACK = items.Attack( (4,6,0), element = stats.RESIST_CRUSHING ) TECHNIQUES = ( invocations.Invocation( "Rock", effects.PhysicalAttackRoll( att_stat=stats.REFLEXES, on_success = ( effects.HealthDamage( (2,8,0), stat_bonus=stats.STRENGTH, element=stats.RESIST_CRUSHING, anim=animobs.RedBoom ), ), on_failure = ( effects.NoEffect( anim=animobs.SmallBoom ) ,) ), com_tar=targetarea.SingleTarget(reach=10), shot_anim=animobs.SlingStone, ai_tar=invocations.TargetEnemy() ), ) def init_monster( self ): self.levels.append( base.Humanoid( 15, self ) )
class SwampDragonfly(base.Monster): name = "Swamp Dragonfly" statline = { stats.STRENGTH: 10, stats.TOUGHNESS: 9, stats.REFLEXES: 13, \ stats.INTELLIGENCE: 1, stats.PIETY: 7, stats.CHARISMA: 1, \ stats.RESIST_ACID: 150 } SPRITENAME = "monster_bugs.png" FRAME = 2 TEMPLATES = (stats.BUG, ) MOVE_POINTS = 14 VOICE = None HABITAT = (context.HAB_FOREST, context.SET_EVERY, context.DES_EARTH, context.MTY_BEAST, context.MTY_CREATURE, context.GEN_DRAGON) ENC_LEVEL = 3 ATTACK = items.Attack((1, 6, 0), element=stats.RESIST_PIERCING) TECHNIQUES = (invocations.MPInvocation( "Acid Breath", effects.OpposedRoll( att_skill=stats.PHYSICAL_ATTACK, att_stat=stats.REFLEXES, att_modifier=10, def_stat=stats.REFLEXES, on_success=(effects.HealthDamage((1, 6, 0), stat_bonus=None, element=stats.RESIST_ACID, anim=animobs.GreenExplosion), ), on_failure=(effects.NoEffect(anim=animobs.SmallBoom), )), com_tar=targetarea.SingleTarget(), shot_anim=animobs.GreenSpray, ai_tar=invocations.TargetEnemy(), mp_cost=3), ) def init_monster(self): self.levels.append(base.Beast(2, self))
class EvilEye( base.Monster ): name = "Evil Eye" statline = { stats.STRENGTH: 6, stats.TOUGHNESS: 12, stats.REFLEXES: 12, \ stats.INTELLIGENCE: 10, stats.PIETY: 10, stats.CHARISMA: 2, \ stats.MAGIC_ATTACK: 20, stats.MAGIC_DEFENSE: 10 } SPRITENAME = "monster_default.png" FRAME = 18 TEMPLATES = () MOVE_POINTS = 6 VOICE = None HABITAT = ( context.HAB_CAVE, context.HAB_TUNNELS, context.SET_EVERY, context.DES_LUNAR, context.MTY_BOSS, context.MTY_BEAST, context.GEN_CHAOS ) ENC_LEVEL = 3 ATTACK = items.Attack( (2,4,0), element = stats.RESIST_LUNAR, skill_mod=stats.REFLEXES, hit_anim=animobs.PurpleExplosion, extra_effect = effects.OpposedRoll( att_stat=stats.REFLEXES, def_stat=stats.REFLEXES, on_success = ( effects.Paralyze( max_duration = 3 ) ,) ) ) TECHNIQUES = ( invocations.MPInvocation( "Evil Gaze", effects.OpposedRoll( att_stat=stats.REFLEXES, def_stat=stats.REFLEXES, att_modifier=10, on_success = ( effects.Paralyze( max_duration = 3 ) ,), on_failure = ( effects.NoEffect( anim=animobs.SmallBoom ) ,) ), com_tar=targetarea.SingleTarget(reach=4), shot_anim=animobs.PurpleVortex, ai_tar=invocations.TargetMobileEnemy(), mp_cost=3 ), ) def init_monster( self ): self.levels.append( base.Beast( 3, 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 AirElemental(base.Monster): name = "Air Elemental" statline = { stats.STRENGTH: 20, stats.TOUGHNESS: 20, stats.REFLEXES: 30, \ stats.INTELLIGENCE: 12, stats.PIETY: 12, stats.CHARISMA: 12, stats.RESIST_WIND: 100 } SPRITENAME = "monster_e_air.png" FRAME = 0 TEMPLATES = (stats.ELEMENTAL, stats.AIR) MOVE_POINTS = 20 HABITAT = (context.HAB_EVERY, context.SET_EVERY, context.DES_AIR, context.MTY_ELEMENTAL, context.SUMMON_ELEMENTAL) ENC_LEVEL = 12 ATTACK = items.Attack((1, 10, 0), element=stats.RESIST_SLASHING, extra_effect=effects.HealthDamage( (1, 10, 0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_WIND, anim=animobs.Spiral)) TECHNIQUES = (invocations.MPInvocation( "Tornado", effects.OpposedRoll(def_stat=stats.REFLEXES, on_success=(effects.HealthDamage( (3, 8, 0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_WIND, anim=animobs.Spiral), ), on_failure=(effects.HealthDamage( (1, 12, 0), stat_bonus=None, element=stats.RESIST_WIND, anim=animobs.Spiral), )), mp_cost=10, com_tar=targetarea.Blast(radius=3), shot_anim=animobs.Whirlwind, ai_tar=invocations.TargetEnemy()), invocations.MPInvocation( "Lightning Bolt", effects.OpposedRoll(def_stat=stats.REFLEXES, on_success=(effects.HealthDamage( (3, 12, 0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_LIGHTNING, anim=animobs.BlueZap), ), on_failure=(effects.HealthDamage( (2, 10, 0), stat_bonus=None, element=stats.RESIST_LIGHTNING, anim=animobs.BlueZap), )), mp_cost=5, com_tar=targetarea.SingleTarget(), shot_anim=animobs.Lightning, ai_tar=invocations.TargetEnemy())) def init_monster(self): self.levels.append(base.Beast(12, self))
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 GemOfHolograms(Consumable): true_name = "Gem of Holograms" true_desc = "This gem may be used to summon an illusory monster to aid you in combat." itemtype = GEM mass_per_q = 3 cost_per_q = 600 tech = invocations.Invocation( "Create Illusion", effects.CallMonster({(context.HAB_EVERY, context.SET_EVERY): True}, 5, anim=animobs.BlueSparkle), com_tar=targetarea.SingleTarget(reach=5), ai_tar=invocations.TargetEmptySpot(), exp_tar=None)
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 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 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 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 ) )
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 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 Umbull( base.Monster ): name = "Umbull" statline = { stats.STRENGTH: 23, stats.TOUGHNESS: 19, stats.REFLEXES: 13, \ stats.INTELLIGENCE: 9, stats.PIETY: 11, stats.CHARISMA: 13 } SPRITENAME = "monster_default.png" FRAME = 4 TEMPLATES = () MOVE_POINTS = 8 HABITAT = ( context.HAB_CAVE, context.SET_EVERY, context.MAP_DUNGEON, context.DES_EARTH ) ENC_LEVEL = 9 COMBAT_AI = aibrain.BruiserAI() TREASURE = treasuretype.Standard() ATTACK = items.Attack( (3,6,0), element = stats.RESIST_SLASHING ) TECHNIQUES = (invocations.Invocation( "Freezing Gaze", effects.OpposedRoll( att_modifier=20, on_success = ( effects.Paralyze( max_duration = 6 ) ,), on_failure =( effects.NoEffect( anim=animobs.SmallBoom ) ,) ), com_tar=targetarea.SingleTarget(), shot_anim=animobs.PurpleVortex, ai_tar=invocations.TargetMobileEnemy() ), ) def init_monster( self ): self.levels.append( base.Defender( 9, self ) )
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 ) )
import targetarea import enchantments # Techniques SHORTBOW = invocations.Invocation( "Arrow", effects.PhysicalAttackRoll( att_stat=stats.REFLEXES, att_modifier=5, on_success=(effects.HealthDamage((1, 6, 0), stat_bonus=None, element=stats.RESIST_PIERCING, anim=animobs.RedBoom), ), on_failure=(effects.NoEffect(anim=animobs.SmallBoom), )), com_tar=targetarea.SingleTarget(reach=7), shot_anim=animobs.Arrow, ai_tar=invocations.TargetEnemy()) LONGBOW = invocations.Invocation( "Arrow", effects.PhysicalAttackRoll( att_stat=stats.REFLEXES, att_modifier=5, on_success=(effects.HealthDamage((1, 8, 0), stat_bonus=None, element=stats.RESIST_PIERCING, anim=animobs.RedBoom), ), on_failure=(effects.NoEffect(anim=animobs.SmallBoom), )), com_tar=targetarea.SingleTarget(reach=8), shot_anim=animobs.Arrow,
"Blessing", "Increases the physical and magic attack scores of all allies within 6 tiles by +5%. This effect lasts until the end of combat.", effects.TargetIsAlly(on_true=(effects.Enchant( enchantments.BlessingEn, anim=animobs.YellowSparkle), )), rank=1, gems={SOLAR: 1}, com_tar=targetarea.SelfCentered(), ai_tar=invocations.TargetAllyWithoutEnchantment(enchantments.BlessingEn), mpfudge=-1) MINOR_CURE = Spell("Minor Cure", "This spell will heal one nearby ally for 1-10 damage.", effects.HealthRestore(dice=(1, 10, 0)), rank=1, gems={SOLAR: 1}, com_tar=targetarea.SingleTarget(reach=1), ai_tar=invocations.TargetWoundedAlly(), exp_tar=targetarea.SinglePartyMember()) # CIRCLE 2 MODERATE_CURE = Spell("Moderate Cure", "This spell will heal one nearby ally for 6-20 damage.", effects.HealthRestore(dice=(2, 8, 4)), rank=2, gems={SOLAR: 2}, com_tar=targetarea.SingleTarget(reach=1), ai_tar=invocations.TargetWoundedAlly(), exp_tar=targetarea.SinglePartyMember(), mpfudge=-2)
import stats import invocations # CIRCLE ONE CURSE = Spell( "Curse", "Decreases the physical attack score of enemies within 6 tiles by 5%. This effect lasts until the end of combat.", effects.TargetIsEnemy( on_true = ( effects.Enchant( enchantments.CurseEn, anim=animobs.PurpleSparkle ) ,) ), rank=1, gems={LUNAR:1}, com_tar=targetarea.SelfCentered(), ai_tar=invocations.TargetEnemyWithoutEnchantment(enchantments.CurseEn), mpfudge=-1 ) WIZARD_MISSILE = Spell( "Wizard Missile", "This mystic bolt always strikes its target for 1-6 damage.", effects.HealthDamage((1,6,0), stat_bonus=None, element=stats.RESIST_LUNAR, anim=animobs.PurpleExplosion ), rank=1, gems={LUNAR:1}, com_tar=targetarea.SingleTarget(), shot_anim=animobs.WizardMissile, ai_tar=invocations.TargetEnemy(), mpfudge=-1 ) # CIRCLE TWO SLEEP = Spell( "Sleep", "Causes living creatures in a 2 tile radius to fall asleep.", effects.TargetIs( pat=effects.ANIMAL, anim=animobs.PurpleSparkle, on_true = ( effects.OpposedRoll( att_modifier=0, on_success = ( effects.CauseSleep(), )) ,) ), rank=2, gems={LUNAR:2}, com_tar=targetarea.Blast(radius=2), ai_tar=invocations.TargetMobileEnemy(min_distance=3) ) ENERVATE = Spell( "Enervate", "A ray of negative energy strikes one opponent, draining 4-16 mana instantly.",
# CIRCLE ONE # CIRCLE TWO CHAOS_BOLT = Spell( "Chaos Bolt", "This mystic bolt does 1d8 damage to health and an additional 1d8 damage to mana.", effects.OpposedRoll( on_success = ( effects.HealthDamage((1,8,0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_SOLAR, anim=animobs.YellowExplosion ), effects.ManaDamage((1,8,0), stat_bonus=stats.INTELLIGENCE, anim=animobs.PurpleExplosion ), ), on_failure = ( effects.HealthDamage((1,4,0), stat_bonus=None, element=stats.RESIST_SOLAR, anim=animobs.YellowExplosion ), effects.ManaDamage((1,4,0), stat_bonus=None, anim=animobs.PurpleExplosion ), )), rank=2, gems={LUNAR:1,SOLAR:1}, com_tar=targetarea.SingleTarget(), shot_anim=animobs.WizardMissile, ai_tar=invocations.TargetEnemy(), mpfudge=-3 ) # CIRCLE THREE CHAOTIC_AID = Spell( "Chaotic Aid", "This spell calls forth a servant of chaos to aid you in battle.", effects.CallMonster( {context.GEN_CHAOS: True, context.MTY_FIGHTER: True}, 5, anim=animobs.OrangeSparkle ), rank=3, gems={EARTH:1,AIR:1}, com_tar=targetarea.SingleTarget(reach=2), ai_tar=invocations.TargetEmptySpot(), mpfudge = 3 ) # CIRCLE FOUR
import stats import context import invocations # Necromancers get EARTH, LUNAR, and WATER magic. These spells use at least two # of those colors. # CIRCLE ONE ICE_BOLT = Spell( "Icy Bolt", "This attack does 1d8 cold damage to a single target.", effects.OpposedRoll( att_modifier=15, on_success = ( effects.HealthDamage( (1,8,0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_COLD, anim=animobs.BlueExplosion ) ,), on_failure = ( effects.HealthDamage( (1,3,0), stat_bonus=None, element=stats.RESIST_COLD, anim=animobs.BlueExplosion ) ,) ), rank=1, gems={LUNAR:1,WATER:1}, com_tar=targetarea.SingleTarget(), shot_anim=animobs.BlueBolt, mpfudge=-1, ai_tar=invocations.TargetEnemy() ) RAISE_SKELETON = Spell( "Raise Skeleton", "You conjure dark forces to animate a skeleton which will fight on your behaf.", effects.CallMonster( {context.MTY_UNDEAD: True, context.DES_LUNAR: context.MAYBE, context.GEN_UNDEAD: context.MAYBE}, 2, anim=animobs.PurpleSparkle ), rank=1, gems={EARTH:1,LUNAR:1}, com_tar=targetarea.SingleTarget(reach=2), ai_tar=invocations.TargetEmptySpot() ) # CIRCLE 2 RAISE_CORPSE = Spell( "Raise Corpse", "You conjure dark forces to animate a lesser undead creature which will fight on your behaf.", effects.CallMonster( {context.MTY_UNDEAD: True, context.DES_LUNAR: context.MAYBE, context.GEN_UNDEAD: context.MAYBE}, 4, anim=animobs.PurpleSparkle ), rank=2, gems={EARTH:1,LUNAR:1}, com_tar=targetarea.SingleTarget(reach=2), ai_tar=invocations.TargetEmptySpot(), mpfudge=4 ) TOUCH_OF_DEATH = Spell( "Touch of Death",
"Increases the physical and magical defense of all allies within 6 tiles by +5%. This effect lasts until the end of combat.", effects.TargetIsAlly(on_true=( effects.Enchant(enchantments.AirArmor, anim=animobs.BlueSparkle), )), rank=1, gems={AIR: 1}, com_tar=targetarea.SelfCentered(), ai_tar=invocations.TargetAllyWithoutEnchantment(enchantments.AirArmor)) PROBE = Spell("Probe", "This spell reveals secret knowledge about one target creature.", effects.NoEffect(anim=animobs.BlueSparkle, children=(effects.Probe(), )), rank=1, gems={AIR: 1}, mpfudge=-1, com_tar=targetarea.SingleTarget(), exp_tar=targetarea.SingleTarget()) # CIRCLE TWO SILENCE = Spell( "Silence", "Targets within a 2 tile radius may be silenced, preventing them from casting spells.", effects.OpposedRoll( att_modifier=0, on_success=(effects.CauseSilence(), ), on_failure=(effects.NoEffect(anim=animobs.SmallBoom), )), rank=2, gems={AIR: 1}, com_tar=targetarea.Blast(radius=2), ai_tar=invocations.TargetEnemy())
ACID_SPRAY = Spell( "Acid Spray", "A stream of acid sprays forth, burning enemies for 1d6 damage. This spell has a short range but can affect several targets.", effects.OpposedRoll( on_success = ( effects.HealthDamage( (1,6,0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_ACID, anim=animobs.GreenExplosion ) ,), on_failure = ( effects.HealthDamage( (1,2,0), stat_bonus=None, element=stats.RESIST_ACID, anim=animobs.GreenExplosion ) ,) ), rank=1, gems={FIRE:1,EARTH:1}, com_tar=targetarea.Cone(reach=3), ai_tar=invocations.TargetEnemy() ) # CIRCLE TWO CALL_ANIMAL = Spell( "Call Animal", "This spell will summon a natural creature to fight on your behaf.", effects.CallMonster( {context.MTY_CREATURE: True, context.DES_EARTH: context.MAYBE, context.GEN_NATURE: context.MAYBE, context.DES_SOLAR: context.MAYBE}, 4, anim=animobs.OrangeSparkle ), rank=2, gems={EARTH:1,SOLAR:1}, com_tar=targetarea.SingleTarget(reach=2), ai_tar=invocations.TargetEmptySpot(), mpfudge = 4 ) # CIRCLE THREE CALL_CREATURE = Spell( "Call Creature", "This spell will summon a large natural creature to fight on your behaf.", effects.CallMonster( {context.MTY_CREATURE: True, context.DES_EARTH: context.MAYBE, context.GEN_NATURE: context.MAYBE, context.DES_SOLAR: context.MAYBE}, 6, anim=animobs.OrangeSparkle ), rank=3, gems={EARTH:2,SOLAR:1}, com_tar=targetarea.SingleTarget(reach=2), ai_tar=invocations.TargetEmptySpot(), mpfudge = 6 ) SLIMY_WEAPON = Spell( "Slimy Weapon", "One ally's weapon will be coated in caustic slime which causes an extra 1d10 acid damage and may corrode an opponent's armor.", effects.Enchant( enchantments.AcidWepEn, anim=animobs.OrangeSparkle ), rank=3, gems={EARTH:1}, com_tar=targetarea.SingleTarget(), ai_tar=invocations.TargetAllyWithoutEnchantment(enchantments.AcidWepEn) )
SHOCK_SPHERE = Spell( "Shock Sphere", "An electrical burst will deal 1-6 points of damage to all enemies within two tiles of the caster.", effects.TargetIsEnemy( on_true = ( effects.OpposedRoll( on_success = ( effects.HealthDamage( (1,6,0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_LIGHTNING, anim=animobs.BlueZap ) ,), on_failure = ( effects.HealthDamage( (1,3,0), stat_bonus=None, element=stats.RESIST_LIGHTNING, anim=animobs.BlueZap ) ,) ) ,) ), rank=1, gems={AIR:1,LUNAR:1}, com_tar=targetarea.SelfCentered(radius=2,exclude_middle=True), ai_tar=invocations.TargetEnemy() ) # CIRCLE TWO LIGHTNING_BOLT = Spell( "Lightning Bolt", "This spell conjures magical lightning, which will unerringly hit one foe for 2d8 damage.", effects.HealthDamage((2,8,0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_LIGHTNING, anim=animobs.BlueZap ), rank=2, gems={AIR:1,LUNAR:1}, com_tar=targetarea.SingleTarget(), shot_anim=animobs.Lightning, ai_tar=invocations.TargetEnemy(), mpfudge=-2 ) # CIRCLE THREE FIRE_SIGN = Spell( "Fire Sign", "Burns all enemies within 6 tiles with a flaming sigil, doing 2d4 damage and preventing them from hiding.", effects.TargetIsEnemy( on_true = ( effects.OpposedRoll( on_success = ( effects.HealthDamage( (2,4,0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_FIRE, anim=animobs.RedCloud ) ,), on_failure = ( effects.HealthDamage( (1,4,1), stat_bonus=None, element=stats.RESIST_FIRE, anim=animobs.RedCloud ) ,)), effects.Enchant( enchantments.FireSignEn, anim=None ) ) ), rank=3, gems={AIR:1,FIRE:1}, com_tar=targetarea.SelfCentered(), ai_tar=invocations.TargetEnemy() )
BLAST_UNDEAD = Spell( "Blast Undead", "This mystic bolt deals 1-6 damage to undead creatures.", effects.TargetIs(pat=effects.UNDEAD, on_true=(effects.HealthDamage( (1, 6, 0), stat_bonus=stats.PIETY, element=stats.RESIST_SOLAR, anim=animobs.YellowExplosion), ), on_false=(effects.NoEffect(anim=animobs.SmallBoom), )), rank=1, gems={ SOLAR: 1, WATER: 1 }, com_tar=targetarea.SingleTarget(), shot_anim=animobs.YellowBolt, mpfudge=-1) # CIRCLE TWO WEAPON_BLESSING = Spell( "Weapon Blessing", "One ally's weapon will be blessed to do an extra 1-8 points of damage.", effects.Enchant(enchantments.BlessedWepEn, anim=animobs.YellowSparkle), rank=2, gems={ AIR: 1, SOLAR: 1 }, com_tar=targetarea.SinglePartyMember(),