Many things

Added doors
Fixed holding force distance
Inmcreased interaction ray length
Fixed player not walking when looking up/down
Added placeholder crosshair
Added group trigger
Made monitor rigid body
Fixed lighting
Added sound emitters for kreb
This commit is contained in:
Thomas Muller 2024-12-22 14:27:52 -05:00
parent 18a5ebfd50
commit cf3a29d7c3
12 changed files with 537 additions and 171 deletions

2
assets

@ -1 +1 @@
Subproject commit b96079177daaf913e8b988e493a7bc773ece00a5 Subproject commit d98c81e159c1c0ec2d794e7afb2607a709f27120

View file

@ -0,0 +1,99 @@
@tool
extends AnimatableBody3D
@export_category('Door')
@export
var interactable: bool = true
@export
var autoclose_time: float = 0.0
@export
var open_sound: AudioStream
@export
var close_sound: AudioStream
@onready
var _timer = $Timer
@onready
var _player = $AudioStreamPlayer3D
var _anim: AnimationPlayer
var _open = false
func _get_configuration_warnings() -> PackedStringArray:
var warns = []
var animation_found = false
var animation_player: AnimationPlayer
for c in get_children():
if c is AnimationPlayer:
if animation_found:
warns.append('Multiple AnimationPlayers')
animation_found = true
animation_player = c
if not animation_found:
warns.append('Add an AnimationPlayer')
if animation_found and not animation_player.has_animation('open'):
warns.append('AnimationPlayer missing "open" animation')
return warns
func _ready():
for c in get_children():
if c is AnimationPlayer:
_anim = c
break
_anim.animation_finished.connect(_on_anim_finished)
_timer.timeout.connect(_on_close_timer)
func _toggle_open():
# Dont allow closing if the timer is running
if not _timer.is_stopped():
return
if not _open:
open()
else:
close()
func _on_anim_finished(anim_name):
_open = !_open
func _on_close_timer():
if _open:
_toggle_open()
func open():
if open_sound:
_player.stream = open_sound
_player.play()
_anim.play('open')
if autoclose_time != 0.0:
_timer.start(autoclose_time)
func close():
if close_sound:
_player.stream = close_sound
_player.play()
_anim.play_backwards('open')
func activate(should_open: bool):
if should_open:
open()
else:
close()
func interact(other):
if not interactable:
return
_toggle_open()

View file

@ -0,0 +1,11 @@
[gd_scene load_steps=2 format=3 uid="uid://3s4o76uxcabo"]
[ext_resource type="Script" path="res://components/door_component.gd" id="1_vtx8n"]
[node name="DoorComponent" type="AnimatableBody3D"]
script = ExtResource("1_vtx8n")
[node name="Timer" type="Timer" parent="."]
one_shot = true
[node name="AudioStreamPlayer3D" type="AudioStreamPlayer3D" parent="."]

View file

@ -0,0 +1,21 @@
extends Area3D
@export var group: String
var activated_lockout = false
signal state_changed(pressed: bool)
signal activated_once()
func _on_body_entered(body: Node3D) -> void:
if body.is_in_group(group):
state_changed.emit(true)
if not activated_lockout:
activated_lockout = true
activated_once.emit()
func _on_body_exited(body: Node3D) -> void:
if body.is_in_group(group):
state_changed.emit(false)

View file

@ -0,0 +1,9 @@
[gd_scene load_steps=2 format=3 uid="uid://dnq81gfo5y4oy"]
[ext_resource type="Script" path="res://components/group_trigger_component.gd" id="1_8jjbb"]
[node name="GroupTriggerComponent" type="Area3D"]
script = ExtResource("1_8jjbb")
[connection signal="body_entered" from="." to="." method="_on_body_entered"]
[connection signal="body_exited" from="." to="." method="_on_body_exited"]

View file

@ -11,10 +11,16 @@ config_version=5
[application] [application]
config/name="fml-avs" config/name="fml-avs"
run/main_scene="res://scenes/devworld.tscn" run/main_scene="res://scenes/level_pool.tscn"
config/features=PackedStringArray("4.3", "Forward Plus") config/features=PackedStringArray("4.3", "Forward Plus")
config/icon="res://icon.svg" config/icon="res://icon.svg"
[global_group]
players=""
monitors=""
can_hold=""
[input] [input]
move_forward={ move_forward={

View file

@ -1,9 +1,8 @@
[gd_scene load_steps=8 format=3 uid="uid://vv1rwk4sfpch"] [gd_scene load_steps=7 format=3 uid="uid://vv1rwk4sfpch"]
[ext_resource type="PackedScene" uid="uid://cpo6l8pmxj6wo" path="res://assets/maps/devworld.blend" id="1_pj3hd"] [ext_resource type="PackedScene" uid="uid://cpo6l8pmxj6wo" path="res://assets/maps/devworld.blend" id="1_pj3hd"]
[ext_resource type="PackedScene" uid="uid://cy86jyiy6skvk" path="res://scenes/player.tscn" id="2_b2roh"] [ext_resource type="PackedScene" uid="uid://cy86jyiy6skvk" path="res://scenes/player.tscn" id="2_b2roh"]
[ext_resource type="PackedScene" uid="uid://nnxd1djnxech" path="res://scenes/phys_cube.tscn" id="3_8byy4"] [ext_resource type="PackedScene" uid="uid://nnxd1djnxech" path="res://scenes/phys_cube.tscn" id="3_8byy4"]
[ext_resource type="PackedScene" path="res://assets/models/general/mirror.blend" id="4_8rfge"]
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_2mm68"] [sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_2mm68"]
sky_horizon_color = Color(0.64625, 0.65575, 0.67075, 1) sky_horizon_color = Color(0.64625, 0.65575, 0.67075, 1)
@ -46,10 +45,10 @@ enable_shadows = true
[node name="devworld" parent="." instance=ExtResource("1_pj3hd")] [node name="devworld" parent="." instance=ExtResource("1_pj3hd")]
[node name="cameratri" parent="devworld/player" index="1"] [node name="cameratri" parent="devworld/player" index="0"]
visible = false visible = false
[node name="cameraframe" parent="devworld/player" index="2"] [node name="cameraframe" parent="devworld/player" index="1"]
visible = false visible = false
[node name="Point" parent="devworld" index="2"] [node name="Point" parent="devworld" index="2"]
@ -61,8 +60,4 @@ transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 5.803,
[node name="PhysCube" parent="." instance=ExtResource("3_8byy4")] [node name="PhysCube" parent="." instance=ExtResource("3_8byy4")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.348621, 0.889988, -0.509634) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.348621, 0.889988, -0.509634)
[node name="mirror" parent="." instance=ExtResource("4_8rfge")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.21713, 1.33524, 15.4176)
[editable path="devworld"] [editable path="devworld"]
[editable path="mirror"]

210
scenes/level_pool.tscn Normal file
View file

@ -0,0 +1,210 @@
[gd_scene load_steps=21 format=4 uid="uid://bbqug1s083mdi"]
[ext_resource type="PackedScene" uid="uid://ci2uamlnv8swy" path="res://assets/maps/levelpool.blend" id="1_cpckw"]
[ext_resource type="PackedScene" uid="uid://cy86jyiy6skvk" path="res://scenes/player.tscn" id="2_eggmh"]
[ext_resource type="PackedScene" uid="uid://3s4o76uxcabo" path="res://components/door_component.tscn" id="3_clecd"]
[ext_resource type="Texture2D" uid="uid://bj7g1cro2pvlp" path="res://assets/textures/dev/tiles01_black.png" id="4_ngwgs"]
[ext_resource type="AudioStream" uid="uid://cieprqff0h2nm" path="res://assets/sounds/door.wav" id="5_yad6d"]
[ext_resource type="PackedScene" uid="uid://dnq81gfo5y4oy" path="res://components/group_trigger_component.tscn" id="6_f2del"]
[ext_resource type="PackedScene" uid="uid://bfv04lp2tbxtd" path="res://scenes/monitor.tscn" id="6_qd2wd"]
[ext_resource type="AudioStream" uid="uid://d20ver6nfndbt" path="res://assets/sounds/dialog/start_dialog.wav" id="7_r1xli"]
[ext_resource type="AudioStream" uid="uid://dbw14jkekqjrb" path="res://assets/sounds/dialog/win_dialog.wav" id="8_u6ajb"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_soh1s"]
resource_name = "tiles01_black"
cull_mode = 2
albedo_texture = ExtResource("4_ngwgs")
[sub_resource type="ArrayMesh" id="ArrayMesh_86pmw"]
_surfaces = [{
"aabb": AABB(3.69908, -2, -6.30092, 2.60184, 0.5, 2.60184),
"format": 34896613377,
"index_count": 96,
"index_data": PackedByteArray("AgAHAAYAAgADAAcAAAAHAAQAAAADAAcAAAAFAAQAAAABAAUAAQAGAAUAAQACAAYACQAPAAsACQANAA8ACgAPAAsACgAOAA8ACgAMAAgACgAOAAwACAANAAkACAAMAA0ABwANAAYABwAPAA0ABwAOAAQABwAPAA4AAgALAAMAAgAJAAsAAAALAAMAAAAKAAsABQAOAAQABQAMAA4ABgAMAAUABgANAAwAAAAIAAEAAAAKAAgAAQAJAAIAAQAIAAkA"),
"name": "tiles01_black",
"primitive": 3,
"uv_scale": Vector4(0, 0, 0, 0),
"vertex_count": 16,
"vertex_data": PackedByteArray("Y+IAAGPiAACbHQAAY+IAAJsdAACbHQAAY+IAAJsdAAD//wAA//8AAAAAAAD//wAAAAAAAAAAAAD//wAAAAAAAJsd//9j4gAAmx3//5sdAABj4v//Y+IAAGPi//+bHQAAAAD/////AAAAAP//AAAAAP///////wAA/////wAAAAA=")
}]
blend_shape_mode = 0
[sub_resource type="ArrayMesh" id="ArrayMesh_4vkxm"]
resource_name = "levelpool_Cube_004"
_surfaces = [{
"aabb": AABB(3.69908, -2, -6.30092, 2.60184, 0.5, 2.60184),
"attribute_data": PackedByteArray("meXQo5nlmeWZ5ZnlLDbQoyw20KMsNpnlLDbQoyw20KMsNiw2meXQo5nl0KOZ5Sw2meUsNpnl0KP//9Cj///////////HG9CjxxvQo8cb///HG9CjxxvQo8cbxxv//9Cj///Qo///xxv//8cb///Qoyw29XcsNpnlLDb1dyw29XcsNiw2meX1d5nl9XeZ5ZnlmeWZ5Sw29XeZ5fV3meUsNpnlLDaZ5fV3xxv1d8cb///HG/V3xxv1d8cbxxv///V3///1d///////////xxv1d///9Xf//8cb///HG///9Xc="),
"format": 34896613399,
"index_count": 96,
"index_data": PackedByteArray("CAAaABYACAAMABoAAQAZAA8AAQALABkAAgATABAAAgAFABMABQAWABMABQAIABYAIAA1ACcAIAAuADUAJAA2ACgAJAAyADYAIwArAB0AIwAxACsAHQAuACAAHQArAC4AGAAtABUAGAA0AC0AGwAzABEAGwA3ADMABwAmAAoABwAfACYAAwApAA0AAwAlACkAEgAwAA4AEgAqADAAFwAsABQAFwAvACwAAAAcAAQAAAAiABwABgAhAAkABgAeACEA"),
"material": SubResource("StandardMaterial3D_soh1s"),
"name": "tiles01_black",
"primitive": 3,
"uv_scale": Vector4(9.21532, 9.21532, 0, 0),
"vertex_count": 56,
"vertex_data": PackedByteArray("Y+IAAGPiAABj4gAAY+L/v2PiAABj4v8/Y+IAAGPi/7+bHQAAY+IAAJsdAABj4v8/mx0AAGPi/7+bHQAAmx0AgJsdAACbHf8/mx0AAJsd/79j4gAAmx0AgGPiAACbHf+/Y+IAAJsd/z9j4gAAmx3/v///AAD//wCA//8AAP///7///wAA////P///AAD//wAAAAAAAP//AIAAAAAA////PwAAAAD//wAAAAAAAAAAAAAAAAAAAAD/PwAAAAAAAAAA//8AAAAAAAD//wAAAAD/v///AAAAAP8///8AAAAAAACbHf//Y+IAAJsd//9j4v+/mx3//2Pi/7+bHf//mx0AgJsd//+bHf+/mx3//5sd/79j4v//Y+IAAGPi//9j4v+/Y+L//2Pi/z9j4v//Y+L/v2Pi//+bHQCAY+L//5sd/79j4v//mx3/P2Pi//+bHf+/AAD/////AIAAAP//////vwAA/////wAAAAD//wAAAAAAAP//AAD/vwAA//8AAAAA////////AID/////////v/////////8/////////AAD/////AAAAAP////8AAP+//////wAA/z//////AAAAAP///3////9/AAD/f/9/AAD///9/AAD/f/9/AAD/f///AAD/f/9/AAD/f///////fwAA/3//fwAA/3///////38AAP9//z//f/9///8AAP9//z//f////38AAP9//z//f////3////9/AAD/f/8//3////9/////f/9/AAD/f///////f/9/AAD///9/////fwAA/3//fwAA/3///////38AAP9//38AAP9///////9//z//f////3////9//z//f/9///////9/AAD/f/8//3////9/////fwAA/3//P/9/")
}]
blend_shape_mode = 0
shadow_mesh = SubResource("ArrayMesh_86pmw")
[sub_resource type="BoxShape3D" id="BoxShape3D_yaaik"]
size = Vector3(4, 5, 1)
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_gs8og"]
albedo_texture = ExtResource("4_ngwgs")
[sub_resource type="BoxMesh" id="BoxMesh_ytxur"]
size = Vector3(4, 5, 1)
[sub_resource type="Animation" id="Animation_lexij"]
resource_name = "open"
tracks/0/type = "bezier"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("CollisionShape3D:position:y")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"handle_modes": PackedInt32Array(0, 0),
"points": PackedFloat32Array(0, -0.25, 0, 0.5, 0, 4, -0.5, 0, 0.25, 0),
"times": PackedFloat32Array(0, 1)
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_prvv0"]
_data = {
"open": SubResource("Animation_lexij")
}
[sub_resource type="BoxShape3D" id="BoxShape3D_epqy0"]
size = Vector3(0.3, 0.5, 2.3)
[sub_resource type="BoxShape3D" id="BoxShape3D_dsbsn"]
size = Vector3(2, 2, 2)
[sub_resource type="BoxShape3D" id="BoxShape3D_vryv4"]
size = Vector3(4, 4, 1)
[node name="LevelPool" type="Node3D"]
[node name="OmniLight3D" type="OmniLight3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 10, 0)
light_energy = 9.0
shadow_enabled = true
shadow_blur = 1.695
omni_range = 162.191
[node name="levelpool" parent="." instance=ExtResource("1_cpckw")]
[node name="Light" parent="levelpool" index="1"]
visible = false
light_energy = 9.0
shadow_enabled = true
omni_range = 34.554
[node name="player" parent="levelpool" index="2"]
visible = false
[node name="holerim" parent="levelpool" index="4"]
mesh = SubResource("ArrayMesh_4vkxm")
[node name="Cube_003" parent="levelpool" index="10"]
visible = false
[node name="Cube_004" parent="levelpool" index="11"]
visible = false
[node name="monitor012" parent="levelpool" index="12"]
visible = false
[node name="CollisionShape3D" parent="levelpool/monitor012/@StaticBody3D@17259" index="0"]
disabled = true
[node name="Player" parent="." instance=ExtResource("2_eggmh")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.012538, 19)
[node name="EntranceDoor" parent="." instance=ExtResource("3_clecd")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, 11.5)
open_sound = ExtResource("5_yad6d")
close_sound = ExtResource("5_yad6d")
[node name="CollisionShape3D" type="CollisionShape3D" parent="EntranceDoor"]
shape = SubResource("BoxShape3D_yaaik")
[node name="CSGMesh3D" type="CSGMesh3D" parent="EntranceDoor/CollisionShape3D"]
material_override = SubResource("StandardMaterial3D_gs8og")
mesh = SubResource("BoxMesh_ytxur")
[node name="AnimationPlayer" type="AnimationPlayer" parent="EntranceDoor"]
libraries = {
"": SubResource("AnimationLibrary_prvv0")
}
[node name="ExitDoor" parent="." instance=ExtResource("3_clecd")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, -11.5)
interactable = false
open_sound = ExtResource("5_yad6d")
close_sound = ExtResource("5_yad6d")
[node name="CollisionShape3D" type="CollisionShape3D" parent="ExitDoor"]
shape = SubResource("BoxShape3D_yaaik")
[node name="CSGMesh3D" type="CSGMesh3D" parent="ExitDoor/CollisionShape3D"]
material_override = SubResource("StandardMaterial3D_gs8og")
mesh = SubResource("BoxMesh_ytxur")
[node name="AnimationPlayer" type="AnimationPlayer" parent="ExitDoor"]
libraries = {
"": SubResource("AnimationLibrary_prvv0")
}
[node name="Monitor" parent="." instance=ExtResource("6_qd2wd")]
transform = Transform3D(-0.877007, 0, -0.480477, 0, 1, 0, 0.480477, 0, -0.877007, -4.23016, 0.344398, -2.70049)
script = null
[node name="HoleRim" type="StaticBody3D" parent="."]
[node name="CollisionShape3D" type="CollisionShape3D" parent="HoleRim"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.85, 0.25, -4.85)
shape = SubResource("BoxShape3D_epqy0")
[node name="CollisionShape3D2" type="CollisionShape3D" parent="HoleRim"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6.15, 0.25, -5.15)
shape = SubResource("BoxShape3D_epqy0")
[node name="CollisionShape3D3" type="CollisionShape3D" parent="HoleRim"]
transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 5.15, 0.25, -3.85)
shape = SubResource("BoxShape3D_epqy0")
[node name="CollisionShape3D4" type="CollisionShape3D" parent="HoleRim"]
transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 4.85, 0.25, -6.15)
shape = SubResource("BoxShape3D_epqy0")
[node name="WinBox" parent="." instance=ExtResource("6_f2del")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5, -1, -5)
group = "monitors"
[node name="CollisionShape3D" type="CollisionShape3D" parent="WinBox"]
shape = SubResource("BoxShape3D_dsbsn")
[node name="DialogTrigger" parent="." instance=ExtResource("6_f2del")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.05, 10.5)
group = "players"
[node name="CollisionShape3D" type="CollisionShape3D" parent="DialogTrigger"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0022583, -0.0446777, 0)
shape = SubResource("BoxShape3D_vryv4")
[node name="Kreb" type="Node3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.70194, 1.2497, 6.87629)
[node name="StartDialog" type="AudioStreamPlayer3D" parent="Kreb"]
stream = ExtResource("7_r1xli")
[node name="WinDialog" type="AudioStreamPlayer3D" parent="Kreb"]
stream = ExtResource("8_u6ajb")
[connection signal="activated_once" from="WinBox" to="Kreb/WinDialog" method="play" binds= [0.0]]
[connection signal="activated_once" from="DialogTrigger" to="Kreb/StartDialog" method="play" binds= [0]]
[connection signal="finished" from="Kreb/WinDialog" to="ExitDoor" method="open"]
[editable path="levelpool"]

26
scenes/monitor.tscn Normal file
View file

@ -0,0 +1,26 @@
[gd_scene load_steps=4 format=3 uid="uid://bfv04lp2tbxtd"]
[ext_resource type="PackedScene" uid="uid://duuedavsf44c7" path="res://assets/models/general/monitor01.blend" id="1_6l6n4"]
[sub_resource type="ConvexPolygonShape3D" id="ConvexPolygonShape3D_tfpjr"]
points = PackedVector3Array(-12, 6.00235, -12, -11.0016, 0, -12, -12, 6.00235, -7.99922, -12, 30, -12, -11.0016, 0, 12, 10.9992, 0, -12, -12, 30, -7.99922, 12, 30, -12, 10.9992, 0, 12, -11.0016, 3.00117, 12, 12, 6.00235, -12, 12, 30, -7.99922, -8.00157, 25.9975, 12, 10.9992, 3.00117, 12, 12, 6.00235, -7.99922, 7.99922, 25.9975, 12)
[sub_resource type="BoxShape3D" id="BoxShape3D_wfrja"]
size = Vector3(0.6, 0.75, 0.6)
[node name="Monitor" type="RigidBody3D" groups=["can_hold", "monitors"]]
[node name="monitor012" parent="." instance=ExtResource("1_6l6n4")]
[node name="@StaticBody3D@17265" parent="monitor012" index="1"]
visible = false
[node name="CollisionShape3D" parent="monitor012/@StaticBody3D@17265" index="0"]
shape = SubResource("ConvexPolygonShape3D_tfpjr")
disabled = true
[node name="CollisionShape3D" type="CollisionShape3D" parent="." groups=["can_hold"]]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.374, 0)
shape = SubResource("BoxShape3D_wfrja")
[editable path="monitor012"]

View file

@ -6,7 +6,7 @@
[sub_resource type="CapsuleMesh" id="CapsuleMesh_muavk"] [sub_resource type="CapsuleMesh" id="CapsuleMesh_muavk"]
[node name="Player" type="CharacterBody3D"] [node name="Player" type="CharacterBody3D" groups=["players"]]
script = ExtResource("1_ocinr") script = ExtResource("1_ocinr")
[node name="CollisionShape3D" type="CollisionShape3D" parent="."] [node name="CollisionShape3D" type="CollisionShape3D" parent="."]
@ -22,6 +22,7 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
fov = 90.0 fov = 90.0
[node name="Ball" type="CSGSphere3D" parent="."] [node name="Ball" type="CSGSphere3D" parent="."]
visible = false
radius = 0.1 radius = 0.1
[node name="Flashlight" type="SpotLight3D" parent="."] [node name="Flashlight" type="SpotLight3D" parent="."]
@ -31,3 +32,14 @@ shadow_enabled = true
distance_fade_enabled = true distance_fade_enabled = true
spot_range = 23.178 spot_range = 23.178
spot_angle = 40.14 spot_angle = 40.14
[node name="CenterContainer" type="CenterContainer" parent="."]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="ColorRect" type="ColorRect" parent="CenterContainer"]
custom_minimum_size = Vector2(10, 10)
layout_mode = 2

View file

@ -1,25 +0,0 @@
extends RigidBody3D
#
#const QUAKE = 0.0625 / 2
#const g = -800 * QUAKE
#
#@export
#var push_force = 400
#@export
#var max_velocity: float = 1000.0
#
#
##var is_held = false
##var target_velocity: Vector3 = Vector3(0, 0, 0)
##
##
##func _physics_process(delta):
##if is_held:
##linear_velocity = target_velocity * delta
##else:
##linear_velocity.y += g * delta
#
#
func can_hold(player):
return true

View file

@ -14,6 +14,8 @@ const SIDE_SPEED = 350 * QUAKE
const UP_SPEED = 270 * QUAKE const UP_SPEED = 270 * QUAKE
const JUMP_SPEED = 270 * QUAKE const JUMP_SPEED = 270 * QUAKE
@export
var interact_range: float = 5.0
@export @export
var hold_force = 400 var hold_force = 400
@export @export
@ -34,183 +36,183 @@ var _flashlight: SpotLight3D = $Flashlight
var _paused = false var _paused = false
var _noclip = false var _noclip = false
var _held_object = null var _held_object: Object
var _held_object_distance: float
func _ready(): func _ready():
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func _process(_delta): func _process(_delta):
# Do this on the render tick so it doesnt jitter at higher FPS # Do this on the render tick so it doesnt jitter at higher FPS
_ball.global_position = _camera.global_position - _camera.global_transform.basis.z * 2.0 _ball.global_position = _camera.global_position - _camera.global_transform.basis.z * interact_range
func _physics_process(delta): func _physics_process(delta):
# Shamelessly stolen code from quake :) # Shamelessly stolen code from quake :)
var fmove = 0.0 var fmove = 0.0
var smove = 0.0 var smove = 0.0
var upmove = 0.0 var upmove = 0.0
if Input.is_action_pressed("move_forward"): if Input.is_action_pressed("move_forward"):
fmove += -FORWARD_SPEED fmove += -FORWARD_SPEED
if Input.is_action_pressed("move_backward"): if Input.is_action_pressed("move_backward"):
fmove += FORWARD_SPEED fmove += FORWARD_SPEED
if Input.is_action_pressed("move_left"): if Input.is_action_pressed("move_left"):
smove += -SIDE_SPEED smove += -SIDE_SPEED
if Input.is_action_pressed("move_right"): if Input.is_action_pressed("move_right"):
smove += SIDE_SPEED smove += SIDE_SPEED
#if Input.is_action_pressed("up"): #if Input.is_action_pressed("up"):
# upmove += UP_SPEED # upmove += UP_SPEED
if Input.is_action_pressed("run"): if Input.is_action_pressed("run"):
fmove *= 2.0 fmove *= 2.0
smove *= 2.0 smove *= 2.0
var wishvel = Vector3() var wishvel = Vector3()
var cam_xform: Transform3D = _camera.get_global_transform()
var cam_basis: Basis = cam_xform.basis
wishvel = cam_basis.z * fmove + cam_basis.x * smove if _noclip:
wishvel = _camera.global_basis.z * fmove + _camera.global_basis.x * smove
else:
wishvel = basis.z * fmove + basis.x * smove
if _noclip: if _noclip:
wishvel.y += upmove wishvel.y += upmove
var wishdir = wishvel.normalized() var wishdir = wishvel.normalized()
var wishspeed = wishvel.length() var wishspeed = wishvel.length()
if wishspeed > MAX_SPEED: if wishspeed > MAX_SPEED:
wishvel *= MAX_SPEED / wishspeed wishvel *= MAX_SPEED / wishspeed
wishspeed = MAX_SPEED wishspeed = MAX_SPEED
if Input.is_action_just_pressed("jump") and is_on_floor(): if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y += JUMP_SPEED velocity.y += JUMP_SPEED
var vel = velocity var vel = velocity
if _noclip: if _noclip:
vel = wishvel * 2 vel = wishvel * 2
elif is_on_floor(): elif is_on_floor():
vel = _apply_friction(vel, delta) vel = _apply_friction(vel, delta)
vel = _apply_accel(vel, wishdir, wishspeed, delta) vel = _apply_accel(vel, wishdir, wishspeed, delta)
else: else:
vel = _apply_air_accel(vel, wishvel, wishspeed, delta) vel = _apply_air_accel(vel, wishvel, wishspeed, delta)
if not _noclip and not is_on_floor(): if not _noclip and not is_on_floor():
vel.y += g * delta vel.y += g * delta
velocity = vel velocity = vel
move_and_slide() move_and_slide()
if _held_object: if _held_object:
_apply_holding_force(delta) _apply_holding_force(delta)
func _apply_friction(vel: Vector3, delta: float): func _apply_friction(vel: Vector3, delta: float):
var speed = sqrt(vel.x ** 2 + vel.z ** 2) var speed = sqrt(vel.x ** 2 + vel.z ** 2)
if(speed == 0.0): return vel if(speed == 0.0): return vel
# TODO: edge detect friction? # TODO: edge detect friction?
var friction = FRICTION var friction = FRICTION
var control = 0.0 var control = 0.0
if speed < STOP_SPEED: if speed < STOP_SPEED:
control = STOP_SPEED control = STOP_SPEED
else: else:
control = speed control = speed
var newspeed = speed - delta * control * friction var newspeed = speed - delta * control * friction
if newspeed < 0.0: if newspeed < 0.0:
newspeed = 0.0 newspeed = 0.0
else: else:
newspeed /= speed newspeed /= speed
return vel * newspeed return vel * newspeed
func _apply_accel(vel: Vector3, wishdir: Vector3, wishspeed: float, delta: float): func _apply_accel(vel: Vector3, wishdir: Vector3, wishspeed: float, delta: float):
var currentspeed = vel.dot(wishdir) var currentspeed = vel.dot(wishdir)
var addspeed = wishspeed - currentspeed var addspeed = wishspeed - currentspeed
if addspeed <= 0.0: if addspeed <= 0.0:
return vel return vel
var accelspeed = ACCEL * delta * wishspeed var accelspeed = ACCEL * delta * wishspeed
if accelspeed > addspeed: if accelspeed > addspeed:
accelspeed = addspeed accelspeed = addspeed
return vel + accelspeed * wishdir return vel + accelspeed * wishdir
func _apply_air_accel(vel: Vector3, wishvel: Vector3, wishspeed: float, delta: float): func _apply_air_accel(vel: Vector3, wishvel: Vector3, wishspeed: float, delta: float):
var wishveloc = wishvel.normalized() var wishveloc = wishvel.normalized()
var wishspd = wishvel.length() var wishspd = wishvel.length()
if wishspd > MAX_AIR_SPEED: if wishspd > MAX_AIR_SPEED:
wishspd = MAX_AIR_SPEED wishspd = MAX_AIR_SPEED
var currentspeed = vel.dot(wishveloc) var currentspeed = vel.dot(wishveloc)
var addspeed = wishspd - currentspeed var addspeed = wishspd - currentspeed
if addspeed <= 0: if addspeed <= 0:
return vel return vel
var accelspeed = AIR_ACCEL * wishspeed * delta var accelspeed = AIR_ACCEL * wishspeed * delta
if accelspeed > addspeed: if accelspeed > addspeed:
accelspeed = addspeed accelspeed = addspeed
return vel + accelspeed * wishveloc return vel + accelspeed * wishveloc
func _apply_holding_force(delta): func _apply_holding_force(delta):
var delta_position = _ball.global_position - _held_object.global_position var hold_point = _camera.global_position - _camera.global_transform.basis.z * _held_object_distance
var move_speed = min(delta_position.length() * hold_force, max_hold_velocity) var delta_position = hold_point - _held_object.global_position
_held_object.linear_velocity = delta_position.normalized() * move_speed * delta var move_speed = min(delta_position.length() * hold_force, max_hold_velocity)
_held_object.linear_velocity = delta_position.normalized() * move_speed * delta
func _input(event): func _input(event):
if event.is_action_pressed("pause"): if event.is_action_pressed("pause"):
_paused = not _paused _paused = not _paused
if _paused: if _paused:
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
else: else:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
if _paused: return if _paused: return
if event.is_action_pressed('noclip'): if event.is_action_pressed('noclip'):
_noclip = not _noclip _noclip = not _noclip
if _noclip: if _noclip:
_collider.disabled = true _collider.disabled = true
else: else:
_collider.disabled = false _collider.disabled = false
if event.is_action_pressed('flashlight'): if event.is_action_pressed('flashlight'):
_flashlight.visible = not _flashlight.visible _flashlight.visible = not _flashlight.visible
# Camera # Camera
if event is InputEventMouseMotion: if event is InputEventMouseMotion:
rotation.y += -event.relative.x * 0.005 rotation.y += -event.relative.x * 0.005
_camera.rotation.x += -event.relative.y * 0.005 _camera.rotation.x += -event.relative.y * 0.005
_camera.rotation.x = clamp(_camera.rotation.x, deg_to_rad(-90), deg_to_rad(90)) _camera.rotation.x = clamp(_camera.rotation.x, deg_to_rad(-90), deg_to_rad(90))
# Rotate flashlight # Rotate flashlight
_flashlight.rotation.x = _camera.rotation.x _flashlight.rotation.x = _camera.rotation.x
if event.is_action_pressed("interact"): if event.is_action_pressed("interact"):
# Handle dropping things # Handle dropping things
if _held_object: if _held_object:
#_held_object.drop() #_held_object.drop()
_held_object = null _held_object = null
return return
var space_state = get_world_3d().direct_space_state var space_state = get_world_3d().direct_space_state
# use global coordinates, not local to node # use global coordinates, not local to node
var query = PhysicsRayQueryParameters3D.create(_camera.global_position, _ball.global_position) var ray_end = _camera.global_position - _camera.global_transform.basis.z * interact_range
# Don't collide with ourselves var query = PhysicsRayQueryParameters3D.create(_camera.global_position, ray_end)
query.exclude = [self] # Don't collide with ourselves
var result = space_state.intersect_ray(query) query.exclude = [self]
if result.has('collider'): var result = space_state.intersect_ray(query)
print(result) if result.has('collider'):
var other: Node3D = result.collider var other: Node3D = result.collider
if other.has_method('interact'): if other.has_method('interact'):
other.interact(self) other.interact(self)
if other.has_method('can_hold'): if other.is_in_group('can_hold'):
print('Object') _held_object = other
if other.can_hold(self): _held_object_distance = (Vector3(result.position) - _camera.global_position).length()
print('Can Hold')
_held_object = other
print(_held_object)