diff --git a/Game/Assets/Characters/Player.gd b/Game/Assets/Characters/Player.gd index 35a2a3a..bed15a6 100644 --- a/Game/Assets/Characters/Player.gd +++ b/Game/Assets/Characters/Player.gd @@ -19,11 +19,12 @@ extends CharacterBody3D @onready var weapon = $Head/Camera/Hand/Weapon -@onready var body_height = body.shape.height -@onready var body_y = body.position.y -@onready var mesh_height = mesh.mesh.mid_height -@onready var mesh_y = mesh.position.y -@onready var climb_check_y = climb_check.position.y +# climb functions - temporarily disabled +#@onready var body_height = body.shape.height +#@onready var body_y = body.position.y +#@onready var mesh_height = mesh.mesh.mid_height +#@onready var mesh_y = mesh.position.y +#@onready var climb_check_y = climb_check.position.y @onready var ground_check_y = ground_check.position.y var input_active = false @@ -38,20 +39,21 @@ var view_zoom := view_zoom_target : crosshair.modulate.a = clamp(1 - (zoom - 1), 0, 1) vignette.modulate.a = (zoom - 1) / 3 -var climb_height := 0.75 -var climb_time := 0.15 -var climb_state := 0.0 : - set(factor): - #print("climb_state is now ", factor) - climb_state = factor - body.shape.height = body_height - factor * climb_height - body.position.y = body_y + factor * climb_height / 2 - - mesh.mesh.mid_height = mesh_height - factor * climb_height - mesh.position.y = mesh_y + factor * climb_height / 2 - - ground_check.position.y = ground_check_y + factor * climb_height / 2 - climb_check.position.y = climb_check_y + factor * climb_height / 2 +# climbing code - disabled for now +#var climb_height := 0.75 +#var climb_time := 0.15 +#var climb_state := 0.0 : +# set(factor): +# #print("climb_state is now ", factor) +# climb_state = factor +# body.shape.height = body_height - factor * climb_height +# body.position.y = body_y + factor * climb_height / 2 +# +# mesh.mesh.mid_height = mesh_height - factor * climb_height +# mesh.position.y = mesh_y + factor * climb_height / 2 +# +# ground_check.position.y = ground_check_y + factor * climb_height / 2 +# climb_check.position.y = climb_check_y + factor * climb_height / 2 var direction := Vector3.ZERO var accel := 0 @@ -73,7 +75,7 @@ var jump := 14 var velocity := Vector3.ZERO var gravity_vec := Vector3.ZERO -@puppet func update_movement(player_transform, head_rotation): +@rpc func update_movement(player_transform, head_rotation): global_transform = player_transform head.set_rotation(head_rotation) @@ -83,12 +85,12 @@ func _ready() -> void: # generate_info() - rpc_config(&'move_and_slide', MultiplayerAPI.RPC_MODE_REMOTE) - rpc_config(&"aim", MultiplayerAPI.RPC_MODE_REMOTE) - rpc_config(&"set_global_transform", MultiplayerAPI.RPC_MODE_REMOTE) - rpc_config(&"set_linear_velocity", MultiplayerAPI.RPC_MODE_REMOTE) - head.rpc_config(&"set_rotation", MultiplayerAPI.RPC_MODE_REMOTE) - rpc_config(&"set_info", MultiplayerAPI.RPC_MODE_REMOTE) + rpc_config(&'move_and_slide', MultiplayerAPI.RPC_MODE_ANY) + rpc_config(&"aim", MultiplayerAPI.RPC_MODE_ANY) + rpc_config(&"set_global_transform", MultiplayerAPI.RPC_MODE_ANY) + rpc_config(&"set_linear_velocity", MultiplayerAPI.RPC_MODE_ANY) + head.rpc_config(&"set_rotation", MultiplayerAPI.RPC_MODE_ANY) + rpc_config(&"set_info", MultiplayerAPI.RPC_MODE_ANY) # rpc_config(&'move_and_slide', MultiplayerAPI.RPC_MODE_PUPPETSYNC) # rpc_config(&"aim", MultiplayerAPI.RPC_MODE_PUPPETSYNC) @@ -144,30 +146,30 @@ func _process(delta): view_zoom = max(view_zoom_target, view_zoom - delta * 4) func damage(hp: int): - var target = main.player_list.players[self.get_network_master()] + var target = main.player_list.players[self.get_network_authority()] target.health -= hp #if target.health <= 0: # int(name) is the player instance node name signifying owner's PID # die() func die(killer_pid: int): -# if get_tree().get_rpc_sender_id() != get_network_master(): +# if get_tree().get_rpc_sender_id() != get_network_authority(): # print ("Death requested by a non-master. Ignoring") # return - main.rpc(&'destroy_player', self.get_network_master()) + main.rpc(&'destroy_player', self.get_network_authority()) - main.chat.rpc(&'chat_notification', "Player [/i][b][color=" + main.player_list.players[self.get_network_master()].color.to_html() + "]" + main.player_list.players[self.get_network_master()].name + "[/color][/b][i] was killed by " + main.player_list.players[killer_pid].name ) + main.chat.rpc(&'chat_notification', "Player [/i][b][color=" + main.player_list.players[self.get_network_authority()].color.to_html() + "]" + main.player_list.players[self.get_network_authority()].name + "[/color][/b][i] was killed by " + main.player_list.players[killer_pid].name ) #queue_free() func update_color(pid) -> void: #change player's wolrdmodel color ## @onready var player_material = ## var material = player_material - if pid != get_network_master(): + if pid != self.get_network_authority(): print("Requesting color change for a different PID") return var player_material = mesh.mesh.surface_get_material(0).duplicate() - player_material.albedo_color = main.player_list.get(self.get_network_master()).color - print("Updating color of player pid ", self.get_network_master(), " to ", player_material.albedo_color ) + player_material.albedo_color = main.player_list.get(self.get_network_authority()).color + print("Updating color of player pid ", self.get_network_authority(), " to ", player_material.albedo_color ) mesh.mesh.surface_set_material(0, player_material) func _physics_process(delta): @@ -223,7 +225,7 @@ func _physics_process(delta): gravity_vec.y = linear_velocity.y # update puppets -# if get_tree().network_peer.get_unique_id() == 1: +# if get_tree().multiplayer.get_network_unique_id() == 1: # rpc(&'update_movement', global_transform, head.get_rotation()) # else: # rpc_id(1, &'update_movement', global_transform, head.get_rotation()) @@ -231,21 +233,21 @@ func _physics_process(delta): rpc(&'update_movement', global_transform, head.get_rotation()) # (stair) climbing - - if get_slide_count() > 1 and climb_check.is_colliding() and false: # disabled - Tween is undergoing redesign in Godot 4 - #print("climb started at climb state: ", climb_state) - var test_y = climb_height * (1 - climb_state) - #print("test_y: ", test_y) - var climb_test_start = global_transform.translated(Vector3(0, test_y, 0)) - var climb_test_step = Vector3(0,0,-0.1).rotated(Vector3.UP, rotation.y) - if not test_move(climb_test_start, climb_test_step): # no collision - var step = climb_check.get_collision_point().y - var start = global_transform.origin.y -# print("step: ", step, " start: ", start) - climb_state = clamp((step - start) / climb_height, 0, 1) - global_transform.origin.y += climb_height * climb_state - #print("climb state to start: ", climb_state) -# print("Climb height: ", step - start, " Climb state: ", climb_state) - climb_tween.remove_all() - climb_tween.interpolate_property(self, "climb_state", climb_state, 0.0, climb_time, Tween.TRANS_CUBIC, Tween.EASE_IN) - climb_tween.start() + # ↓ disabled - Tween is undergoing redesign in Godot 4 +# if get_slide_count() > 1 and climb_check.is_colliding() and false: +# #print("climb started at climb state: ", climb_state) +# var test_y = climb_height * (1 - climb_state) +# #print("test_y: ", test_y) +# var climb_test_start = global_transform.translated(Vector3(0, test_y, 0)) +# var climb_test_step = Vector3(0,0,-0.1).rotated(Vector3.UP, rotation.y) +# if not test_move(climb_test_start, climb_test_step): # no collision +# var step = climb_check.get_collision_point().y +# var start = global_transform.origin.y +## print("step: ", step, " start: ", start) +# climb_state = clamp((step - start) / climb_height, 0, 1) +# global_transform.origin.y += climb_height * climb_state +# #print("climb state to start: ", climb_state) +## print("Climb height: ", step - start, " Climb state: ", climb_state) +# climb_tween.remove_all() +# climb_tween.interpolate_property(self, "climb_state", climb_state, 0.0, climb_time, Tween.TRANS_CUBIC, Tween.EASE_IN) +# climb_tween.start() diff --git a/Game/Assets/HUD/Chat.gd b/Game/Assets/HUD/Chat.gd index 4dc8846..f4e7ef1 100644 --- a/Game/Assets/HUD/Chat.gd +++ b/Game/Assets/HUD/Chat.gd @@ -52,16 +52,16 @@ func _unhandled_input(_event) -> void: get_tree().get_root().set_input_as_handled() # doesn't work over network due to missing RPC implementation in Godot 4 -@remotesync func chat_message(sender_pid: int, recipient_team, message: String) -> void: +@rpc func chat_message(sender_pid: int, recipient_team, message: String) -> void: var sender_info = main.player_list.get(sender_pid) chat_history.append_bbcode('\n' + '[b][color=' + sender_info.color.to_html() +']' + str(sender_info.name) + '[/color][/b] : [i]' + message + '[/i]') -@remotesync func chat_notification(message: String) -> void: +@rpc func chat_notification(message: String) -> void: chat_history.append_bbcode('\n · ' + '[i]' + message + '[/i]') func _on_Editor_text_submitted(new_text): # RPC is currently not implemented in the engine - var sender_id = get_tree().get_network_unique_id() + var sender_id = get_tree().multiplayer.get_network_unique_id() var new_message = [sender_id, 0, new_text] rpc(&'chat_message',sender_id, 0, new_text) chat_editor.text = '' diff --git a/Game/Assets/Weapons/Weapon.gd b/Game/Assets/Weapons/Weapon.gd index 4c08013..6d23bc3 100644 --- a/Game/Assets/Weapons/Weapon.gd +++ b/Game/Assets/Weapons/Weapon.gd @@ -17,8 +17,8 @@ var impact_player = preload("res://Assets/Effects/ImpactPlayer.tscn") #enum Trigger {TRIGGER_PRIMARY, TRIGGER_SECONDARY} -@remotesync func shoot(): - #print("SHOOT from PID ", get_tree().get_network_unique_id(), " controlled by ", player.get_network_master()) +@rpc func shoot(): + #print("SHOOT from PID ", get_tree().multiplayer.get_network_unique_id(), " controlled by ", player.get_network_authority()) var space_state = get_world_3d().direct_space_state var from = camera.get_global_transform().origin @@ -31,16 +31,16 @@ var impact_player = preload("res://Assets/Effects/ImpactPlayer.tscn") if ray: # did we hit anything? if ray['collider'].has_method(&'damage'): - if get_tree().get_network_unique_id() == 1: # make sure this can only run on the server + if get_tree().multiplayer.get_network_unique_id() == 1: # make sure this can only run on the server #print("SHOT HIT ", ray['collider']) ray['collider'].damage(50) # apply damage - if main.player_list.get(ray['collider'].get_network_master()).health <= 0: # if he ded - ray['collider'].die(self.get_network_master()) + if main.player_list.get(ray['collider'].get_network_authority()).health <= 0: # if he ded + ray['collider'].die(self.get_network_authority()) - main.player_list.players[player.get_network_master()].score += 1 # give the killer a point - main.rpc(&'player_list_update', main.player_list.get(player.get_network_master()).serialize(), player.get_network_master()) + main.player_list.players[player.get_network_authority()].score += 1 # give the killer a point + main.rpc(&'player_list_update', main.player_list.get(player.get_network_authority()).serialize(), player.get_network_authority()) # boardcast the new health value to all peers - main.rpc(&'player_list_update', main.player_list.get(ray['collider'].get_network_master()).serialize(), ray['collider'].get_network_master()) + main.rpc(&'player_list_update', main.player_list.get(ray['collider'].get_network_authority()).serialize(), ray['collider'].get_network_authority()) impact_vfx = impact_player.instantiate() @@ -54,7 +54,7 @@ var impact_player = preload("res://Assets/Effects/ImpactPlayer.tscn") #print(ray) -@puppetsync func trigger(index: int, active: bool) -> void: +@rpc func trigger(index: int, active: bool) -> void: #print("Weapon " + str(name) + ", Trigger " + str(index) + ", active: " + str(active)) if index == 0 and active and $Handgun/AnimationPlayer.is_playing() == false: diff --git a/Game/Main.gd b/Game/Main.gd index 0421ab7..d54fe0d 100644 --- a/Game/Main.gd +++ b/Game/Main.gd @@ -6,7 +6,7 @@ enum NetworkRole {NONE, CLIENT, SERVER, DEDICATED_SERVER, RELAY_SERVER} const NET_PORT = 12597 const NET_SERVER = "localhost" #liblast.unfa.xyz" -var peer = NetworkedMultiplayerENet.new() +var peer = ENetMultiplayerPeer.new() var role = NetworkRole.NONE: set(new_role): @@ -98,11 +98,11 @@ class PlayerList: return players[pid] # func update(): -# if get_tree().network_peer.get_unique_id() == 1: +# if get_tree().multiplayer.get_network_unique_id() == 1: # for i in players.keys: # rpc(&'player_list_update', i, players[i].serialize()) # else: -# rpc_id(1, &'player_list_update', players[get_tree().network_peer.get_unique_id()].serialize()) +# rpc_id(1, &'player_list_update', players[get_tree().multiplayer.get_network_unique_id()].serialize()) @onready var player_list = PlayerList.new() @@ -150,7 +150,7 @@ func _input(_event) -> void: #@remote func update_player_list(player_list): # self.player_list = player_list -@remote func player_list_update(info, pid = get_tree().get_rpc_sender_id()): +@rpc func player_list_update(info, pid = get_tree().get_rpc_sender_id()): var new_info = PlayerInfo.new() new_info.deserialize(info) print("Recieved player info: ", info) @@ -165,12 +165,12 @@ func _input(_event) -> void: #chat.chat_notification("Player [b]" + new_info.name + "[/b] changed color to [b][color=" + new_info.color.to_html() + "]" + new_info.name + "[/color][/b]") $Players.get_node(str(pid)).update_color(pid) - elif get_tree().network_peer.get_unique_id() == 1: + elif get_tree().multiplayer.get_network_unique_id() == 1: for i in player_list.players.keys(): #notify existing players the new one has joined # if i != pid: chat.rpc_id(i, &'chat_notification', "Player [b]" + new_info.name + "[/b] joined") - if get_tree().network_peer.get_unique_id() == 1: # if we're server, we should store this + if get_tree().multiplayer.get_network_unique_id() == 1: # if we're server, we should store this pid = get_tree().get_rpc_sender_id() #disallow clients setting player_info for other players than themselves player_list.set(pid, new_info) rpc(&'player_list_update', info, pid) # broadcast the new entry to clients @@ -178,16 +178,16 @@ func _input(_event) -> void: player_list.set(pid, new_info) # server relays other PID's data func push_local_player_info(): # - var id = get_tree().network_peer.get_unique_id() + var id = get_tree().multiplayer.get_network_unique_id() #print("PLayer info vsr2str: ", var2str(player_list.get(id)) ) if id != 1: - rpc_id(1, &'player_list_update', player_list.get(id).serialize(), get_tree().get_network_unique_id()) + rpc_id(1, &'player_list_update', player_list.get(id).serialize(), get_tree().multiplayer.get_network_unique_id()) else: rpc(&'player_list_update', player_list.get(id).serialize(), 1) -@remotesync func destroy_player(pid: int): +@rpc func destroy_player(pid: int): var player_node = $Players.get_node(str(pid)) assert(player_node != null, "Attempting to delete a player node that does not exist") @@ -195,7 +195,7 @@ func push_local_player_info(): # player_node.queue_free() #player.queue_free() - var is_local = true if pid == local_player.get_network_master() else false + var is_local = true if pid == local_player.get_network_authority() else false create_player(pid, is_local, true) @@ -206,7 +206,7 @@ func create_player(pid: int, is_local:= false, respawn:= false) -> void: var spawnpoint = $Map/SpawnPoints.get_children()[randi() % len($Map/SpawnPoints.get_children())] new_player.name = str(pid) new_player.global_transform = spawnpoint.global_transform - new_player.set_network_master(pid) + new_player.set_network_authority(pid) $Players.add_child(new_player) var new_info: PlayerInfo @@ -220,7 +220,7 @@ func create_player(pid: int, is_local:= false, respawn:= false) -> void: player_list.set(pid, new_info) # superfluous and harmful code that messes up player data: -# if get_tree().network_peer.get_unique_id() != 1: # if we're not the server - update the server +# if get_tree().multiplayer.get_network_unique_id() != 1: # if we're not the server - update the server # rpc_id(1, &'player_list_update', new_info.serialize(), pid) # send local player info to the server # else: # if we're the server, update the clients # rpc(&'player_list_update', new_info.serialize(), pid) @@ -248,7 +248,7 @@ func _on_Host_pressed(): # start server and create a local player $NetworkTesting/Connect.disabled = true peer.create_server(NET_PORT, 16) - get_tree().network_peer = peer + get_tree().multiplayer.network_peer = peer create_player(1, true) focus = GameFocus.GAME chat.chat_notification("Started server") @@ -258,13 +258,13 @@ func _on_Connect_pressed(): $NetworkTesting/Connect.disabled = true peer.create_client(NET_SERVER, NET_PORT) - get_tree().network_peer = peer + get_tree().multiplayer.network_peer = peer func _player_connected(pid) -> void: print("player connected, id: ", pid) create_player(pid, false) - if get_tree().network_peer.get_unique_id() == 1: # if we're the server + if get_tree().multiplayer.get_network_unique_id() == 1: # if we're the server for i in player_list.players.keys(): # send the player_list to the new client #pass rpc_id(pid, &'player_list_update', player_list.get(i).serialize(), i) # send local player info to the server @@ -278,13 +278,13 @@ func _player_connected(pid) -> void: func _player_disconnected(pid) -> void: print("player disconnected, id: ", pid) - if get_tree().network_peer.get_unique_id() == 1: # if we're the server, broadcast that a player left + if get_tree().multiplayer.get_network_unique_id() == 1: # if we're the server, broadcast that a player left chat.rpc(&'chat_notification', "Player [b]" + player_list.get(pid).name + "[/b] left") func _connected_ok() -> void: print("connected to server") chat.chat_notification("Connected to server") - var pid = get_tree().get_network_unique_id() + var pid = get_tree().multiplayer.get_network_unique_id() create_player(pid, true) focus = GameFocus.GAME role = NetworkRole.CLIENT @@ -300,7 +300,7 @@ func _server_disconnected() -> void: func _ready() -> void: - peer.compression_mode = NetworkedMultiplayerENet.COMPRESS_ZSTD + #peer.compression_mode = NetworkedMultiplayerENet.COMPRESS_ZSTD print("Commandline arguments: ", OS.get_cmdline_args()) get_tree().connect("network_peer_connected", self._player_connected) @@ -313,11 +313,11 @@ func _ready() -> void: start_dedicated_server() func _on_TextEdit_text_submitted(new_text): - player_list.players[get_tree().network_peer.get_unique_id()].name = new_text + player_list.players[get_tree().multiplayer.get_network_unique_id()].name = new_text push_local_player_info() #chat_announcement("Player " + old_name + " is now known as " + new_name) func _on_ColorPickerButton_color_changed(color): - player_list.players[get_tree().network_peer.get_unique_id()].color = color + player_list.players[get_tree().multiplayer.get_network_unique_id()].color = color push_local_player_info() #local_player.rpc(&'set_color', color) diff --git a/Game/Main.tscn b/Game/Main.tscn index cde74e4..ed82ae6 100644 --- a/Game/Main.tscn +++ b/Game/Main.tscn @@ -1,14 +1,14 @@ -[gd_scene load_steps=5 format=2] +[gd_scene load_steps=5 format=3 uid="uid://o68cawatyat2"] -[ext_resource path="res://Map.tscn" type="PackedScene" id=1] -[ext_resource path="res://Assets/UI/GUI.tscn" type="PackedScene" id=2] -[ext_resource path="res://Main.gd" type="Script" id=3] -[ext_resource path="res://Assets/HUD/HUD.tscn" type="PackedScene" id=4] +[ext_resource type="PackedScene" path="res://Map.tscn" id="1"] +[ext_resource type="PackedScene" path="res://Assets/UI/GUI.tscn" id="2"] +[ext_resource type="Script" path="res://Main.gd" id="3"] +[ext_resource type="PackedScene" path="res://Assets/HUD/HUD.tscn" id="4"] [node name="Main" type="Node"] -script = ExtResource( 3 ) +script = ExtResource( "3" ) -[node name="HUD" parent="." instance=ExtResource( 4 )] +[node name="HUD" parent="." instance=ExtResource( "4" )] [node name="AnimationPlayer" parent="HUD/Crosshair" index="1"] blend_times = [] @@ -23,7 +23,7 @@ structured_text_bidi_override_options = [] [node name="Editor" parent="HUD/Chat/VBoxContainer/Typing" index="1"] structured_text_bidi_override_options = [] -[node name="GUI" parent="." instance=ExtResource( 2 )] +[node name="GUI" parent="." instance=ExtResource( "2" )] [node name="Players" type="Node3D" parent="."] script = null @@ -31,7 +31,7 @@ __meta__ = { "_edit_lock_": true } -[node name="Map" parent="." instance=ExtResource( 1 )] +[node name="Map" parent="." instance=ExtResource( "1" )] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1) [node name="NetworkTesting" type="VBoxContainer" parent="."]