import math K_NORMAL = 100 K_DEFUP = 50 MIN_DMG = 1 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 = 1000/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): self.name = name self.who = who self.where = where self.damage = damage self.status = status 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): 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: 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!") elif delta_hp < 0: print(f" -> {target.name} suffered {-delta_hp} damage!") 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!") enemies = [ Combatant("Six-Seven kid", 100, 100, 100, 100, 100, 100, False, False) ] party_members = [ Combatant("Terra", 100, 100, 100, 100, 100, 100, False, False), Combatant("Locke", 100, 100, 100, 100, 100, 100, False, False), Combatant("Celes", 100, 100, 100, 100, 100, 100, False, False), Combatant("Cyan", 100, 100, 100, 100, 100, 100, False, False) ] tick_counter = 0 action_queue = [] while True: print(f"Tick #{tick_counter}!") for e in enemies: if e.ko or e.stone: continue e.atb -= 1 if e.atb == 0: action_queue.append(Action("Physical Attack", e, party_members[0], Damage(25,0,0,0), StatusChange(0, 0, 0))) for p in party_members: if p.ko or p.stone: continue p.atb -= 1 if p.atb == 0: print(f"{p.name} is ready to attack with {p.hp} health!") should_loop = True while should_loop: print(f"Action(attack / heal / defend): ", end="") act = input() if act == "attack": action_queue.append(Action("Physical Attack", p, enemies[0], Damage(25,0,0,0), StatusChange(0, 0, 0))) should_loop = False elif act == "heal": action_queue.append(Action("Cure", p, p, Damage(0,0,0,42), StatusChange(0, 0, 0))) should_loop = False elif act == "defend": action_queue.append(Action("Defend", p, p, Damage(0,0,0,0), StatusChange(0, 0, 1))) should_loop = False else: print("Idk what you mean I told you attack and heal and defend are the only valid options bruh") if len(action_queue) != 0: action = action_queue.pop(0) print(f"Executing: {action}") action.execute() if all(e.ko for e in enemies): print("\nVICTORY! all enemies were defeated.") break if all(p.ko for p in party_members): print("\nGAME OVER! the party was defeated.") break tick_counter += 1