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/
|
||||
/android/
|
||||
releases/
|
||||
|
|
|
@ -12,9 +12,7 @@ func _on_dropoff(body: Node3D) -> void:
|
|||
player.released_player.rpc_id(player.get_multiplayer_authority())
|
||||
(player.get_node("ReleaseTimer") as Timer).stop()
|
||||
($DamageTimer as Timer).start()
|
||||
for i: int in range(Multiplayer.players.size()):
|
||||
if Multiplayer.players[i].id == caught_player.get_multiplayer_authority():
|
||||
Multiplayer.players[i].captured = true
|
||||
Multiplayer.players[caught_player.get_multiplayer_authority()].captured = true
|
||||
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 = 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"]
|
||||
size = Vector3(10, 10, 10)
|
||||
|
||||
[node name="EscapeArea" type="Area3D"]
|
||||
script = ExtResource("1_ubptc")
|
||||
script = SubResource("GDScript_yuux7")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||
shape = SubResource("BoxShape3D_eij3b")
|
||||
|
|
|
@ -5,7 +5,7 @@ var done: bool = false
|
|||
|
||||
func _ready() -> void:
|
||||
if multiplayer.is_server():
|
||||
Multiplayer.fuseboxes += 1
|
||||
Multiplayer.add_fusebox.rpc()
|
||||
|
||||
func _on_fixing_started(body: Node3D) -> void:
|
||||
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:
|
||||
($Hinge as Node3D).rotation.y = 0
|
||||
done = true
|
||||
Multiplayer.fuseboxes -= 1
|
||||
Multiplayer.remove_fusebox.rpc()
|
||||
|
|
|
@ -5,16 +5,25 @@ const SPEED: float = 5.0
|
|||
const JUMP_VELOCITY: float = 4.5
|
||||
|
||||
@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 needle: Area3D = $Syringe/SyringeNeedle
|
||||
|
||||
@onready var bag: Node3D = $Bag
|
||||
@onready var captured: Node3D = $Bag/Captured
|
||||
|
||||
@onready var mesh: MeshInstance3D = $Mesh
|
||||
@onready var collision: CollisionShape3D = $Collision
|
||||
|
||||
var hunter: bool = true
|
||||
var caught_player: Player = null
|
||||
var new_spawn: Vector3
|
||||
|
||||
var crouching: bool = false
|
||||
var speed_penalty: float = 0.0
|
||||
|
||||
@export var health: int = 100
|
||||
|
||||
func _ready() -> void:
|
||||
|
@ -31,9 +40,9 @@ func _ready() -> void:
|
|||
func _physics_process(delta: float) -> void:
|
||||
# Zoom
|
||||
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"):
|
||||
camera.position.z += 1
|
||||
spring_arm.spring_length += 1
|
||||
|
||||
if is_multiplayer_authority():
|
||||
# Focus
|
||||
|
@ -49,15 +58,31 @@ func _physics_process(delta: float) -> void:
|
|||
velocity += get_gravity() * delta
|
||||
|
||||
# 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
|
||||
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
|
||||
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()
|
||||
|
||||
velocity.x = direction.x * SPEED
|
||||
velocity.z = direction.z * SPEED
|
||||
velocity.x = direction.x * (SPEED - speed_penalty)
|
||||
velocity.z = direction.z * (SPEED - speed_penalty)
|
||||
|
||||
# Hunter specific
|
||||
if hunter:
|
||||
|
@ -67,6 +92,11 @@ func _physics_process(delta: float) -> void:
|
|||
syringe.position.z += 0.1
|
||||
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():
|
||||
pass
|
||||
|
||||
|
@ -127,7 +157,7 @@ func get_imprisoned(coffin_path: NodePath) -> void:
|
|||
# This is called on any player that has just stabbed/caught another.
|
||||
@rpc("any_peer", "call_local", "reliable")
|
||||
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)
|
||||
caught_player = player
|
||||
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"]
|
||||
|
||||
|
@ -14,6 +14,8 @@ height = 1.8
|
|||
height = 0.2
|
||||
radius = 0.05
|
||||
|
||||
[sub_resource type="SeparationRayShape3D" id="SeparationRayShape3D_merdl"]
|
||||
|
||||
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_merdl"]
|
||||
properties/0/path = NodePath(".:position")
|
||||
properties/0/spawn = true
|
||||
|
@ -30,6 +32,15 @@ properties/3/replication_mode = 1
|
|||
properties/4/path = NodePath(".:health")
|
||||
properties/4/spawn = true
|
||||
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"]
|
||||
script = ExtResource("1_merdl")
|
||||
|
@ -68,8 +79,11 @@ radius = 0.3
|
|||
[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)
|
||||
|
||||
[node name="View" type="Camera3D" parent="ViewY/ViewX"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 4)
|
||||
[node name="Arm" type="SpringArm3D" parent="ViewY/ViewX"]
|
||||
shape = SubResource("SeparationRayShape3D_merdl")
|
||||
spring_length = 10.0
|
||||
|
||||
[node name="View" type="Camera3D" parent="ViewY/ViewX/Arm"]
|
||||
size = 5.0
|
||||
|
||||
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."]
|
||||
|
|
|
@ -9,7 +9,7 @@ custom_features=""
|
|||
export_filter="all_resources"
|
||||
include_filter=""
|
||||
exclude_filter=""
|
||||
export_path="../../FreeFTF.x86_64"
|
||||
export_path="releases/FreeFTF.x86_64"
|
||||
patches=PackedStringArray()
|
||||
encryption_include_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
|
||||
kill $(pgrep -x -f \"{temp_dir}/{exe_name} {cmd_args}\")
|
||||
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
|
||||
extends Node
|
||||
|
||||
const ADDRESS: String = "127.0.0.1"
|
||||
const PORT: int = 4516
|
||||
|
||||
var peer: ENetMultiplayerPeer = null
|
||||
var players: Array[Dictionary] = []
|
||||
var players: Dictionary = {}
|
||||
var fuseboxes: int = 0
|
||||
|
||||
var playerlist_label: Label = null
|
||||
|
||||
var entered_username: String = ""
|
||||
|
||||
## Host Specific
|
||||
|
||||
# Hosts server
|
||||
|
@ -19,39 +20,58 @@ func host_server() -> void:
|
|||
peer = null
|
||||
return
|
||||
multiplayer.multiplayer_peer = peer
|
||||
|
||||
if multiplayer.peer_connected.connect(_on_player_joined) != OK:
|
||||
print("Failed to connect signal")
|
||||
if multiplayer.peer_disconnected.connect(_on_player_left) != OK:
|
||||
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())
|
||||
player_username.rpc_id(1, Options.username)
|
||||
|
||||
# Runs when player joins
|
||||
func _on_player_joined(id: int) -> void:
|
||||
players.push_back({
|
||||
players[id] = {
|
||||
"id": id,
|
||||
"username": "Waiting...",
|
||||
"loaded": false,
|
||||
"hunter": false,
|
||||
"captured": false,
|
||||
"escaped": false,
|
||||
})
|
||||
}
|
||||
|
||||
send_playerlist()
|
||||
|
||||
# Runs when player leaves
|
||||
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()
|
||||
|
||||
# Prepares the label text for the playerlist on the join/host screen
|
||||
func send_playerlist() -> void:
|
||||
var playerlist: String = ""
|
||||
|
||||
for player: Dictionary in players:
|
||||
playerlist += str(player.id)
|
||||
for id: int in players:
|
||||
playerlist += players[id].username
|
||||
playerlist += "\n"
|
||||
|
||||
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.
|
||||
@rpc("authority", "call_local", "reliable")
|
||||
func switch_scene(path: String) -> void:
|
||||
|
@ -60,8 +80,8 @@ func switch_scene(path: String) -> void:
|
|||
_scene_loaded.rpc_id(1)
|
||||
while true:
|
||||
var loaded: bool = true
|
||||
for player: Dictionary in players:
|
||||
if player.loaded == false:
|
||||
for id: int in players:
|
||||
if players[id].loaded == false:
|
||||
loaded = false
|
||||
break
|
||||
if loaded:
|
||||
|
@ -77,17 +97,14 @@ func switch_scene(path: String) -> void:
|
|||
# Callback to switch_scene from the remote peer
|
||||
@rpc("any_peer", "call_local", "reliable")
|
||||
func _scene_loaded() -> void:
|
||||
var id: int = multiplayer.get_remote_sender_id()
|
||||
if multiplayer.is_server():
|
||||
for i: int in range(players.size()):
|
||||
if players[i].id == multiplayer.get_remote_sender_id():
|
||||
players[i].loaded = true
|
||||
players[multiplayer.get_remote_sender_id()].loaded = true
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if multiplayer.multiplayer_peer and multiplayer.is_server() and !players.is_empty():
|
||||
var lost: bool = true
|
||||
for player: Dictionary in players:
|
||||
if (!player.captured or !player.escaped) and !player.hunter:
|
||||
for id: int in players:
|
||||
if !(players[id].captured or players[id].escaped) and !players[id].hunter:
|
||||
lost = false
|
||||
if lost:
|
||||
terminate_multiplayer.rpc()
|
||||
|
@ -95,20 +112,42 @@ func _process(_delta: float) -> void:
|
|||
## Client Specific
|
||||
|
||||
# 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()
|
||||
if peer.create_client(ADDRESS, PORT) != OK:
|
||||
peer = null
|
||||
if peer.create_client(ip_address, PORT) != OK:
|
||||
terminate_multiplayer()
|
||||
return
|
||||
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
|
||||
|
||||
# Terminates all Multiplayer functionality.
|
||||
@rpc("authority", "call_local", "reliable")
|
||||
func terminate_multiplayer() -> void:
|
||||
multiplayer.multiplayer_peer = null
|
||||
players = []
|
||||
players = {}
|
||||
fuseboxes = 0
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
||||
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:
|
||||
if playerlist_label != null:
|
||||
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:
|
||||
if multiplayer.is_server():
|
||||
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():
|
||||
if i < Multiplayer.players.size():
|
||||
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)
|
||||
|
||||
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]
|
||||
|
||||
Multiplayer="*res://global/multiplayer.gd"
|
||||
Options="*res://global/options.gd"
|
||||
|
||||
[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)
|
||||
]
|
||||
}
|
||||
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]
|
||||
|
||||
|
|
|
@ -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
|
||||
extends Control
|
||||
|
||||
func _ready() -> void:
|
||||
Multiplayer.playerlist_label = $PlayerList
|
||||
@onready var options_list: VBoxContainer = $OptionsList
|
||||
@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")
|
||||
|
||||
[node name="PlayerList" type="Label" parent="."]
|
||||
visible = false
|
||||
layout_mode = 1
|
||||
anchors_preset = 9
|
||||
anchor_bottom = 1.0
|
||||
offset_right = 1.0
|
||||
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"]
|
||||
|
||||
[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"]
|
||||
layout_mode = 3
|
||||
|
@ -9,9 +9,10 @@ anchor_right = 1.0
|
|||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_fg6en")
|
||||
script = ExtResource("1_nmq56")
|
||||
|
||||
[node name="StartGameButton" type="Button" parent="."]
|
||||
visible = false
|
||||
layout_mode = 1
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
|
@ -24,6 +25,7 @@ offset_right = 48.0
|
|||
offset_bottom = 15.5
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
disabled = true
|
||||
text = "Start Game"
|
||||
|
||||
[node name="PlayerList" type="Label" parent="."]
|
||||
|
@ -32,6 +34,5 @@ anchors_preset = 9
|
|||
anchor_bottom = 1.0
|
||||
offset_right = 1.0
|
||||
grow_vertical = 2
|
||||
text = "1"
|
||||
|
||||
[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:
|
||||
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:
|
||||
Multiplayer.join_server()
|
||||
if get_tree().change_scene_to_file("res://ui/join_game.tscn") != OK:
|
||||
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
|
||||
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/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