feat: Implement initial main scene, player scripts, and core game manager systems for input, actions, playerboard, special tiles, and UI.

This commit is contained in:
Yogi Wiguna
2026-03-12 12:06:32 +08:00
parent 686ea2587e
commit 412e7bdcdd
8 changed files with 9 additions and 8610 deletions
+1 -6
View File
@@ -53,7 +53,6 @@ func after_action_completed():
if not player.is_bot and not player.is_in_group("Bots"):
var main = player.get_tree().get_root().get_node_or_null("Main")
if main:
main.ui_manager.update_button_states()
main.ui_manager.update_playerboard_ui()
# Add this line to sync all boards
@@ -180,9 +179,8 @@ func clear_highlights():
if not enhanced_gridmap or not player.is_multiplayer_authority():
return
# Store the current action state before clearing
# Clear highlights normally
var main = player.get_tree().get_root().get_node_or_null("Main")
var current_state = main.ui_manager.current_action_state if main else null
var hover_id = enhanced_gridmap.hover_item
@@ -205,9 +203,6 @@ func clear_highlights():
for child in slot.get_children():
child.hide()
# Restore highlights based on current action state
if main and current_state == main.ui_manager.ActionState.MOVING and player.is_my_turn:
player.highlight_movement_range()
func clear_playerboard_highlights():
# Never allow bots to clear highlights for human players
+4 -65
View File
@@ -56,30 +56,6 @@ func _process(delta):
movement_manager.simple_move_to(target_position)
# Targeting Mode Preview
var main = player.get_node_or_null("/root/Main")
if main and main.ui_manager and main.ui_manager.current_action_state == main.ui_manager.ActionState.TARGETING:
# Use mouse position raycast to determine hover
var viewport = player.get_viewport()
var mouse_pos = viewport.get_mouse_position()
var camera = viewport.get_camera_3d()
var from = camera.project_ray_origin(mouse_pos)
var to = from + camera.project_ray_normal(mouse_pos) * 1000
var hover_grid = player.raycast_to_grid(from, to)
# print("Targeting Hover: %s, Skill: %d" % [hover_grid, main.ui_manager.pending_skill_id]) # Debug
# Only update if valid position
if hover_grid != Vector2i(-1, -1):
var st_manager = player.get_node_or_null("SpecialTilesManager")
if st_manager:
var area = st_manager.get_skill_affected_area(main.ui_manager.pending_skill_id, hover_grid)
# Choose highlight color/mesh based on skill
# User Request: Use default hover item (1)
var highlight_id = 1
player.highlight_cells_if_authorized(area, highlight_id)
func handle_unhandled_input(event):
# Early return if not authorized human player
@@ -163,48 +139,11 @@ func handle_grid_click(grid_position: Vector2i):
var main = player.get_node("/root/Main")
if not main:
return
match main.ui_manager.current_action_state:
main.ui_manager.ActionState.MOVING:
if grid_position in player.highlighted_cells:
movement_manager.move_to_clicked_position(grid_position)
main.ui_manager.ActionState.GRABBING:
if grid_position in player.highlighted_cells or grid_position == player.current_position:
player.grab_item(grid_position)
main.ui_manager.ActionState.RANDOMIZING:
if grid_position in player.highlighted_cells:
main.randomize_item_at_position(grid_position)
# Add TARGETING State
main.ui_manager.ActionState.TARGETING:
var skill_id = main.ui_manager.pending_skill_id
if skill_id != -1:
var st_manager = player.get_node_or_null("SpecialTilesManager")
if st_manager:
# Clear Highlights FIRST to avoid overwriting the newly placed tiles
player.clear_highlights()
st_manager.execute_targeted_effect(skill_id, grid_position)
# Reset state
main.ui_manager.pending_skill_id = -1
main.ui_manager.current_action_state = main.ui_manager.ActionState.NONE
# Action logic previously here has been removed along with ActionMenu.
# Standard movement/interaction is now handled via keyboard/joystick.
func handle_slot_gui_input(event, slot_index, slot_ui) -> int:
if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT:
var main = player.get_tree().get_root().get_node_or_null("Main")
if main.ui_manager.current_action_state == main.ui_manager.ActionState.ARRANGING:
if player.selected_playerboard_slot == -1:
player.select_playerboard_slot(slot_index)
return slot_index
else:
if player.selected_playerboard_slot == slot_index:
player.deselect_playerboard_slot()
return slot_index
elif player.can_move_to_target_playerboard_slot():
player.target_playerboard_slot(slot_index)
main.emit_signal("can_move_item", true)
return slot_index
else:
return -1
# Arrangement mode has been removed along with ActionMenu.
return -1
+2 -66
View File
@@ -474,7 +474,6 @@ func auto_put_item() -> bool:
var main = player.get_tree().get_root().get_node_or_null("Main")
if main and main.ui_manager and not (player.is_bot or player.is_in_group("Bots")):
main.ui_manager.update_playerboard_ui()
main.ui_manager.current_action_state = main.ui_manager.ActionState.NONE
# === Server Sync ===
player.rpc("sync_grid_item", cell.x, cell.y, cell.z, item)
@@ -488,71 +487,8 @@ func auto_put_item() -> bool:
# ARRANGE Operations
# =============================================================================
func arrange_playerboard_item(slot_index: int):
if player.action_points < 2 or player.playerboard[slot_index] == -1:
return
#var selected_item = player.playerboard[slot_index]
var adjacent_slots = get_adjacent_playerboard_slots(slot_index)
var main = player.get_tree().get_root().get_node_or_null("Main")
if not main or not main.ui_manager.playerboard_ui:
return
# Store the selected slot
selected_playerboard_slot = slot_index
# Highlight selected slot
var selected_slot_ui = main.ui_manager.playerboard_ui.get_child(slot_index)
if selected_slot_ui.get_child_count() > 1:
selected_slot_ui.get_child(1).show()
# Highlight valid adjacent slots
for adj_slot in adjacent_slots:
if player.playerboard[adj_slot] == -1: # Only highlight empty adjacent slots
if not (player.is_bot or player.is_in_group("Bots")):
var adj_slot_ui = main.ui_manager.playerboard_ui.get_child(adj_slot)
if adj_slot_ui.get_child_count() > 2:
adj_slot_ui.get_child(2).show()
player.action_manager.highlighted_cells.append(adj_slot)
# Connect to slot click signals
for i in range(player.playerboard.size()):
var slot = main.ui_manager.playerboard_ui.get_child(i)
if not slot.gui_input.is_connected(player._on_slot_clicked):
slot.gui_input.connect(player._on_slot_clicked.bind(i))
func handle_slot_clicked(slot_index: int):
var main = player.get_tree().get_root().get_node_or_null("Main")
if not main or main.ui_manager.current_action_state != main.ui_manager.ActionState.ARRANGING:
return
if selected_playerboard_slot == -1 or slot_index == selected_playerboard_slot:
return
var adjacent_slots = get_adjacent_playerboard_slots(selected_playerboard_slot)
if slot_index in adjacent_slots and player.playerboard[slot_index] == -1 and not (slot_index in HIDDEN_SLOTS):
# Move item to empty target slot
var selected_item = player.playerboard[selected_playerboard_slot]
player.playerboard[slot_index] = selected_item
player.playerboard[selected_playerboard_slot] = -1
if player.is_multiplayer_authority():
player.rpc("sync_playerboard", player.playerboard)
player.consume_action_points(2)
player.has_performed_action = true
# Clear highlights
player.clear_highlights()
player.clear_playerboard_highlights()
# Reset selection
selected_playerboard_slot = -1
# Update the visual representation
if not (player.is_bot or player.is_in_group("Bots")):
main.ui_manager.update_playerboard_ui()
main.ui_manager.current_action_state = main.ui_manager.ActionState.NONE
# Arrangement mode has been removed along with ActionMenu.
pass
# =============================================================================
# Helper Functions
@@ -64,10 +64,6 @@ func execute_targeted_effect(effect: int, target_pos: Vector2i):
if player.is_multiplayer_authority():
player.rpc("trigger_screen_shake", "light")
# Also reset action loop? (ONLY for human players)
if not (player.is_bot or player.is_in_group("Bots")):
var main = player.get_tree().get_root().get_node_or_null("Main")
if main and main.ui_manager:
main.ui_manager.current_action_state = main.ui_manager.ActionState.NONE
# Random shape patterns for 3x3 area (relative offsets from center)
-56
View File
@@ -11,12 +11,6 @@ const item_tex = [
]
# Node references - will be set by Main
var action_menu
var move_button
var grab_button
var put_button
var randomize_button
var arrange_button
# var victory_ui_scene = preload("res://scenes/ui/victory_ui.tscn")
var victory_ui_scene = null
var powerup_inventory_ui_script = preload("res://scripts/ui/powerup_inventory_ui.gd")
@@ -33,31 +27,12 @@ var player_name_label: Label # Shows player name on main UI
var local_player_character
var _previous_playerboard_state: Array = []
enum ActionState {
NONE,
MOVING,
GRABBING,
ARRANGING,
RANDOMIZING,
TARGETING
}
var current_action_state = ActionState.NONE
var pending_skill_id: int = -1
func initialize(player_node):
# Get PowerUp Inventory UI from scene
powerup_inventory_ui = player_node.get_node_or_null("PowerUpInventoryUI")
# Get node references from main scene
action_menu = player_node.get_node("ActionMenu")
var button_container = player_node.get_node("ActionMenu/ActionButtonContainer")
move_button = button_container.get_node("MoveButton")
grab_button = button_container.get_node("GrabButton")
put_button = button_container.get_node("PutButton")
randomize_button = button_container.get_node("RandomizeButton") # renamed main_node to player_node which is Main
arrange_button = player_node.get_node("ActionMenu/ActionButtonContainer/ArrangeButton")
playerboard_ui = player_node.get_node("PlayerboardUI")
# Connect PlayerName label (Level/XP/Name UI)
@@ -78,18 +53,6 @@ func set_local_player(player):
player_name_label.text = player.display_name
print("[UIManager] Updated PlayerName label to: ", player.display_name)
func setup_action_buttons(action_state_callback):
move_button.pressed.connect(func(): action_state_callback.call(ActionState.MOVING))
grab_button.pressed.connect(func(): action_state_callback.call(ActionState.GRABBING))
put_button.pressed.connect(func():
if local_player_character:
local_player_character.auto_put_item()
)
randomize_button.pressed.connect(func(): action_state_callback.call(ActionState.RANDOMIZING))
arrange_button.pressed.connect(func():
if local_player_character and local_player_character.action_points >= 2:
action_state_callback.call(ActionState.ARRANGING)
)
func setup_playerboard_ui():
for child in playerboard_ui.get_children():
@@ -238,25 +201,6 @@ func _pulse_slot_effect(slot: Control):
slot.modulate = Color(1.5, 1.5, 1.5) # Overbright
tween.parallel().tween_property(slot, "modulate", original_modulate, 0.3)
func update_button_states():
if not local_player_character or local_player_character.is_in_group("Bots"):
move_button.visible = false
grab_button.visible = false
put_button.visible = false
randomize_button.visible = false
arrange_button.visible = false
return
move_button.visible = true
grab_button.visible = true
put_button.visible = true
randomize_button.visible = true
arrange_button.visible = true
move_button.disabled = false
grab_button.disabled = false
put_button.disabled = false
arrange_button.disabled = false