12var opponent_card := {}
15var player_turn := true
22func battle(player_card:Dictionary, opponent_card:Dictionary, reward:int = 100) -> Dictionary:
23 if player_card.is_empty()
or opponent_card.is_empty():
24 return {
"winner":
"none",
"log": [
"No battle could be started."],
"reward": 0}
26 var player = player_card.duplicate(true)
27 var opponent = opponent_card.duplicate(true)
28 var player_hp =
int(player.get(
"health", 1))
29 var opponent_hp =
int(opponent.get(
"health", 1))
30 var player_turn = randi_range(0, 1) == 0
32 "%s faces %s." % [player.get(
"name",
"Player"), opponent.get(
"name",
"Opponent")]
35 while player_hp > 0
and opponent_hp > 0:
37 var damage = _roll_damage(player, opponent)
39 log.append(
"%s hits for %d." % [player.get(
"name",
"Player"), damage])
41 var damage = _roll_damage(opponent, player)
43 log.append(
"%s hits for %d." % [opponent.get(
"name",
"Opponent"), damage])
44 player_turn =
not player_turn
46 var player_won = player_hp > 0
47 log.append(
"%s wins." % [player.get(
"name",
"Player")
if player_won
else opponent.get(
"name",
"Opponent")])
49 "winner":
"player" if player_won
else "opponent",
50 "reward": reward
if player_won
else 0,
55func _roll_damage(attacker:Dictionary, defender:Dictionary) -> int:
56 return max(1,
int(attacker.get(
"attack", 1)) + randi_range(1, 6) -
int(defender.get(
"defense", 0)))
61func start_battle(selected_player_card:Dictionary, selected_opponent_card:Dictionary, battle_reward:int = 100, starting_opponent_hp:int = -1) -> Dictionary:
62 player_card = selected_player_card.duplicate(true)
63 opponent_card = selected_opponent_card.duplicate(true)
64 player_hp =
int(player_card.get(
"health", 1))
65 opponent_hp = starting_opponent_hp
if starting_opponent_hp > 0
else int(opponent_card.get(
"health", 1))
66 player_turn = randi_range(0, 1) == 0
67 reward = battle_reward
68 active =
not player_card.is_empty()
and not opponent_card.is_empty()
72 log.append(
"%s faces %s." % [player_card.get(
"name",
"Player"), opponent_card.get(
"name",
"Opponent")])
73 log.append(
"%s has initiative." % [player_card.get(
"name",
"Player")
if player_turn
else opponent_card.get(
"name",
"Opponent")])
75 log.append(
"No battle could be started.")
80func clear_opponent() -> void:
91func take_turn() -> Dictionary:
97 var player_roll = randi_range(1, 6)
98 var player_damage = _calculate_damage(player_card, opponent_card, player_roll)
99 opponent_hp -= player_damage
100 log.append(
"%s rolls %d and deals %d damage." % [player_card.get(
"name",
"Player"), player_roll, player_damage])
101 last_event = _make_turn_event(
"player",
"opponent", player_card, opponent_card, player_roll, player_damage, max(0, opponent_hp))
103 var opponent_roll = randi_range(1, 6)
104 var opponent_damage = _calculate_damage(opponent_card, player_card, opponent_roll)
105 player_hp -= opponent_damage
106 log.append(
"%s rolls %d and deals %d damage." % [opponent_card.get(
"name",
"Opponent"), opponent_roll, opponent_damage])
107 last_event = _make_turn_event(
"opponent",
"player", opponent_card, player_card, opponent_roll, opponent_damage, max(0, player_hp))
109 if player_hp <= 0
or opponent_hp <= 0:
111 last_event[
"defeated"] = true
112 last_event[
"winner"] = get_winner()
113 log.append(
"%s wins." % [player_card.get(
"name",
"Player")
if player_hp > 0
else opponent_card.get(
"name",
"Opponent")])
115 player_turn =
not player_turn
121func get_state() -> Dictionary:
124 "player_card": player_card,
125 "opponent_card": opponent_card,
126 "player_hp": max(0, player_hp),
127 "opponent_hp": max(0, opponent_hp),
128 "player_turn": player_turn,
129 "winner": get_winner(),
130 "reward": reward
if get_winner() ==
"player" else 0,
131 "log": log.duplicate(),
132 "last_event": last_event.duplicate(true)
137func get_winner() -> String:
140 if player_card.is_empty()
or opponent_card.is_empty():
142 return "player" if player_hp > 0
else "opponent"
145func _calculate_damage(attacker:Dictionary, defender:Dictionary, roll:int) -> int:
146 return max(1,
int(attacker.get(
"attack", 1)) + roll -
int(defender.get(
"defense", 0)))
149func _make_turn_event(attacker_side:String, defender_side:String, attacker:Dictionary, defender:Dictionary, roll:int, damage:int, defender_hp:int) -> Dictionary:
152 "attacker": attacker_side,
153 "defender": defender_side,
154 "attacker_id": str(attacker.get(
"id", attacker.get(
"base_id",
""))),
155 "defender_id": str(defender.get(
"id", defender.get(
"base_id",
""))),
156 "attacker_name": str(attacker.get(
"name",
"Attacker")),
157 "defender_name": str(defender.get(
"name",
"Defender")),
160 "hp_after": defender_hp,
161 "defeated": defender_hp <= 0
int
Run a complete battle immediately and return winner/reward/log state.