import math import copy import random import arcade import gamestate from battle import Combatant, Action, Damage, StatusChange from menu import MenuItem from text import TextRenderer import assets import battle_data enemies = [] party_members = [] enemy_turn = None battle_music = None enemy_ai_data = {} party_menus = [] spells = [] inventory = [] action_queue = [] cur_action = None action_timer = 0 party_text = TextRenderer(3, 206, 210) ene_text = TextRenderer(123, 206, 210) menu_text = TextRenderer(3, 76, 210) action_text = TextRenderer(110, 215, 210) menu_open = 0 menu_queue = [] menu = [] battle_id = 0 def switch(game): global enemies, party_members, battle_music, enemy_turn, enemy_ai_data, party_menus, spells, inventory enemies = copy.deepcopy(battle_data.battles[battle_id]["enemies"]) party_members = copy.deepcopy(battle_data.battles[battle_id]["party_members"]) enemy_turn = copy.deepcopy(battle_data.battles[battle_id]["enemy_turn_func"]) enemy_ai_data = copy.deepcopy(battle_data.battles[battle_id]["init_ai_data"]) party_menus = copy.deepcopy(battle_data.battles[battle_id]["menus"]) spells = copy.deepcopy(battle_data.battles[battle_id]["spells"]) inventory = copy.deepcopy(battle_data.battles[battle_id]["inventory"]) battle_music = assets.sounds[battle_data.battles[battle_id]["mus_id"]].play(loops=True) close_menu() def close_menu(): global menu, menu_open menu = [] menu_open = 0 menu_text.reset("") # !!! CHATGPT !!! def open_spell_menu(user, aparty, eparty): global menu party_idx = party_members.index(user) spell_list = spells[party_idx] menu = [] for i, spell in enumerate(spell_list): menu.append( MenuItem( spell[0], 19, 64 - (i * 13), None, None, None, None, spell_action, (user, spell, aparty, eparty), open_menu ) ) if len(menu) == 0: return for i, m in enumerate(menu): m.up = menu[(i - 1) % len(menu)] m.down = menu[(i + 1) % len(menu)] menu[0].select() def spell_action(data): user, spell, aparty, eparty = data name, mp_cost, (action_name, func, target_type) = spell open_target_menu( user, aparty, eparty, target_type, lambda targets: action_queue.append(func(user, targets[0])), lambda *a: open_spell_menu(user, aparty, eparty)) def open_item_menu(user, aparty, eparty): global menu menu = [] for i, item in enumerate(inventory): if item[1] <= 0: continue menu.append( MenuItem( f"{item[0]} x{item[1]}", 19, 64 - (i * 13), None, None, None, None, item_action, (user, item, aparty, eparty), open_menu ) ) if len(menu) == 0: return for i, m in enumerate(menu): m.up = menu[(i - 1) % len(menu)] m.down = menu[(i + 1) % len(menu)] menu[0].select() def item_action(data): user, item, aparty, eparty = data name, amount, (action_name, func, target_type) = item def use(targets): action_queue.append(func(user, targets[0])) item[1] -= 1 open_target_menu(user, aparty, eparty, target_type, use, lambda *a: open_item_menu(user, aparty, eparty)) def open_target_menu(user, aparty, eparty, target_type, on_pick, back): """ target_type: "enemy", "ally", "self", "all_enemies", "all_allies" on_pick: called with a LIST of targets back: called when the player cancels (reopens the previous menu) """ global menu # No selection needed if target_type == None: on_pick([user]); close_menu(); return pool = eparty if target_type else aparty candidates = [c for c in pool if not c.ko] # drop the `not c.ko` for revive items if not candidates: return menu = [] for i, c in enumerate(candidates): menu.append(MenuItem( c.name, 19, 64 - (i * 13), None, None, None, None, target_picked, (c, on_pick), back )) for i, m in enumerate(menu): m.up = menu[(i - 1) % len(menu)] m.down = menu[(i + 1) % len(menu)] menu[0].select() def target_picked(data): target, on_pick = data on_pick([target]) close_menu() def open_menu(data): global menu whose, junk, aparty, eparty = data menu = [] party_idx = party_members.index(whose) for i, m in enumerate(party_menus[party_idx]): menu.append(MenuItem(m[0], 19, 64-(i*13), None, None, None, None, menu_action, (whose, aparty, eparty, m[1]))) for i, m in enumerate(menu): m.up = menu[(i - 1) % len(menu)] m.down = menu[(i + 1) % len(menu)] menu[0].select() def menu_action(data): user, aparty, eparty, action = data match action: case "unselectable": return case "phys_att": def queue_attack(targets): action_queue.append(Action( "Támadás", user, targets[0], Damage(166, 0, 0, 0), StatusChange(0, 0, 0), battle_data.anim_default)) open_target_menu(user, aparty, eparty, "enemy", queue_attack, lambda *a: open_menu((user, 0, aparty, eparty))) case "magic": open_spell_menu(user, aparty, eparty) case "items": open_item_menu(user, aparty, eparty) case _: print(f"Unknown action: {action}") close_menu() # !!! CHATGPT VÉGE !!! def update(game, dt): global menu_open, cur_action, action_timer for e in enemies: if e.ko or e.stone: continue e.atb -= 1 if e.atb <= 0: act = enemy_turn(e, enemies, party_members, enemy_ai_data) if act: action_queue.append(act) e.atb = math.inf 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 act!") menu_queue.append(p) p.atb = math.inf if len(action_queue) != 0 and cur_action == None: action = action_queue.pop(0) print(f"Executing: {action}") cur_action = action action_timer = 0 if cur_action != None: if cur_action.animation(cur_action, action_text, action_timer, dt): cur_action = None else: action_timer += dt # Szövegek Frissítése partytext = "" enetext = "" for m in party_members: partytext += f"=={m.name}==\nHP: {m.hp}\n" for e in enemies: enetext += f"=={e.name}==\nHP: {e.hp}\n" if len(menu_queue) != 0 and menu_open == 0: whose = menu_queue.pop(0) menu_open = whose menu_text.reset(f"{whose.name} menüje") menu_text.type_all() open_menu((whose, 67, party_members, enemies)) for m in menu: m.update() if len(enemies) != 0 and all(e.ko for e in enemies): print("\nVICTORY! all enemies were defeated.") battle_music.stop() gamestate.switch_gamestate(game,"overworld") return if len(party_members) != 0 and all(a.ko for a in party_members): print("\nGAME OVER! the party was defeated.") battle_music.stop() gamestate.switch_gamestate(game,"gameover") return party_text.reset(partytext) ene_text.reset(enetext) party_text.type_all() ene_text.type_all() def draw(game): for m in menu: m.render() party_text.render() ene_text.render() menu_text.render() action_text.render()