def calc_initiative(self): pc_initiative = [(pc, d20() + pc.saves['DEX']) for pc in self.pcs] enemies_initiative = [(enemy, d20() + enemy.saves['DEX']) for enemy in self.enemies] self.battle_order = [ (t[0], 0 if t[0] in self.pcs else 1) for t in sorted(pc_initiative + enemies_initiative, key=lambda x: x[1], reverse=True) ]
def on_turn_start(self, creature): save_attempt = d20() + creature.saves[self.save_stat] if save_attempt >= self.save_dc: self.logger.log_action("{0} saved from {1}".format( creature.name, self.name)) return False return True
def attempt_to_break_free(self, creature): save_attempt = d20() + creature.saves[self.save_stat] if save_attempt >= self.save_dc: self.logger.log_action("{0} broke free from {1}".format( creature.name, self.name)) return False return True
def apply(self, creature): save_attempt = d20() + creature.saves[self.save_stat] if save_attempt >= self.save_dc: self.logger.log_action("{0} saved from {1}".format( creature.name, self.name)) return else: creature.applied_effects.append(self)
def do_damage(self, attacker, target): save_check = d20() + target.saves[self.save_stat] damage = calc_roll(self.dice) if save_check > self.save_dc: damage = ceil(damage / 2.0) target.take_damage(damage, self.damage_type) self.log_attack(attacker, target, damage)
def calc_attack_roll(attacker, target): """ Rolls a d20 and checks for advantage and disadvantage Args: attacker (Combatant): A Combatant target (Combatant): A Combatant Returns: (int): The resulting attack roll with advantage and disadvantage calculated in """ has_advantage = attacker.check_for_advantage(target) has_disadvantage = attacker.check_for_disadvantage(target) if has_advantage and not has_disadvantage: return max(d20(), d20()) elif has_disadvantage and not has_advantage: return min(d20(), d20()) else: return d20()
def on_turn_end(self, creature): if self.turns_left <= 0: return False save_attempt = d20() + creature.saves[self.save_stat] if save_attempt >= self.save_dc: self.logger.log_action("{0} saved from {1}".format( creature.name, self.name)) return False else: self.logger.log_action("{0} failed to save from {1}".format( creature.name, self.name)) return True
def do_damage(self, attacker, target): damage = 0 if self.stat_bonus is not None: attack_bonus = attacker.proficiency + \ attacker.saves[self.stat_bonus] if self.stat_bonus else 0 die_roll = calc_attack_roll(attacker, target) hit_check = die_roll + attack_bonus + self.bonus_to_hit if hit_check >= attacker.ac or die_roll == 20: roll_damage = calc_roll(self.dice) if die_roll == 20: roll_damage *= 2 damage = roll_damage + self.bonus_to_damage else: save_check = d20() + target.saves[self.save_stat] if save_check <= self.save_dc: damage = calc_roll(self.dice) + self.bonus_to_damage target.take_damage(damage, self.damage_type) self.log_attack(attacker, target, damage)