Stripping networking, player, and ship stuff
This commit is contained in:
parent
cef87a7e2f
commit
58be46ff19
@ -2,7 +2,7 @@ class_name Interactable
|
||||
|
||||
extends Node3D
|
||||
|
||||
var player_reference: Player
|
||||
#var player_reference: Player
|
||||
|
||||
|
||||
func interact():
|
||||
|
@ -1,36 +0,0 @@
|
||||
[gd_scene load_steps=7 format=3 uid="uid://dm31ddavxv5gt"]
|
||||
|
||||
[ext_resource type="Script" path="res://assets/core/interactables/ship-helm/ship_helm.gd" id="1_lsarv"]
|
||||
[ext_resource type="PackedScene" uid="uid://d2e3plio1db16" path="res://assets/core/interactables/ship-helm/ship_helm.blend" id="2_n3ctg"]
|
||||
[ext_resource type="Texture2D" uid="uid://becx0d2aass76" path="res://addons/kennysprototypetextures/Purple/texture_purple (1).png" id="3_sgyh6"]
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_vj8ph"]
|
||||
albedo_texture = ExtResource("3_sgyh6")
|
||||
uv1_triplanar = true
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_mtdgj"]
|
||||
albedo_texture = ExtResource("3_sgyh6")
|
||||
uv1_triplanar = true
|
||||
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_u6a0w"]
|
||||
size = Vector3(1, 1.23828, 0.332275)
|
||||
|
||||
[node name="ShipHelm" type="StaticBody3D"]
|
||||
collision_layer = 256
|
||||
collision_mask = 7
|
||||
script = ExtResource("1_lsarv")
|
||||
|
||||
[node name="ship_helm" parent="." instance=ExtResource("2_n3ctg")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.681346, 0)
|
||||
|
||||
[node name="Cube" parent="ship_helm" index="0"]
|
||||
material_override = SubResource("StandardMaterial3D_vj8ph")
|
||||
|
||||
[node name="Torus" parent="ship_helm" index="1"]
|
||||
material_override = SubResource("StandardMaterial3D_mtdgj")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.901878, 0.0608378)
|
||||
shape = SubResource("BoxShape3D_u6a0w")
|
||||
|
||||
[editable path="ship_helm"]
|
Binary file not shown.
@ -1,51 +0,0 @@
|
||||
[remap]
|
||||
|
||||
importer="scene"
|
||||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://d2e3plio1db16"
|
||||
path="res://.godot/imported/ship_helm.blend-ff92b4e852f739448ae2d5004545d8b0.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/core/interactables/ship-helm/ship_helm.blend"
|
||||
dest_files=["res://.godot/imported/ship_helm.blend-ff92b4e852f739448ae2d5004545d8b0.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
nodes/root_type=""
|
||||
nodes/root_name=""
|
||||
nodes/apply_root_scale=true
|
||||
nodes/root_scale=1.0
|
||||
nodes/import_as_skeleton_bones=false
|
||||
meshes/ensure_tangents=true
|
||||
meshes/generate_lods=true
|
||||
meshes/create_shadow_meshes=true
|
||||
meshes/light_baking=1
|
||||
meshes/lightmap_texel_size=0.2
|
||||
meshes/force_disable_compression=false
|
||||
skins/use_named_skins=true
|
||||
animation/import=true
|
||||
animation/fps=30
|
||||
animation/trimming=false
|
||||
animation/remove_immutable_tracks=true
|
||||
animation/import_rest_as_RESET=false
|
||||
import_script/path=""
|
||||
_subresources={}
|
||||
blender/nodes/visible=0
|
||||
blender/nodes/active_collection_only=false
|
||||
blender/nodes/punctual_lights=true
|
||||
blender/nodes/cameras=true
|
||||
blender/nodes/custom_properties=true
|
||||
blender/nodes/modifiers=1
|
||||
blender/meshes/colors=false
|
||||
blender/meshes/uvs=true
|
||||
blender/meshes/normals=true
|
||||
blender/meshes/tangents=true
|
||||
blender/meshes/skins=2
|
||||
blender/meshes/export_bones_deforming_mesh_only=false
|
||||
blender/materials/unpack_enabled=true
|
||||
blender/materials/export_materials=1
|
||||
blender/animation/limit_playback=true
|
||||
blender/animation/always_sample=true
|
||||
blender/animation/group_tracks=true
|
@ -1,15 +0,0 @@
|
||||
class_name ShipHelm
|
||||
extends Interactable
|
||||
|
||||
@export var parent_ship: Ship
|
||||
|
||||
func interact():
|
||||
if player_reference.is_network_authority:
|
||||
if !parent_ship.ship_is_piloted:
|
||||
player_reference.set_is_piloting(true)
|
||||
parent_ship.set_piloting_player(player_reference)
|
||||
|
||||
elif parent_ship.ship_is_piloted:
|
||||
player_reference.set_is_piloting(false)
|
||||
parent_ship.remove_piloting_player()
|
||||
|
@ -1,70 +0,0 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://7t1x82gvrw8a"]
|
||||
|
||||
[ext_resource type="Script" path="res://assets/core/networking/scripts/lobby.gd" id="1_o4fbq"]
|
||||
[ext_resource type="PackedScene" uid="uid://biryul3n6thlw" path="res://assets/core/networking/scenes/user_box_prefab.tscn" id="2_dpthk"]
|
||||
|
||||
[node name="Lobby" type="Control" node_paths=PackedStringArray("host_button", "leave_button", "start_button", "show_lobbies_button", "user_list_box", "lobby_list_box")]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_o4fbq")
|
||||
host_button = NodePath("Panel/HBoxContainer/Buttons/Host")
|
||||
leave_button = NodePath("Panel/HBoxContainer/Buttons/Leave")
|
||||
start_button = NodePath("Panel/HBoxContainer/Buttons/Start")
|
||||
show_lobbies_button = NodePath("Panel/HBoxContainer/Buttons/ShowLobbies")
|
||||
user_list_box = NodePath("Panel/HBoxContainer/PlayerList")
|
||||
lobby_list_box = NodePath("Panel/HBoxContainer/LobbyList")
|
||||
user_box_prefab = ExtResource("2_dpthk")
|
||||
|
||||
[node name="Panel" type="Panel" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="Panel"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Buttons" type="VBoxContainer" parent="Panel/HBoxContainer"]
|
||||
custom_minimum_size = Vector2(500, 0)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 6
|
||||
size_flags_vertical = 4
|
||||
|
||||
[node name="Host" type="Button" parent="Panel/HBoxContainer/Buttons"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 4
|
||||
text = "Host Lobby"
|
||||
|
||||
[node name="Start" type="Button" parent="Panel/HBoxContainer/Buttons"]
|
||||
layout_mode = 2
|
||||
disabled = true
|
||||
text = "Start"
|
||||
|
||||
[node name="ShowLobbies" type="Button" parent="Panel/HBoxContainer/Buttons"]
|
||||
layout_mode = 2
|
||||
text = "Show Lobbies"
|
||||
|
||||
[node name="Leave" type="Button" parent="Panel/HBoxContainer/Buttons"]
|
||||
layout_mode = 2
|
||||
disabled = true
|
||||
text = "Leave Lobby"
|
||||
|
||||
[node name="PlayerList" type="VBoxContainer" parent="Panel/HBoxContainer"]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="LobbyList" type="VBoxContainer" parent="Panel/HBoxContainer"]
|
||||
visible = false
|
||||
layout_mode = 2
|
@ -1,20 +0,0 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://biryul3n6thlw"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://fwub8fvl2u4i" path="res://addons/ingameconsole/ps1hagrid.png" id="1_gtutw"]
|
||||
|
||||
[node name="UserBox" type="HBoxContainer"]
|
||||
offset_right = 610.0
|
||||
offset_bottom = 128.0
|
||||
|
||||
[node name="PFP" type="TextureRect" parent="."]
|
||||
custom_minimum_size = Vector2(128, 128)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
texture = ExtResource("1_gtutw")
|
||||
expand_mode = 1
|
||||
|
||||
[node name="Username" type="Label" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "Hagrid 1"
|
||||
horizontal_alignment = 1
|
@ -1,418 +0,0 @@
|
||||
extends Node
|
||||
|
||||
const STEAM_APP_ID: int = 480
|
||||
|
||||
const PACKET_READ_LIMIT: int = 32
|
||||
|
||||
var level_scene: PackedScene
|
||||
var player_scene: PackedScene
|
||||
|
||||
var lobby_data
|
||||
var lobby_id: int = 0
|
||||
var lobby_members: Array = []
|
||||
var lobby_members_max: int = 10
|
||||
var lobby_vote_kick: bool = false
|
||||
var lobby_type: int = Steam.LOBBY_TYPE_PUBLIC
|
||||
var steam_id: int = 0
|
||||
var steam_username: String = ""
|
||||
var avatar_texture_cache: Dictionary = {}
|
||||
var is_host: bool = false
|
||||
var host_id: int
|
||||
|
||||
var uuid_counter: int = 0
|
||||
|
||||
var node_map: Dictionary = {}
|
||||
|
||||
signal lobby_created(lobby_id: int)
|
||||
signal lobby_joined(lobby_id: int)
|
||||
signal user_joined_lobby(user_id: int)
|
||||
signal user_left_lobby(user_id: int)
|
||||
signal host_left_lobby()
|
||||
signal on_game_started()
|
||||
signal on_lobbies_received(these_lobbies: Array)
|
||||
|
||||
signal property_update_received(node_id: int, property_name: String, value: Variant)
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
player_scene = load("res://assets/core/player-controller/scenes/player.tscn") as PackedScene
|
||||
level_scene = load("res://assets/core/enviroment/dev-level/dev-level.tscn") as PackedScene
|
||||
_init_steam()
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
Steam.run_callbacks()
|
||||
|
||||
if lobby_id > 0:
|
||||
read_all_p2p_packets()
|
||||
|
||||
|
||||
func _init_steam() -> void:
|
||||
var init_result = Steam.steamInitEx(true, STEAM_APP_ID)
|
||||
print("Steam Init Result: " + str(init_result))
|
||||
|
||||
if init_result['status'] > 0:
|
||||
printerr("Steam failed to initialize, shutting down: " + str(init_result))
|
||||
#get_tree().quit()
|
||||
|
||||
steam_id = Steam.getSteamID()
|
||||
steam_username = Steam.getFriendPersonaName(steam_id)
|
||||
|
||||
Steam.p2p_session_request.connect(_on_p2p_session_request)
|
||||
Steam.p2p_session_connect_fail.connect(_on_p2p_session_connect_fail)
|
||||
|
||||
Steam.join_requested.connect(_on_lobby_join_requested)
|
||||
Steam.lobby_chat_update.connect(_on_lobby_chat_update)
|
||||
Steam.lobby_created.connect(_on_lobby_created)
|
||||
#Steam.lobby_data_update.connect(_on_lobby_data_update)
|
||||
#Steam.lobby_invite.connect(_on_lobby_invite)
|
||||
Steam.lobby_joined.connect(_on_lobby_joined)
|
||||
Steam.lobby_match_list.connect(_on_lobby_match_list)
|
||||
Steam.lobby_message.connect(_on_lobby_message)
|
||||
Steam.persona_state_change.connect(_on_persona_change)
|
||||
|
||||
|
||||
func _on_lobby_join_requested(this_lobby_id: int, friend_id: int):
|
||||
var owner_name: String = Steam.getFriendPersonaName(friend_id)
|
||||
print("Trying to join " + owner_name + "'s lobby...")
|
||||
join_lobby(this_lobby_id)
|
||||
|
||||
|
||||
func _on_lobby_chat_update(this_lobby_id: int, change_id: int, making_change_id: int, chat_state: int) -> void:
|
||||
var changer_name: String = Steam.getFriendPersonaName(change_id)
|
||||
|
||||
# If a player has joined the lobby
|
||||
if chat_state == Steam.CHAT_MEMBER_STATE_CHANGE_ENTERED:
|
||||
print("%s has joined the lobby." % changer_name)
|
||||
|
||||
elif chat_state == Steam.CHAT_MEMBER_STATE_CHANGE_LEFT:
|
||||
user_left_lobby.emit(change_id)
|
||||
print("%s has left the lobby." % changer_name)
|
||||
|
||||
elif chat_state == Steam.CHAT_MEMBER_STATE_CHANGE_KICKED:
|
||||
print("%s has been kicked from the lobby." % changer_name)
|
||||
|
||||
elif chat_state == Steam.CHAT_MEMBER_STATE_CHANGE_BANNED:
|
||||
print("%s has been banned from the lobby." % changer_name)
|
||||
|
||||
else:
|
||||
print("%s did... something." % changer_name)
|
||||
|
||||
get_lobby_members()
|
||||
|
||||
|
||||
func _on_lobby_created(connect: int, this_lobby_id: int) -> void:
|
||||
if connect == 1:
|
||||
lobby_id = this_lobby_id
|
||||
lobby_created.emit(lobby_id)
|
||||
print("Lobby created with ID: " + str(lobby_id))
|
||||
|
||||
Steam.setLobbyJoinable(lobby_id, true)
|
||||
Steam.setLobbyData(lobby_id, "name", str(steam_username) + "'s Lobby")
|
||||
|
||||
var set_relay: bool = Steam.allowP2PPacketRelay(true)
|
||||
|
||||
|
||||
#func _on_lobby_data_update():
|
||||
# pass
|
||||
|
||||
|
||||
#func _on_lobby_invite():
|
||||
# pass
|
||||
|
||||
|
||||
func _on_lobby_joined(this_lobby_id: int, _permissions: int, _locked: bool, response: int) -> void:
|
||||
if response == Steam.CHAT_ROOM_ENTER_RESPONSE_SUCCESS:
|
||||
lobby_id = this_lobby_id
|
||||
get_lobby_members()
|
||||
make_p2p_handshake()
|
||||
lobby_joined.emit(lobby_id)
|
||||
else:
|
||||
var fail_reason: String
|
||||
|
||||
match response:
|
||||
Steam.CHAT_ROOM_ENTER_RESPONSE_DOESNT_EXIST: fail_reason = "This lobby no longer exists."
|
||||
Steam.CHAT_ROOM_ENTER_RESPONSE_NOT_ALLOWED: fail_reason = "You don't have permission to join this lobby."
|
||||
Steam.CHAT_ROOM_ENTER_RESPONSE_FULL: fail_reason = "The lobby is now full."
|
||||
Steam.CHAT_ROOM_ENTER_RESPONSE_ERROR: fail_reason = "Uh... something unexpected happened!"
|
||||
Steam.CHAT_ROOM_ENTER_RESPONSE_BANNED: fail_reason = "You are banned from this lobby."
|
||||
Steam.CHAT_ROOM_ENTER_RESPONSE_LIMITED: fail_reason = "You cannot join due to having a limited account."
|
||||
Steam.CHAT_ROOM_ENTER_RESPONSE_CLAN_DISABLED: fail_reason = "This lobby is locked or disabled."
|
||||
Steam.CHAT_ROOM_ENTER_RESPONSE_COMMUNITY_BAN: fail_reason = "This lobby is community locked."
|
||||
Steam.CHAT_ROOM_ENTER_RESPONSE_MEMBER_BLOCKED_YOU: fail_reason = "A user in the lobby has blocked you from joining."
|
||||
Steam.CHAT_ROOM_ENTER_RESPONSE_YOU_BLOCKED_MEMBER: fail_reason = "A user you have blocked is in the lobby."
|
||||
|
||||
print("Failed to join this chat room: %s" % fail_reason)
|
||||
|
||||
|
||||
func _on_lobby_match_list(these_lobbies: Array) -> void:
|
||||
on_lobbies_received.emit(these_lobbies)
|
||||
|
||||
|
||||
func _on_lobby_message():
|
||||
pass
|
||||
|
||||
|
||||
func _on_persona_change(this_steam_id: int, _flags: int) -> void:
|
||||
if lobby_id > 0 and lobby_members:
|
||||
for member in lobby_members:
|
||||
if member["steam_id"] == this_steam_id:
|
||||
var user: String = str(this_steam_id) + ":" + Steam.getFriendPersonaName(this_steam_id)
|
||||
print("User (%s) had information change, updating lobby list." % user)
|
||||
get_lobby_members()
|
||||
break
|
||||
|
||||
|
||||
func _on_p2p_session_request(remote_id: int):
|
||||
var this_requester: String = Steam.getFriendPersonaName(remote_id)
|
||||
print("P2P session request from: " + this_requester)
|
||||
Steam.acceptP2PSessionWithUser(remote_id)
|
||||
make_p2p_handshake()
|
||||
|
||||
|
||||
func _on_p2p_session_connect_fail(steam_id: int, session_error: int) -> void:
|
||||
# If no error was given
|
||||
if session_error == 0:
|
||||
print("WARNING: Session failure with %s: no error given" % steam_id)
|
||||
|
||||
# Else if target user was not running the same game
|
||||
elif session_error == 1:
|
||||
print("WARNING: Session failure with %s: target user not running the same game" % steam_id)
|
||||
|
||||
# Else if local user doesn't own app / game
|
||||
elif session_error == 2:
|
||||
print("WARNING: Session failure with %s: local user doesn't own app / game" % steam_id)
|
||||
|
||||
# Else if target user isn't connected to Steam
|
||||
elif session_error == 3:
|
||||
print("WARNING: Session failure with %s: target user isn't connected to Steam" % steam_id)
|
||||
|
||||
# Else if connection timed out
|
||||
elif session_error == 4:
|
||||
print("WARNING: Session failure with %s: connection timed out" % steam_id)
|
||||
|
||||
# Else if unused
|
||||
elif session_error == 5:
|
||||
print("WARNING: Session failure with %s: unused" % steam_id)
|
||||
|
||||
# Else no known error
|
||||
else:
|
||||
print("WARNING: Session failure with %s: unknown error %s" % [steam_id, session_error])
|
||||
|
||||
|
||||
func host_lobby():
|
||||
if lobby_id == 0:
|
||||
Steam.createLobby(lobby_type, lobby_members_max)
|
||||
is_host = true
|
||||
host_id = steam_id
|
||||
else:
|
||||
printerr("Cannot host lobby, already in a lobby")
|
||||
|
||||
|
||||
func join_lobby(this_lobby_id: int):
|
||||
print("Attempting to join lobby: " + str(this_lobby_id))
|
||||
lobby_members.clear()
|
||||
Steam.joinLobby(this_lobby_id)
|
||||
host_id = Steam.getLobbyOwner(this_lobby_id)
|
||||
|
||||
|
||||
func leave_lobby():
|
||||
if lobby_id != 0:
|
||||
Steam.leaveLobby(lobby_id)
|
||||
lobby_id = 0
|
||||
host_id = 0
|
||||
|
||||
for this_member in lobby_members:
|
||||
if this_member["steam_id"] != steam_id:
|
||||
Steam.closeP2PSessionWithUser(this_member["steam_id"])
|
||||
|
||||
lobby_members.clear()
|
||||
print("Left lobby.")
|
||||
|
||||
|
||||
|
||||
func get_lobbies():
|
||||
Steam.addRequestLobbyListDistanceFilter(Steam.LOBBY_DISTANCE_FILTER_WORLDWIDE)
|
||||
Steam.requestLobbyList()
|
||||
|
||||
|
||||
func get_lobby_members():
|
||||
lobby_members.clear()
|
||||
var member_count: int = Steam.getNumLobbyMembers(lobby_id)
|
||||
|
||||
for this_member in range(0, member_count):
|
||||
var member_steam_id: int = Steam.getLobbyMemberByIndex(lobby_id, this_member)
|
||||
var member_steam_name: String = Steam.getFriendPersonaName(member_steam_id)
|
||||
lobby_members.append({"steam_id":member_steam_id, "steam_name":member_steam_name})
|
||||
user_joined_lobby.emit(member_steam_id)
|
||||
await request_player_avatar(member_steam_id)
|
||||
|
||||
|
||||
func make_p2p_handshake():
|
||||
print("Sending p2p handshake to the lobby...")
|
||||
send_p2p_packet(0, {"message":"handshake", "from":steam_id})
|
||||
|
||||
|
||||
func send_p2p_packet(target: int, packet_data: Dictionary) -> void:
|
||||
# Set the send_type and channel
|
||||
var send_type: int = Steam.P2P_SEND_RELIABLE
|
||||
var channel: int = 0
|
||||
|
||||
# Create a data array to send the data through
|
||||
var this_data: PackedByteArray
|
||||
|
||||
# Compress the PackedByteArray we create from our dictionary using the GZIP compression method
|
||||
var compressed_data: PackedByteArray = var_to_bytes(packet_data).compress(FileAccess.COMPRESSION_GZIP)
|
||||
this_data.append_array(compressed_data)
|
||||
|
||||
# If sending a packet to everyone
|
||||
if target == 0:
|
||||
# If there is more than one user, send packets
|
||||
if lobby_members.size() > 1:
|
||||
# Loop through all members that aren't you
|
||||
for this_member in lobby_members:
|
||||
if this_member['steam_id'] != steam_id:
|
||||
Steam.sendP2PPacket(this_member['steam_id'], this_data, send_type, channel)
|
||||
#print("Sent packet to %s." % this_member['steam_name'])
|
||||
# If sending a packet to everyone except the host
|
||||
elif target == 1:
|
||||
if lobby_members.size() > 1:
|
||||
# Loop through all members that aren't the host
|
||||
for this_member in lobby_members:
|
||||
if this_member['steam_id'] != host_id:
|
||||
Steam.sendP2PPacket(this_member['steam_id'], this_data, send_type, channel)
|
||||
# Else send it to someone specific
|
||||
else:
|
||||
Steam.sendP2PPacket(target, this_data, send_type, channel)
|
||||
|
||||
|
||||
func read_all_p2p_packets(read_count: int = 0):
|
||||
if read_count >= PACKET_READ_LIMIT:
|
||||
return
|
||||
|
||||
if Steam.getAvailableP2PPacketSize(0) > 0:
|
||||
read_p2p_packet()
|
||||
read_all_p2p_packets(read_count + 1)
|
||||
|
||||
|
||||
func read_p2p_packet() -> void:
|
||||
var packet_size: int = Steam.getAvailableP2PPacketSize(0)
|
||||
|
||||
# There is a packet
|
||||
if packet_size > 0:
|
||||
var this_packet: Dictionary = Steam.readP2PPacket(packet_size, 0)
|
||||
|
||||
if this_packet.is_empty() or this_packet == null:
|
||||
print("WARNING: read an empty packet with non-zero size!")
|
||||
|
||||
# Get the remote user's ID
|
||||
var packet_sender: int = this_packet['remote_steam_id']
|
||||
|
||||
# Make the packet data readable
|
||||
var packet_code: PackedByteArray = this_packet['data']
|
||||
|
||||
# Decompress the array before turning it into a useable dictionary
|
||||
var readable_data: Dictionary = bytes_to_var(packet_code.decompress_dynamic(-1, FileAccess.COMPRESSION_GZIP))
|
||||
|
||||
# Handshake packet
|
||||
if "message" in readable_data and readable_data["message"] == "handshake":
|
||||
if packet_sender != steam_id:
|
||||
print("Received handshake packet from %s." % Steam.getFriendPersonaName(packet_sender))
|
||||
|
||||
# Start game packet
|
||||
if "message" in readable_data and readable_data["message"] == "start_game":
|
||||
print("Received game start packet.")
|
||||
_on_game_started()
|
||||
|
||||
# Property update packet
|
||||
if "message" in readable_data and readable_data["message"] == "property_update":
|
||||
if "node_id" in readable_data and "property_name" in readable_data and "value" in readable_data:
|
||||
emit_signal("property_update_received", readable_data["node_id"], readable_data["property_name"], readable_data["value"])
|
||||
|
||||
|
||||
func register_node(node: Node) -> String:
|
||||
var uuid = generate_uuid()
|
||||
node_map[uuid] = node
|
||||
return uuid
|
||||
|
||||
|
||||
func generate_uuid() -> String:
|
||||
uuid_counter += 1
|
||||
return str(uuid_counter)
|
||||
|
||||
|
||||
func request_player_avatar(user_id: int, size: int = 128) -> void:
|
||||
var avatar_texture: ImageTexture = null
|
||||
Steam.getPlayerAvatar(Steam.AVATAR_LARGE, user_id)
|
||||
print("Attempting to get avatar for " + Steam.getFriendPersonaName(user_id) + ".....")
|
||||
|
||||
Steam.avatar_loaded.connect(func(loaded_user_id: int, avatar_size: int, avatar_buffer: PackedByteArray):
|
||||
if loaded_user_id == user_id:
|
||||
var avatar_image: Image = Image.create_from_data(avatar_size, avatar_size, false, Image.FORMAT_RGBA8, avatar_buffer)
|
||||
|
||||
if avatar_size != size:
|
||||
avatar_image.resize(size, size, Image.INTERPOLATE_LANCZOS)
|
||||
|
||||
avatar_texture = ImageTexture.create_from_image(avatar_image)
|
||||
avatar_texture_cache[user_id] = avatar_texture
|
||||
)
|
||||
|
||||
|
||||
while not avatar_texture_cache.has(user_id):
|
||||
await get_tree().process_frame
|
||||
|
||||
|
||||
func get_player_avatar(user_id: int) -> ImageTexture:
|
||||
if avatar_texture_cache.has(user_id):
|
||||
return avatar_texture_cache[user_id]
|
||||
else:
|
||||
await request_player_avatar(user_id)
|
||||
return avatar_texture_cache[user_id]
|
||||
|
||||
|
||||
func start_game():
|
||||
print("Starting game...")
|
||||
var packet_data = {"message":"start_game"}
|
||||
send_p2p_packet(0, packet_data)
|
||||
_on_game_started()
|
||||
|
||||
|
||||
func _on_game_started():
|
||||
print("Game started.")
|
||||
var level: Node = level_scene.instantiate()
|
||||
get_tree().root.add_child(level)
|
||||
on_game_started.emit()
|
||||
|
||||
|
||||
for member in lobby_members:
|
||||
var player: Player = player_scene.instantiate()
|
||||
player.name = "Player_" + str(member["steam_id"])
|
||||
player.username = Steam.getFriendPersonaName(member["steam_id"])
|
||||
player.steam_id = member["steam_id"]
|
||||
|
||||
if member["steam_id"] == steam_id:
|
||||
player.is_network_authority = true
|
||||
else:
|
||||
player.is_network_authority = false
|
||||
|
||||
level.add_child(player)
|
||||
|
||||
|
||||
func sync_property_to_host(node_id: String, property_name: String, value: Variant):
|
||||
var packet_data = {"message":"property_update", "node_id": node_id, "property_name": property_name, "value": value}
|
||||
send_p2p_packet(host_id, packet_data)
|
||||
|
||||
|
||||
func sync_property_to_peer(node_id: String, property_name: String, value: Variant, target_peer: int):
|
||||
var packet_data = {"message":"property_update", "node_id": node_id, "property_name": property_name, "value": value}
|
||||
send_p2p_packet(target_peer, packet_data)
|
||||
|
||||
|
||||
func sync_property_to_all(node_id: String, property_name: String, value: Variant):
|
||||
var packet_data = {"message":"property_update", "node_id": node_id, "property_name":property_name, "value":value}
|
||||
send_p2p_packet(0, packet_data)
|
||||
|
||||
|
||||
func sync_property_to_all_except_host(node_id: String, property_name: String, value: Variant):
|
||||
var packet_data = {"message":"property_update", "node_id": node_id, "property_name":property_name, "value":value}
|
||||
send_p2p_packet(1, packet_data)
|
@ -1,193 +0,0 @@
|
||||
extends Control
|
||||
|
||||
@export var host_button: Button
|
||||
@export var leave_button: Button
|
||||
@export var start_button: Button
|
||||
@export var show_lobbies_button: Button
|
||||
@export var user_list_box: VBoxContainer
|
||||
@export var lobby_list_box: VBoxContainer
|
||||
@export var user_box_prefab: PackedScene
|
||||
|
||||
var added_users = []
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
host_button.pressed.connect(_on_host)
|
||||
leave_button.pressed.connect(_on_leave)
|
||||
start_button.pressed.connect(_on_start)
|
||||
show_lobbies_button.pressed.connect(_on_show_lobbies)
|
||||
|
||||
NetworkManager.lobby_created.connect(_on_lobby_created)
|
||||
NetworkManager.lobby_joined.connect(_on_lobby_joined)
|
||||
NetworkManager.user_joined_lobby.connect(_on_user_joined_lobby)
|
||||
NetworkManager.user_left_lobby.connect(_on_user_left_lobby)
|
||||
NetworkManager.on_game_started.connect(_on_game_started)
|
||||
NetworkManager.on_lobbies_received.connect(_on_lobbies_received)
|
||||
|
||||
GameConsole.register_command(Command.new("update", update_ui, [], "Updates the lobby UI"))
|
||||
|
||||
|
||||
func _on_host():
|
||||
NetworkManager.host_lobby()
|
||||
show_lobbies_button.disabled = true
|
||||
|
||||
|
||||
func _on_leave():
|
||||
NetworkManager.leave_lobby()
|
||||
reset_ui()
|
||||
|
||||
|
||||
func _on_show_lobbies():
|
||||
lobby_list_box.visible = true
|
||||
NetworkManager.get_lobbies()
|
||||
|
||||
|
||||
func _on_lobbies_received(these_lobbies: Array):
|
||||
var friend_lobbies = get_lobbies_with_friends()
|
||||
|
||||
# Clear the lobby list box before adding new lobbies
|
||||
for child in lobby_list_box.get_children():
|
||||
child.queue_free()
|
||||
|
||||
if friend_lobbies.size() == 0:
|
||||
var no_lobbies_label = Label.new()
|
||||
no_lobbies_label.text = "No lobbies available"
|
||||
lobby_list_box.add_child(no_lobbies_label)
|
||||
else:
|
||||
for lobby_id in friend_lobbies.keys():
|
||||
# Pull lobby data from Steam, these are specific to our example
|
||||
var lobby_name: String = Steam.getLobbyData(lobby_id, "name")
|
||||
var lobby_mode: String = Steam.getLobbyData(lobby_id, "mode")
|
||||
|
||||
# Get the current number of members
|
||||
var lobby_num_members: int = Steam.getNumLobbyMembers(lobby_id)
|
||||
|
||||
# Create a button for the lobby
|
||||
var lobby_button: Button = Button.new()
|
||||
lobby_button.set_text(lobby_name + " " + str(lobby_num_members) + "/" + str(Steam.getLobbyMemberLimit(lobby_id)))
|
||||
lobby_button.set_size(Vector2(800, 50))
|
||||
lobby_button.set_name("lobby_%s" % lobby_id)
|
||||
lobby_button.connect("pressed", Callable(self, "join_lobby").bind(lobby_id))
|
||||
|
||||
# Add the new lobby to the list
|
||||
lobby_list_box.add_child(lobby_button)
|
||||
|
||||
|
||||
|
||||
func get_lobbies_with_friends() -> Dictionary:
|
||||
var results: Dictionary = {}
|
||||
|
||||
for i in range(0, Steam.getFriendCount()):
|
||||
var steam_id: int = Steam.getFriendByIndex(i, Steam.FRIEND_FLAG_IMMEDIATE)
|
||||
var game_info: Dictionary = Steam.getFriendGamePlayed(steam_id)
|
||||
|
||||
if game_info.is_empty():
|
||||
# This friend is not playing a game
|
||||
continue
|
||||
else:
|
||||
# They are playing a game, check if it's the same game as ours
|
||||
var app_id: int = game_info['id']
|
||||
var lobby = game_info['lobby']
|
||||
|
||||
if app_id != Steam.getAppID() or lobby is String:
|
||||
# Either not in this game, or not in a lobby
|
||||
continue
|
||||
|
||||
if not results.has(lobby):
|
||||
results[lobby] = []
|
||||
|
||||
results[lobby].append(steam_id)
|
||||
|
||||
return results
|
||||
|
||||
|
||||
func get_friends_in_lobbies() -> Dictionary:
|
||||
var results: Dictionary = {}
|
||||
|
||||
for i in range(0, Steam.getFriendCount()):
|
||||
var steam_id: int = Steam.getFriendByIndex(i, Steam.FRIEND_FLAG_IMMEDIATE)
|
||||
var game_info: Dictionary = Steam.getFriendGamePlayed(steam_id)
|
||||
|
||||
if game_info.is_empty():
|
||||
# This friend is not playing a game
|
||||
continue
|
||||
else:
|
||||
# They are playing a game, check if it's the same game as ours
|
||||
var app_id: int = game_info['id']
|
||||
var lobby = game_info['lobby']
|
||||
|
||||
if app_id != Steam.getAppID() or lobby is String:
|
||||
# Either not in this game, or not in a lobby
|
||||
continue
|
||||
|
||||
results[steam_id] = lobby
|
||||
|
||||
return results
|
||||
|
||||
|
||||
func join_lobby(lobby_id: int):
|
||||
NetworkManager.join_lobby(lobby_id)
|
||||
|
||||
|
||||
func _on_lobby_created(lobby_id: int):
|
||||
print("Lobby created")
|
||||
host_button.disabled = true
|
||||
leave_button.disabled = false
|
||||
start_button.disabled = false
|
||||
user_list_box.visible = true
|
||||
|
||||
|
||||
func _on_lobby_joined(lobby_id: int):
|
||||
host_button.disabled = true
|
||||
leave_button.disabled = false
|
||||
user_list_box.visible = true
|
||||
lobby_list_box.visible = false
|
||||
|
||||
|
||||
func _on_user_joined_lobby(user_id: int):
|
||||
if user_id in added_users:
|
||||
return # User already added, skip
|
||||
added_users.append(user_id)
|
||||
update_ui()
|
||||
|
||||
|
||||
func _on_user_left_lobby(user_id: int):
|
||||
added_users.erase(user_id)
|
||||
update_ui()
|
||||
|
||||
|
||||
func _on_start():
|
||||
NetworkManager.start_game()
|
||||
visible = false
|
||||
|
||||
|
||||
func _on_game_started():
|
||||
visible = false
|
||||
|
||||
|
||||
func reset_ui():
|
||||
host_button.disabled = false
|
||||
leave_button.disabled = true
|
||||
start_button.disabled = true
|
||||
user_list_box.visible = false
|
||||
lobby_list_box.visible = false
|
||||
show_lobbies_button.disabled = false
|
||||
added_users.clear()
|
||||
for child in user_list_box.get_children():
|
||||
child.queue_free()
|
||||
|
||||
for child in lobby_list_box.get_children():
|
||||
child.queue_free()
|
||||
|
||||
|
||||
func update_ui() -> void:
|
||||
for child in user_list_box.get_children():
|
||||
child.queue_free()
|
||||
|
||||
for user_id in added_users:
|
||||
var user_box = user_box_prefab.instantiate()
|
||||
user_box.get_node("Username").text = str(Steam.getFriendPersonaName(user_id))
|
||||
user_list_box.add_child(user_box)
|
||||
|
||||
var avatar_texture = await NetworkManager.get_player_avatar(user_id)
|
||||
user_box.get_node("PFP").texture = avatar_texture
|
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 4.4 KiB |
@ -1,34 +0,0 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://c3lblkyavjtol"
|
||||
path="res://.godot/imported/2d_crosshair_dot.png-61f11b68155f3e5bb55efff33412dc26.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/core/player-controller/2d_crosshair_dot.png"
|
||||
dest_files=["res://.godot/imported/2d_crosshair_dot.png-61f11b68155f3e5bb55efff33412dc26.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
@ -1,8 +0,0 @@
|
||||
shader_type canvas_item;
|
||||
|
||||
uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap;
|
||||
|
||||
void fragment(){
|
||||
vec4 color = vec4(texture(SCREEN_TEXTURE, SCREEN_UV).rgb, texture(TEXTURE, UV).a);
|
||||
COLOR = vec4(1.0 - color.rgb, color.a);
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
[gd_scene load_steps=5 format=3 uid="uid://c6w0ivy4hetrl"]
|
||||
|
||||
[ext_resource type="Script" path="res://assets/core/player-controller/scripts/player.gd" id="1_bv7t4"]
|
||||
[ext_resource type="Script" path="res://assets/core/player-controller/scripts/player_interacter.gd" id="2_wvu3d"]
|
||||
|
||||
[sub_resource type="CapsuleMesh" id="CapsuleMesh_v7b3h"]
|
||||
radius = 0.35
|
||||
|
||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_qlkab"]
|
||||
radius = 0.35
|
||||
|
||||
[node name="Player" type="CharacterBody3D" node_paths=PackedStringArray("camera")]
|
||||
script = ExtResource("1_bv7t4")
|
||||
camera = NodePath("Neck/Camera3D")
|
||||
|
||||
[node name="PlayerTag" type="Label3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.26654, 0)
|
||||
billboard = 1
|
||||
text = "username"
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
|
||||
mesh = SubResource("CapsuleMesh_v7b3h")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||
shape = SubResource("CapsuleShape3D_qlkab")
|
||||
|
||||
[node name="Neck" type="Node3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.65, 0)
|
||||
|
||||
[node name="Camera3D" type="Camera3D" parent="Neck"]
|
||||
|
||||
[node name="RayCast3D" type="RayCast3D" parent="Neck/Camera3D" node_paths=PackedStringArray("player")]
|
||||
target_position = Vector3(0, 0, -2.5)
|
||||
script = ExtResource("2_wvu3d")
|
||||
player = NodePath("../../..")
|
@ -1,130 +0,0 @@
|
||||
[gd_scene load_steps=12 format=3 uid="uid://c6w0ivy4hetrl"]
|
||||
|
||||
[ext_resource type="Script" path="res://assets/core/player-controller/scripts/player.gd" id="1_bv7t4"]
|
||||
[ext_resource type="Texture2D" uid="uid://fwub8fvl2u4i" path="res://addons/ingameconsole/ps1hagrid.png" id="2_omgn1"]
|
||||
[ext_resource type="Script" path="res://assets/core/player-controller/scripts/player_interacter.gd" id="2_wvu3d"]
|
||||
[ext_resource type="Script" path="res://assets/core/player-controller/scripts/player_hud.gd" id="3_02ne1"]
|
||||
[ext_resource type="Shader" path="res://assets/core/player-controller/scenes/inverted_crosshair.gdshader" id="3_rakxt"]
|
||||
[ext_resource type="Texture2D" uid="uid://c3lblkyavjtol" path="res://assets/core/player-controller/2d_crosshair_dot.png" id="4_3uwxe"]
|
||||
|
||||
[sub_resource type="CapsuleMesh" id="CapsuleMesh_v7b3h"]
|
||||
radius = 0.35
|
||||
height = 1.5
|
||||
|
||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_qlkab"]
|
||||
radius = 0.35
|
||||
|
||||
[sub_resource type="SphereMesh" id="SphereMesh_vu2l8"]
|
||||
radius = 0.35
|
||||
height = 0.7
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wmxrr"]
|
||||
shader = ExtResource("3_rakxt")
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_0n7pd"]
|
||||
shader = ExtResource("3_rakxt")
|
||||
|
||||
[node name="Player" type="CharacterBody3D" node_paths=PackedStringArray("camera", "neck", "player_avatar_face", "body", "head", "player_hud")]
|
||||
collision_mask = 242
|
||||
script = ExtResource("1_bv7t4")
|
||||
camera = NodePath("Neck/Camera3D")
|
||||
neck = NodePath("Neck")
|
||||
player_avatar_face = NodePath("Neck/Camera3D/PlayerAvatarFace")
|
||||
body = NodePath("Body")
|
||||
head = NodePath("Neck/Head")
|
||||
player_hud = NodePath("PlayerHUD")
|
||||
|
||||
[node name="PlayerTag" type="Label3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.26654, 0)
|
||||
visibility_range_begin = 0.7
|
||||
visibility_range_end = 15.0
|
||||
billboard = 1
|
||||
text = "username"
|
||||
|
||||
[node name="Body" type="MeshInstance3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.5, 0)
|
||||
mesh = SubResource("CapsuleMesh_v7b3h")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||
shape = SubResource("CapsuleShape3D_qlkab")
|
||||
|
||||
[node name="Neck" type="Node3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.65, 0)
|
||||
|
||||
[node name="Camera3D" type="Camera3D" parent="Neck"]
|
||||
|
||||
[node name="RayCast3D" type="RayCast3D" parent="Neck/Camera3D" node_paths=PackedStringArray("player")]
|
||||
target_position = Vector3(0, 0, -2.5)
|
||||
collision_mask = 256
|
||||
script = ExtResource("2_wvu3d")
|
||||
player = NodePath("../../..")
|
||||
|
||||
[node name="PlayerAvatarFace" type="Sprite3D" parent="Neck/Camera3D"]
|
||||
transform = Transform3D(-0.1, 0, -8.74228e-09, 0, 0.1, 0, 8.74228e-09, 0, -0.1, 0, 0, -0.349588)
|
||||
flip_h = true
|
||||
shaded = true
|
||||
double_sided = false
|
||||
texture = ExtResource("2_omgn1")
|
||||
|
||||
[node name="Head" type="MeshInstance3D" parent="Neck"]
|
||||
mesh = SubResource("SphereMesh_vu2l8")
|
||||
|
||||
[node name="PlayerHUD" type="CanvasLayer" parent="." node_paths=PackedStringArray("fps_label")]
|
||||
script = ExtResource("3_02ne1")
|
||||
fps_label = NodePath("Debug/HBoxContainer/VBoxContainer/MarginContainer/FPSLabel")
|
||||
|
||||
[node name="Overlay" type="Control" parent="PlayerHUD"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
mouse_filter = 1
|
||||
|
||||
[node name="CenterContainer" type="CenterContainer" parent="PlayerHUD/Overlay"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="PlayerHUD/Overlay/CenterContainer"]
|
||||
material = SubResource("ShaderMaterial_wmxrr")
|
||||
layout_mode = 2
|
||||
texture = ExtResource("4_3uwxe")
|
||||
|
||||
[node name="Debug" type="Control" parent="PlayerHUD"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
mouse_filter = 1
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="PlayerHUD/Debug"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
alignment = 2
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="PlayerHUD/Debug/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="PlayerHUD/Debug/HBoxContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_top = 5
|
||||
theme_override_constants/margin_right = 5
|
||||
|
||||
[node name="FPSLabel" type="Label" parent="PlayerHUD/Debug/HBoxContainer/VBoxContainer/MarginContainer"]
|
||||
material = SubResource("ShaderMaterial_0n7pd")
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 35
|
||||
text = "999 FPS"
|
||||
horizontal_alignment = 2
|
||||
vertical_alignment = 1
|
@ -1,202 +0,0 @@
|
||||
class_name Player extends CharacterBody3D
|
||||
|
||||
var player_tag: Label3D
|
||||
var username: String = ""
|
||||
var is_piloting: bool = false
|
||||
|
||||
var is_network_authority: bool = false
|
||||
var network_uuid: String = ""
|
||||
var steam_id: int = 0
|
||||
|
||||
@export_category("Player")
|
||||
@export_range(1, 35, 1) var speed: float = 5.0
|
||||
@export_range(10, 400, 1) var acceleration: float = 100.0
|
||||
|
||||
@export_range(0.1, 3.0, 0.1) var jump_height: float = 1.0
|
||||
@export_range(0.1, 3.0, 0.1, "or_greater") var camera_sens: float = 1.0
|
||||
@export_range(0.1, 3.0, 0.1, "or_greater") var joystick_camera_sens_multiplier: float = 5.0
|
||||
@export var camera: Camera3D
|
||||
@export var neck: Node3D
|
||||
@export var player_avatar_face: Sprite3D
|
||||
@export var body: MeshInstance3D
|
||||
@export var head: MeshInstance3D
|
||||
@export var player_hud: CanvasLayer
|
||||
|
||||
|
||||
var jumping: bool = false
|
||||
var is_using_joystick: bool = false
|
||||
var gravity: float = ProjectSettings.get_setting("physics/3d/default_gravity")
|
||||
|
||||
var move_dir: Vector2 # Input direction for movement
|
||||
var look_dir: Vector2 # Input direction for look/aim
|
||||
var walk_vel: Vector3 # Walking velocity
|
||||
var grav_vel: Vector3 # Gravity velocity
|
||||
var jump_vel: Vector3 # Jumping velocity
|
||||
|
||||
var current_ship: Ship
|
||||
|
||||
var previous_global_position: Vector3
|
||||
var previous_global_rotation: Vector3
|
||||
var previous_head_vert_rotation: Vector3
|
||||
|
||||
var neck_rotation_sync: Vector3
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
NetworkManager.property_update_received.connect(_on_property_update)
|
||||
network_uuid = NetworkManager.register_node(self)
|
||||
|
||||
player_tag = get_node("PlayerTag")
|
||||
player_tag.text = username
|
||||
player_avatar_face.texture = await NetworkManager.get_player_avatar(steam_id)
|
||||
|
||||
if is_network_authority:
|
||||
camera.make_current()
|
||||
body.hide()
|
||||
head.hide()
|
||||
player_avatar_face.hide()
|
||||
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
||||
else:
|
||||
player_hud.hide()
|
||||
|
||||
|
||||
func _input(event):
|
||||
if !is_network_authority: return
|
||||
if event.is_action_pressed("esc") and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
|
||||
release_mouse()
|
||||
elif event.is_action_pressed("esc") and not Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
|
||||
capture_mouse()
|
||||
|
||||
if Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
|
||||
if event is InputEventMouseMotion:
|
||||
is_using_joystick = false
|
||||
look_dir = event.relative * 0.001
|
||||
_rotate_camera()
|
||||
elif event is InputEventJoypadMotion:
|
||||
is_using_joystick = true
|
||||
|
||||
if Input.is_action_just_pressed("jump") and !is_piloting:
|
||||
jumping = true
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if !is_network_authority: return
|
||||
if is_piloting and current_ship != null:
|
||||
velocity = Vector3.ZERO + _gravity(delta)
|
||||
else:
|
||||
velocity = walk(delta) + _gravity(delta) + _jump(delta)
|
||||
|
||||
global_rotation.x = 0.0
|
||||
global_rotation.z = 0.0
|
||||
|
||||
if Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
|
||||
_handle_joypad_camera_rotation(delta)
|
||||
move_and_slide()
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if !is_network_authority: return
|
||||
|
||||
# If the global_position has changed, notify the NetworkManager
|
||||
if previous_global_position != global_position:
|
||||
NetworkManager.sync_property_to_all(network_uuid, "global_position", global_position)
|
||||
previous_global_position = global_position
|
||||
|
||||
if previous_global_rotation != global_rotation:
|
||||
NetworkManager.sync_property_to_all(network_uuid, "global_rotation", global_rotation)
|
||||
previous_global_rotation = global_rotation
|
||||
|
||||
if previous_head_vert_rotation != neck.rotation:
|
||||
NetworkManager.sync_property_to_all(network_uuid, "neck_rotation_sync", neck_rotation_sync)
|
||||
previous_global_rotation = neck.rotation
|
||||
|
||||
|
||||
func capture_mouse() -> void:
|
||||
if !is_network_authority: return
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
||||
|
||||
|
||||
func release_mouse() -> void:
|
||||
if !is_network_authority: return
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
||||
|
||||
|
||||
func _rotate_camera(sens_mod: float = 1.0) -> void:
|
||||
if !is_network_authority: return
|
||||
var camera_sens_final = camera_sens
|
||||
if is_using_joystick:
|
||||
camera_sens_final = camera_sens * joystick_camera_sens_multiplier
|
||||
|
||||
rotation.y -= look_dir.x * camera_sens_final * sens_mod
|
||||
neck.rotation.x = clamp(neck.rotation.x - look_dir.y * camera_sens_final * sens_mod, -1.5, 1.5)
|
||||
neck_rotation_sync = neck.rotation
|
||||
|
||||
|
||||
func _handle_joypad_camera_rotation(delta: float, sens_mod: float = 1.0) -> void:
|
||||
var joypad_dir: Vector2 = Input.get_vector("look_left","look_right","look_up","look_down")
|
||||
if joypad_dir.length() > 0:
|
||||
look_dir += joypad_dir * delta
|
||||
_rotate_camera(sens_mod)
|
||||
look_dir = Vector2.ZERO
|
||||
|
||||
|
||||
func walk(delta: float) -> Vector3:
|
||||
if Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
|
||||
move_dir = Input.get_vector("move_left", "move_right", "move_forwards", "move_backwards")
|
||||
var _forward: Vector3 = neck.global_transform.basis * Vector3(move_dir.x, 0, move_dir.y)
|
||||
var walk_dir: Vector3 = Vector3(_forward.x, 0, _forward.z).normalized()
|
||||
walk_vel = walk_vel.move_toward(walk_dir * speed * move_dir.length(), acceleration * delta)
|
||||
return walk_vel
|
||||
|
||||
|
||||
func _gravity(delta: float) -> Vector3:
|
||||
grav_vel = Vector3.ZERO if is_on_floor() else grav_vel.move_toward(Vector3(0, velocity.y - gravity, 0), gravity * delta)
|
||||
return grav_vel
|
||||
|
||||
|
||||
func _jump(delta: float) -> Vector3:
|
||||
if jumping:
|
||||
if is_on_floor(): jump_vel = Vector3(0, sqrt(4 * jump_height * gravity), 0)
|
||||
jumping = false
|
||||
return jump_vel
|
||||
jump_vel = Vector3.ZERO if is_on_floor() else jump_vel.move_toward(Vector3.ZERO, gravity * delta)
|
||||
return jump_vel
|
||||
|
||||
|
||||
func player_entered_ship(ship_global_position: Vector3, ship: Ship):
|
||||
if !is_network_authority: return
|
||||
current_ship = ship
|
||||
print(ship.ship_id)
|
||||
print(global_position)
|
||||
|
||||
|
||||
func player_exited_ship(ship_global_position: Vector3, ship: Ship):
|
||||
if !is_network_authority: return
|
||||
current_ship = null
|
||||
print(ship.ship_id)
|
||||
print(global_position)
|
||||
|
||||
|
||||
func set_is_piloting(state: bool):
|
||||
if !is_network_authority: return
|
||||
is_piloting = state
|
||||
print("player is piloting: ", str(is_piloting))
|
||||
|
||||
|
||||
func ship_entered(_ship: Ship):
|
||||
current_ship = _ship
|
||||
|
||||
|
||||
func ship_exited():
|
||||
current_ship = null
|
||||
|
||||
|
||||
func _on_property_update(node_id: String, property_name: String, value: Variant) -> void:
|
||||
if NetworkManager.node_map.has(node_id):
|
||||
if property_name == "neck_rotation_sync" and !is_network_authority:
|
||||
neck.rotation = value
|
||||
else:
|
||||
var node = NetworkManager.node_map[node_id]
|
||||
node.set(property_name, value)
|
||||
else:
|
||||
printerr("Received property update but node_id is wrong? Expected " + str(network_uuid) + " but got " + str(node_id))
|
@ -1,7 +0,0 @@
|
||||
extends CanvasLayer
|
||||
|
||||
|
||||
@export var fps_label: Label
|
||||
|
||||
func _process(delta):
|
||||
fps_label.text = str(Engine.get_frames_per_second()) + " FPS"
|
@ -1,16 +0,0 @@
|
||||
extends RayCast3D
|
||||
|
||||
@export var player: Player
|
||||
|
||||
var current_interactable: Interactable
|
||||
var has_processed_interact_frame: bool = false
|
||||
|
||||
func _process(delta):
|
||||
if is_colliding() and get_collider() is Interactable:
|
||||
if Input.is_action_just_pressed("interact") and !has_processed_interact_frame:
|
||||
current_interactable = get_collider() as Interactable
|
||||
GameConsole.log_debug("interacted with interactable: " + current_interactable.name)
|
||||
current_interactable.player_reference = player
|
||||
current_interactable.interact()
|
||||
has_processed_interact_frame = true
|
||||
has_processed_interact_frame = false
|
@ -1,168 +0,0 @@
|
||||
class_name Ship
|
||||
|
||||
extends RigidBody3D
|
||||
|
||||
@export var player_detection_area: Area3D
|
||||
@export var helm_location_marker: Marker3D
|
||||
@export var base_turn_speed: float = 50.0
|
||||
@export var max_turn_speed: float = 50.0
|
||||
@export var base_lift_speed: float = 50.0
|
||||
@export var top_speed: float = 50.0
|
||||
@export var move_speed: float = 50.0
|
||||
@export var acceleration: float = 5.0 # Increased acceleration for smoother interpolation
|
||||
@export var interpolation_damp: float = 0.1 # Damping for smoother rotation
|
||||
|
||||
var piloting_player: Player = null
|
||||
var ship_is_piloted: bool = false
|
||||
var target_position: Vector3 = Vector3.ZERO
|
||||
var target_rotation: Quaternion = Quaternion()
|
||||
var predicted_position: Vector3
|
||||
var predicted_rotation: Quaternion
|
||||
var last_input_time: float = 0.0
|
||||
|
||||
var network_uuid: String = ""
|
||||
|
||||
func _ready():
|
||||
network_uuid = NetworkManager.register_node(self)
|
||||
NetworkManager.property_update_received.connect(_on_property_update)
|
||||
|
||||
# Preserve current position and rotation at the start
|
||||
target_position = global_position
|
||||
target_rotation = global_transform.basis.get_rotation_quaternion()
|
||||
predicted_position = global_position
|
||||
predicted_rotation = global_transform.basis.get_rotation_quaternion()
|
||||
|
||||
player_detection_area.body_entered.connect(_on_player_entered)
|
||||
player_detection_area.body_exited.connect(_on_player_exited)
|
||||
|
||||
func _process(delta: float):
|
||||
if ship_is_piloted:
|
||||
if piloting_player.steam_id == NetworkManager.steam_id:
|
||||
# This player is piloting
|
||||
handle_input(delta)
|
||||
send_network_update()
|
||||
else:
|
||||
# Another player is piloting, interpolate
|
||||
interpolate_position_and_rotation(delta)
|
||||
else:
|
||||
# No one is piloting, just interpolate
|
||||
interpolate_position_and_rotation(delta)
|
||||
|
||||
func handle_input(delta: float):
|
||||
var forward_input = 0.0
|
||||
var turn_input = 0.0
|
||||
var vertical_input = 0.0
|
||||
|
||||
# Forward and backward movement
|
||||
if Input.is_action_pressed("move_forwards"):
|
||||
forward_input += 1
|
||||
if Input.is_action_pressed("move_backwards"):
|
||||
forward_input -= 1
|
||||
|
||||
# Left and right turning
|
||||
if Input.is_action_pressed("move_left"):
|
||||
turn_input += 1
|
||||
if Input.is_action_pressed("move_right"):
|
||||
turn_input -= 1
|
||||
|
||||
# Up and down movement
|
||||
if Input.is_action_pressed("jump"):
|
||||
vertical_input += 1
|
||||
if Input.is_action_pressed("crouch"):
|
||||
vertical_input -= 1
|
||||
|
||||
# Apply torque for turning
|
||||
if turn_input != 0:
|
||||
var torque = Vector3.UP * turn_input * base_turn_speed
|
||||
apply_torque(torque)
|
||||
|
||||
# Clamp the angular velocity to the maximum turn speed
|
||||
if angular_velocity.length() > max_turn_speed:
|
||||
angular_velocity = angular_velocity.normalized() * max_turn_speed
|
||||
|
||||
# Apply force for forward and backward movement
|
||||
if forward_input != 0:
|
||||
var forward_direction = -global_transform.basis.z.normalized()
|
||||
var forward_force = forward_direction * forward_input * move_speed
|
||||
apply_central_force(forward_force)
|
||||
|
||||
# Apply force for vertical movement
|
||||
if vertical_input != 0:
|
||||
var vertical_force = Vector3.UP * vertical_input * base_lift_speed
|
||||
apply_central_force(vertical_force)
|
||||
|
||||
# Update predicted state
|
||||
predicted_position = predict_position(delta)
|
||||
predicted_rotation = predict_rotation(delta)
|
||||
last_input_time = Time.get_ticks_msec()
|
||||
|
||||
func predict_position(delta: float):
|
||||
var velocity = linear_velocity
|
||||
return global_position + velocity * delta
|
||||
|
||||
func predict_rotation(delta: float):
|
||||
var angular_velocity_quat = Quaternion(Vector3.UP, angular_velocity.y * delta)
|
||||
return global_transform.basis.get_rotation_quaternion() * angular_velocity_quat
|
||||
|
||||
func interpolate_position_and_rotation(delta: float):
|
||||
# Smooth interpolation with damping
|
||||
global_position = lerp(global_position, target_position, 1.0 - exp(-acceleration * delta))
|
||||
global_transform.basis = Basis(slerp_damp(global_transform.basis.get_rotation_quaternion(), target_rotation, interpolation_damp, 1.0))
|
||||
|
||||
func slerp_damp(from: Quaternion, to: Quaternion, damping: float, dt: float):
|
||||
var t = 1.0 - exp(-damping * dt)
|
||||
return from.slerp(to, t)
|
||||
|
||||
func send_network_update():
|
||||
if NetworkManager.is_host and ship_is_piloted and piloting_player.steam_id == NetworkManager.steam_id:
|
||||
# Host is piloting, synchronize with clients
|
||||
NetworkManager.sync_property_to_all_except_host(network_uuid, "global_position", predicted_position)
|
||||
NetworkManager.sync_property_to_all_except_host(network_uuid, "global_rotation", predicted_rotation)
|
||||
|
||||
elif !NetworkManager.is_host and ship_is_piloted and piloting_player.steam_id == NetworkManager.steam_id:
|
||||
# Client is piloting, send updates to the host
|
||||
NetworkManager.sync_property_to_all_except_host(network_uuid, "global_position", predicted_position)
|
||||
NetworkManager.sync_property_to_all_except_host(network_uuid, "global_rotation", predicted_rotation)
|
||||
|
||||
func receive_global_position_update(value: Vector3):
|
||||
target_position = value
|
||||
|
||||
func receive_global_rotation_update(value: Quaternion):
|
||||
target_rotation = value
|
||||
|
||||
func _on_player_entered(body):
|
||||
if body is Player and body.get_parent() != self:
|
||||
if !body.is_network_authority: return
|
||||
body.call_deferred("reparent", self, true)
|
||||
body.ship_entered(self)
|
||||
print("Player entered the ship area.")
|
||||
|
||||
func _on_player_exited(body):
|
||||
if body is Player and body.get_parent() != get_node("/root/DevLevel/"):
|
||||
if !body.is_network_authority: return
|
||||
body.call_deferred("reparent", get_node("/root/DevLevel/"), true)
|
||||
body.ship_exited()
|
||||
print("Player exited the ship area.")
|
||||
|
||||
func set_piloting_player(player: Player):
|
||||
piloting_player = player
|
||||
ship_is_piloted = piloting_player != null
|
||||
if piloting_player:
|
||||
print("Player", piloting_player.username, "is now piloting the ship.")
|
||||
else:
|
||||
print("The ship is no longer piloted.")
|
||||
|
||||
func remove_piloting_player():
|
||||
piloting_player = null
|
||||
ship_is_piloted = false
|
||||
print("The ship is no longer piloted.")
|
||||
|
||||
func _on_property_update(node_id: String, property_name: String, value: Variant) -> void:
|
||||
if NetworkManager.node_map.has(node_id) and node_id == network_uuid:
|
||||
if property_name == "global_position":
|
||||
receive_global_position_update(value)
|
||||
elif property_name == "global_rotation":
|
||||
receive_global_rotation_update(value)
|
||||
else:
|
||||
var node = NetworkManager.node_map[node_id]
|
||||
node.set(property_name, value)
|
@ -1,8 +1,6 @@
|
||||
[gd_scene load_steps=8 format=3 uid="uid://y0xb2vktsr1k"]
|
||||
[gd_scene load_steps=6 format=3 uid="uid://y0xb2vktsr1k"]
|
||||
|
||||
[ext_resource type="Script" path="res://assets/core/ships/ship_script.gd" id="1_ghft7"]
|
||||
[ext_resource type="Texture2D" uid="uid://gymb0tju4y67" path="res://addons/kennysprototypetextures/Dark/texture_black (1).png" id="2_3koq8"]
|
||||
[ext_resource type="PackedScene" uid="uid://dm31ddavxv5gt" path="res://assets/core/interactables/ship-helm/ship-helm.tscn" id="3_eyiku"]
|
||||
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_6gbwt"]
|
||||
size = Vector3(5, 0.15, 20)
|
||||
@ -17,15 +15,11 @@ size = Vector3(5, 0.15, 20)
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_7o08p"]
|
||||
size = Vector3(4.99609, 3.11252, 20.0022)
|
||||
|
||||
[node name="ShuttleClass" type="RigidBody3D" node_paths=PackedStringArray("player_detection_area", "helm_location_marker")]
|
||||
[node name="ShuttleClass" type="RigidBody3D"]
|
||||
collision_layer = 8
|
||||
collision_mask = 200
|
||||
mass = 700.0
|
||||
gravity_scale = 0.0
|
||||
script = ExtResource("1_ghft7")
|
||||
player_detection_area = NodePath("PlayerDetectionArea")
|
||||
helm_location_marker = NodePath("HelmLocationMarker")
|
||||
base_lift_speed = 5.0
|
||||
|
||||
[node name="ShipToShipCol" type="CollisionShape3D" parent="."]
|
||||
shape = SubResource("BoxShape3D_6gbwt")
|
||||
@ -50,7 +44,3 @@ shape = SubResource("BoxShape3D_7o08p")
|
||||
|
||||
[node name="HelmLocationMarker" type="Marker3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.1, 0)
|
||||
|
||||
[node name="ShipHelm" parent="." node_paths=PackedStringArray("parent_ship") instance=ExtResource("3_eyiku")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -7.54699)
|
||||
parent_ship = NodePath("..")
|
||||
|
@ -1,71 +0,0 @@
|
||||
|
||||
extends RigidBody3D
|
||||
|
||||
@export var ship_area: Area3D
|
||||
@export var ship_helm: ShipHelm
|
||||
|
||||
var ship_id: int = 0
|
||||
var ship_is_piloted: bool = false
|
||||
var base_turn_speed: float = 1
|
||||
var top_turn_speed: float = 50.0
|
||||
var ship_lift_speed: float = 20 # Adjust this value as needed
|
||||
var acceleration: float = 50
|
||||
var deceleration: float = acceleration * 0.5
|
||||
var ship_top_speed: float = 100
|
||||
var current_speed: float = 0.0
|
||||
var max_force: float = 1000.0
|
||||
|
||||
var piloting_player: Player = null
|
||||
|
||||
|
||||
func _ready():
|
||||
ship_area.body_entered.connect(_on_area_3d_body_entered)
|
||||
ship_area.body_exited.connect(_on_area_3d_body_exited)
|
||||
ship_id = randi_range(1000, 9999)
|
||||
GameConsole.log_debug("Ship ID: " + str(ship_id))
|
||||
|
||||
|
||||
func _physics_process(delta):
|
||||
global_rotation.x = lerpf(global_rotation.x, 0, 0.5)
|
||||
global_rotation.z = lerpf(global_rotation.z, 0, 0.5)
|
||||
|
||||
if ship_is_piloted:
|
||||
var turn_speed = base_turn_speed / max(mass, 1) # changes speeds based on how THICC the ship is
|
||||
if Input.is_action_pressed("move_left"):
|
||||
angular_velocity.y += turn_speed
|
||||
elif Input.is_action_pressed("move_right"):
|
||||
angular_velocity.y -= turn_speed
|
||||
|
||||
if Input.is_action_pressed("jump"):
|
||||
# Apply an impulse to achieve instantaneous upward velocity
|
||||
apply_impulse(Vector3.UP * ship_lift_speed)
|
||||
|
||||
if Input.is_action_pressed("move_forwards"):
|
||||
current_speed = min(current_speed + acceleration * delta, ship_top_speed)
|
||||
else:
|
||||
current_speed = max(current_speed - deceleration * delta, 0.0)
|
||||
|
||||
var desired_velocity = -transform.basis.z * current_speed
|
||||
var forward_force = (desired_velocity - linear_velocity) * mass
|
||||
forward_force = forward_force.normalized() * min(forward_force.length(), max_force)
|
||||
apply_central_force(forward_force)
|
||||
|
||||
if Input.is_action_pressed("crouch"):
|
||||
apply_impulse(Vector3.DOWN * ship_lift_speed)
|
||||
|
||||
angular_velocity.y = clamp(angular_velocity.y, -top_turn_speed, top_turn_speed)
|
||||
|
||||
|
||||
func _on_area_3d_body_entered(body):
|
||||
if body is Player:
|
||||
piloting_player = body
|
||||
body.player_entered_ship(global_position, self)
|
||||
body.set_block_signals(true)
|
||||
|
||||
|
||||
func _on_area_3d_body_exited(body):
|
||||
if body is Player:
|
||||
ship_helm.is_being_piloted = false
|
||||
body.player_exited_ship(global_position, self)
|
||||
piloting_player = null
|
||||
body.set_block_signals(false)
|
@ -18,7 +18,6 @@ config/icon="res://assets/icon.png"
|
||||
[autoload]
|
||||
|
||||
GameConsole="*res://addons/ingameconsole/GameConsole.tscn"
|
||||
NetworkManager="*res://assets/core/networking/scripts/NetworkManager.gd"
|
||||
|
||||
[debug]
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user