feat: Implement nausea symptom system and related features
Build / Export windows (push) Successful in 10m56s
Build / Export linux (push) Successful in 6m10s

- Added SymptomManager autoload for managing symptom intensities.
- Introduced nausea tilt effect for camera roll based on nausea intensity.
- Created color desaturation shader and overlay for visual feedback.
- Developed TreatmentManager to handle nausea ramping during IV treatment.
- Added hospital room scene with first-person controller and interactions.
- Implemented sit-down interaction for the treatment chair.
- Created IV insertion sequence with animations and completion signal.
- Added player controller with movement and interaction capabilities.
- Integrated nausea effects into the player experience with smooth transitions.
This commit is contained in:
2026-05-30 14:14:38 +02:00
parent 2eb7f9b2cb
commit 8462a2fde7
16 changed files with 867 additions and 3 deletions
+33
View File
@@ -0,0 +1,33 @@
[gd_scene load_steps=3 format=3 uid="uid://dchair1nt0001a"]
[ext_resource type="Script" path="res://scripts/character/chair_interaction.gd" id="1_chair"]
[sub_resource type="BoxShape3D" id="Shape_Trigger"]
size = Vector3(1.6, 2.0, 1.6)
[node name="ChairInteraction" type="Area3D" node_paths=PackedStringArray("seat_transform_path")]
script = ExtResource("1_chair")
seat_transform_path = NodePath("SeatMarker")
[node name="TriggerShape" type="CollisionShape3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
shape = SubResource("Shape_Trigger")
[node name="SeatMarker" type="Marker3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.35)
[node name="PromptLayer" type="CanvasLayer" parent="."]
[node name="PromptLabel" type="Label" parent="PromptLayer"]
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -100.0
offset_top = 60.0
offset_right = 100.0
offset_bottom = 90.0
horizontal_alignment = 1
vertical_alignment = 1
text = "Press E to sit"
+200
View File
@@ -0,0 +1,200 @@
[gd_scene load_steps=20 format=3 uid="uid://b1hosp1room01a"]
[ext_resource type="PackedScene" path="res://scenes/hospital/player.tscn" id="1_player"]
[ext_resource type="PackedScene" path="res://scenes/hospital/chair_interaction.tscn" id="2_chair"]
[ext_resource type="PackedScene" path="res://scenes/hospital/iv_insertion.tscn" id="3_iv"]
[ext_resource type="PackedScene" path="res://scenes/symptoms/nausea_overlay.tscn" id="4_overlay"]
[ext_resource type="Script" path="res://scripts/game_systems/treatment_manager.gd" id="5_treatment"]
; --- Materials ---
[sub_resource type="StandardMaterial3D" id="Mat_Floor"]
albedo_color = Color(0.72, 0.74, 0.76, 1)
roughness = 0.6
[sub_resource type="StandardMaterial3D" id="Mat_Wall"]
albedo_color = Color(0.86, 0.88, 0.85, 1)
roughness = 0.85
[sub_resource type="StandardMaterial3D" id="Mat_Ceiling"]
albedo_color = Color(0.93, 0.94, 0.94, 1)
roughness = 0.9
[sub_resource type="StandardMaterial3D" id="Mat_Bed"]
albedo_color = Color(0.3, 0.45, 0.55, 1)
roughness = 0.7
[sub_resource type="StandardMaterial3D" id="Mat_Chair"]
albedo_color = Color(0.2, 0.5, 0.4, 1)
roughness = 0.7
[sub_resource type="StandardMaterial3D" id="Mat_Metal"]
albedo_color = Color(0.8, 0.82, 0.85, 1)
metallic = 0.7
roughness = 0.3
[sub_resource type="StandardMaterial3D" id="Mat_Wood"]
albedo_color = Color(0.55, 0.42, 0.3, 1)
roughness = 0.6
; --- Meshes ---
[sub_resource type="PlaneMesh" id="Mesh_Floor"]
size = Vector2(6, 8)
[sub_resource type="BoxMesh" id="Mesh_BedFrame"]
size = Vector3(1, 0.5, 2)
[sub_resource type="BoxMesh" id="Mesh_BedMattress"]
size = Vector3(0.95, 0.2, 1.95)
[sub_resource type="BoxMesh" id="Mesh_ChairSeat"]
size = Vector3(0.7, 0.15, 0.7)
[sub_resource type="BoxMesh" id="Mesh_ChairBack"]
size = Vector3(0.7, 0.8, 0.15)
[sub_resource type="CylinderMesh" id="Mesh_IVPole"]
top_radius = 0.02
bottom_radius = 0.02
height = 1.8
[sub_resource type="BoxMesh" id="Mesh_Table"]
size = Vector3(0.5, 0.7, 0.5)
[sub_resource type="BoxMesh" id="Mesh_Wall"]
size = Vector3(0.1, 3, 8)
; --- Collision shapes ---
[sub_resource type="WorldBoundaryShape3D" id="Shape_Floor"]
[sub_resource type="BoxShape3D" id="Shape_Wall"]
size = Vector3(0.1, 3, 8)
[node name="HospitalRoom" type="Node3D"]
; ---------------- Structure ----------------
[node name="Floor" type="StaticBody3D" parent="."]
[node name="FloorMesh" type="MeshInstance3D" parent="Floor"]
mesh = SubResource("Mesh_Floor")
surface_material_override/0 = SubResource("Mat_Floor")
[node name="FloorCollision" type="CollisionShape3D" parent="Floor"]
shape = SubResource("Shape_Floor")
[node name="Ceiling" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, -1, 0, 0, 0, 1, 0, 3, 0)
mesh = SubResource("Mesh_Floor")
surface_material_override/0 = SubResource("Mat_Ceiling")
[node name="WallNorth" type="StaticBody3D" parent="."]
transform = Transform3D(0, 0, 1, 0, 1, 0, -1, 0, 0, 0, 1.5, -4)
[node name="WallNorthMesh" type="MeshInstance3D" parent="WallNorth"]
mesh = SubResource("Mesh_Wall")
surface_material_override/0 = SubResource("Mat_Wall")
[node name="WallNorthCollision" type="CollisionShape3D" parent="WallNorth"]
shape = SubResource("Shape_Wall")
[node name="WallSouth" type="StaticBody3D" parent="."]
transform = Transform3D(0, 0, 1, 0, 1, 0, -1, 0, 0, 0, 1.5, 4)
[node name="WallSouthMesh" type="MeshInstance3D" parent="WallSouth"]
mesh = SubResource("Mesh_Wall")
surface_material_override/0 = SubResource("Mat_Wall")
[node name="WallSouthCollision" type="CollisionShape3D" parent="WallSouth"]
shape = SubResource("Shape_Wall")
[node name="WallEast" type="StaticBody3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3, 1.5, 0)
[node name="WallEastMesh" type="MeshInstance3D" parent="WallEast"]
mesh = SubResource("Mesh_Wall")
surface_material_override/0 = SubResource("Mat_Wall")
[node name="WallEastCollision" type="CollisionShape3D" parent="WallEast"]
shape = SubResource("Shape_Wall")
[node name="WallWest" type="StaticBody3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3, 1.5, 0)
[node name="WallWestMesh" type="MeshInstance3D" parent="WallWest"]
mesh = SubResource("Mesh_Wall")
surface_material_override/0 = SubResource("Mat_Wall")
[node name="WallWestCollision" type="CollisionShape3D" parent="WallWest"]
shape = SubResource("Shape_Wall")
; ---------------- Furniture ----------------
[node name="Bed" type="Node3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.8, 0, -2)
[node name="BedFrame" type="MeshInstance3D" parent="Bed"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.25, 0)
mesh = SubResource("Mesh_BedFrame")
surface_material_override/0 = SubResource("Mat_Metal")
[node name="BedMattress" type="MeshInstance3D" parent="Bed"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.6, 0)
mesh = SubResource("Mesh_BedMattress")
surface_material_override/0 = SubResource("Mat_Bed")
[node name="Chair" type="Node3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.2, 0, 1.5)
[node name="ChairSeat" type="MeshInstance3D" parent="Chair"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
mesh = SubResource("Mesh_ChairSeat")
surface_material_override/0 = SubResource("Mat_Chair")
[node name="ChairBack" type="MeshInstance3D" parent="Chair"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.95, -0.27)
mesh = SubResource("Mesh_ChairBack")
surface_material_override/0 = SubResource("Mat_Chair")
[node name="ChairInteraction" parent="." instance=ExtResource("2_chair")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.2, 0, 1.5)
[node name="IVStand" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 0.9, 1.5)
mesh = SubResource("Mesh_IVPole")
surface_material_override/0 = SubResource("Mat_Metal")
[node name="BedsideTable" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.5, 0.35, 1.5)
mesh = SubResource("Mesh_Table")
surface_material_override/0 = SubResource("Mat_Wood")
; ---------------- Lighting ----------------
[node name="OverheadLight" type="DirectionalLight3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 0.5, 0.866, 0, -0.866, 0.5, 0, 2.9, 0)
light_energy = 0.9
shadow_enabled = true
[node name="CeilingLamp" type="OmniLight3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.7, 0)
light_energy = 1.5
omni_range = 8.0
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
; ---------------- Player ----------------
; Spawn near south wall (z=3), rotated ~ -45deg to face the chair (chair at x=1.2, z=1.5).
[node name="Player" parent="." instance=ExtResource("1_player")]
transform = Transform3D(0.7071, 0, 0.7071, 0, 1, 0, -0.7071, 0, 0.7071, -1.5, 0, 3)
; ---------------- IV Insertion ----------------
; Positioned roughly in front of and below the seated player's view.
[node name="IVInsertion" parent="." instance=ExtResource("3_iv")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.0, 1.1, 1.4)
; ---------------- Symptom Overlay ----------------
[node name="NauseaOverlay" parent="." instance=ExtResource("4_overlay")]
; ---------------- Treatment Manager ----------------
[node name="TreatmentManager" type="Node" parent="."]
script = ExtResource("5_treatment")
[connection signal="player_seated" from="ChairInteraction" to="IVInsertion" method="begin_sequence"]
[connection signal="iv_completed" from="IVInsertion" to="TreatmentManager" method="start_ramp"]
+46
View File
@@ -0,0 +1,46 @@
[gd_scene load_steps=8 format=3 uid="uid://div1nsert0001a"]
[ext_resource type="Script" path="res://scripts/character/iv_insertion.gd" id="1_iv"]
[sub_resource type="StandardMaterial3D" id="Mat_Skin"]
albedo_color = Color(0.82, 0.64, 0.55, 1)
roughness = 0.7
[sub_resource type="StandardMaterial3D" id="Mat_Needle"]
albedo_color = Color(0.85, 0.86, 0.9, 1)
metallic = 0.8
roughness = 0.2
[sub_resource type="StandardMaterial3D" id="Mat_Tape"]
albedo_color = Color(0.95, 0.93, 0.85, 1)
roughness = 0.9
[sub_resource type="BoxMesh" id="Mesh_Forearm"]
size = Vector3(0.4, 0.08, 0.1)
[sub_resource type="CylinderMesh" id="Mesh_Needle"]
top_radius = 0.004
bottom_radius = 0.004
height = 0.12
[sub_resource type="BoxMesh" id="Mesh_Tape"]
size = Vector3(0.08, 0.005, 0.06)
[node name="IVInsertion" type="Node3D" node_paths=PackedStringArray()]
script = ExtResource("1_iv")
[node name="Arm" type="Node3D" parent="."]
[node name="Forearm" type="MeshInstance3D" parent="Arm"]
mesh = SubResource("Mesh_Forearm")
surface_material_override/0 = SubResource("Mat_Skin")
[node name="Needle" type="MeshInstance3D" parent="Arm"]
transform = Transform3D(1, 0, 0, 0, 0, -1, 0, 1, 0, 0.05, 0.12, 0)
mesh = SubResource("Mesh_Needle")
surface_material_override/0 = SubResource("Mat_Needle")
[node name="Tape" type="MeshInstance3D" parent="Arm"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.05, 0.045, 0)
mesh = SubResource("Mesh_Tape")
surface_material_override/0 = SubResource("Mat_Tape")
+25
View File
@@ -0,0 +1,25 @@
[gd_scene load_steps=4 format=3 uid="uid://c0play3r0001a"]
[ext_resource type="Script" path="res://scripts/character/player_controller.gd" id="1_player"]
[ext_resource type="Script" path="res://scripts/symptoms/nausea_tilt.gd" id="2_tilt"]
[sub_resource type="CapsuleShape3D" id="Shape_Body"]
radius = 0.3
height = 1.8
[node name="Player" type="CharacterBody3D"]
script = ExtResource("1_player")
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.9, 0)
shape = SubResource("Shape_Body")
[node name="Camera3D" type="Camera3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.6, 0)
current = true
script = ExtResource("2_tilt")
[node name="InteractionRay" type="RayCast3D" parent="Camera3D"]
target_position = Vector3(0, 0, -2.5)
collide_with_areas = true
collide_with_bodies = true
+22
View File
@@ -0,0 +1,22 @@
[gd_scene load_steps=4 format=3 uid="uid://cnaus3aov0001a"]
[ext_resource type="Script" path="res://scripts/symptoms/nausea_desaturation.gd" id="1_desat"]
[ext_resource type="Shader" path="res://assets/shaders/desaturation.gdshader" id="2_shader"]
[sub_resource type="ShaderMaterial" id="Mat_Desat"]
shader = ExtResource("2_shader")
shader_parameter/desaturation = 0.0
[node name="NauseaOverlay" type="CanvasLayer"]
layer = 2
[node name="DesaturationRect" type="ColorRect" parent="."]
material = SubResource("Mat_Desat")
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
color = Color(1, 1, 1, 1)
script = ExtResource("1_desat")