feat: Implement core game managers, player movement logic, and initial UI scenes.
This commit is contained in:
+169
-15
@@ -78,6 +78,17 @@ var spawn_point_selected = false
|
||||
|
||||
# Action for hilighter
|
||||
var highlighted_spawn_points = []
|
||||
var _is_highlighting: bool = false
|
||||
|
||||
# Character selection and animation
|
||||
@onready var anim_player: AnimationPlayer = $AnimationPlayer
|
||||
@onready var character_bob: Node3D = $Bob
|
||||
@onready var character_masbro: Node3D = $Masbro
|
||||
@onready var character_gatot: Node3D = $Gatot
|
||||
@onready var character_oldpop: Node3D = $Oldpop
|
||||
|
||||
var selected_character: String = "Masbro" # Default character (matches tscn default visibility)
|
||||
const AVAILABLE_CHARACTERS: Array[String] = ["Bob", "Masbro", "Gatot", "Oldpop"]
|
||||
|
||||
|
||||
@export var movement_range: int = 1:
|
||||
@@ -124,6 +135,9 @@ func _ready():
|
||||
|
||||
_init_managers()
|
||||
|
||||
# Initialize character selection from LobbyManager
|
||||
_setup_character()
|
||||
|
||||
# Early setup for bots
|
||||
if is_bot == true or is_in_group("Bots"):
|
||||
# Initialize behavior tree for bots
|
||||
@@ -162,11 +176,13 @@ func _ready():
|
||||
enhanced_gridmap.initialize_astar()
|
||||
enhanced_gridmap.set_diagonal_movement(use_diagonal_movement)
|
||||
|
||||
# Request current spawn positions before highlighting
|
||||
request_spawn_positions_update()
|
||||
|
||||
highlight_available_spawn_points()
|
||||
# Remove this line as goals are now managed by the host
|
||||
# Skip manual spawn selection if random spawn is enabled
|
||||
# Host will assign positions via RPC
|
||||
if not LobbyManager.get_randomize_spawn():
|
||||
# Request current spawn positions before highlighting
|
||||
request_spawn_positions_update()
|
||||
highlight_available_spawn_points()
|
||||
# Remove this line as goals are now managed by the host
|
||||
#append_random_goals()
|
||||
|
||||
playerboard.resize(25)
|
||||
@@ -181,21 +197,26 @@ func _ready():
|
||||
if enhanced_gridmap:
|
||||
enhanced_gridmap.initialize_astar()
|
||||
enhanced_gridmap.set_diagonal_movement(use_diagonal_movement)
|
||||
current_position = find_valid_starting_position()
|
||||
update_player_position(current_position)
|
||||
# Only set position if not using random spawn (host will assign via RPC)
|
||||
# AND not already assigned
|
||||
if not LobbyManager.get_randomize_spawn() and not spawn_point_selected:
|
||||
current_position = find_valid_starting_position()
|
||||
update_player_position(current_position)
|
||||
|
||||
#append_random_goals()
|
||||
playerboard.resize(25)
|
||||
playerboard.fill(-1)
|
||||
|
||||
# Ensure proper initial positioning
|
||||
global_position = Vector3(
|
||||
current_position.x * cell_size.x + cell_size.x * 0.5,
|
||||
1.0,
|
||||
current_position.y * cell_size.z + cell_size.z * 0.5
|
||||
)
|
||||
if is_multiplayer_authority():
|
||||
rpc("sync_position", current_position)
|
||||
# Ensure proper initial positioning (only if NOT using random spawn and not already positioned)
|
||||
# When random spawn is enabled, the host assigns positions via set_spawn_position RPC
|
||||
if not LobbyManager.get_randomize_spawn() and not spawn_point_selected:
|
||||
global_position = Vector3(
|
||||
current_position.x * cell_size.x + cell_size.x * 0.5,
|
||||
1.0,
|
||||
current_position.y * cell_size.z + cell_size.z * 0.5
|
||||
)
|
||||
if is_multiplayer_authority():
|
||||
rpc("sync_position", current_position)
|
||||
|
||||
func _init_managers():
|
||||
movement_manager = load("res://scripts/managers/player_movement_manager.gd").new()
|
||||
@@ -233,6 +254,125 @@ func _init_managers():
|
||||
add_child(powerup_manager)
|
||||
powerup_manager.initialize(self, enhanced_gridmap)
|
||||
|
||||
# =============================================================================
|
||||
# Character Selection
|
||||
# =============================================================================
|
||||
|
||||
func set_character(character_name: String) -> void:
|
||||
"""Show only the selected character model and hide others. Updates AnimationPlayer root."""
|
||||
if character_name not in AVAILABLE_CHARACTERS:
|
||||
push_warning("Invalid character name: %s" % character_name)
|
||||
return
|
||||
|
||||
selected_character = character_name
|
||||
|
||||
# Hide all character models
|
||||
if character_bob: character_bob.visible = false
|
||||
if character_masbro: character_masbro.visible = false
|
||||
if character_gatot: character_gatot.visible = false
|
||||
if character_oldpop: character_oldpop.visible = false
|
||||
|
||||
# Show selected character and update AnimationPlayer root
|
||||
var active_character: Node3D = null
|
||||
match character_name:
|
||||
"Bob":
|
||||
if character_bob:
|
||||
character_bob.visible = true
|
||||
active_character = character_bob
|
||||
"Masbro":
|
||||
if character_masbro:
|
||||
character_masbro.visible = true
|
||||
active_character = character_masbro
|
||||
"Gatot":
|
||||
if character_gatot:
|
||||
character_gatot.visible = true
|
||||
active_character = character_gatot
|
||||
"Oldpop":
|
||||
if character_oldpop:
|
||||
character_oldpop.visible = true
|
||||
active_character = character_oldpop
|
||||
|
||||
# Update AnimationPlayer's root node to point to active character
|
||||
if anim_player and active_character:
|
||||
anim_player.root_node = anim_player.get_path_to(active_character)
|
||||
# Start with idle animation
|
||||
play_idle_animation()
|
||||
|
||||
@rpc("any_peer", "call_local", "reliable")
|
||||
func sync_character(character_name: String) -> void:
|
||||
"""Sync character selection across all clients."""
|
||||
set_character(character_name)
|
||||
|
||||
func _setup_character() -> void:
|
||||
"""Initialize character based on LobbyManager selection or defaults."""
|
||||
var character_name = "Masbro" # Default
|
||||
var player_authority_id = get_multiplayer_authority()
|
||||
|
||||
# Look up character from LobbyManager for this player (works for all players)
|
||||
if LobbyManager:
|
||||
var players = LobbyManager.get_players()
|
||||
for player_data in players:
|
||||
if player_data.get("id") == player_authority_id:
|
||||
character_name = player_data.get("character", "Masbro")
|
||||
break
|
||||
|
||||
set_character(character_name)
|
||||
|
||||
# If this is our local player, also sync to other clients for late joiners
|
||||
if is_multiplayer_authority():
|
||||
rpc("sync_character", character_name)
|
||||
|
||||
# =============================================================================
|
||||
# Animation Functions
|
||||
# =============================================================================
|
||||
|
||||
# Animation speed multiplier for fast-paced gameplay
|
||||
const ANIMATION_SPEED: float = 2.0
|
||||
|
||||
func play_walk_animation() -> void:
|
||||
"""Play walking animation at increased speed."""
|
||||
if anim_player and anim_player.has_animation("animation-pack/walk_forward"):
|
||||
anim_player.play("animation-pack/walk_forward", -1, ANIMATION_SPEED)
|
||||
|
||||
func play_pickup_animation() -> void:
|
||||
"""Play pickup/grab tile animation at increased speed."""
|
||||
if anim_player and anim_player.has_animation("animation-pack/take_tile_1"):
|
||||
anim_player.play("animation-pack/take_tile_1", -1, ANIMATION_SPEED)
|
||||
|
||||
func play_put_animation() -> void:
|
||||
"""Play put/drop tile animation at increased speed."""
|
||||
if anim_player and anim_player.has_animation("animation-pack/drop_tile_1"):
|
||||
anim_player.play("animation-pack/drop_tile_1", -1, ANIMATION_SPEED)
|
||||
|
||||
func play_special_animation() -> void:
|
||||
"""Play special ability animation (backflip) at increased speed."""
|
||||
if anim_player and anim_player.has_animation("animation-pack/backflip_1"):
|
||||
anim_player.play("animation-pack/backflip_1", -1, ANIMATION_SPEED * 1.5)
|
||||
|
||||
func play_idle_animation() -> void:
|
||||
"""Play idle animation at normal speed."""
|
||||
if anim_player and anim_player.has_animation("animation-pack/idle"):
|
||||
anim_player.play("animation-pack/idle")
|
||||
|
||||
# =============================================================================
|
||||
# Screen Shake
|
||||
# =============================================================================
|
||||
|
||||
@rpc("any_peer", "call_local", "reliable")
|
||||
func trigger_screen_shake(shake_type: String) -> void:
|
||||
"""Trigger screen shake effect. Called via RPC when targeted or completing goals."""
|
||||
var main = get_tree().get_root().get_node_or_null("Main")
|
||||
if main:
|
||||
var screen_shake_manager = main.get_node_or_null("ScreenShakeManager")
|
||||
if screen_shake_manager:
|
||||
match shake_type:
|
||||
"targeted":
|
||||
screen_shake_manager.shake_targeted()
|
||||
"goal":
|
||||
screen_shake_manager.shake_goal_complete()
|
||||
_:
|
||||
screen_shake_manager.shake_light()
|
||||
|
||||
# Add function to check if position is at finish line
|
||||
func is_at_finish_line() -> bool:
|
||||
return race_manager.is_at_finish_line()
|
||||
@@ -1121,6 +1261,20 @@ func sync_position(pos: Vector2i):
|
||||
current_position.y * cell_size.z + cell_size.z * 0.5
|
||||
) + cell_offset
|
||||
|
||||
@rpc("any_peer", "call_local", "reliable")
|
||||
func set_spawn_position(pos: Vector2i):
|
||||
"""Set spawn position - used by random spawn system."""
|
||||
current_position = pos
|
||||
spawn_point_selected = true
|
||||
# Clear any spawn highlights
|
||||
clear_spawn_highlights()
|
||||
# Update visual position
|
||||
global_position = Vector3(
|
||||
current_position.x * cell_size.x + cell_size.x * 0.5,
|
||||
cell_size.y,
|
||||
current_position.y * cell_size.z + cell_size.z * 0.5
|
||||
) + cell_offset
|
||||
|
||||
func highlight_valid_obstacle_cells():
|
||||
action_manager.highlight_valid_obstacle_cells()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user