feat: Implement Stop N Go game mode with phase management, mission objectives, and visual HUD elements.

This commit is contained in:
Yogi Wiguna
2026-02-26 10:40:55 +08:00
parent 36485c7f25
commit 3cd67c02ab
6 changed files with 127 additions and 44 deletions
+18 -12
View File
@@ -195,6 +195,9 @@ func _run_ai_tick():
print("[BotController] Action Taken: Put")
return
if not is_instance_valid(actor):
return
var goals_achv = _is_goals_achieved()
if actor.action_points > 1: # Only print if they have multi-AP
@@ -256,7 +259,7 @@ func _try_use_powerup() -> bool:
NotificationManager.send_message(actor, NotificationManager.MESSAGES.USED_SPECIAL_POWER, NotificationManager.MessageType.POWERUP)
await _wait_with_variance(action_delay)
if not is_instance_valid(self): return true # Early exit if deleted
if not is_instance_valid(actor) or not is_instance_valid(self): return true # Early exit if deleted
_is_processing_action = false
_current_action = "idle"
@@ -301,7 +304,7 @@ func _try_attack_chase() -> bool:
_is_processing_action = true
_current_action = "attacking"
await _wait_with_variance(action_delay) # Shorter delay for attacks? perhaos
if not is_instance_valid(self): return true
if not is_instance_valid(self) or not is_instance_valid(actor): return true
_is_processing_action = false
_current_action = "idle"
return true
@@ -365,7 +368,7 @@ func _try_grab() -> bool:
# Wait for animation
await _wait_with_variance(action_delay)
if not is_instance_valid(self): return true
if not is_instance_valid(self) or not is_instance_valid(actor): return true
_is_processing_action = false
_current_action = "idle"
return true
@@ -466,17 +469,19 @@ func _try_move() -> bool:
var max_wait_time = 2.0
var elapsed = 0.0
while actor.is_player_moving and is_instance_valid(self):
while is_instance_valid(actor) and actor.is_player_moving and is_instance_valid(self):
await get_tree().process_frame
elapsed += get_process_delta_time()
if elapsed > max_wait_time:
print("[BotController] %s movement TIMEOUT after %.1fs" % [actor.name, elapsed])
if is_instance_valid(actor):
print("[BotController] %s movement TIMEOUT after %.1fs" % [actor.name, elapsed])
break
if not is_instance_valid(self): return true
if not is_instance_valid(self) or not is_instance_valid(actor): return true
_is_processing_action = false
_current_action = "idle"
print("[BotController] %s move finished. New Pos: %s" % [actor.name, actor.current_position])
if is_instance_valid(actor):
print("[BotController] %s move finished. New Pos: %s" % [actor.name, actor.current_position])
return true
else:
print("[BotController] %s simple_move_to BLOCKED (others). Trying unstuck move." % actor.name)
@@ -515,15 +520,16 @@ func _try_unstuck_move() -> bool:
# Proper wait for movement completion
var max_wait = 1.5
var elapsed = 0.0
while actor.is_player_moving and is_instance_valid(self):
while is_instance_valid(actor) and actor.is_player_moving and is_instance_valid(self):
await get_tree().process_frame
elapsed += get_process_delta_time()
if elapsed > max_wait: break
if not is_instance_valid(self): return true
if not is_instance_valid(self) or not is_instance_valid(actor): return true
_is_processing_action = false
_current_action = "idle"
print("[BotController] %s Unstuck move finished at %s" % [actor.name, actor.current_position])
if is_instance_valid(actor):
print("[BotController] %s Unstuck move finished at %s" % [actor.name, actor.current_position])
return true
return false
@@ -580,7 +586,7 @@ func _try_put(high_priority: bool = false) -> bool:
print("[BotController] %s put unneeded tile %d at %s (Panic: %s)" % [actor.name, item, put_position, is_panic])
await _wait_with_variance(action_delay)
if not is_instance_valid(self): return true
if not is_instance_valid(actor) or not is_instance_valid(self): return true
_is_processing_action = false
_current_action = "idle"
return true
@@ -631,7 +637,7 @@ func _try_arrange() -> bool:
print("[BotController] %s arranged slot %d -> %d" % [actor.name, arrangement.source_slot, arrangement.target_slot])
await _wait_with_variance(action_delay)
if not is_instance_valid(self): return true
if not is_instance_valid(actor) or not is_instance_valid(self): return true
_is_processing_action = false
_current_action = "idle"
return true