first commit
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
[gd_scene load_steps=8 format=3 uid="uid://dxn87yj8qnfpp"]
|
||||
|
||||
[ext_resource type="MeshLibrary" uid="uid://54tpx8cmksfc" path="res://addons/enhanced_gridmap/meshlibrary/default.tres" id="1_110wo"]
|
||||
[ext_resource type="Script" path="res://addons/enhanced_gridmap/enhanced_gridmap.gd" id="2_hbe1v"]
|
||||
[ext_resource type="Script" path="res://scenes/player.gd" id="3_4ksq5"]
|
||||
[ext_resource type="PackedScene" uid="uid://faku1hodioqu" path="res://assets/character.glb" id="4_0d1yx"]
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_xqgey"]
|
||||
albedo_color = Color(0.85, 0.085, 0.238, 1)
|
||||
|
||||
[sub_resource type="CapsuleMesh" id="CapsuleMesh_l8ldl"]
|
||||
material = SubResource("StandardMaterial3D_xqgey")
|
||||
|
||||
[sub_resource type="SphereShape3D" id="SphereShape3D_3oo5r"]
|
||||
|
||||
[node name="Main" type="Node3D"]
|
||||
|
||||
[node name="EnhancedGridMap" type="GridMap" parent="."]
|
||||
mesh_library = ExtResource("1_110wo")
|
||||
data = {
|
||||
"cells": PackedInt32Array(0, 0, 0, 0, 1, 0, 0, 2, 4, 0, 3, 0, 0, 4, 4, 0, 5, 0, 0, 6, 0, 0, 7, 0, 0, 8, 4, 0, 9, 0, 1, 0, 0, 1, 1, 0, 1, 2, 0, 1, 3, 0, 1, 4, 0, 1, 5, 4, 1, 6, 0, 1, 7, 0, 1, 8, 4, 1, 9, 4, 2, 0, 0, 2, 1, 0, 2, 2, 4, 2, 3, 0, 2, 4, 0, 2, 5, 4, 2, 6, 0, 2, 7, 0, 2, 8, 0, 2, 9, 0, 3, 0, 0, 3, 1, 0, 3, 2, 0, 3, 3, 0, 3, 4, 0, 3, 5, 0, 3, 6, 0, 3, 7, 0, 3, 8, 4, 3, 9, 0, 4, 0, 0, 4, 1, 4, 4, 2, 0, 4, 3, 0, 4, 4, 4, 4, 5, 0, 4, 6, 0, 4, 7, 0, 4, 8, 0, 4, 9, 4, 5, 0, 4, 5, 1, 0, 5, 2, 0, 5, 3, 4, 5, 4, 0, 5, 5, 4, 5, 6, 0, 5, 7, 0, 5, 8, 0, 5, 9, 0, 6, 0, 0, 6, 1, 0, 6, 2, 0, 6, 3, 0, 6, 4, 0, 6, 5, 0, 6, 6, 0, 6, 7, 0, 6, 8, 0, 6, 9, 4, 7, 0, 0, 7, 1, 0, 7, 2, 4, 7, 3, 0, 7, 4, 0, 7, 5, 0, 7, 6, 0, 7, 7, 0, 7, 8, 0, 7, 9, 0, 8, 0, 0, 8, 1, 0, 8, 2, 0, 8, 3, 0, 8, 4, 0, 8, 5, 0, 8, 6, 0, 8, 7, 0, 8, 8, 4, 8, 9, 0, 9, 0, 0, 9, 1, 0, 9, 2, 4, 9, 3, 0, 9, 4, 4, 9, 5, 0, 9, 6, 4, 9, 7, 0, 9, 8, 0, 9, 9, 0)
|
||||
}
|
||||
script = ExtResource("2_hbe1v")
|
||||
|
||||
[node name="CharacterBody3D" type="CharacterBody3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, 0)
|
||||
script = ExtResource("3_4ksq5")
|
||||
enhanced_gridmap_path = NodePath("../EnhancedGridMap")
|
||||
player_path = NodePath(".")
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="CharacterBody3D"]
|
||||
visible = false
|
||||
mesh = SubResource("CapsuleMesh_l8ldl")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="CharacterBody3D"]
|
||||
shape = SubResource("SphereShape3D_3oo5r")
|
||||
|
||||
[node name="character2" parent="CharacterBody3D" instance=ExtResource("4_0d1yx")]
|
||||
|
||||
[node name="Camera3D" type="Camera3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 10, 30, 10)
|
||||
fov = 55.0
|
||||
|
||||
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5, 10, 5)
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
extends Node3D # This script is attached to a Node3D (main scene)
|
||||
|
||||
var multiplayer_peer = ENetMultiplayerPeer.new() # Create a new ENet multiplayer peer
|
||||
|
||||
const PORT = 9999 # Define the port for multiplayer
|
||||
const ADDRESS = "127.0.0.1" # Define the IP address for multiplayer
|
||||
|
||||
var connected_peer_ids = [] # List of connected peer IDs
|
||||
var local_player_character : CharacterBody3D # Reference to the local player character
|
||||
var player_scene = preload("res://scenes/player.tscn") # Preload the player scene
|
||||
var current_turn_index = 0 # Index of the current turn
|
||||
@export var players = [] # List of player IDs
|
||||
var game_started = false # Flag to track if the game has started
|
||||
|
||||
var max_message_input_char = 51 # Maximum characters allowed in a message
|
||||
|
||||
func _on_host_pressed(): # Called when the host button is pressed
|
||||
$NetworkInfo/NetworkSideDisplay.text = "Server"
|
||||
$Menu.visible = false
|
||||
multiplayer_peer.create_server(PORT) # Create a multiplayer server
|
||||
multiplayer.multiplayer_peer = multiplayer_peer
|
||||
$NetworkInfo/UniquePeerID.text = str(multiplayer.get_unique_id())
|
||||
|
||||
add_player_character(1) # Add host player character
|
||||
|
||||
players.append(1) # Add host to players list
|
||||
if players.size() == 2:
|
||||
start_game() # Start game if two players are connected
|
||||
|
||||
multiplayer_peer.peer_connected.connect(_on_peer_connected) # Connect peer connected signal
|
||||
|
||||
func _on_join_pressed(): # Called when the join button is pressed
|
||||
$NetworkInfo/NetworkSideDisplay.text = "Client"
|
||||
$Menu.visible = false
|
||||
multiplayer_peer.create_client(ADDRESS, PORT) # Create a multiplayer client
|
||||
multiplayer.multiplayer_peer = multiplayer_peer
|
||||
$NetworkInfo/UniquePeerID.text = str(multiplayer.get_unique_id())
|
||||
|
||||
func _on_peer_connected(new_peer_id): # Called when a new peer connects
|
||||
if multiplayer.is_server():
|
||||
await get_tree().create_timer(1).timeout
|
||||
rpc("add_newly_connected_player_character", new_peer_id) # RPC call to add new player
|
||||
rpc_id(new_peer_id, "add_previously_connected_player_characters", connected_peer_ids) # RPC call to sync existing players
|
||||
add_player_character(new_peer_id)
|
||||
players.append(new_peer_id)
|
||||
if players.size() == 2 and not game_started:
|
||||
start_game() # Start game if two players are connected
|
||||
|
||||
func _on_peer_disconnected(peer_id): # Called when a peer disconnects
|
||||
if multiplayer.is_server():
|
||||
connected_peer_ids.erase(peer_id)
|
||||
players.erase(peer_id)
|
||||
if players.size() < 2:
|
||||
game_started = false
|
||||
|
||||
func add_player_character(peer_id): # Add a player character to the game
|
||||
connected_peer_ids.append(peer_id)
|
||||
var player_character = player_scene.instantiate()
|
||||
player_character.set_multiplayer_authority(peer_id)
|
||||
add_child(player_character)
|
||||
player_character.add_to_group("Players",true)
|
||||
if peer_id == multiplayer.get_unique_id():
|
||||
local_player_character = player_character
|
||||
|
||||
@rpc
|
||||
func add_newly_connected_player_character(new_peer_id): # RPC function to add a new player character
|
||||
add_player_character(new_peer_id)
|
||||
|
||||
@rpc
|
||||
func add_previously_connected_player_characters(peer_ids): # RPC function to add existing player characters
|
||||
for peer_id in peer_ids:
|
||||
add_player_character(peer_id)
|
||||
|
||||
func _process(_delta): # Called every frame
|
||||
if multiplayer.is_server() and game_started:
|
||||
rpc("sync_turn_index", current_turn_index) # RPC call to sync turn index
|
||||
|
||||
func start_game(): # Start the game
|
||||
if multiplayer.is_server():
|
||||
game_started = true
|
||||
connected_peer_ids.sort()
|
||||
rpc("sync_game_start", connected_peer_ids) # RPC call to sync game start
|
||||
current_turn_index = -1
|
||||
next_turn()
|
||||
|
||||
@rpc
|
||||
func sync_game_start(peer_ids): # RPC function to sync game start
|
||||
connected_peer_ids = peer_ids
|
||||
game_started = true
|
||||
|
||||
@rpc("reliable")
|
||||
func sync_turn_index(index): # RPC function to sync turn index
|
||||
current_turn_index = index
|
||||
|
||||
func next_turn(): # Move to the next turn
|
||||
if multiplayer.is_server():
|
||||
current_turn_index += 1
|
||||
if current_turn_index >= connected_peer_ids.size():
|
||||
current_turn_index = -1
|
||||
next_turn()
|
||||
else:
|
||||
rpc("set_current_turn", connected_peer_ids[current_turn_index]) # RPC call to set current turn
|
||||
|
||||
func request_next_turn(): # Request to move to the next turn
|
||||
if multiplayer.is_server():
|
||||
end_current_turn()
|
||||
else:
|
||||
rpc_id(1, "server_end_current_turn") # RPC call to end turn on server
|
||||
|
||||
@rpc("any_peer")
|
||||
func server_end_current_turn(): # RPC function to end current turn on server
|
||||
if multiplayer.is_server():
|
||||
end_current_turn()
|
||||
|
||||
@rpc("any_peer", "call_local")
|
||||
func set_current_turn(player_id): # RPC function to set the current turn
|
||||
var players = get_tree().get_nodes_in_group("Players")
|
||||
for player in players:
|
||||
player.is_my_turn = (player.name == str(player_id))
|
||||
if player.is_my_turn:
|
||||
player.start_turn()
|
||||
|
||||
func end_current_turn(): # End the current turns
|
||||
if multiplayer.is_server():
|
||||
next_turn()
|
||||
rpc("sync_turn_index", current_turn_index) # RPC call to sync turn index
|
||||
|
||||
func _on_message_input_text_submitted(new_text): # Handle message input
|
||||
if new_text.length() > max_message_input_char:
|
||||
new_text = new_text.substr(0, max_message_input_char) + " ... "
|
||||
local_player_character.rpc("display_message", new_text) # RPC call to display message
|
||||
$MessageInput.text = ""
|
||||
$MessageInput.release_focus()
|
||||
@@ -0,0 +1,103 @@
|
||||
[gd_scene load_steps=5 format=3 uid="uid://dxn87yj8qnfpp"]
|
||||
|
||||
[ext_resource type="MeshLibrary" uid="uid://54tpx8cmksfc" path="res://addons/enhanced_gridmap/meshlibrary/default.tres" id="1_110wo"]
|
||||
[ext_resource type="Script" path="res://scenes/main.gd" id="1_xcpe3"]
|
||||
[ext_resource type="Script" path="res://addons/enhanced_gridmap/enhanced_gridmap.gd" id="2_hbe1v"]
|
||||
[ext_resource type="Environment" uid="uid://jbptgqvstei3" path="res://assets/main-environment.tres" id="4_ky38j"]
|
||||
|
||||
[node name="Main" type="Node3D"]
|
||||
script = ExtResource("1_xcpe3")
|
||||
|
||||
[node name="EnhancedGridMap" type="GridMap" parent="."]
|
||||
mesh_library = ExtResource("1_110wo")
|
||||
cell_size = Vector3(1, 1, 1)
|
||||
data = {
|
||||
"cells": PackedInt32Array(0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 3, 0, 0, 4, 0, 0, 5, 0, 0, 6, 0, 0, 7, 0, 0, 8, 0, 0, 9, 0, 1, 0, 0, 1, 1, 0, 1, 2, 0, 1, 3, 0, 1, 4, 0, 1, 5, 0, 1, 6, 0, 1, 7, 4, 1, 8, 0, 1, 9, 4, 2, 0, 4, 2, 1, 0, 2, 2, 0, 2, 3, 0, 2, 4, 0, 2, 5, 0, 2, 6, 0, 2, 7, 0, 2, 8, 0, 2, 9, 0, 3, 0, 0, 3, 1, 0, 3, 2, 0, 3, 3, 0, 3, 4, 0, 3, 5, 0, 3, 6, 0, 3, 7, 4, 3, 8, 0, 3, 9, 0, 4, 0, 0, 4, 1, 0, 4, 2, 0, 4, 3, 0, 4, 4, 0, 4, 5, 0, 4, 6, 0, 4, 7, 0, 4, 8, 0, 4, 9, 4, 5, 0, 0, 5, 1, 0, 5, 2, 0, 5, 3, 0, 5, 4, 0, 5, 5, 0, 5, 6, 0, 5, 7, 0, 5, 8, 0, 5, 9, 0, 6, 0, 4, 6, 1, 0, 6, 2, 0, 6, 3, 0, 6, 4, 0, 6, 5, 0, 6, 6, 0, 6, 7, 0, 6, 8, 0, 6, 9, 4, 7, 0, 0, 7, 1, 0, 7, 2, 0, 7, 3, 0, 7, 4, 0, 7, 5, 0, 7, 6, 0, 7, 7, 0, 7, 8, 0, 7, 9, 0, 8, 0, 0, 8, 1, 0, 8, 2, 0, 8, 3, 0, 8, 4, 4, 8, 5, 0, 8, 6, 0, 8, 7, 0, 8, 8, 0, 8, 9, 0, 9, 0, 0, 9, 1, 0, 9, 2, 0, 9, 3, 0, 9, 4, 0, 9, 5, 0, 9, 6, 0, 9, 7, 0, 9, 8, 0, 9, 9, 0)
|
||||
}
|
||||
script = ExtResource("2_hbe1v")
|
||||
non_walkable_items = Array[int]([4, 5])
|
||||
|
||||
[node name="Camera3D" type="Camera3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 5, 30, 5)
|
||||
visible = false
|
||||
environment = ExtResource("4_ky38j")
|
||||
fov = 35.5
|
||||
|
||||
[node name="Camera3D2" type="Camera3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 5, 30, 5)
|
||||
environment = ExtResource("4_ky38j")
|
||||
fov = 35.5
|
||||
|
||||
[node name="Panel" type="Panel" parent="."]
|
||||
anchors_preset = 5
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -77.0
|
||||
offset_top = 6.0
|
||||
offset_right = 77.0
|
||||
offset_bottom = 59.0
|
||||
grow_horizontal = 2
|
||||
|
||||
[node name="NetworkInfo" type="VBoxContainer" parent="."]
|
||||
anchors_preset = 5
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -58.0
|
||||
offset_top = 7.0
|
||||
offset_right = 58.0
|
||||
offset_bottom = 57.0
|
||||
grow_horizontal = 2
|
||||
|
||||
[node name="NetworkSideDisplay" type="Label" parent="NetworkInfo"]
|
||||
layout_mode = 2
|
||||
text = "Network Side"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="UniquePeerID" type="Label" parent="NetworkInfo"]
|
||||
layout_mode = 2
|
||||
text = "Unique Peer ID"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Menu" type="VBoxContainer" parent="."]
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -85.0
|
||||
offset_top = -33.0
|
||||
offset_right = 85.0
|
||||
offset_bottom = 33.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Host" type="Button" parent="Menu"]
|
||||
layout_mode = 2
|
||||
text = "Host"
|
||||
|
||||
[node name="Join" type="Button" parent="Menu"]
|
||||
layout_mode = 2
|
||||
text = "Join"
|
||||
|
||||
[node name="MessageInput" type="LineEdit" parent="."]
|
||||
anchors_preset = 7
|
||||
anchor_left = 0.5
|
||||
anchor_top = 1.0
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 1.0
|
||||
offset_left = -210.0
|
||||
offset_top = -46.0
|
||||
offset_right = 210.0
|
||||
offset_bottom = -15.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 0
|
||||
placeholder_text = "Chat"
|
||||
alignment = 1
|
||||
|
||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||
environment = ExtResource("4_ky38j")
|
||||
|
||||
[connection signal="pressed" from="Menu/Host" to="." method="_on_host_pressed"]
|
||||
[connection signal="pressed" from="Menu/Join" to="." method="_on_join_pressed"]
|
||||
[connection signal="text_submitted" from="MessageInput" to="." method="_on_message_input_text_submitted"]
|
||||
@@ -0,0 +1,187 @@
|
||||
extends Node3D # This script is attached to a Node3D
|
||||
|
||||
# Export variables for inspector configuration
|
||||
@export var enhanced_gridmap_path: NodePath = "/root/Main/EnhancedGridMap" # Path to the EnhancedGridMap node
|
||||
var enhanced_gridmap: EnhancedGridMap # References to the EnhancedGridMap node
|
||||
@export var current_position: Vector2i # Current grid position of the player
|
||||
var is_player_moving: bool = false # Flag to prevent movement while already moving
|
||||
|
||||
# Customizable cell size and offset
|
||||
@export var cell_size: Vector3 = Vector3(2, 2, 2) # Size of each grid cell
|
||||
@export var cell_offset: Vector3 = Vector3(0, 0, 0) # Offset for the grid
|
||||
|
||||
# Center offset flags
|
||||
@export var center_x: bool = false # Center the player on X axis
|
||||
@export var center_y: bool = false # Center the player on Y axis
|
||||
@export var center_z: bool = false # Center the player on Z axis
|
||||
|
||||
# Diagonal movement flag
|
||||
@export var use_diagonal_movement: bool = false: # Allow diagonal movement
|
||||
set(value):
|
||||
use_diagonal_movement = value
|
||||
if enhanced_gridmap:
|
||||
enhanced_gridmap.set_diagonal_movement(value)
|
||||
|
||||
# Turn management variables
|
||||
@export var is_my_turn: bool = false: # Flag to indicate if it's this player's turn
|
||||
set(value):
|
||||
is_my_turn = value
|
||||
if is_my_turn and is_multiplayer_authority():
|
||||
rpc("display_message", "It's your turn!") # RPC call to display turn message
|
||||
@export var has_moved_this_turn = false # Flag to track if player has moved this turn
|
||||
@onready var main_scene = get_tree().current_scene # Reference to the main scene
|
||||
|
||||
func _ready(): # Called when the node enters the scene tree
|
||||
name = str(get_multiplayer_authority()) # Set the node name to the multiplayer authority ID
|
||||
$Name.text = str(name) # Set the displayed name
|
||||
|
||||
enhanced_gridmap = get_node(enhanced_gridmap_path) # Get the EnhancedGridMap node
|
||||
|
||||
if main_scene:
|
||||
enhanced_gridmap = main_scene.get_node("EnhancedGridMap") # Get EnhancedGridMap from main scene
|
||||
else:
|
||||
push_error("Main scene not found") # Error if main scene not found
|
||||
|
||||
if not enhanced_gridmap:
|
||||
push_error("EnhancedGridMap node not found. Please set the correct path in the inspector.")
|
||||
return
|
||||
|
||||
enhanced_gridmap.initialize_astar() # Initialize A* pathfinding
|
||||
enhanced_gridmap.set_diagonal_movement(use_diagonal_movement) # Set diagonal movement option
|
||||
|
||||
current_position = find_valid_starting_position() # Find a valid starting position
|
||||
update_player_position(current_position) # Update player's position
|
||||
|
||||
set_process_unhandled_input(is_multiplayer_authority()) # Only process input for the authority
|
||||
|
||||
func find_valid_starting_position() -> Vector2i: # Find a valid starting position
|
||||
var rng = RandomNumberGenerator.new()
|
||||
rng.randomize()
|
||||
|
||||
var max_attempts = 100
|
||||
var attempts = 0
|
||||
|
||||
while attempts < max_attempts:
|
||||
current_position = Vector2i(0, rng.randi_range(0, 9)) # Generate random position
|
||||
var cell_item = enhanced_gridmap.get_cell_item(Vector3i(current_position.x, 0, current_position.y))
|
||||
|
||||
if cell_item not in enhanced_gridmap.non_walkable_items:
|
||||
return current_position # Return valid position
|
||||
|
||||
attempts += 1
|
||||
|
||||
return Vector2i(0, 0) # Default position if no valid position found
|
||||
|
||||
func _physics_process(_delta): # Called every physics frame
|
||||
if is_multiplayer_authority():
|
||||
rpc("remote_set_position", global_position) # RPC call to sync position
|
||||
|
||||
func _unhandled_input(event): # Handle input events
|
||||
if not is_multiplayer_authority() or not is_my_turn or is_player_moving:
|
||||
return
|
||||
|
||||
if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT:
|
||||
var camera = get_viewport().get_camera_3d()
|
||||
var from = camera.project_ray_origin(event.position)
|
||||
var to = from + camera.project_ray_normal(event.position) * 1000
|
||||
|
||||
var click_position = raycast_to_grid(from, to)
|
||||
if click_position != Vector2i(-1, -1):
|
||||
move_player_to_clicked_position(click_position)
|
||||
|
||||
func raycast_to_grid(from: Vector3, to: Vector3) -> Vector2i: # Convert 3D raycast to grid position
|
||||
var plane = Plane(Vector3.UP, cell_offset.y)
|
||||
var intersection = plane.intersects_ray(from, to - from)
|
||||
|
||||
if intersection:
|
||||
var adjusted_intersection = intersection - cell_offset
|
||||
var grid_position = Vector2i(
|
||||
floor(adjusted_intersection.x / cell_size.x),
|
||||
floor(adjusted_intersection.z / cell_size.z)
|
||||
)
|
||||
|
||||
if grid_position.x >= 0 and grid_position.x < enhanced_gridmap.columns and \
|
||||
grid_position.y >= 0 and grid_position.y < enhanced_gridmap.rows:
|
||||
return grid_position
|
||||
|
||||
return Vector2i(-1, -1) # Invalid position
|
||||
|
||||
func move_player_to_clicked_position(grid_position: Vector2i): # Move player to clicked position
|
||||
var cell_item = enhanced_gridmap.get_cell_item(Vector3i(grid_position.x, 0, grid_position.y))
|
||||
|
||||
if cell_item in enhanced_gridmap.non_walkable_items:
|
||||
print("Cannot move to non-walkable cell")
|
||||
return
|
||||
|
||||
var path = enhanced_gridmap.find_path(Vector2(current_position), Vector2(grid_position))
|
||||
|
||||
if path.size() > 1:
|
||||
path.pop_front()
|
||||
move_player_along_path(path)
|
||||
else:
|
||||
print("No valid path found")
|
||||
|
||||
func move_player_along_path(path: Array): # Move player along calculated path
|
||||
is_player_moving = true
|
||||
var tween = create_tween()
|
||||
tween.set_trans(Tween.TRANS_CUBIC)
|
||||
tween.set_ease(Tween.EASE_IN_OUT)
|
||||
|
||||
for point in path:
|
||||
var target_position = grid_to_world(Vector2i(point.x, point.y))
|
||||
tween.tween_property(self, "position", target_position, 0.5)
|
||||
|
||||
tween.tween_callback(func():
|
||||
current_position = Vector2i(path[-1].x, path[-1].y)
|
||||
is_player_moving = false
|
||||
enhanced_gridmap.clear_path_visualization()
|
||||
has_moved_this_turn = true
|
||||
end_turn()
|
||||
)
|
||||
|
||||
func update_player_position(grid_position: Vector2i): # Update player's position
|
||||
position = grid_to_world(grid_position)
|
||||
|
||||
func grid_to_world(grid_position: Vector2i) -> Vector3: # Convert grid position to world position
|
||||
var world_position = Vector3(
|
||||
grid_position.x * cell_size.x,
|
||||
cell_size.y,
|
||||
grid_position.y * cell_size.z
|
||||
)
|
||||
|
||||
world_position.x += cell_size.x * 0.5
|
||||
world_position.z += cell_size.z * 0.5
|
||||
|
||||
if center_x:
|
||||
world_position.x += cell_size.x * 0.5
|
||||
if center_y:
|
||||
world_position.y += cell_size.y * 0.5
|
||||
if center_z:
|
||||
world_position.z += cell_size.z * 0.5
|
||||
|
||||
return world_position + cell_offset
|
||||
|
||||
func start_turn(): # Start player's turn
|
||||
has_moved_this_turn = false
|
||||
is_my_turn = true
|
||||
if is_multiplayer_authority():
|
||||
rpc("display_message", "It's your turn!") # RPC call to display turn message
|
||||
|
||||
func end_turn(): # End player's turn
|
||||
is_my_turn = false
|
||||
has_moved_this_turn = false
|
||||
if is_multiplayer_authority():
|
||||
get_node("/root/Main").request_next_turn() # Request next turn from main scene
|
||||
|
||||
@rpc("any_peer", "call_local", "unreliable")
|
||||
func remote_set_position(authority_position): # RPC function to sync position
|
||||
global_position = authority_position
|
||||
|
||||
@rpc("any_peer", "call_local")
|
||||
func display_message(message): # RPC function to display messages
|
||||
$Bubble.show()
|
||||
$Bubble/Message.show()
|
||||
$Bubble/Message.text = str(message)
|
||||
await get_tree().create_timer(3).timeout
|
||||
$Bubble.hide()
|
||||
$Bubble/Message.hide()
|
||||
@@ -0,0 +1,58 @@
|
||||
[gd_scene load_steps=7 format=3 uid="uid://1dbdbg3q5778"]
|
||||
|
||||
[ext_resource type="Script" path="res://scenes/player.gd" id="1_qecr4"]
|
||||
[ext_resource type="Texture2D" uid="uid://b4y41h16q6m34" path="res://assets/textures/bub.png" id="2_5w327"]
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_xqgey"]
|
||||
albedo_color = Color(0.85, 0.085, 0.238, 1)
|
||||
|
||||
[sub_resource type="CapsuleMesh" id="CapsuleMesh_l8ldl"]
|
||||
material = SubResource("StandardMaterial3D_xqgey")
|
||||
|
||||
[sub_resource type="SphereShape3D" id="SphereShape3D_3oo5r"]
|
||||
|
||||
[sub_resource type="FontVariation" id="FontVariation_q2tkp"]
|
||||
spacing_glyph = 5
|
||||
|
||||
[node name="CharacterBody3D" type="CharacterBody3D"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, 0)
|
||||
script = ExtResource("1_qecr4")
|
||||
cell_size = Vector3(1, 1, 1)
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
|
||||
mesh = SubResource("CapsuleMesh_l8ldl")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||
shape = SubResource("SphereShape3D_3oo5r")
|
||||
|
||||
[node name="Name" type="Label3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.47085, 0)
|
||||
billboard = 1
|
||||
modulate = Color(0.32, 0.614667, 1, 1)
|
||||
text = "username"
|
||||
font = SubResource("FontVariation_q2tkp")
|
||||
font_size = 48
|
||||
outline_size = 26
|
||||
uppercase = true
|
||||
autowrap_mode = 2
|
||||
|
||||
[node name="Bubble" type="Sprite3D" parent="."]
|
||||
transform = Transform3D(1.4, 0, 0, 0, 1.4, 0, 0, 0, 1.4, 0, 7.5, 0)
|
||||
visible = false
|
||||
billboard = 1
|
||||
texture = ExtResource("2_5w327")
|
||||
|
||||
[node name="Message" type="Label3D" parent="Bubble"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.00144005, 0)
|
||||
billboard = 1
|
||||
double_sided = false
|
||||
no_depth_test = true
|
||||
render_priority = 1
|
||||
text = ". . ."
|
||||
font = SubResource("FontVariation_q2tkp")
|
||||
font_size = 48
|
||||
outline_size = 26
|
||||
uppercase = true
|
||||
autowrap_mode = 3
|
||||
justification_flags = 171
|
||||
width = 700.0
|
||||
Reference in New Issue
Block a user