This commit is contained in:
team3
2026-09-16 13:21:45 +02:00
parent 8a188c5d5c
commit 49e8f2d95e
27 changed files with 1772 additions and 265 deletions

View File

@@ -16,6 +16,9 @@ var level: int = Data.START_LEVEL
var xp: int = 0
var shop_locked: bool = false ## eingefrorener Shop bleibt über die Runde
var last_element: int = -1 ## zuletzt gewählte Spezialisierung für Schnellkauf
var last_sale: Dictionary = {} ## letzter Verkauf, für Rückgängig
## Statistik für den Endbildschirm.
var stats := {"wins": 0, "losses": 0, "gold_earned": 0, "spent": 0, "max_star": 1}
var bench: Array = [] ## Avatar oder null
var board: Dictionary = {} ## Vector2i -> Avatar
@@ -111,6 +114,7 @@ func buy(index: int, pool: Pool, chosen_element: int = -1) -> bool:
if not pool.take(element):
return false
gold -= entry.price()
stats["spent"] += entry.price()
bench[slot] = entry.to_avatar(element)
entry.sold = true
if entry.element < 0:
@@ -123,8 +127,39 @@ func sell_bench(index: int, pool: Pool) -> bool:
return false
var a: Avatar = bench[index]
pool.return_avatar(a)
gold += maxi(1, a.invested)
var refund := maxi(1, a.invested)
gold += refund
bench[index] = null
last_sale = {"avatar": a, "refund": refund, "index": index}
return true
## Macht den letzten Bankverkauf rückgängig, solange Gold und Platz da sind.
func undo_sell(pool: Pool) -> bool:
if last_sale.is_empty():
return false
var a: Avatar = last_sale["avatar"]
var refund: int = last_sale["refund"]
if gold < refund:
return false
var idx: int = last_sale["index"]
if bench[idx] != null:
idx = free_bench_slot()
if idx < 0:
return false
# Bausteine wieder aus dem Vorrat nehmen; ist er leer, geht es nicht.
if not pool.take(a.elements[0]):
return false
if a.star >= 2:
for i in 2:
pool.take(a.elements[0])
if a.star >= 3:
for e in a.elements:
for i in 3:
pool.take(e)
gold -= refund
bench[idx] = a
last_sale = {}
return true
@@ -338,6 +373,7 @@ func upgrade(hex: Vector2i, new_element: int, pool: Pool) -> bool:
a.star += 1
a.elements.append(new_element)
unlock(new_element)
stats["max_star"] = maxi(stats["max_star"], a.star)
return true
@@ -377,8 +413,10 @@ func register_result(won: bool) -> void:
last_won = won
if won:
streak = maxi(1, streak + 1)
stats["wins"] += 1
else:
streak = mini(-1, streak - 1)
stats["losses"] += 1
## Nur Leben abziehen. Das Ausscheiden setzt Game._check_eliminations,
@@ -392,3 +430,63 @@ func board_units() -> Array:
for hex in board:
out.append(board[hex])
return out
# --- Speichern -------------------------------------------------------------
static func _avatar_to_dict(a: Avatar) -> Dictionary:
return {"role": a.role, "elements": Array(a.elements), "star": a.star, "invested": a.invested}
static func _avatar_from_dict(d: Dictionary) -> Avatar:
var els: Array[int] = []
for e in d["elements"]:
els.append(int(e))
var a := Avatar.new(int(d["role"]), els, int(d["star"]))
a.invested = int(d["invested"])
return a
func to_dict() -> Dictionary:
var b := []
for a in bench:
b.append(null if a == null else _avatar_to_dict(a))
var brd := []
for hex in board:
brd.append({"x": hex.x, "y": hex.y, "a": _avatar_to_dict(board[hex])})
var sh := []
for e in shop:
sh.append({"role": e.role, "element": e.element, "sold": e.sold})
return {
"pid": pid, "pname": pname, "is_bot": is_bot, "gold": gold, "hp": hp, "streak": streak,
"alive": alive, "last_won": last_won, "placement": placement, "level": level, "xp": xp,
"shop_locked": shop_locked, "last_element": last_element, "unlocked": Array(unlocked),
"bench": b, "board": brd, "shop": sh, "stats": stats.duplicate(),
}
static func from_dict(d: Dictionary) -> PlayerState:
var p := PlayerState.new(int(d["pid"]), d["pname"], d["is_bot"])
p.gold = int(d["gold"])
p.hp = int(d["hp"])
p.streak = int(d["streak"])
p.alive = d["alive"]
p.last_won = d["last_won"]
p.placement = int(d["placement"])
p.level = int(d["level"])
p.xp = int(d["xp"])
p.shop_locked = d["shop_locked"]
p.last_element = int(d["last_element"])
for i in mini(p.unlocked.size(), d["unlocked"].size()):
p.unlocked[i] = d["unlocked"][i]
for i in mini(p.bench.size(), d["bench"].size()):
p.bench[i] = null if d["bench"][i] == null else _avatar_from_dict(d["bench"][i])
for entry in d["board"]:
p.board[Vector2i(int(entry["x"]), int(entry["y"]))] = _avatar_from_dict(entry["a"])
for entry in d["shop"]:
var se := ShopEntry.new(int(entry["role"]), int(entry["element"]))
se.sold = entry["sold"]
p.shop.append(se)
for k in d["stats"]:
p.stats[k] = int(d["stats"][k])
return p