0.1.0
Added a basic test map, options menu, bug fixes, and much more.
This commit is contained in:
parent
d72b5ac57b
commit
2dce012535
34 changed files with 1268 additions and 84 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
||||||
# Godot 4+ specific ignores
|
# Godot 4+ specific ignores
|
||||||
.godot/
|
.godot/
|
||||||
/android/
|
/android/
|
||||||
|
releases/
|
||||||
|
|
|
@ -12,9 +12,7 @@ func _on_dropoff(body: Node3D) -> void:
|
||||||
player.released_player.rpc_id(player.get_multiplayer_authority())
|
player.released_player.rpc_id(player.get_multiplayer_authority())
|
||||||
(player.get_node("ReleaseTimer") as Timer).stop()
|
(player.get_node("ReleaseTimer") as Timer).stop()
|
||||||
($DamageTimer as Timer).start()
|
($DamageTimer as Timer).start()
|
||||||
for i: int in range(Multiplayer.players.size()):
|
Multiplayer.players[caught_player.get_multiplayer_authority()].captured = true
|
||||||
if Multiplayer.players[i].id == caught_player.get_multiplayer_authority():
|
|
||||||
Multiplayer.players[i].captured = true
|
|
||||||
elif !player.hunter and player.visible and caught_player and caught_player.health > 0:
|
elif !player.hunter and player.visible and caught_player and caught_player.health > 0:
|
||||||
caught_player.go_free.rpc_id(caught_player.get_multiplayer_authority())
|
caught_player.go_free.rpc_id(caught_player.get_multiplayer_authority())
|
||||||
caught_player = null
|
caught_player = null
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
extends Area3D
|
|
||||||
|
|
||||||
func _on_body_entered(body: Node3D) -> void:
|
|
||||||
if multiplayer.is_server() and body is Player:
|
|
||||||
var player: Player = body
|
|
||||||
if !player.hunter:
|
|
||||||
for i: int in range(Multiplayer.players.size()):
|
|
||||||
if Multiplayer.players[i].id == player.get_multiplayer_authority():
|
|
||||||
Multiplayer.players[i].escaped = true
|
|
||||||
player.get_caught.rpc_id(player.get_multiplayer_authority(), $"../SpectatorCamera".get_path())
|
|
|
@ -1 +0,0 @@
|
||||||
uid://bvjyyj4m56b7b
|
|
|
@ -1,12 +1,16 @@
|
||||||
[gd_scene load_steps=3 format=3 uid="uid://dbgqg1wtqmhw3"]
|
[gd_scene load_steps=3 format=3 uid="uid://bncmv3p36y2qg"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://bvjyyj4m56b7b" path="res://entities/escape_area.gd" id="1_ubptc"]
|
[sub_resource type="GDScript" id="GDScript_yuux7"]
|
||||||
|
script/source = "class_name EscapeArea
|
||||||
|
extends Area3D
|
||||||
|
|
||||||
|
"
|
||||||
|
|
||||||
[sub_resource type="BoxShape3D" id="BoxShape3D_eij3b"]
|
[sub_resource type="BoxShape3D" id="BoxShape3D_eij3b"]
|
||||||
size = Vector3(10, 10, 10)
|
size = Vector3(10, 10, 10)
|
||||||
|
|
||||||
[node name="EscapeArea" type="Area3D"]
|
[node name="EscapeArea" type="Area3D"]
|
||||||
script = ExtResource("1_ubptc")
|
script = SubResource("GDScript_yuux7")
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||||
shape = SubResource("BoxShape3D_eij3b")
|
shape = SubResource("BoxShape3D_eij3b")
|
||||||
|
|
|
@ -5,7 +5,7 @@ var done: bool = false
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
if multiplayer.is_server():
|
if multiplayer.is_server():
|
||||||
Multiplayer.fuseboxes += 1
|
Multiplayer.add_fusebox.rpc()
|
||||||
|
|
||||||
func _on_fixing_started(body: Node3D) -> void:
|
func _on_fixing_started(body: Node3D) -> void:
|
||||||
if multiplayer.is_server() and !done and body is Player:
|
if multiplayer.is_server() and !done and body is Player:
|
||||||
|
@ -16,4 +16,4 @@ func _on_fixing_started(body: Node3D) -> void:
|
||||||
func complete_fusebox() -> void:
|
func complete_fusebox() -> void:
|
||||||
($Hinge as Node3D).rotation.y = 0
|
($Hinge as Node3D).rotation.y = 0
|
||||||
done = true
|
done = true
|
||||||
Multiplayer.fuseboxes -= 1
|
Multiplayer.remove_fusebox.rpc()
|
||||||
|
|
|
@ -5,16 +5,25 @@ const SPEED: float = 5.0
|
||||||
const JUMP_VELOCITY: float = 4.5
|
const JUMP_VELOCITY: float = 4.5
|
||||||
|
|
||||||
@onready var camera_x: Node3D = $ViewY/ViewX
|
@onready var camera_x: Node3D = $ViewY/ViewX
|
||||||
@onready var camera: Camera3D = $ViewY/ViewX/View
|
@onready var spring_arm: SpringArm3D = $ViewY/ViewX/Arm
|
||||||
|
@onready var camera: Camera3D = $ViewY/ViewX/Arm/View
|
||||||
|
|
||||||
@onready var syringe: Node3D = $Syringe
|
@onready var syringe: Node3D = $Syringe
|
||||||
@onready var needle: Area3D = $Syringe/SyringeNeedle
|
@onready var needle: Area3D = $Syringe/SyringeNeedle
|
||||||
|
|
||||||
@onready var bag: Node3D = $Bag
|
@onready var bag: Node3D = $Bag
|
||||||
@onready var captured: Node3D = $Bag/Captured
|
@onready var captured: Node3D = $Bag/Captured
|
||||||
|
|
||||||
|
@onready var mesh: MeshInstance3D = $Mesh
|
||||||
|
@onready var collision: CollisionShape3D = $Collision
|
||||||
|
|
||||||
var hunter: bool = true
|
var hunter: bool = true
|
||||||
var caught_player: Player = null
|
var caught_player: Player = null
|
||||||
var new_spawn: Vector3
|
var new_spawn: Vector3
|
||||||
|
|
||||||
|
var crouching: bool = false
|
||||||
|
var speed_penalty: float = 0.0
|
||||||
|
|
||||||
@export var health: int = 100
|
@export var health: int = 100
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
|
@ -31,9 +40,9 @@ func _ready() -> void:
|
||||||
func _physics_process(delta: float) -> void:
|
func _physics_process(delta: float) -> void:
|
||||||
# Zoom
|
# Zoom
|
||||||
if Input.is_action_just_released("zoom_in") and camera.position.z > 0:
|
if Input.is_action_just_released("zoom_in") and camera.position.z > 0:
|
||||||
camera.position.z += -1
|
spring_arm.spring_length -= 1
|
||||||
elif Input.is_action_just_released("zoom_out"):
|
elif Input.is_action_just_released("zoom_out"):
|
||||||
camera.position.z += 1
|
spring_arm.spring_length += 1
|
||||||
|
|
||||||
if is_multiplayer_authority():
|
if is_multiplayer_authority():
|
||||||
# Focus
|
# Focus
|
||||||
|
@ -49,15 +58,31 @@ func _physics_process(delta: float) -> void:
|
||||||
velocity += get_gravity() * delta
|
velocity += get_gravity() * delta
|
||||||
|
|
||||||
# Jumping
|
# Jumping
|
||||||
if Input.is_action_just_pressed("jump") and is_on_floor():
|
if Input.is_action_just_pressed("jump") and is_on_floor() and !crouching:
|
||||||
velocity.y = JUMP_VELOCITY
|
velocity.y = JUMP_VELOCITY
|
||||||
|
if hunter:
|
||||||
|
speed_penalty += 2.0
|
||||||
|
if speed_penalty > SPEED - 1.0:
|
||||||
|
speed_penalty = SPEED - 1.0
|
||||||
|
|
||||||
|
# Crouching
|
||||||
|
if Input.is_action_just_pressed("crouch") and is_on_floor() and !hunter:
|
||||||
|
if crouching:
|
||||||
|
mesh.rotation_degrees.x = 0.0
|
||||||
|
collision.rotation_degrees.x = 0.0
|
||||||
|
camera_x.position.y = 0.5
|
||||||
|
else:
|
||||||
|
mesh.rotation_degrees.x = -90.0
|
||||||
|
collision.rotation_degrees.x = -90.0
|
||||||
|
camera_x.position.y = 0.0
|
||||||
|
crouching = !crouching
|
||||||
|
|
||||||
# Movement
|
# Movement
|
||||||
var input_dir: Vector2 = Input.get_vector("move_left", "move_right", "move_forwards", "move_backwards")
|
var input_dir: Vector2 = Input.get_vector("move_left", "move_right", "move_forwards", "move_backwards")
|
||||||
var direction: Vector3 = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
|
var direction: Vector3 = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
|
||||||
|
|
||||||
velocity.x = direction.x * SPEED
|
velocity.x = direction.x * (SPEED - speed_penalty)
|
||||||
velocity.z = direction.z * SPEED
|
velocity.z = direction.z * (SPEED - speed_penalty)
|
||||||
|
|
||||||
# Hunter specific
|
# Hunter specific
|
||||||
if hunter:
|
if hunter:
|
||||||
|
@ -67,6 +92,11 @@ func _physics_process(delta: float) -> void:
|
||||||
syringe.position.z += 0.1
|
syringe.position.z += 0.1
|
||||||
syringe.position.z = clampf(syringe.position.z, -0.8, -0.3)
|
syringe.position.z = clampf(syringe.position.z, -0.8, -0.3)
|
||||||
|
|
||||||
|
if speed_penalty > 0.0:
|
||||||
|
speed_penalty -= delta / 3.0
|
||||||
|
if speed_penalty <= 0.0:
|
||||||
|
speed_penalty = 0.0
|
||||||
|
|
||||||
if move_and_slide():
|
if move_and_slide():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -127,7 +157,7 @@ func get_imprisoned(coffin_path: NodePath) -> void:
|
||||||
# This is called on any player that has just stabbed/caught another.
|
# This is called on any player that has just stabbed/caught another.
|
||||||
@rpc("any_peer", "call_local", "reliable")
|
@rpc("any_peer", "call_local", "reliable")
|
||||||
func capture_player(player_path: NodePath) -> void:
|
func capture_player(player_path: NodePath) -> void:
|
||||||
if multiplayer.get_remote_sender_id() == 1:
|
if multiplayer.get_remote_sender_id() == 1 and !caught_player:
|
||||||
var player: Player = get_node(player_path)
|
var player: Player = get_node(player_path)
|
||||||
caught_player = player
|
caught_player = player
|
||||||
captured.visible = true
|
captured.visible = true
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
[gd_scene load_steps=6 format=3 uid="uid://4hmftsrl305n"]
|
[gd_scene load_steps=7 format=3 uid="uid://4hmftsrl305n"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://dtlssj0xohnpc" path="res://entities/player.gd" id="1_merdl"]
|
[ext_resource type="Script" uid="uid://dtlssj0xohnpc" path="res://entities/player.gd" id="1_merdl"]
|
||||||
|
|
||||||
|
@ -14,6 +14,8 @@ height = 1.8
|
||||||
height = 0.2
|
height = 0.2
|
||||||
radius = 0.05
|
radius = 0.05
|
||||||
|
|
||||||
|
[sub_resource type="SeparationRayShape3D" id="SeparationRayShape3D_merdl"]
|
||||||
|
|
||||||
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_merdl"]
|
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_merdl"]
|
||||||
properties/0/path = NodePath(".:position")
|
properties/0/path = NodePath(".:position")
|
||||||
properties/0/spawn = true
|
properties/0/spawn = true
|
||||||
|
@ -30,6 +32,15 @@ properties/3/replication_mode = 1
|
||||||
properties/4/path = NodePath(".:health")
|
properties/4/path = NodePath(".:health")
|
||||||
properties/4/spawn = true
|
properties/4/spawn = true
|
||||||
properties/4/replication_mode = 1
|
properties/4/replication_mode = 1
|
||||||
|
properties/5/path = NodePath("Bag/Captured:visible")
|
||||||
|
properties/5/spawn = true
|
||||||
|
properties/5/replication_mode = 1
|
||||||
|
properties/6/path = NodePath("Mesh:rotation")
|
||||||
|
properties/6/spawn = true
|
||||||
|
properties/6/replication_mode = 1
|
||||||
|
properties/7/path = NodePath("Collision:rotation")
|
||||||
|
properties/7/spawn = true
|
||||||
|
properties/7/replication_mode = 1
|
||||||
|
|
||||||
[node name="Player" type="CharacterBody3D"]
|
[node name="Player" type="CharacterBody3D"]
|
||||||
script = ExtResource("1_merdl")
|
script = ExtResource("1_merdl")
|
||||||
|
@ -68,8 +79,11 @@ radius = 0.3
|
||||||
[node name="ViewX" type="Node3D" parent="ViewY"]
|
[node name="ViewX" type="Node3D" parent="ViewY"]
|
||||||
transform = Transform3D(1, 0, 0, 0, 0.866025, 0.5, 0, -0.5, 0.866025, 0, 0.5, 0)
|
transform = Transform3D(1, 0, 0, 0, 0.866025, 0.5, 0, -0.5, 0.866025, 0, 0.5, 0)
|
||||||
|
|
||||||
[node name="View" type="Camera3D" parent="ViewY/ViewX"]
|
[node name="Arm" type="SpringArm3D" parent="ViewY/ViewX"]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 4)
|
shape = SubResource("SeparationRayShape3D_merdl")
|
||||||
|
spring_length = 10.0
|
||||||
|
|
||||||
|
[node name="View" type="Camera3D" parent="ViewY/ViewX/Arm"]
|
||||||
size = 5.0
|
size = 5.0
|
||||||
|
|
||||||
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."]
|
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."]
|
||||||
|
|
|
@ -9,7 +9,7 @@ custom_features=""
|
||||||
export_filter="all_resources"
|
export_filter="all_resources"
|
||||||
include_filter=""
|
include_filter=""
|
||||||
exclude_filter=""
|
exclude_filter=""
|
||||||
export_path="../../FreeFTF.x86_64"
|
export_path="releases/FreeFTF.x86_64"
|
||||||
patches=PackedStringArray()
|
patches=PackedStringArray()
|
||||||
encryption_include_filters=""
|
encryption_include_filters=""
|
||||||
encryption_exclude_filters=""
|
encryption_exclude_filters=""
|
||||||
|
@ -39,3 +39,70 @@ unzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\"
|
||||||
ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash
|
ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash
|
||||||
kill $(pgrep -x -f \"{temp_dir}/{exe_name} {cmd_args}\")
|
kill $(pgrep -x -f \"{temp_dir}/{exe_name} {cmd_args}\")
|
||||||
rm -rf \"{temp_dir}\""
|
rm -rf \"{temp_dir}\""
|
||||||
|
|
||||||
|
[preset.1]
|
||||||
|
|
||||||
|
name="Windows Desktop"
|
||||||
|
platform="Windows Desktop"
|
||||||
|
runnable=true
|
||||||
|
advanced_options=true
|
||||||
|
dedicated_server=false
|
||||||
|
custom_features=""
|
||||||
|
export_filter="all_resources"
|
||||||
|
include_filter=""
|
||||||
|
exclude_filter=""
|
||||||
|
export_path="releases/FreeFTF.x86_64.exe"
|
||||||
|
patches=PackedStringArray()
|
||||||
|
encryption_include_filters=""
|
||||||
|
encryption_exclude_filters=""
|
||||||
|
seed=0
|
||||||
|
encrypt_pck=false
|
||||||
|
encrypt_directory=false
|
||||||
|
script_export_mode=2
|
||||||
|
|
||||||
|
[preset.1.options]
|
||||||
|
|
||||||
|
custom_template/debug=""
|
||||||
|
custom_template/release=""
|
||||||
|
debug/export_console_wrapper=1
|
||||||
|
binary_format/embed_pck=true
|
||||||
|
texture_format/s3tc_bptc=true
|
||||||
|
texture_format/etc2_astc=false
|
||||||
|
binary_format/architecture="x86_64"
|
||||||
|
codesign/enable=false
|
||||||
|
codesign/timestamp=true
|
||||||
|
codesign/timestamp_server_url=""
|
||||||
|
codesign/digest_algorithm=1
|
||||||
|
codesign/description=""
|
||||||
|
codesign/custom_options=PackedStringArray()
|
||||||
|
application/modify_resources=false
|
||||||
|
application/icon=""
|
||||||
|
application/console_wrapper_icon=""
|
||||||
|
application/icon_interpolation=4
|
||||||
|
application/file_version=""
|
||||||
|
application/product_version=""
|
||||||
|
application/company_name=""
|
||||||
|
application/product_name=""
|
||||||
|
application/file_description=""
|
||||||
|
application/copyright=""
|
||||||
|
application/trademarks=""
|
||||||
|
application/export_angle=0
|
||||||
|
application/export_d3d12=0
|
||||||
|
application/d3d12_agility_sdk_multiarch=true
|
||||||
|
ssh_remote_deploy/enabled=false
|
||||||
|
ssh_remote_deploy/host="user@host_ip"
|
||||||
|
ssh_remote_deploy/port="22"
|
||||||
|
ssh_remote_deploy/extra_args_ssh=""
|
||||||
|
ssh_remote_deploy/extra_args_scp=""
|
||||||
|
ssh_remote_deploy/run_script="Expand-Archive -LiteralPath '{temp_dir}\\{archive_name}' -DestinationPath '{temp_dir}'
|
||||||
|
$action = New-ScheduledTaskAction -Execute '{temp_dir}\\{exe_name}' -Argument '{cmd_args}'
|
||||||
|
$trigger = New-ScheduledTaskTrigger -Once -At 00:00
|
||||||
|
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries
|
||||||
|
$task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings
|
||||||
|
Register-ScheduledTask godot_remote_debug -InputObject $task -Force:$true
|
||||||
|
Start-ScheduledTask -TaskName godot_remote_debug
|
||||||
|
while (Get-ScheduledTask -TaskName godot_remote_debug | ? State -eq running) { Start-Sleep -Milliseconds 100 }
|
||||||
|
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue"
|
||||||
|
ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue
|
||||||
|
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue
|
||||||
|
Remove-Item -Recurse -Force '{temp_dir}'"
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
class_name MultiplayerClass
|
class_name MultiplayerClass
|
||||||
extends Node
|
extends Node
|
||||||
|
|
||||||
const ADDRESS: String = "127.0.0.1"
|
|
||||||
const PORT: int = 4516
|
const PORT: int = 4516
|
||||||
|
|
||||||
var peer: ENetMultiplayerPeer = null
|
var peer: ENetMultiplayerPeer = null
|
||||||
var players: Array[Dictionary] = []
|
var players: Dictionary = {}
|
||||||
var fuseboxes: int = 0
|
var fuseboxes: int = 0
|
||||||
|
|
||||||
var playerlist_label: Label = null
|
var playerlist_label: Label = null
|
||||||
|
|
||||||
|
var entered_username: String = ""
|
||||||
|
|
||||||
## Host Specific
|
## Host Specific
|
||||||
|
|
||||||
# Hosts server
|
# Hosts server
|
||||||
|
@ -19,39 +20,58 @@ func host_server() -> void:
|
||||||
peer = null
|
peer = null
|
||||||
return
|
return
|
||||||
multiplayer.multiplayer_peer = peer
|
multiplayer.multiplayer_peer = peer
|
||||||
|
|
||||||
if multiplayer.peer_connected.connect(_on_player_joined) != OK:
|
if multiplayer.peer_connected.connect(_on_player_joined) != OK:
|
||||||
print("Failed to connect signal")
|
print("Failed to connect signal")
|
||||||
if multiplayer.peer_disconnected.connect(_on_player_left) != OK:
|
if multiplayer.peer_disconnected.connect(_on_player_left) != OK:
|
||||||
print("Failed to connect signal")
|
print("Failed to connect signal")
|
||||||
|
|
||||||
|
if get_tree().change_scene_to_file("res://ui/lobby.tscn") != OK:
|
||||||
|
print("Failed to change to scene.")
|
||||||
|
|
||||||
_on_player_joined(multiplayer.get_unique_id())
|
_on_player_joined(multiplayer.get_unique_id())
|
||||||
|
player_username.rpc_id(1, Options.username)
|
||||||
|
|
||||||
# Runs when player joins
|
# Runs when player joins
|
||||||
func _on_player_joined(id: int) -> void:
|
func _on_player_joined(id: int) -> void:
|
||||||
players.push_back({
|
players[id] = {
|
||||||
"id": id,
|
"id": id,
|
||||||
|
"username": "Waiting...",
|
||||||
"loaded": false,
|
"loaded": false,
|
||||||
"hunter": false,
|
"hunter": false,
|
||||||
"captured": false,
|
"captured": false,
|
||||||
"escaped": false,
|
"escaped": false,
|
||||||
})
|
}
|
||||||
|
|
||||||
send_playerlist()
|
send_playerlist()
|
||||||
|
|
||||||
# Runs when player leaves
|
# Runs when player leaves
|
||||||
func _on_player_left(id: int) -> void:
|
func _on_player_left(id: int) -> void:
|
||||||
players = players.filter(func (player: Dictionary) -> bool: return player.id != id)
|
if !players.erase(id):
|
||||||
|
print("Player was never registered!")
|
||||||
|
send_playerlist()
|
||||||
|
|
||||||
|
# Receives the players username
|
||||||
|
@rpc("any_peer", "call_local", "reliable")
|
||||||
|
func player_username(username: String) -> void:
|
||||||
|
players[multiplayer.get_remote_sender_id()].username = username
|
||||||
send_playerlist()
|
send_playerlist()
|
||||||
|
|
||||||
# Prepares the label text for the playerlist on the join/host screen
|
# Prepares the label text for the playerlist on the join/host screen
|
||||||
func send_playerlist() -> void:
|
func send_playerlist() -> void:
|
||||||
var playerlist: String = ""
|
var playerlist: String = ""
|
||||||
|
|
||||||
for player: Dictionary in players:
|
for id: int in players:
|
||||||
playerlist += str(player.id)
|
playerlist += players[id].username
|
||||||
playerlist += "\n"
|
playerlist += "\n"
|
||||||
|
|
||||||
update_playerlist.rpc(playerlist)
|
update_playerlist.rpc(playerlist)
|
||||||
|
|
||||||
|
@rpc("any_peer", "call_local", "reliable")
|
||||||
|
func request_playerlist() -> void:
|
||||||
|
if multiplayer.is_server():
|
||||||
|
send_playerlist()
|
||||||
|
|
||||||
# Switches the scene, and waits until everyone is fully loaded.
|
# Switches the scene, and waits until everyone is fully loaded.
|
||||||
@rpc("authority", "call_local", "reliable")
|
@rpc("authority", "call_local", "reliable")
|
||||||
func switch_scene(path: String) -> void:
|
func switch_scene(path: String) -> void:
|
||||||
|
@ -60,8 +80,8 @@ func switch_scene(path: String) -> void:
|
||||||
_scene_loaded.rpc_id(1)
|
_scene_loaded.rpc_id(1)
|
||||||
while true:
|
while true:
|
||||||
var loaded: bool = true
|
var loaded: bool = true
|
||||||
for player: Dictionary in players:
|
for id: int in players:
|
||||||
if player.loaded == false:
|
if players[id].loaded == false:
|
||||||
loaded = false
|
loaded = false
|
||||||
break
|
break
|
||||||
if loaded:
|
if loaded:
|
||||||
|
@ -77,17 +97,14 @@ func switch_scene(path: String) -> void:
|
||||||
# Callback to switch_scene from the remote peer
|
# Callback to switch_scene from the remote peer
|
||||||
@rpc("any_peer", "call_local", "reliable")
|
@rpc("any_peer", "call_local", "reliable")
|
||||||
func _scene_loaded() -> void:
|
func _scene_loaded() -> void:
|
||||||
var id: int = multiplayer.get_remote_sender_id()
|
|
||||||
if multiplayer.is_server():
|
if multiplayer.is_server():
|
||||||
for i: int in range(players.size()):
|
players[multiplayer.get_remote_sender_id()].loaded = true
|
||||||
if players[i].id == multiplayer.get_remote_sender_id():
|
|
||||||
players[i].loaded = true
|
|
||||||
|
|
||||||
func _process(_delta: float) -> void:
|
func _process(_delta: float) -> void:
|
||||||
if multiplayer.multiplayer_peer and multiplayer.is_server() and !players.is_empty():
|
if multiplayer.multiplayer_peer and multiplayer.is_server() and !players.is_empty():
|
||||||
var lost: bool = true
|
var lost: bool = true
|
||||||
for player: Dictionary in players:
|
for id: int in players:
|
||||||
if (!player.captured or !player.escaped) and !player.hunter:
|
if !(players[id].captured or players[id].escaped) and !players[id].hunter:
|
||||||
lost = false
|
lost = false
|
||||||
if lost:
|
if lost:
|
||||||
terminate_multiplayer.rpc()
|
terminate_multiplayer.rpc()
|
||||||
|
@ -95,20 +112,42 @@ func _process(_delta: float) -> void:
|
||||||
## Client Specific
|
## Client Specific
|
||||||
|
|
||||||
# Joins a server
|
# Joins a server
|
||||||
func join_server() -> void:
|
func join_server(username: String = Options.username, ip_address: String = Options.ip_address) -> void:
|
||||||
|
if !username:
|
||||||
|
username = Options.username
|
||||||
|
if !ip_address:
|
||||||
|
ip_address = Options.ip_address
|
||||||
|
|
||||||
|
entered_username = username
|
||||||
|
|
||||||
peer = ENetMultiplayerPeer.new()
|
peer = ENetMultiplayerPeer.new()
|
||||||
if peer.create_client(ADDRESS, PORT) != OK:
|
if peer.create_client(ip_address, PORT) != OK:
|
||||||
peer = null
|
terminate_multiplayer()
|
||||||
return
|
return
|
||||||
multiplayer.multiplayer_peer = peer
|
multiplayer.multiplayer_peer = peer
|
||||||
|
|
||||||
|
if multiplayer.connected_to_server.connect(_on_server_joined) != OK:
|
||||||
|
print("Failed to connect signal")
|
||||||
|
if multiplayer.connection_failed.connect(_on_server_join_failed) != OK:
|
||||||
|
print("Failed to connect signal")
|
||||||
|
|
||||||
|
# After successful join
|
||||||
|
func _on_server_joined() -> void:
|
||||||
|
if get_tree().change_scene_to_file("res://ui/lobby.tscn") != OK:
|
||||||
|
print("Failed to change to scene.")
|
||||||
|
player_username.rpc_id(1, entered_username)
|
||||||
|
|
||||||
|
# After unsuccessful join
|
||||||
|
func _on_server_join_failed() -> void:
|
||||||
|
terminate_multiplayer()
|
||||||
|
|
||||||
## Shared
|
## Shared
|
||||||
|
|
||||||
# Terminates all Multiplayer functionality.
|
# Terminates all Multiplayer functionality.
|
||||||
@rpc("authority", "call_local", "reliable")
|
@rpc("authority", "call_local", "reliable")
|
||||||
func terminate_multiplayer() -> void:
|
func terminate_multiplayer() -> void:
|
||||||
multiplayer.multiplayer_peer = null
|
multiplayer.multiplayer_peer = null
|
||||||
players = []
|
players = {}
|
||||||
fuseboxes = 0
|
fuseboxes = 0
|
||||||
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
||||||
if get_tree().change_scene_to_file("res://ui/main_menu.tscn") != OK:
|
if get_tree().change_scene_to_file("res://ui/main_menu.tscn") != OK:
|
||||||
|
@ -119,3 +158,13 @@ func terminate_multiplayer() -> void:
|
||||||
func update_playerlist(list: String) -> void:
|
func update_playerlist(list: String) -> void:
|
||||||
if playerlist_label != null:
|
if playerlist_label != null:
|
||||||
playerlist_label.text = list
|
playerlist_label.text = list
|
||||||
|
|
||||||
|
# Adds Fusebox
|
||||||
|
@rpc("authority", "call_local", "reliable")
|
||||||
|
func add_fusebox() -> void:
|
||||||
|
fuseboxes += 1
|
||||||
|
|
||||||
|
# Removes Fusebox
|
||||||
|
@rpc("authority", "call_local", "reliable")
|
||||||
|
func remove_fusebox() -> void:
|
||||||
|
fuseboxes -= 1
|
||||||
|
|
34
global/options.gd
Normal file
34
global/options.gd
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
class_name OptionsClass
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
var username: String = "DefaultUsername"
|
||||||
|
var ip_address: String = "127.0.0.1"
|
||||||
|
var data_collection: bool = false
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
load_options()
|
||||||
|
|
||||||
|
func save_options() -> void:
|
||||||
|
var save_data: String = JSON.stringify({
|
||||||
|
"username": username,
|
||||||
|
"ip_address": ip_address,
|
||||||
|
"data_collection": data_collection,
|
||||||
|
})
|
||||||
|
|
||||||
|
var file: FileAccess = FileAccess.open("user://options.json", FileAccess.WRITE)
|
||||||
|
|
||||||
|
if file and !file.store_string(save_data):
|
||||||
|
print("Failed to save settings.")
|
||||||
|
|
||||||
|
func load_options() -> void:
|
||||||
|
var file: FileAccess = FileAccess.open("user://options.json", FileAccess.READ)
|
||||||
|
|
||||||
|
if file:
|
||||||
|
var save_data: Dictionary = JSON.parse_string(file.get_as_text())
|
||||||
|
if save_data:
|
||||||
|
if save_data.has("username"):
|
||||||
|
username = save_data.username
|
||||||
|
if save_data.has("ip_address"):
|
||||||
|
ip_address = save_data.ip_address
|
||||||
|
if save_data.has("data_collection"):
|
||||||
|
data_collection = save_data.data_collection
|
1
global/options.gd.uid
Normal file
1
global/options.gd.uid
Normal file
|
@ -0,0 +1 @@
|
||||||
|
uid://m3aryyjtncwx
|
242
maps/assets/map.gltf
Normal file
242
maps/assets/map.gltf
Normal file
File diff suppressed because one or more lines are too long
37
maps/assets/map.gltf.import
Normal file
37
maps/assets/map.gltf.import
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="scene"
|
||||||
|
importer_version=1
|
||||||
|
type="PackedScene"
|
||||||
|
uid="uid://bago2uuxpae22"
|
||||||
|
path="res://.godot/imported/map.gltf-c3a1ee560168fb25b24f2e9bfd0cd850.scn"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://maps/assets/map.gltf"
|
||||||
|
dest_files=["res://.godot/imported/map.gltf-c3a1ee560168fb25b24f2e9bfd0cd850.scn"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
nodes/root_type=""
|
||||||
|
nodes/root_name=""
|
||||||
|
nodes/apply_root_scale=true
|
||||||
|
nodes/root_scale=1.0
|
||||||
|
nodes/import_as_skeleton_bones=false
|
||||||
|
nodes/use_node_type_suffixes=true
|
||||||
|
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={}
|
||||||
|
gltf/naming_version=1
|
||||||
|
gltf/embedded_image_handling=1
|
BIN
maps/assets/map_0.png
Normal file
BIN
maps/assets/map_0.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 211 B |
38
maps/assets/map_0.png.import
Normal file
38
maps/assets/map_0.png.import
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://bv1exi2cc5vji"
|
||||||
|
path.s3tc="res://.godot/imported/map_0.png-bde32f7cbb719c1cd3adb7b4e7780a34.s3tc.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
generator_parameters={
|
||||||
|
"md5": "28ac435753fa790c09d222ee0f776064"
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://maps/assets/map_0.png"
|
||||||
|
dest_files=["res://.godot/imported/map_0.png-bde32f7cbb719c1cd3adb7b4e7780a34.s3tc.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=2
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=true
|
||||||
|
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=0
|
BIN
maps/assets/test_map.exr
Normal file
BIN
maps/assets/test_map.exr
Normal file
Binary file not shown.
27
maps/assets/test_map.exr.import
Normal file
27
maps/assets/test_map.exr.import
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="2d_array_texture"
|
||||||
|
type="CompressedTexture2DArray"
|
||||||
|
uid="uid://bh7jk5uhw4bqg"
|
||||||
|
path.bptc="res://.godot/imported/test_map.exr-8ee8e6411c22dfab2a271ee543ced25b.bptc.ctexarray"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://maps/assets/test_map.exr"
|
||||||
|
dest_files=["res://.godot/imported/test_map.exr-8ee8e6411c22dfab2a271ee543ced25b.bptc.ctexarray"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=2
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/channel_pack=1
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
slices/horizontal=1
|
||||||
|
slices/vertical=2
|
BIN
maps/assets/test_map.lmbake
Normal file
BIN
maps/assets/test_map.lmbake
Normal file
Binary file not shown.
BIN
maps/assets/test_map.lmbake.depren
Normal file
BIN
maps/assets/test_map.lmbake.depren
Normal file
Binary file not shown.
20
maps/map.gd
20
maps/map.gd
|
@ -4,9 +4,25 @@ extends Node3D
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
if multiplayer.is_server():
|
if multiplayer.is_server():
|
||||||
randomize()
|
randomize()
|
||||||
Multiplayer.players[randi_range(0, Multiplayer.players.size() - 1)].hunter = true
|
var random_id: int = Multiplayer.players.keys()[randi_range(0, Multiplayer.players.size() - 1)]
|
||||||
|
Multiplayer.players[random_id].hunter = true
|
||||||
for i: int in $PlayerSpawners.get_children().size():
|
for i: int in $PlayerSpawners.get_children().size():
|
||||||
if i < Multiplayer.players.size():
|
if i < Multiplayer.players.size():
|
||||||
var spawner: PlayerSpawner = $PlayerSpawners.get_child(i)
|
var spawner: PlayerSpawner = $PlayerSpawners.get_child(i)
|
||||||
var player: Dictionary = Multiplayer.players[i]
|
var player: Dictionary = Multiplayer.players[Multiplayer.players.keys()[i]]
|
||||||
spawner.spawn_player(player)
|
spawner.spawn_player(player)
|
||||||
|
|
||||||
|
func _on_exit_entered(body: Node3D) -> void:
|
||||||
|
if multiplayer.is_server() and (body is Player):
|
||||||
|
var player: Player = body
|
||||||
|
if !player.hunter and Multiplayer.fuseboxes <= 0:
|
||||||
|
Multiplayer.players[player.get_multiplayer_authority()].escaped = true
|
||||||
|
player.get_caught.rpc_id(player.get_multiplayer_authority(), $SpectatorCamera.get_path())
|
||||||
|
|
||||||
|
func _process(_delta: float) -> void:
|
||||||
|
if Multiplayer.fuseboxes <= 0:
|
||||||
|
(($EscapeArea/Light as CSGBox3D).material as StandardMaterial3D).albedo_color.r8 = 0
|
||||||
|
(($EscapeArea/Light as CSGBox3D).material as StandardMaterial3D).albedo_color.g8 = 255
|
||||||
|
else:
|
||||||
|
(($EscapeArea/Light as CSGBox3D).material as StandardMaterial3D).albedo_color.r8 = 255
|
||||||
|
(($EscapeArea/Light as CSGBox3D).material as StandardMaterial3D).albedo_color.g8 = 0
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -19,6 +19,7 @@ boot_splash/show_image=false
|
||||||
[autoload]
|
[autoload]
|
||||||
|
|
||||||
Multiplayer="*res://global/multiplayer.gd"
|
Multiplayer="*res://global/multiplayer.gd"
|
||||||
|
Options="*res://global/options.gd"
|
||||||
|
|
||||||
[debug]
|
[debug]
|
||||||
|
|
||||||
|
@ -125,6 +126,11 @@ focus={
|
||||||
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":false,"script":null)
|
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":false,"script":null)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
crouch={
|
||||||
|
"deadzone": 0.2,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":67,"key_label":0,"unicode":99,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
[rendering]
|
[rendering]
|
||||||
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
class_name HostGame
|
|
||||||
extends JoinGame
|
|
||||||
|
|
||||||
func _on_start_game_button_pressed() -> void:
|
|
||||||
Multiplayer.switch_scene.rpc("res://maps/test_map.tscn")
|
|
|
@ -1,5 +1,10 @@
|
||||||
class_name JoinGame
|
class_name JoinGame
|
||||||
extends Control
|
extends Control
|
||||||
|
|
||||||
func _ready() -> void:
|
@onready var options_list: VBoxContainer = $OptionsList
|
||||||
Multiplayer.playerlist_label = $PlayerList
|
@onready var username_input: LineEdit = $OptionsList/UsernameOption/OptionInput
|
||||||
|
@onready var ip_address_input: LineEdit = $OptionsList/IpAddressOption/OptionInput
|
||||||
|
|
||||||
|
func _on_join_button_pressed() -> void:
|
||||||
|
options_list.visible = false
|
||||||
|
Multiplayer.join_server(username_input.text, ip_address_input.text)
|
||||||
|
|
|
@ -12,8 +12,56 @@ grow_vertical = 2
|
||||||
script = ExtResource("1_ju2tq")
|
script = ExtResource("1_ju2tq")
|
||||||
|
|
||||||
[node name="PlayerList" type="Label" parent="."]
|
[node name="PlayerList" type="Label" parent="."]
|
||||||
|
visible = false
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
anchors_preset = 9
|
anchors_preset = 9
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
offset_right = 1.0
|
offset_right = 1.0
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
|
text = "Connecting to the server..."
|
||||||
|
|
||||||
|
[node name="OptionsList" type="VBoxContainer" parent="."]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 8
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_top = 0.5
|
||||||
|
anchor_right = 0.5
|
||||||
|
anchor_bottom = 0.5
|
||||||
|
offset_left = -20.0
|
||||||
|
offset_top = -20.0
|
||||||
|
offset_right = 20.0
|
||||||
|
offset_bottom = 20.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
|
||||||
|
[node name="UsernameOption" type="HBoxContainer" parent="OptionsList"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 8
|
||||||
|
|
||||||
|
[node name="OptionName" type="Label" parent="OptionsList/UsernameOption"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Username:"
|
||||||
|
|
||||||
|
[node name="OptionInput" type="LineEdit" parent="OptionsList/UsernameOption"]
|
||||||
|
custom_minimum_size = Vector2(175, 0)
|
||||||
|
layout_mode = 2
|
||||||
|
max_length = 20
|
||||||
|
|
||||||
|
[node name="IpAddressOption" type="HBoxContainer" parent="OptionsList"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 8
|
||||||
|
|
||||||
|
[node name="OptionName" type="Label" parent="OptionsList/IpAddressOption"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "IP Address:"
|
||||||
|
|
||||||
|
[node name="OptionInput" type="LineEdit" parent="OptionsList/IpAddressOption"]
|
||||||
|
custom_minimum_size = Vector2(175, 0)
|
||||||
|
layout_mode = 2
|
||||||
|
max_length = 20
|
||||||
|
|
||||||
|
[node name="JoinButton" type="Button" parent="OptionsList"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Join Server"
|
||||||
|
|
||||||
|
[connection signal="pressed" from="OptionsList/JoinButton" to="." method="_on_join_button_pressed"]
|
||||||
|
|
15
ui/lobby.gd
Normal file
15
ui/lobby.gd
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
class_name HostGame
|
||||||
|
extends JoinGame
|
||||||
|
|
||||||
|
@onready var start_button: Button = $StartGameButton
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
Multiplayer.playerlist_label = $PlayerList
|
||||||
|
if multiplayer.is_server():
|
||||||
|
start_button.disabled = false
|
||||||
|
start_button.visible = true
|
||||||
|
Multiplayer.request_playerlist.rpc_id(1)
|
||||||
|
|
||||||
|
func _on_start_game_button_pressed() -> void:
|
||||||
|
Multiplayer.switch_scene.rpc("res://maps/test_map.tscn")
|
|
@ -1,6 +1,6 @@
|
||||||
[gd_scene load_steps=2 format=3 uid="uid://corjvfihg047u"]
|
[gd_scene load_steps=2 format=3 uid="uid://corjvfihg047u"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://cuumy3t2hkgcu" path="res://ui/host_game.gd" id="1_fg6en"]
|
[ext_resource type="Script" uid="uid://cuumy3t2hkgcu" path="res://ui/lobby.gd" id="1_nmq56"]
|
||||||
|
|
||||||
[node name="HostGame" type="Control"]
|
[node name="HostGame" type="Control"]
|
||||||
layout_mode = 3
|
layout_mode = 3
|
||||||
|
@ -9,9 +9,10 @@ anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
script = ExtResource("1_fg6en")
|
script = ExtResource("1_nmq56")
|
||||||
|
|
||||||
[node name="StartGameButton" type="Button" parent="."]
|
[node name="StartGameButton" type="Button" parent="."]
|
||||||
|
visible = false
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
anchors_preset = 8
|
anchors_preset = 8
|
||||||
anchor_left = 0.5
|
anchor_left = 0.5
|
||||||
|
@ -24,6 +25,7 @@ offset_right = 48.0
|
||||||
offset_bottom = 15.5
|
offset_bottom = 15.5
|
||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
|
disabled = true
|
||||||
text = "Start Game"
|
text = "Start Game"
|
||||||
|
|
||||||
[node name="PlayerList" type="Label" parent="."]
|
[node name="PlayerList" type="Label" parent="."]
|
||||||
|
@ -32,6 +34,5 @@ anchors_preset = 9
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
offset_right = 1.0
|
offset_right = 1.0
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
text = "1"
|
|
||||||
|
|
||||||
[connection signal="pressed" from="StartGameButton" to="." method="_on_start_game_button_pressed"]
|
[connection signal="pressed" from="StartGameButton" to="." method="_on_start_game_button_pressed"]
|
|
@ -3,10 +3,12 @@ extends Control
|
||||||
|
|
||||||
func _on_host_game_button_pressed() -> void:
|
func _on_host_game_button_pressed() -> void:
|
||||||
Multiplayer.host_server()
|
Multiplayer.host_server()
|
||||||
if get_tree().change_scene_to_file("res://ui/host_game.tscn") != OK:
|
|
||||||
print("Failed to change to scene.")
|
|
||||||
|
|
||||||
func _on_join_game_button_pressed() -> void:
|
func _on_join_game_button_pressed() -> void:
|
||||||
Multiplayer.join_server()
|
|
||||||
if get_tree().change_scene_to_file("res://ui/join_game.tscn") != OK:
|
if get_tree().change_scene_to_file("res://ui/join_game.tscn") != OK:
|
||||||
print("Failed to change to scene.")
|
print("Failed to change to scene.")
|
||||||
|
|
||||||
|
|
||||||
|
func _on_options_button_pressed() -> void:
|
||||||
|
if get_tree().change_scene_to_file("res://ui/options_menu.tscn") != OK:
|
||||||
|
print("Failed to change to scene.")
|
||||||
|
|
|
@ -38,5 +38,23 @@ text = "Host Game"
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
text = "Join Game"
|
text = "Join Game"
|
||||||
|
|
||||||
|
[node name="OptionsButton" type="Button" parent="MainContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Options"
|
||||||
|
|
||||||
|
[node name="Version" type="Label" parent="."]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 3
|
||||||
|
anchor_left = 1.0
|
||||||
|
anchor_top = 1.0
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_left = -40.0
|
||||||
|
offset_top = -23.0
|
||||||
|
grow_horizontal = 0
|
||||||
|
grow_vertical = 0
|
||||||
|
text = "0.1.0"
|
||||||
|
|
||||||
[connection signal="pressed" from="MainContainer/HostGameButton" to="." method="_on_host_game_button_pressed"]
|
[connection signal="pressed" from="MainContainer/HostGameButton" to="." method="_on_host_game_button_pressed"]
|
||||||
[connection signal="pressed" from="MainContainer/JoinGameButton" to="." method="_on_join_game_button_pressed"]
|
[connection signal="pressed" from="MainContainer/JoinGameButton" to="." method="_on_join_game_button_pressed"]
|
||||||
|
[connection signal="pressed" from="MainContainer/OptionsButton" to="." method="_on_options_button_pressed"]
|
||||||
|
|
27
ui/options_menu.gd
Normal file
27
ui/options_menu.gd
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
class_name OptionsMenu
|
||||||
|
extends Control
|
||||||
|
|
||||||
|
@onready var username_input: LineEdit = $OptionsList/UsernameOption/OptionInput
|
||||||
|
@onready var ip_address_input: LineEdit = $OptionsList/IpAddressOption/OptionInput
|
||||||
|
@onready var data_collection_input: CheckBox = $OptionsList/DataCollectionOption/OptionInput
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
username_input.text = Options.username
|
||||||
|
ip_address_input.text = Options.ip_address
|
||||||
|
data_collection_input.button_pressed = Options.data_collection
|
||||||
|
|
||||||
|
func _username_changed(text: String) -> void:
|
||||||
|
Options.username = text
|
||||||
|
Options.save_options()
|
||||||
|
|
||||||
|
func _ip_address_changed(text: String) -> void:
|
||||||
|
Options.ip_address = text
|
||||||
|
Options.save_options()
|
||||||
|
|
||||||
|
func _data_collection_changed(new_option: bool) -> void:
|
||||||
|
Options.data_collection = new_option
|
||||||
|
Options.save_options()
|
||||||
|
|
||||||
|
func _main_menu() -> void:
|
||||||
|
if get_tree().change_scene_to_file("res://ui/main_menu.tscn") != OK:
|
||||||
|
print("Failed to change to scene.")
|
1
ui/options_menu.gd.uid
Normal file
1
ui/options_menu.gd.uid
Normal file
|
@ -0,0 +1 @@
|
||||||
|
uid://fpohmcdqnk35
|
78
ui/options_menu.tscn
Normal file
78
ui/options_menu.tscn
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
[gd_scene load_steps=2 format=3 uid="uid://bxeejl1m7w5mn"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://fpohmcdqnk35" path="res://ui/options_menu.gd" id="1_ibk6l"]
|
||||||
|
|
||||||
|
[node name="OptionsMenu" type="Control"]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
script = ExtResource("1_ibk6l")
|
||||||
|
|
||||||
|
[node name="OptionsList" type="VBoxContainer" parent="."]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 13
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_right = 0.5
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_left = -78.5
|
||||||
|
offset_right = 78.5
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
|
||||||
|
[node name="UsernameOption" type="HBoxContainer" parent="OptionsList"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 8
|
||||||
|
|
||||||
|
[node name="OptionName" type="Label" parent="OptionsList/UsernameOption"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Username:"
|
||||||
|
|
||||||
|
[node name="OptionInput" type="LineEdit" parent="OptionsList/UsernameOption"]
|
||||||
|
custom_minimum_size = Vector2(175, 0)
|
||||||
|
layout_mode = 2
|
||||||
|
max_length = 20
|
||||||
|
|
||||||
|
[node name="IpAddressOption" type="HBoxContainer" parent="OptionsList"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 8
|
||||||
|
|
||||||
|
[node name="OptionName" type="Label" parent="OptionsList/IpAddressOption"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "IP Address:"
|
||||||
|
|
||||||
|
[node name="OptionInput" type="LineEdit" parent="OptionsList/IpAddressOption"]
|
||||||
|
custom_minimum_size = Vector2(175, 0)
|
||||||
|
layout_mode = 2
|
||||||
|
max_length = 20
|
||||||
|
|
||||||
|
[node name="DataCollectionOption" type="HBoxContainer" parent="OptionsList"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 8
|
||||||
|
|
||||||
|
[node name="OptionName" type="Label" parent="OptionsList/DataCollectionOption"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Server data collection allowed:"
|
||||||
|
|
||||||
|
[node name="OptionInput" type="CheckBox" parent="OptionsList/DataCollectionOption"]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="Button" type="Button" parent="."]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 3
|
||||||
|
anchor_left = 1.0
|
||||||
|
anchor_top = 1.0
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_left = -157.0
|
||||||
|
offset_top = -31.0
|
||||||
|
grow_horizontal = 0
|
||||||
|
grow_vertical = 0
|
||||||
|
text = "Back to Main Menu"
|
||||||
|
|
||||||
|
[connection signal="text_changed" from="OptionsList/UsernameOption/OptionInput" to="." method="_username_changed"]
|
||||||
|
[connection signal="text_changed" from="OptionsList/IpAddressOption/OptionInput" to="." method="_ip_address_changed"]
|
||||||
|
[connection signal="toggled" from="OptionsList/DataCollectionOption/OptionInput" to="." method="_data_collection_changed"]
|
||||||
|
[connection signal="pressed" from="Button" to="." method="_main_menu"]
|
Loading…
Add table
Add a link
Reference in a new issue