class Hydra( base.Monster ): name = "Hydra" statline = { stats.STRENGTH: 21, stats.TOUGHNESS: 20, stats.REFLEXES: 12, \ stats.INTELLIGENCE: 3, stats.PIETY: 10, stats.CHARISMA: 9, stats.PHYSICAL_ATTACK: 20 } SPRITENAME = "monster_default.png" FRAME = 3 TEMPLATES = (stats.REPTILE,stats.EARTH,) MOVE_POINTS = 8 HABITAT = ( context.HAB_EVERY, context.SET_EVERY, context.DES_EARTH, context.MTY_BOSS ) ENC_LEVEL = 11 VOICE = dialogue.voice.GREEK COMBAT_AI = aibrain.BruiserAI() TREASURE = treasuretype.Low() ATTACK = items.Attack( (2,10,0), element = stats.RESIST_PIERCING ) 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 ), effects.TargetIs( effects.ALIVE, on_true=( effects.OpposedRoll( att_stat=None, def_stat=stats.TOUGHNESS, on_success = ( effects.Enchant( enchantments.PoisonClassic ) ,) ), )) ), on_failure = ( effects.HealthDamage( (2,6,0), stat_bonus=None, element=stats.RESIST_POISON, anim=animobs.PoisonCloud ) ,) ), com_tar=targetarea.Blast(radius=2), ai_tar=invocations.TargetEnemy(min_distance=3), mp_cost=20, shot_anim=animobs.GreenComet ), ) def init_monster( self ): self.levels.append( base.Terror( 10, self ) ) self.condition.append( enchantments.PermaMegaRegeneration() )
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 ) )
def critical_hit_effect( self, roll_mod=0 ): return effects.TargetIs( effects.ANIMAL, on_true=( effects.PercentRoll( roll_skill=stats.CRITICAL_HIT, roll_stat=None, roll_modifier=min(roll_mod*2,0), target_affects=True, on_success=( effects.InstaKill( anim=animobs.CriticalHit ) ,) ) ,) )
class Harpy( base.Monster ): name = "Harpy" statline = { stats.STRENGTH: 10, stats.TOUGHNESS: 10, stats.REFLEXES: 15, \ stats.INTELLIGENCE: 7, stats.PIETY: 12, stats.CHARISMA: 17 } SPRITENAME = "monster_default.png" FRAME = 38 TEMPLATES = () MOVE_POINTS = 8 VOICE = dialogue.voice.GREEK HABITAT = ( context.HAB_EVERY, context.HAB_CAVE, context.SET_EVERY, context.DES_LUNAR, context.MTY_HUMANOID, context.MTY_BOSS, context.GEN_CHAOS ) ENC_LEVEL = 6 TREASURE = treasuretype.Standard() ATTACK = items.Attack( (2,4,0), element = stats.RESIST_SLASHING ) TECHNIQUES = (invocations.MPInvocation( "Sleep Song", effects.TargetIsEnemy( anim=animobs.SonicHit, on_true = ( effects.TargetIs( pat=effects.ANIMAL, on_true = ( effects.OpposedRoll( att_modifier=0, on_success = ( effects.CauseSleep(), )),) ,), )), com_tar=targetarea.SelfCentered(radius=6,delay_from=-1), ai_tar=invocations.TargetMobileEnemy(), mp_cost=8 ), ) def init_monster( self ): self.levels.append( base.Humanoid( 7, self ) )
class SleepySand(Enhancer): NAMEPAT = "Sleepysand {0}" DESCPAT = "{0} They may put the target to sleep." PLUSRANK = 3 AFFECTS = (BULLET, ) ATTACK_ON_HIT = effects.TargetIs( pat=effects.ANIMAL, on_true=(effects.OpposedRoll(att_modifier=50, on_success=(effects.CauseSleep(), )), ))
class BlessedAmmo(Enhancer): NAMEPAT = "Blessed {0}" DESCPAT = "{0} They do extra damage to unholy creatures." PLUSRANK = 2 AFFECTS = (ARROW, BULLET) ATTACK_ON_HIT = effects.TargetIs(effects.UNHOLY, on_true=(effects.HealthDamage( (1, 8, 0), stat_bonus=None, element=stats.RESIST_SOLAR, anim=animobs.YellowExplosion), ))
class Smasher(Enhancer): NAMEPAT = "{1} of Smashing" DESCPAT = "{0} It does extra damage to constructs." PLUSRANK = 1 AFFECTS = (AXE, MACE, STAFF) ATTACK_ON_HIT = effects.TargetIs(effects.CONSTRUCT, on_true=(effects.HealthDamage( (2, 4, 0), stat_bonus=None, element=stats.RESIST_ATOMIC, anim=animobs.EarthBoom), )) TYPE = ET_SECONDARY
class HarvestWeapon(Enhancer): NAMEPAT = "{0} of Harvest" DESCPAT = "{0} It does extra damage to plants." PLUSRANK = 1 AFFECTS = (SWORD, AXE, STAFF, POLEARM, FARMTOOL) ATTACK_ON_HIT = effects.TargetIs(effects.PLANT, on_true=(effects.HealthDamage( (2, 4, 0), stat_bonus=None, element=stats.RESIST_LUNAR, anim=animobs.PurpleExplosion), )) TYPE = ET_SECONDARY
class Blessed(Enhancer): NAMEPAT = "Anointed {0}" DESCPAT = "{0} This weapon does extra damage to unholy creatures." PLUSRANK = 1 AFFECTS = (SWORD, MACE, STAFF, POLEARM, LANCE) ATTACK_ON_HIT = effects.TargetIs(effects.UNHOLY, on_true=(effects.HealthDamage( (1, 6, 0), stat_bonus=None, element=stats.RESIST_SOLAR, anim=animobs.YellowExplosion), )) BONUSES_PER_RANK = stats.StatMod({stats.MAGIC_DEFENSE: 5}) TYPE = ET_SECONDARY
class VenomWand(ManaWeapon): true_name = "Venom Wand" true_desc = "A hit from this wand will poison living creatures." itemtype = WAND MP_COST = 2 avatar_image = "avatar_wand.png" avatar_frame = 10 mass = 5 attackdata = Attack( (1,8,1), skill_mod=stats.REFLEXES, damage_mod=stats.INTELLIGENCE, \ element=stats.RESIST_WATER, reach=7, hit_anim=animobs.GreenCloud, shot_anim = animobs.GreenSpray, extra_effect=effects.TargetIs( effects.ALIVE, on_true=( effects.Enchant( enchantments.PoisonClassic ), ) ) )
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 HolyBow(Enhancer): NAMEPAT = "Holy {0}" DESCPAT = "{0} A hit from this weapon may disrupt unholy creatures." PLUSRANK = 5 AFFECTS = (BOW, SLING) ATTACK_ON_HIT = effects.TargetIs( effects.UNHOLY, on_true=(effects.OpposedRoll( att_stat=stats.PIETY, att_modifier=-10, on_success=(effects.InstaKill(anim=animobs.CriticalHit), ), on_failure=(effects.OpposedRoll( att_modifier=10, on_success=(effects.Paralyze(max_duration=3), ), ), ), ), )) BONUSES_PER_RANK = stats.StatMod({ stats.PHYSICAL_ATTACK: 10, stats.RESIST_LUNAR: 25 }) TYPE = ET_SECONDARY
class HolyWeapon(Enhancer): NAMEPAT = "Holy {0}" DESCPAT = "{0} It does an extra 1d8 holy damage and disrupts unholy creatures." PLUSRANK = 5 AFFECTS = (SWORD, AXE, MACE, DAGGER, STAFF, POLEARM, FARMTOOL, LANCE) ATTACK_ON_HIT = effects.HealthDamage( (1, 8, 0), stat_bonus=None, element=stats.RESIST_SOLAR, anim=animobs.YellowExplosion, on_success=(effects.TargetIs( effects.UNHOLY, on_true=(effects.OpposedRoll( att_stat=stats.PIETY, att_modifier=-20, on_success=(effects.InstaKill(anim=animobs.CriticalHit), ), on_failure=(effects.OpposedRoll(on_success=(effects.Paralyze( max_duration=3), ), ), )), )), )) BONUSES_PER_RANK = stats.StatMod({ stats.PHYSICAL_ATTACK: 5, stats.RESIST_LUNAR: 25 }) TYPE = ET_SECONDARY
gems={AIR: 3}, com_tar=targetarea.Blast(radius=3), shot_anim=animobs.Whirlwind, ai_tar=invocations.TargetEnemy(min_distance=4)) # CIRCLE SIX DISMISSAL = Spell( "Dismissal", "Forces one demon, elemental, or spirit to leave the mortal realm and return to its home plane.", effects.TargetIs( effects.OTHERWORLDLY, anim=animobs.BlueSparkle, on_true=(effects.OpposedRoll( on_success=(effects.InstaKill(anim=animobs.CriticalHit), ), on_failure=(effects.HealthDamage( (3, 12, 0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_SOLAR, anim=animobs.YellowExplosion), )), ), on_false=(effects.NoEffect(anim=animobs.Caption), )), rank=6, gems={AIR: 2}, com_tar=targetarea.SingleTarget(), shot_anim=animobs.MysticBolt) CALL_AIR_ELEMENTAL = Spell( "Call Air Elemental", "This spell will summon a living embodiment of the skies to fight on your behalf.", effects.CallMonster({ context.DES_AIR: True,
rank=2, gems={EARTH: 1}, com_tar=targetarea.SingleTarget(), ai_tar=invocations.TargetAllyWithoutEnchantment( enchantments.BeastlyMightEn)) # CIRCLE 3 SHAPE_FLESH = Spell( "Shape Flesh", "By touching a living creature, you may reshape its flesh so as to either cause or cure 3-18 damage.", effects.TargetIs( effects.ALIVE, on_true=(effects.TargetIsAlly( on_true=(effects.HealthRestore(dice=(3, 6, 0)), ), ), effects.TargetIsEnemy( on_true=(effects.HealthDamage((3, 6, 0), stat_bonus=None, element=stats.RESIST_ATOMIC, anim=animobs.RedBoom), ))), on_false=(effects.NoEffect(anim=animobs.SmallBoom), )), rank=3, gems={EARTH: 2}, com_tar=targetarea.SingleTarget(reach=1), exp_tar=targetarea.SinglePartyMember(), mpfudge=-1) # CIRCLE 4 WOOD_SKIN = Spell( "Wood Skin", "Transforms a single ally, providing +10% to defense plus 25% resistance to slashing, crushing, and piercing damage.",
ai_tar=invocations.TargetEnemy(min_distance=3),shot_anim=animobs.BlueComet ) # CIRCLE SEVEN SUMMONING = Spell( "Summoning", "This spell opens a portal to the nether realms and calls forth a powerful creature for you to command.", effects.CallMonster( {(context.MTY_UNDEAD,context.MTY_DEMON): True, context.DES_LUNAR: context.MAYBE, context.GEN_UNDEAD: context.MAYBE}, 14, anim=animobs.PurpleSparkle ), rank=7, gems={EARTH:2,LUNAR:3}, com_tar=targetarea.SingleTarget(reach=3), ai_tar=invocations.TargetEmptySpot(), mpfudge=13 ) DEEP_DROWNING = Spell( "Deep Drowning", "Conjures a turbulent water vortex in a small area. Enemies trapped inside take 4d12 water damage and may drown.", effects.HealthDamage( (4,12,0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_WATER, anim=animobs.Bubbles, on_success=( effects.TargetIs( effects.CAN_DROWN, on_true=( effects.OpposedRoll( def_stat=stats.TOUGHNESS, on_success = ( effects.InstaKill( anim=animobs.CriticalHit ), )), )) ,) ), rank=7, gems={LUNAR:2,WATER:2}, com_tar=targetarea.Blast(radius=1), ai_tar=invocations.TargetEnemy(min_distance=2),shot_anim=animobs.CrystalBall ) # CIRCLE EIGHT # CIRCLE NINE GREATER_SUMMONING = Spell( "Greater Summoning", "This spell opens a portal to the nether realms and calls forth a diabolical creature to do your bidding.", effects.CallMonster( {(context.MTY_UNDEAD,context.MTY_DEMON): True, context.DES_LUNAR: context.MAYBE, context.GEN_UNDEAD: context.MAYBE}, 18, anim=animobs.PurpleSparkle ), rank=9, gems={EARTH:3,LUNAR:3}, com_tar=targetarea.SingleTarget(reach=3), ai_tar=invocations.TargetEmptySpot(), mpfudge=17 )
def_stat=stats.REFLEXES, on_success=( effects.HealthDamage( (1, 6, 0), stat_bonus=None, element=stats.RESIST_FIRE, anim=animobs.RedCloud), effects.Enchant(enchantments.BurnLowEn), )) POISON_ATTACK = effects.TargetIs( effects.ALIVE, on_true=(effects.OpposedRoll( att_stat=None, def_stat=stats.TOUGHNESS, on_success=( effects.HealthDamage((1, 4, 0), stat_bonus=None, element=stats.RESIST_POISON, anim=animobs.PoisonCloud), effects.Enchant(enchantments.PoisonClassic), )), )) POISON_ATTACK_1d8 = effects.TargetIs( effects.ALIVE, on_true=(effects.OpposedRoll( att_stat=None, def_stat=stats.TOUGHNESS, on_success=( effects.HealthDamage((1, 8, 0), stat_bonus=None, element=stats.RESIST_POISON,
,) ), 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.", effects.ManaDamage((4,4,0), stat_bonus=stats.INTELLIGENCE, anim=animobs.PurpleExplosion ), rank=2, gems={LUNAR:1}, com_tar=targetarea.SingleTarget(), shot_anim=animobs.PurpleVortex, ai_tar=invocations.TargetEnemy(), mpfudge=-1 ) # CIRCLE 3 WITHER = Spell( "Wither", "Conjures a sphere of negative energy, draining a single target for 2d10 dark damage and 1d6 points of strength.", effects.OpposedRoll( on_success = (
self.confusion = 0 self.asleep = False self.silent = False self.aoo_readied = False self.attacks_so_far = 0 def can_act( self ): return self.paralysis < 1 and not self.asleep # This is a complex effect- Check if target is undead. If so, first apply an # enchantment. Then, make skill roll to cause 20-120 solar damage and paralysis. # If that skill roll fails, make an easier skill roll to just cause paralysis. HOLY_SIGN_EFFECT = effects.TargetIs( effects.UNDEAD, on_true = ( \ effects.Enchant(enchantments.HolySignMark,anim=animobs.YellowSparkle,children=( \ effects.OpposedRoll(stats.HOLY_SIGN, stats.CHARISMA, -70, stats.MAGIC_DEFENSE, stats.PIETY, on_success = ( effects.HealthDamage( (20,6,0), stats.PIETY, element=stats.RESIST_SOLAR, anim=animobs.YellowExplosion, on_success= (effects.Paralyze(max_duration=6),) ) ,), on_failure = ( effects.OpposedRoll(stats.HOLY_SIGN, stats.CHARISMA, 5, stats.MAGIC_DEFENSE, stats.PIETY, on_success = ( effects.Paralyze(max_duration=8) # Is there an obfuscated Python competition? ,)),)),)),)) class Combat( object ): def __init__( self, camp, monster_zero ): self.active = [] self.scene = camp.scene self.camp = camp self.ap_spent = collections.defaultdict( int ) self.cstat = collections.defaultdict( CombatStat ) self.no_quit = True self.activate_monster( monster_zero )
rank=1, gems={ SOLAR: 1, AIR: 1 }, com_tar=targetarea.SelfOnly(), ai_tar=invocations.TargetWoundedAlly(), mpfudge=-2) 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(