class InterceptRoll(object): def __init__(self, weapon_to_intercept): self.weapon_to_intercept = weapon_to_intercept def make_roll(self, atroller, attacker, defender, att_bonus, att_roll, fx_record): # First, locate the defender's interceptor. interceptor = self.get_interceptor(defender) if interceptor: def_roll = random.randint(1, 100) def_bonus = interceptor.get_intercept_bonus( ) + defender.get_skill_score(stats.Speed, interceptor.scale.RANGED_SKILL) if def_roll > 95: # A roll greater than 95 always defends. interceptor.pay_for_intercept(defender, self.weapon_to_intercept) return (self.CHILDREN, def_roll + def_bonus) elif def_roll <= 5: # A roll of 5 or less always fails. return (None, def_roll + def_bonus) elif (att_roll + att_bonus + atroller.accuracy) > (def_roll + def_bonus): return (None, def_roll + def_bonus) else: interceptor.pay_for_intercept(defender, self.weapon_to_intercept) return (self.CHILDREN, def_roll + def_bonus) else: return (None, 0) def get_interceptor(self, defender): interceptors = [ part for part in defender.descendants() if hasattr(part, 'can_intercept') and part.can_intercept() and part.is_operational() ] if interceptors: return max(interceptors, key=lambda s: s.get_intercept_bonus()) def can_attempt(self, attacker, defender): return self.get_interceptor(defender) and ( defender.get_current_stamina() > 0) def get_odds(self, atroller, attacker, defender, att_bonus): # Return the odds as a float. interceptor = self.get_interceptor(defender) if interceptor: def_target = interceptor.get_intercept_bonus( ) + defender.get_skill_score(stats.Speed, interceptor.scale.RANGED_SKILL) # The chance to hit is clamped between 5% and 95%. percent = min( max(50 + (att_bonus + atroller.accuracy) - def_target, 5), 95) return float(percent) / 100 else: return 1.0 CHILDREN = (effects.NoEffect(anim=InterceptAnim), )
class DodgeRoll(object): def make_roll(self, atroller, attacker, defender, att_bonus, att_roll, fx_record): # If the attack roll + attack bonus + accuracy is higher than the # defender's defense bonus + maneuverability + 20, or if the attack roll # is greater than 95, the attack hits. def_target = defender.get_dodge_score() + 50 if att_roll > 95: # A roll greater than 95 always hits. return (None, def_target) elif att_roll <= 5: # A roll of 5 or less always misses. return (self.CHILDREN, def_target) elif (att_roll + att_bonus + atroller.accuracy) > (def_target + defender.calc_mobility()): return (None, def_target) else: return (self.CHILDREN, def_target) def can_attempt(self, attacker, defender): return True def get_odds(self, atroller, attacker, defender, att_bonus): # Return the odds as a float. def_target = defender.get_dodge_score() # The chance to hit is clamped between 5% and 95%. percent = min( max( 50 + (att_bonus + atroller.accuracy) - (def_target + defender.calc_mobility()), 5), 95) return float(percent) / 100 CHILDREN = (effects.NoEffect(anim=MissAnim), )
def _fail_fx(info): # On failing, do another skill roll. # If they fail again, trigger a negaive effect. return geffects.SkillRoll( info.att_stat, info.att_skill, on_success=[effects.NoEffect(anim=geffects.FailAnim)], on_failure=[_negative_fx(info)])
class BlockRoll(object): def __init__(self, weapon_to_block): self.weapon_to_block = weapon_to_block def make_roll(self, atroller, attacker, defender, att_bonus, att_roll, fx_record): # First, locate the defender's shield. shield = self.get_shield(defender) if shield: def_roll = random.randint(1, 100) def_bonus = shield.get_block_bonus() + defender.get_skill_score( stats.Speed, shield.scale.MELEE_SKILL) if def_roll > 95: # A roll greater than 95 always defends. shield.pay_for_block(defender, self.weapon_to_block) return (self.CHILDREN, def_roll + def_bonus) elif def_roll <= 5: # A roll of 5 or less always fails. return (None, def_roll + def_bonus) elif (att_roll + att_bonus + atroller.accuracy) > (def_roll + def_bonus): return (None, def_roll + def_bonus) else: shield.pay_for_block(defender, self.weapon_to_block) return (self.CHILDREN, def_roll + def_bonus) else: return (None, 0) def get_shield(self, defender): shields = [ part for part in defender.descendants() if hasattr(part, 'get_block_bonus') and part.is_operational() ] if shields: return max(shields, key=lambda s: s.get_block_bonus()) def can_attempt(self, attacker, defender): return self.get_shield(defender) and (defender.get_current_stamina() > 0) def get_odds(self, atroller, attacker, defender, att_bonus): # Return the odds as a float. shield = self.get_shield(defender) if shield: def_target = shield.get_block_bonus() + defender.get_skill_score( stats.Speed, shield.scale.MELEE_SKILL) # The chance to hit is clamped between 5% and 95%. percent = min( max( 50 + (att_bonus + atroller.accuracy) - (def_target + defender.calc_mobility()), 5), 95) return float(percent) / 100 else: return 1.0 CHILDREN = (effects.NoEffect(anim=BlockAnim), )
def _affect_allies(fx, enemy_anim=None): """Give an effect that only affects allies""" if enemy_anim: on_failure = [ geffects.CheckConditions( [ aitargeters.TargetIsOperational(), aitargeters.TargetIsEnemy() ], on_success=[effects.NoEffect(anim=enemy_anim)]) ] else: on_failure = [] return geffects.CheckConditions( [aitargeters.TargetIsOperational(), aitargeters.TargetIsAlly()], on_success=[fx], on_failure=on_failure)
def _double_skill_roll(info, fx, roll_mod=35, min_chance=25): """Do an opposed skill roll, if it fails do another skill roll.""" return geffects.OpposedSkillRoll( info.att_stat, info.att_skill, info.def_stat, info.def_skill, roll_mod=roll_mod, min_chance=min_chance, on_success=[fx], on_failure=[ geffects.OpposedSkillRoll( info.att_stat, info.att_skill, info.def_stat, info.def_skill, roll_mod=25, min_chance=25, on_success=[fx], on_failure=[effects.NoEffect(anim=geffects.ResistAnim)]) ])
def __init__(self, fx): wrapfx = effects.NoEffect(anim=geffects.MusicAnim, children=[fx]) super().__init__(wrapfx)
def _get_fx(self, info): children = [ geffects.DoEncourage(info.att_stat, info.att_skill), geffects.DispelEnchantments(enchantments.ON_DISPEL_NEGATIVE) ] return effects.NoEffect(children=children, anim=geffects.OverloadAnim)
def __init__(self): fx = geffects.CheckConditions( [aitargeters.TargetIsOperational()], on_success=[effects.NoEffect(anim=geffects.HeckleAnim)]) wrapfx = effects.NoEffect(anim=geffects.BadMusicAnim, children=[fx]) super().__init__(wrapfx)