diff --git a/assets/text/text.csv b/assets/text/text.csv index bd9c792..77cc43e 100644 --- a/assets/text/text.csv +++ b/assets/text/text.csv @@ -63,6 +63,8 @@ ACTION_pause,Pause HUD_WARNING,WARNING HUD_ALERT_MSG,"ANTIPSIONIC SURGE DETECTED\nEXERCISE EXTREME CAUTION" HUD_TANK_WARNING,"TANK FULL\nRETURN TO SHIP" +HUD_ALERT_CLEAR_MSG_1,"ADMINISTERING EMERGENCY PROPSIONIC DOSE..." +HUD_ALERT_CLEAR_MSG_2,COMPLETE! , INTERACTIVE_SCANNER_LABEL,"Retinal Scanner" INTERACTIVE_SCANNER_VERB,use diff --git a/src/effects/grunk_splatter/grunk_splatter.tscn b/src/effects/grunk_splatter/grunk_splatter.tscn index f36c608..37c64cc 100644 --- a/src/effects/grunk_splatter/grunk_splatter.tscn +++ b/src/effects/grunk_splatter/grunk_splatter.tscn @@ -108,7 +108,6 @@ radius = 2.0 [node name="GrunkSplatter" type="GPUParticles3D"] sorting_offset = 9.0 -emitting = false amount = 64 lifetime = 0.3 one_shot = true @@ -120,7 +119,6 @@ script = ExtResource("2_grvat") [node name="SubSplatter" type="GPUParticles3D" parent="."] unique_name_in_owner = true sorting_offset = 9.0 -emitting = false amount = 4 lifetime = 0.3 one_shot = true diff --git a/src/game/game_manager.gd b/src/game/game_manager.gd index 70c7808..74d7315 100644 --- a/src/game/game_manager.gd +++ b/src/game/game_manager.gd @@ -12,7 +12,7 @@ signal grunk_emptied(amount: 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. +## Emitted just before the alert level is reset to the clear level. signal alert_cleared ## Emitted after the player's grunk vault reaches a new milestone. @@ -22,6 +22,7 @@ signal milestone_reached(milestone: Milestone) signal player_dead const MAX_ALERT := 6 +const CLEAR_LEVEL := 2 const BASE_TANK_LIMIT := 96000 const BIG_TANK_LIMIT := 198000 @@ -79,6 +80,8 @@ func deposit_tank() -> void: var new_milestone := latest_milestone() if new_milestone != prev_milestone: milestone_reached.emit(new_milestone) + if alert_level >= CLEAR_LEVEL: + clear_alert() func is_tank_full() -> bool: @@ -97,10 +100,10 @@ func raise_alert(delta: int) -> void: alert_level = new_value -## Reset the alert level to zero. +## Reset the alert level to the clear level. func clear_alert() -> void: alert_cleared.emit() - alert_level = 0 + alert_level = CLEAR_LEVEL ## Returns the latest vault milestone reached by the player. diff --git a/src/ui/hud/player_hud.gd b/src/ui/hud/player_hud.gd index 0c0b94c..0895ff4 100644 --- a/src/ui/hud/player_hud.gd +++ b/src/ui/hud/player_hud.gd @@ -7,6 +7,7 @@ class_name PlayerHUD extends Control func _ready() -> void: Game.manager.alert_raised.connect(_on_raise_alert) + Game.manager.alert_cleared.connect(_on_clear_alert) func select_interactive(prop: Interactive) -> void: @@ -19,3 +20,7 @@ func _on_raise_alert(_new_value: int) -> void: func play_tank_full_alert() -> void: alert_player.play("tank_full_alert") + + +func _on_clear_alert() -> void: + alert_player.play("alert_clear") diff --git a/src/ui/hud/player_hud.tscn b/src/ui/hud/player_hud.tscn index 08d2314..78d9f8f 100644 --- a/src/ui/hud/player_hud.tscn +++ b/src/ui/hud/player_hud.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=11 format=3 uid="uid://dq1x21tq06dud"] +[gd_scene load_steps=13 format=3 uid="uid://dq1x21tq06dud"] [ext_resource type="Theme" uid="uid://b07fevr214mmr" path="res://src/ui/hud/hud_theme.tres" id="1_lirk3"] [ext_resource type="Script" uid="uid://lrsv0185bfu" path="res://src/ui/hud/player_hud.gd" id="2_j6lpx"] @@ -6,6 +6,7 @@ [ext_resource type="FontFile" uid="uid://qadtckvw0t3l" path="res://assets/fonts/fontawesome-free-6.7.2-desktop/otfs/Font Awesome 6 Free-Solid-900.otf" id="4_2q5it"] [ext_resource type="PackedScene" uid="uid://b47goj32i6sdh" path="res://src/ui/elements/input_prompt/input_prompt.tscn" id="4_iwjh7"] [ext_resource type="Script" uid="uid://cjs2fen6jo0g0" path="res://src/ui/rumbler.gd" id="4_ud8na"] +[ext_resource type="FontFile" uid="uid://oq8ue2qrfijg" path="res://assets/fonts/Silkscreen/Silkscreen-Regular.ttf" id="7_iwjh7"] [sub_resource type="Animation" id="Animation_n6jee"] length = 0.001 @@ -45,6 +46,54 @@ tracks/2/keys = { "update": 0, "values": [Color(1, 1, 1, 0)] } +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("AlertClearMessage:visible") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("AlertClearMessage/Line1:visible_ratio") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("AlertClearMessage/RichTextLabel:visible_ratio") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("AlertClearMessage:modulate") +tracks/6/interp = 1 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Color(1, 1, 1, 1)] +} [sub_resource type="Animation" id="Animation_5be8f"] resource_name = "grunk_alert" @@ -92,9 +141,62 @@ tracks/0/keys = { "values": [Color(1, 1, 1, 0), Color(1, 1, 1, 1), Color(1, 1, 1, 0), Color(1, 1, 1, 1), Color(1, 1, 1, 0), Color(1, 1, 1, 1), Color(1, 1, 1, 0)] } +[sub_resource type="Animation" id="Animation_65kmv"] +resource_name = "alert_clear" +length = 4.0 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("AlertClearMessage:visible") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 4), +"transitions": PackedFloat32Array(1, 1), +"update": 1, +"values": [true, false] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("AlertClearMessage/Line1:visible_ratio") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.933333), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [0.0, 1.0] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("AlertClearMessage/RichTextLabel:visible_ratio") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 2.4, 2.56667), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 1.0] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("AlertClearMessage:modulate") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 3.5, 4), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Color(1, 1, 1, 1), Color(1, 1, 1, 1), Color(1, 1, 1, 0)] +} + [sub_resource type="AnimationLibrary" id="AnimationLibrary_ud8na"] _data = { &"RESET": SubResource("Animation_n6jee"), +&"alert_clear": SubResource("Animation_65kmv"), &"grunk_alert": SubResource("Animation_5be8f"), &"tank_full_alert": SubResource("Animation_ud8na") } @@ -242,10 +344,10 @@ anchor_left = 0.5 anchor_top = 0.5 anchor_right = 0.5 anchor_bottom = 0.5 -offset_left = -406.72 -offset_top = -295.754 -offset_right = -406.72 -offset_bottom = -295.754 +offset_left = -401.486 +offset_top = -302.289 +offset_right = -401.486 +offset_bottom = -302.289 grow_horizontal = 2 grow_vertical = 2 script = ExtResource("4_ud8na") @@ -303,6 +405,41 @@ theme_type_variation = &"AlertLabel" text = "HUD_ALERT_MSG" horizontal_alignment = 1 +[node name="AlertClearMessage" type="VBoxContainer" parent="AlertHUD"] +visible = false +layout_mode = 1 +anchors_preset = 5 +anchor_left = 0.5 +anchor_right = 0.5 +offset_bottom = 82.0 +grow_horizontal = 2 + +[node name="Line1" type="Label" parent="AlertHUD/AlertClearMessage"] +layout_mode = 2 +theme_type_variation = &"AlertLabel" +theme_override_colors/font_color = Color(0.137255, 0.984314, 0.34902, 1) +theme_override_font_sizes/font_size = 44 +text = "HUD_ALERT_CLEAR_MSG_1" +horizontal_alignment = 1 +visible_characters = 0 +visible_characters_behavior = 1 +visible_ratio = 0.0 + +[node name="RichTextLabel" type="RichTextLabel" parent="AlertHUD/AlertClearMessage"] +custom_minimum_size = Vector2(0, 100) +layout_mode = 2 +theme_override_colors/default_color = Color(0.137255, 0.984314, 0.34902, 1) +theme_override_constants/outline_size = 16 +theme_override_fonts/normal_font = ExtResource("7_iwjh7") +theme_override_font_sizes/normal_font_size = 44 +bbcode_enabled = true +text = "[wave amp=100.0 freq=10.0]COMPLETE![/wave]" +horizontal_alignment = 1 +vertical_alignment = 1 +visible_characters = 0 +visible_characters_behavior = 1 +visible_ratio = 0.0 + [node name="AlertPlayer" type="AnimationPlayer" parent="AlertHUD"] unique_name_in_owner = true libraries = { diff --git a/src/world/grunk_beast/grunk_beast.gd b/src/world/grunk_beast/grunk_beast.gd index 5c849ac..d16645a 100644 --- a/src/world/grunk_beast/grunk_beast.gd +++ b/src/world/grunk_beast/grunk_beast.gd @@ -80,6 +80,12 @@ func path_shorter_than(target: Vector3, limit: float) -> bool: return true +## Clear this beast's pursuit and stalking targets +func clear_aggro() -> void: + blackboard.erase_value("pursuit_target") + blackboard.erase_value("stalking_target") + + func _physics_process(delta: float) -> void: var motion := Vector3.ZERO diff --git a/src/world/grunk_beast/grunk_beast.tscn b/src/world/grunk_beast/grunk_beast.tscn index 3efc685..f3c04ce 100644 --- a/src/world/grunk_beast/grunk_beast.tscn +++ b/src/world/grunk_beast/grunk_beast.tscn @@ -218,7 +218,7 @@ metadata/_custom_type_script = "uid://om57w2acvgb7" script = ExtResource("11_mbqcc") mean_time = 4.0 st_dev_time = 0.6 -wait_time = 3.57092 +wait_time = 3.7153 metadata/_custom_type_script = "uid://beyk2xtbjrsg4" [node name="RandomStalkingBehavior" type="Node" parent="GrunkBeastBehavior/StateSelector/StalkingSequence/RandomDelay"] @@ -264,7 +264,7 @@ metadata/_custom_type_script = "uid://cg016dbe7gs1x" script = ExtResource("11_mbqcc") mean_time = 5.0 st_dev_time = 1.0 -wait_time = 4.97651 +wait_time = 4.12895 metadata/_custom_type_script = "uid://beyk2xtbjrsg4" [node name="PickRandomLurkTarget" type="Node" parent="GrunkBeastBehavior/StateSelector/LurkSequence/RandomDelay"] diff --git a/src/world/spook_manager/spook_manager.gd b/src/world/spook_manager/spook_manager.gd index 7464c38..f8b152b 100644 --- a/src/world/spook_manager/spook_manager.gd +++ b/src/world/spook_manager/spook_manager.gd @@ -2,6 +2,7 @@ class_name SpookManager extends Resource ## A strategy for handling horror elements through the level. const SPAWN_GROUP := "BeastSpawnPoint" +const BEAST_GROUP := "GrunkBeast" @export var grunkbeast_scene: PackedScene @@ -77,4 +78,15 @@ func _on_alert_raised(new_level: int) -> void: func _on_alert_cleared() -> void: - pass # TODO + # Destroy all but one grunk beasts + var beasts := Game.manager.get_tree().get_nodes_in_group(BEAST_GROUP) + if not beasts: + return + + @warning_ignore("unsafe_cast") + var survivor := beasts.pick_random() as GrunkBeast + for beast: Node in beasts: + if beast != survivor: + beast.queue_free() + + survivor.clear_aggro()