12var opponent_card := {}
15var player_turn := true
21func battle(player_card:Dictionary, opponent_card:Dictionary, reward:int = 100) -> Dictionary:
22 if player_card.is_empty()
or opponent_card.is_empty():
23 return {
"winner":
"none",
"log": [
"No battle could be started."],
"reward": 0}
25 var player = player_card.duplicate(true)
26 var opponent = opponent_card.duplicate(true)
27 var player_hp =
int(player.get(
"health", 1))
28 var opponent_hp =
int(opponent.get(
"health", 1))
29 var player_turn = randi_range(0, 1) == 0
31 "%s faces %s." % [player.get(
"name",
"Player"), opponent.get(
"name",
"Opponent")]
34 while player_hp > 0
and opponent_hp > 0:
36 var damage = _roll_damage(player, opponent)
38 log.append(
"%s hits for %d." % [player.get(
"name",
"Player"), damage])
40 var damage = _roll_damage(opponent, player)
42 log.append(
"%s hits for %d." % [opponent.get(
"name",
"Opponent"), damage])
43 player_turn =
not player_turn
45 var player_won = player_hp > 0
46 log.append(
"%s wins." % [player.get(
"name",
"Player")
if player_won
else opponent.get(
"name",
"Opponent")])
48 "winner":
"player" if player_won
else "opponent",
49 "reward": reward
if player_won
else 0,
54func _roll_damage(attacker:Dictionary, defender:Dictionary) -> int:
55 return max(1,
int(attacker.get(
"attack", 1)) + randi_range(1, 6) -
int(defender.get(
"defense", 0)))
60func start_battle(selected_player_card:Dictionary, selected_opponent_card:Dictionary, battle_reward:int = 100, starting_opponent_hp:int = -1) -> Dictionary:
61 player_card = selected_player_card.duplicate(true)
62 opponent_card = selected_opponent_card.duplicate(true)
63 player_hp =
int(player_card.get(
"health", 1))
64 opponent_hp = starting_opponent_hp
if starting_opponent_hp > 0
else int(opponent_card.get(
"health", 1))
65 player_turn = randi_range(0, 1) == 0
66 reward = battle_reward
67 active =
not player_card.is_empty()
and not opponent_card.is_empty()
70 log.append(
"%s faces %s." % [player_card.get(
"name",
"Player"), opponent_card.get(
"name",
"Opponent")])
71 log.append(
"%s has initiative." % [player_card.get(
"name",
"Player")
if player_turn
else opponent_card.get(
"name",
"Opponent")])
73 log.append(
"No battle could be started.")
78func clear_opponent() -> void:
88func take_turn() -> Dictionary:
93 var player_roll = randi_range(1, 6)
94 var player_damage = _calculate_damage(player_card, opponent_card, player_roll)
95 opponent_hp -= player_damage
96 log.append(
"%s rolls %d and deals %d damage." % [player_card.get(
"name",
"Player"), player_roll, player_damage])
98 var opponent_roll = randi_range(1, 6)
99 var opponent_damage = _calculate_damage(opponent_card, player_card, opponent_roll)
100 player_hp -= opponent_damage
101 log.append(
"%s rolls %d and deals %d damage." % [opponent_card.get(
"name",
"Opponent"), opponent_roll, opponent_damage])
103 if player_hp <= 0
or opponent_hp <= 0:
105 log.append(
"%s wins." % [player_card.get(
"name",
"Player")
if player_hp > 0
else opponent_card.get(
"name",
"Opponent")])
107 player_turn =
not player_turn
113func get_state() -> Dictionary:
116 "player_card": player_card,
117 "opponent_card": opponent_card,
118 "player_hp": max(0, player_hp),
119 "opponent_hp": max(0, opponent_hp),
120 "player_turn": player_turn,
121 "winner": get_winner(),
122 "reward": reward
if get_winner() ==
"player" else 0,
123 "log": log.duplicate()
128func get_winner() -> String:
131 if player_card.is_empty()
or opponent_card.is_empty():
133 return "player" if player_hp > 0
else "opponent"
136func _calculate_damage(attacker:Dictionary, defender:Dictionary, roll:int) -> int:
137 return max(1,
int(attacker.get(
"attack", 1)) + roll -
int(defender.get(
"defense", 0)))
int
Run a complete battle immediately and return winner/reward/log state.