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 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 ) )
def get_effect(self, user, att_modifier=0, target=None): """Generate an effect tree for this attack.""" dmg = list(self.damage) dmg[2] += user.get_stat(stats.WEAPON_DAMAGE_BONUS) hit = effects.HealthDamage(att_dice=dmg, stat_bonus=self.damage_mod, element=self.element, anim=self.hit_anim) if self.double_handed: hit.stat_mod = 1.5 miss = effects.NoEffect(anim=animobs.SmallBoom) roll = effects.PhysicalAttackRoll(att_stat=self.skill_mod, att_modifier=att_modifier, on_success=[ hit, ], on_failure=[ miss, ]) if self.extra_effect: roll.on_success.append(self.extra_effect) # If the attacker has critical hit skill, use it. if user.get_stat(stats.CRITICAL_HIT) > 0: hit.on_success.append(user.critical_hit_effect(att_modifier)) return roll
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 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 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 ) )
def unarmed_attack_effect(self, roll_mod=0): """Return the attackdata for this character's unarmed strikes.""" kungfu = self.get_stat(stats.KUNG_FU) // 5 dbonus = 0 if kungfu > 20: dbonus = kungfu - 20 kungfu = 20 dice = (self.KUNG_FU_DAMAGE[kungfu][0], self.KUNG_FU_DAMAGE[kungfu][1], dbonus) hit = effects.HealthDamage(att_dice=dice, stat_bonus=stats.STRENGTH, element=stats.RESIST_CRUSHING, anim=animobs.RedBoom) miss = effects.NoEffect(anim=animobs.SmallBoom) roll = effects.PhysicalAttackRoll(att_stat=stats.STRENGTH, att_modifier=roll_mod, on_success=[ hit, ], on_failure=[ miss, ]) if self.KUNG_FU_DAMAGE[kungfu][2] > 0: dice = (self.KUNG_FU_DAMAGE[kungfu][2], self.KUNG_FU_DAMAGE[kungfu][3], dbonus) hit2 = effects.HealthDamage(att_dice=dice, stat_bonus=stats.PIETY, element=stats.RESIST_SOLAR, anim=animobs.YellowExplosion) hit.on_success.append(hit2) hit.on_failure.append(hit2) # If the attacker has critical hit skill, use it. if self.get_stat(stats.CRITICAL_HIT) > 0: hit.on_success.append(self.critical_hit_effect(roll_mod)) return roll
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))
import invocations import effects import stats import animobs 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,
class CentaurHero(base.Monster): name = "Centaur Hero" statline = { stats.STRENGTH: 18, stats.TOUGHNESS: 18, stats.REFLEXES: 16, \ stats.INTELLIGENCE: 13, stats.PIETY: 15, stats.CHARISMA: 13 } SPRITENAME = "monster_chaos.png" FRAME = 23 TEMPLATES = () MOVE_POINTS = 10 VOICE = dialogue.voice.GREEK HABITAT = (context.HAB_EVERY, context.SET_EVERY, context.MAP_WILDERNESS, context.DES_SOLAR, context.MTY_HUMANOID, context.MTY_FIGHTER, context.MTY_LEADER, context.MTY_BOSS, context.GEN_CHAOS) ENC_LEVEL = 11 TREASURE = treasuretype.Standard((items.ARROW, items.POLEARM, items.BOW)) COMBAT_AI = aibrain.ArcherAI() LONER = True COMPANIONS = (CentaurKnight, CentaurChampion) ATTACK = items.Attack((2, 6, 0), element=stats.RESIST_SLASHING, extra_effect=effects.OpposedRoll( att_stat=None, def_stat=stats.TOUGHNESS, on_success=( effects.HealthDamage( (1, 6, 0), stat_bonus=None, element=stats.RESIST_POISON, anim=animobs.PoisonCloud), effects.Enchant(enchantments.PoisonClassic), ))) TECHNIQUES = (invocations.Invocation( "Arrow 23", effects.PhysicalAttackRoll( att_stat=stats.REFLEXES, on_success=( effects.HealthDamage((2, 8, 0), stat_bonus=stats.STRENGTH, element=stats.RESIST_PIERCING, anim=animobs.RedBoom), 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), )), ), on_failure=(effects.HealthDamage((1, 8, 0), stat_bonus=None, element=stats.RESIST_PIERCING, anim=animobs.RedBoom), )), com_tar=targetarea.SingleTarget(reach=9), shot_anim=animobs.Arrow, ai_tar=invocations.TargetEnemy()), spells.solarspells.MAJOR_CURE, spells.solarspells.CURE_POISON) def init_monster(self): self.levels.append(base.Leader(15, self))