Skip to content

Commit f49fe41

Browse files
committed
Add volley forfeit confirmation and reserve indicator
1 parent 68a81a0 commit f49fe41

File tree

3 files changed

+63
-1
lines changed

3 files changed

+63
-1
lines changed

scenes/Main.tscn

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,3 +341,10 @@ offset_top = 52.0
341341
offset_right = 320.0
342342
offset_bottom = 84.0
343343
text = "Main Menu"
344+
345+
[node name="ForfeitDialog" type="ConfirmationDialog" parent="HUD"]
346+
visible = false
347+
title = "Forfeit Volley"
348+
dialog_text = "End the volley and take threat damage?"
349+
ok_button_text = "Forfeit"
350+
cancel_button_text = "Cancel"

scripts/Main.gd

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ const CARD_POOL: Array[String] = [
9292
@onready var gameover_label: Label = $HUD/GameOverPanel/GameOverLabel
9393
@onready var restart_button: Button = $HUD/GameOverPanel/RestartButton
9494
@onready var menu_button: Button = $HUD/GameOverPanel/MenuButton
95+
@onready var forfeit_dialog: ConfirmationDialog = $HUD/ForfeitDialog
9596
@onready var left_wall: CollisionShape2D = $Walls/LeftWall
9697
@onready var right_wall: CollisionShape2D = $Walls/RightWall
9798
@onready var top_wall: CollisionShape2D = $Walls/TopWall
@@ -148,6 +149,13 @@ var encounter_speed_boost: bool = false
148149
var deck_return_panel: String = ""
149150
var deck_return_info: String = ""
150151

152+
func _update_reserve_indicator() -> void:
153+
if paddle and paddle.has_method("set_reserve_count"):
154+
if state == GameState.PLANNING:
155+
paddle.set_reserve_count(volley_ball_bonus)
156+
else:
157+
paddle.set_reserve_count(volley_ball_reserve)
158+
151159
func _ready() -> void:
152160
randomize()
153161
if get_viewport():
@@ -160,6 +168,8 @@ func _ready() -> void:
160168
restart_button.pressed.connect(_start_run)
161169
if menu_button:
162170
menu_button.pressed.connect(_go_to_menu)
171+
if forfeit_dialog:
172+
forfeit_dialog.confirmed.connect(_confirm_forfeit_volley)
163173
if deck_button:
164174
deck_button.pressed.connect(_show_deck_panel)
165175
if deck_close_button:
@@ -247,11 +257,21 @@ func _set_hud_tooltips() -> void:
247257
func _unhandled_input(event: InputEvent) -> void:
248258
if event.is_action_pressed("ui_cancel"):
249259
App.show_menu()
260+
if event is InputEventKey and event.is_pressed() and not event.is_echo():
261+
var key_event: InputEventKey = event
262+
if key_event.keycode in [KEY_ENTER, KEY_KP_ENTER]:
263+
if state == GameState.VOLLEY and active_balls.is_empty() and volley_ball_reserve > 0:
264+
_prompt_forfeit_volley()
265+
return
250266
if state == GameState.PLANNING and event.is_action_pressed("ui_accept"):
251267
_launch_volley()
252268
if state == GameState.VOLLEY and event.is_action_pressed("ui_select") and active_balls.is_empty() and volley_ball_reserve > 0:
253-
_forfeit_volley()
269+
_prompt_forfeit_volley()
254270
if state == GameState.VOLLEY and event.is_action_pressed("ui_accept") and reserve_launch_cooldown <= 0.0:
271+
if event is InputEventKey:
272+
var launch_key: InputEventKey = event
273+
if launch_key.keycode in [KEY_ENTER, KEY_KP_ENTER]:
274+
return
255275
_launch_reserve_ball()
256276
if state == GameState.PLANNING and event.is_action_pressed("ui_select"):
257277
_end_turn()
@@ -418,6 +438,7 @@ func _start_turn() -> void:
418438
volley_damage_bonus = 0
419439
volley_ball_bonus = 0
420440
volley_ball_reserve = 0
441+
_update_reserve_indicator()
421442
volley_piercing = false
422443
volley_ball_speed_multiplier = 1.0
423444
_apply_paddle_buffs()
@@ -444,6 +465,7 @@ func _launch_volley() -> void:
444465
state = GameState.VOLLEY
445466
var total_balls: int = 1 + volley_ball_bonus
446467
volley_ball_reserve = max(0, total_balls - 1)
468+
_update_reserve_indicator()
447469
reserve_launch_cooldown = 0.1
448470
_spawn_volley_ball()
449471
info_label.text = "Volley in motion."
@@ -454,6 +476,7 @@ func _launch_reserve_ball() -> void:
454476
if volley_ball_reserve <= 0:
455477
return
456478
volley_ball_reserve -= 1
479+
_update_reserve_indicator()
457480
_spawn_volley_ball()
458481
info_label.text = "Extra ball launched."
459482

@@ -499,8 +522,18 @@ func _forfeit_volley() -> void:
499522
if volley_ball_reserve <= 0:
500523
return
501524
volley_ball_reserve = 0
525+
_update_reserve_indicator()
502526
_apply_volley_threat()
503527

528+
func _prompt_forfeit_volley() -> void:
529+
if forfeit_dialog == null:
530+
_forfeit_volley()
531+
return
532+
forfeit_dialog.popup_centered()
533+
534+
func _confirm_forfeit_volley() -> void:
535+
_forfeit_volley()
536+
504537
func _apply_volley_threat() -> void:
505538
var threat: int = _calculate_threat()
506539
hp -= threat
@@ -713,6 +746,7 @@ func _clear_active_balls() -> void:
713746
ball.queue_free()
714747
active_balls.clear()
715748
volley_ball_reserve = 0
749+
_update_reserve_indicator()
716750

717751
func _build_bricks(rows: int, cols: int, base_hp: int, pattern: String) -> void:
718752
for child in bricks_root.get_children():
@@ -886,6 +920,7 @@ func _play_card(card_id: String) -> void:
886920
discard_pile.append(card_id)
887921
hand.erase(card_id)
888922
_refresh_hand()
923+
_update_reserve_indicator()
889924
_update_labels()
890925

891926
func _apply_card_effect(card_id: String) -> void:

scripts/Paddle.gd

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ extends CharacterBody2D
77
@onready var collider: CollisionShape2D = $CollisionShape2D
88

99
var locked_y: float = 0.0
10+
var reserve_count: int = 0
11+
const RESERVE_SIZE: float = 10.0
12+
const RESERVE_GAP: float = 6.0
13+
const RESERVE_COLOR: Color = Color(1, 1, 1, 1)
1014

1115
func _ready() -> void:
1216
locked_y = global_position.y
@@ -25,13 +29,29 @@ func _physics_process(_delta: float) -> void:
2529
global_position.x = clamped_x
2630
global_position.y = locked_y
2731

32+
func _draw() -> void:
33+
if reserve_count <= 0:
34+
return
35+
var total_width: float = reserve_count * RESERVE_SIZE + max(0, reserve_count - 1) * RESERVE_GAP
36+
var start_x: float = -total_width * 0.5
37+
var y: float = -rect.size.y * 0.5 - 8.0 - RESERVE_SIZE
38+
for i in range(reserve_count):
39+
var x: float = start_x + i * (RESERVE_SIZE + RESERVE_GAP)
40+
var rect_box: Rect2 = Rect2(Vector2(x, y), Vector2(RESERVE_SIZE, RESERVE_SIZE))
41+
draw_rect(rect_box, RESERVE_COLOR, false, 2.0)
42+
2843
func set_half_width(value: float) -> void:
2944
half_width = max(20.0, value)
3045
rect.size.x = half_width * 2.0
3146
rect.position.x = -half_width
3247
if collider.shape is RectangleShape2D:
3348
var shape: RectangleShape2D = collider.shape as RectangleShape2D
3449
shape.size.x = half_width * 2.0
50+
queue_redraw()
3551

3652
func set_locked_y(value: float) -> void:
3753
locked_y = value
54+
55+
func set_reserve_count(value: int) -> void:
56+
reserve_count = max(0, value)
57+
queue_redraw()

0 commit comments

Comments
 (0)