import math K_NORMAL = 100 K_DEFUP = 50 MIN_DMG = 1 BASE_DELAY = 30000 class Combatant: def __init__(self, name, maxhp, attack, speed, def_phys, def_fire, def_ice, abs_fire, abs_ice): self.name = name self.max_atb = BASE_DELAY//speed self.atb = self.max_atb self.maxhp = maxhp self.hp = maxhp self.attack = attack self.ko = False self.stone = False self.def_up = False self.def_phys = def_phys self.def_fire = def_fire self.def_ice = def_ice self.abs_fire = abs_fire self.abs_ice = abs_ice # POTENTIAL damage before defense effects class Damage: def __init__(self, phys, fire, ice, healing): self.phys= phys self.fire= fire self.ice= ice self.healing = healing # 0 = keep, 1 = inflict, 2 = remove class StatusChange: def __init__(self, ko, stone, def_up): self.ko = ko self.stone = stone self.def_up = def_up # where = reference to the target, who = reference to the inflictor class Action: def __init__(self, name, who, where, damage, status, animation): self.name = name self.who = who self.where = where self.damage = damage self.status = status self.animation = animation def __str__(self): return ( f"[{self.name}] {self.who.name} -> {self.where.name} " f"(HP influence: ({self.damage.phys},{self.damage.fire},{self.damage.ice},{self.damage.healing}), Status: {self.status.ko}-{self.status.stone}-{self.status.def_up})" ) def __repr__(self): return self.__str__() def execute(self, damage_callback): target = self.where if self.who.ko or self.who.stone: print(f" -> {self.who.name} cannot move!") return self.who.atb = self.who.max_atb if target.ko and self.status.ko != 2: print(f" -> {target.name} is KO'd, move cancelled!") return K = K_DEFUP if target.def_up else K_NORMAL delta_hp = self.damage.healing if self.damage.phys: delta_hp += -max(MIN_DMG, self.damage.phys * (K / (K + target.def_phys))) if self.damage.fire: delta_hp += self.damage.fire if target.abs_fire else -max(MIN_DMG, self.damage.fire * (K / (K + target.def_fire))) if self.damage.ice: delta_hp += self.damage.ice if target.abs_ice else -max(MIN_DMG, self.damage.ice * (K / (K + target.def_ice ))) if self.status.ko == 1: delta_hp = -target.hp elif self.status.ko == 2 and target.ko: target.ko = False print(f" -> {target.name}'s consciousness returned!") delta_hp = round(delta_hp) if delta_hp > 0: print(f" -> {target.name} got healed for {delta_hp} HP!") damage_callback(delta_hp, target) elif delta_hp < 0: print(f" -> {target.name} suffered {-delta_hp} damage!") damage_callback(delta_hp, target) target.hp = max(0, min(target.maxhp, target.hp + delta_hp)) if self.status.stone == 1 and not target.stone: target.stone = True print(f" -> {target.name}'s body petrified!") elif self.status.stone == 2 and target.stone: target.stone = False print(f" -> {target.name}'s body softened back up!") if self.status.def_up == 1 and not target.def_up: target.def_up = True print(f" -> {target.name}'s defense was boosted!") elif self.status.def_up == 2 and target.def_up: target.def_up = False print(f" -> {target.name}'s defense returned to normal!") if target.hp == 0: target.ko = True target.stone = False target.def_up = False print(f" -> {target.name} got hurt and collapsed!")