Files
rrttm/src/gamestates/battle.py
markojozsef 0fd7e99b08 Menü bugfix
2026-10-11 16:28:01 +02:00

310 lines
7.8 KiB
Python

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()