Grunk alarm!

This commit is contained in:
Rob Kelly 2025-03-13 13:34:35 -06:00
parent e2c95766c2
commit 229b3f8f7e
7 changed files with 227 additions and 11 deletions

View File

@ -4,12 +4,14 @@ extends Node3D
@onready var gunk_hall: GunkBody = %GunkHall @onready var gunk_hall: GunkBody = %GunkHall
@onready var bulkhead: Node3D = $Bulkhead @onready var bulkhead: Node3D = $Bulkhead
@onready var open_switch: Node3D = $Bulkhead/Podium/OpenSwitch @onready var open_switch: Node3D = %OpenSwitch
@onready var close_switch: Node3D = $Bulkhead/Podium2/CloseSwitch @onready var close_switch: Node3D = %CloseSwitch
@onready var nodule_spawn_point: Marker3D = $NoduleSpawner/NoduleSpawnPoint @onready var nodule_spawn_point: Marker3D = %NoduleSpawnPoint
@onready var alarm_spawn_point: Marker3D = %AlarmSpawnPoint
static var nodule_scene: PackedScene = load("res://src/world/gunk_node/grunk_nodule.tscn") static var nodule_scene: PackedScene = load("res://src/world/gunk_node/grunk_nodule.tscn")
static var alarm_scene: PackedScene = load("res://src/world/mechanics/alarm/gunk_alarm.tscn")
func reset() -> void: func reset() -> void:
@ -20,8 +22,22 @@ func reset() -> void:
Callable(close_switch, "disable").call() Callable(close_switch, "disable").call()
func spawn_nodule() -> void: func _do_spawn(spawn_point: Node3D, scene: PackedScene) -> void:
for c: Node in nodule_spawn_point.get_children(): for c: Node in spawn_point.get_children():
c.queue_free() c.queue_free()
var instance := nodule_scene.instantiate() var instance := scene.instantiate()
nodule_spawn_point.add_child(instance) spawn_point.add_child(instance)
func spawn_nodule() -> void:
_do_spawn(nodule_spawn_point, nodule_scene)
func spawn_alarm() -> void:
_do_spawn(alarm_spawn_point, alarm_scene)
func trigger_spawned_alarm() -> void:
var alarm: GunkAlarm = alarm_spawn_point.get_child(0)
if alarm:
alarm.trigger()

View File

@ -173,17 +173,58 @@ mesh = SubResource("BoxMesh_goufh")
[node name="CollisionShape3D" type="CollisionShape3D" parent="NoduleSpawner"] [node name="CollisionShape3D" type="CollisionShape3D" parent="NoduleSpawner"]
shape = SubResource("ConcavePolygonShape3D_bg05n") shape = SubResource("ConcavePolygonShape3D_bg05n")
[node name="SpawnSwitch" parent="NoduleSpawner" instance=ExtResource("2_pka60")] [node name="WallSwitch" parent="NoduleSpawner" instance=ExtResource("2_pka60")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, 0.35) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, 0.35)
enabled = true enabled = true
[node name="Label3D" type="Label3D" parent="NoduleSpawner"] [node name="Label3D" type="Label3D" parent="NoduleSpawner"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.9, 0.3) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0.3)
text = "Spawn" text = "Spawn
Nodule"
[node name="NoduleSpawnPoint" type="Marker3D" parent="NoduleSpawner"] [node name="NoduleSpawnPoint" type="Marker3D" parent="NoduleSpawner"]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -3) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -3)
[node name="AlarmSpawner" type="StaticBody3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.5, 1, -6)
[node name="MeshInstance3D" type="MeshInstance3D" parent="AlarmSpawner"]
mesh = SubResource("BoxMesh_goufh")
[node name="CollisionShape3D" type="CollisionShape3D" parent="AlarmSpawner"]
shape = SubResource("ConcavePolygonShape3D_bg05n")
[node name="WallSwitch" parent="AlarmSpawner" instance=ExtResource("2_pka60")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, 0.35)
enabled = true
[node name="Label3D" type="Label3D" parent="AlarmSpawner"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0.3)
text = "Spawn
Alarm"
[node name="AlarmSpawnPoint" type="Marker3D" parent="AlarmSpawner"]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.7, -4)
[node name="AlarmTrigger" type="StaticBody3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.5, 1, -6)
[node name="MeshInstance3D" type="MeshInstance3D" parent="AlarmTrigger"]
mesh = SubResource("BoxMesh_goufh")
[node name="CollisionShape3D" type="CollisionShape3D" parent="AlarmTrigger"]
shape = SubResource("ConcavePolygonShape3D_bg05n")
[node name="AlarmTriggerSwitch" parent="AlarmTrigger" instance=ExtResource("2_pka60")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, 0.35)
enabled = true
[node name="Label3D" type="Label3D" parent="AlarmTrigger"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0.3)
text = "Trigger"
[node name="GunkHall" parent="." instance=ExtResource("4_2uiim")] [node name="GunkHall" parent="." instance=ExtResource("4_2uiim")]
unique_name_in_owner = true unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.5, 0, -31) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.5, 0, -31)
@ -197,6 +238,7 @@ mesh = SubResource("ArrayMesh_x2vho")
shape = SubResource("ConcavePolygonShape3D_qjnj2") shape = SubResource("ConcavePolygonShape3D_qjnj2")
[node name="Bulkhead" parent="." instance=ExtResource("8_0j1ke")] [node name="Bulkhead" parent="." instance=ExtResource("8_0j1ke")]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6.5, 0, -2) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6.5, 0, -2)
[node name="Podium" type="StaticBody3D" parent="Bulkhead"] [node name="Podium" type="StaticBody3D" parent="Bulkhead"]
@ -209,9 +251,14 @@ mesh = SubResource("BoxMesh_goufh")
shape = SubResource("ConcavePolygonShape3D_bg05n") shape = SubResource("ConcavePolygonShape3D_bg05n")
[node name="OpenSwitch" parent="Bulkhead/Podium" instance=ExtResource("2_pka60")] [node name="OpenSwitch" parent="Bulkhead/Podium" instance=ExtResource("2_pka60")]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, 0.35) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, 0.35)
enabled = true enabled = true
[node name="Label3D" type="Label3D" parent="Bulkhead/Podium"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.9, 0.3)
text = "Open"
[node name="Podium2" type="StaticBody3D" parent="Bulkhead"] [node name="Podium2" type="StaticBody3D" parent="Bulkhead"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3, 1, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3, 1, 0)
@ -222,10 +269,17 @@ mesh = SubResource("BoxMesh_goufh")
shape = SubResource("ConcavePolygonShape3D_bg05n") shape = SubResource("ConcavePolygonShape3D_bg05n")
[node name="CloseSwitch" parent="Bulkhead/Podium2" instance=ExtResource("2_pka60")] [node name="CloseSwitch" parent="Bulkhead/Podium2" instance=ExtResource("2_pka60")]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, 0.35) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, 0.35)
[node name="Label3D" type="Label3D" parent="Bulkhead/Podium2"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.9, 0.3)
text = "Close"
[connection signal="activated" from="ResetPodium/ResetSwitch" to="." method="reset"] [connection signal="activated" from="ResetPodium/ResetSwitch" to="." method="reset"]
[connection signal="activated" from="NoduleSpawner/SpawnSwitch" to="." method="spawn_nodule"] [connection signal="activated" from="NoduleSpawner/WallSwitch" to="." method="spawn_nodule"]
[connection signal="activated" from="AlarmSpawner/WallSwitch" to="." method="spawn_alarm"]
[connection signal="activated" from="AlarmTrigger/AlarmTriggerSwitch" to="." method="trigger_spawned_alarm"]
[connection signal="activated" from="Bulkhead/Podium/OpenSwitch" to="Bulkhead" method="open"] [connection signal="activated" from="Bulkhead/Podium/OpenSwitch" to="Bulkhead" method="open"]
[connection signal="activated" from="Bulkhead/Podium/OpenSwitch" to="Bulkhead/Podium/OpenSwitch" method="disable"] [connection signal="activated" from="Bulkhead/Podium/OpenSwitch" to="Bulkhead/Podium/OpenSwitch" method="disable"]
[connection signal="activated" from="Bulkhead/Podium/OpenSwitch" to="Bulkhead/Podium2/CloseSwitch" method="enable"] [connection signal="activated" from="Bulkhead/Podium/OpenSwitch" to="Bulkhead/Podium2/CloseSwitch" method="enable"]

View File

@ -1,13 +1,37 @@
class_name GameManagerType extends Node class_name GameManagerType extends Node
## Autoloaded singleton encapsulating game state. ## Autoloaded singleton encapsulating game state.
## Emitted just after `delta` is added to the player's grunk tank.
signal grunk_collected(delta: float) signal grunk_collected(delta: float)
## Emitted just before the alert level is raised to `new_value`.
signal alert_raised(new_value: int)
## Emitted just before the alert level is reset to zero.
signal alert_cleared
const MAX_ALERT := 6
var grunk_tank := 0.0 var grunk_tank := 0.0
var alert_level := 0 var alert_level := 0
## Add to the player's grunk tank.
func collect_grunk(delta: float) -> void: func collect_grunk(delta: float) -> void:
grunk_tank += delta grunk_tank += delta
grunk_collected.emit(delta) grunk_collected.emit(delta)
## Raise the alert level, if possible.
func raise_alert(delta: int) -> void:
var new_value := clampi(alert_level + delta, 0, MAX_ALERT)
if new_value != alert_level:
alert_raised.emit(new_value)
alert_level = new_value
## Reset the alert level to zero.
func clear_alert() -> void:
alert_cleared.emit()
alert_level = 0

View File

@ -0,0 +1,36 @@
class_name GunkAlarm extends GunkNode
## Raises the grunk alert when triggered.
## Emitted when this alarm is triggered, just after the alert level is raised.
signal triggered
const ALERT_DELTA := 1
var _busy := false
@onready var mesh_instance_3d: MeshInstance3D = %MeshInstance3D
@onready var animation_player: AnimationPlayer = %AnimationPlayer
## Trigger this alarm.
##
## Will not trigger if this alarm is busy (e.g. on cooldown)
func trigger() -> void:
if not _busy:
Game.manager.raise_alert(ALERT_DELTA)
_busy = true
animation_player.play("trigger")
triggered.emit()
func _process(delta: float) -> void:
super._process(delta)
# TODO actual model & animation
var material: StandardMaterial3D = mesh_instance_3d.mesh.surface_get_material(0)
var value := 1.0 - _sustained_damage / durability
material.albedo_color = Color(value, value, value)
func _on_animation_finished(anim_name: StringName) -> void:
if anim_name == "trigger":
_busy = false

View File

@ -0,0 +1 @@
uid://djb5tabjcvwkt

View File

@ -0,0 +1,85 @@
[gd_scene load_steps=8 format=3 uid="uid://dgeg3kkogm71m"]
[ext_resource type="Script" uid="uid://djb5tabjcvwkt" path="res://src/world/mechanics/alarm/gunk_alarm.gd" id="1_piaxx"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_piaxx"]
resource_local_to_scene = true
emission_enabled = true
emission = Color(1, 0, 0, 1)
emission_energy_multiplier = 0.0
[sub_resource type="CylinderMesh" id="CylinderMesh_1uge1"]
resource_local_to_scene = true
material = SubResource("StandardMaterial3D_piaxx")
top_radius = 0.3
bottom_radius = 0.3
height = 0.3
[sub_resource type="CylinderShape3D" id="CylinderShape3D_b4qsp"]
height = 0.3
radius = 0.3
[sub_resource type="Animation" id="Animation_piaxx"]
resource_name = "trigger"
length = 4.0
step = 0.1
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("MeshInstance3D:mesh:material:emission_energy_multiplier")
tracks/0/interp = 2
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1),
"update": 0,
"values": [0.0, 4.0, 0.0, 4.0, 0.0, 4.0, 0.0, 4.0, 0.0]
}
[sub_resource type="Animation" id="Animation_b6er8"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("MeshInstance3D:mesh:material:emission_energy_multiplier")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [0.0]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_b6er8"]
_data = {
&"RESET": SubResource("Animation_b6er8"),
&"trigger": SubResource("Animation_piaxx")
}
[node name="GunkAlarm" type="StaticBody3D"]
collision_layer = 5
collision_mask = 0
script = ExtResource("1_piaxx")
durability = 3.0
value = 10000.0
metadata/_custom_type_script = "uid://bypgxi0gy56yk"
[node name="Label3D" type="Label3D" parent="."]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0.2, 0)
text = "ALARM"
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
unique_name_in_owner = true
mesh = SubResource("CylinderMesh_1uge1")
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
shape = SubResource("CylinderShape3D_b4qsp")
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
unique_name_in_owner = true
libraries = {
&"": SubResource("AnimationLibrary_b6er8")
}
[connection signal="animation_finished" from="AnimationPlayer" to="." method="_on_animation_finished"]