Player tank has limited capacity

This commit is contained in:
Rob Kelly 2025-03-20 22:45:19 -06:00
parent 0ea73b1221
commit 9b7671de48
12 changed files with 117 additions and 35 deletions

Binary file not shown.

Binary file not shown.

View File

@ -15,12 +15,18 @@ func _spray() -> void:
func _fire() -> void: func _fire() -> void:
rumbler.intensity = RUMBLE_INTENSITY
if Game.manager.is_tank_full():
Player.instance.hud.play_tank_full_alert()
idle()
return
_spray() _spray()
spray_effect.visible = true spray_effect.visible = true
beam_particles_1.emitting = true beam_particles_1.emitting = true
beam_particles_2.emitting = true beam_particles_2.emitting = true
rumbler.intensity = RUMBLE_INTENSITY
func _idle() -> void: func _idle() -> void:

View File

@ -14,7 +14,7 @@ const BRUSH_SCALE := 0.2
func _fire() -> void: func _fire() -> void:
if raycast.is_colliding(): if raycast.is_colliding() and not Game.manager.is_tank_full():
brush_animation.play("brush") brush_animation.play("brush")
var collider := raycast.get_collider() var collider := raycast.get_collider()
if collider is GunkBody: if collider is GunkBody:

View File

@ -5,3 +5,5 @@ class_name Game extends Node
static var manager: GameManagerType: static var manager: GameManagerType:
get(): get():
return GameManager return GameManager
static var hud: PlayerHUD

View File

@ -15,6 +15,9 @@ signal alert_cleared
const MAX_ALERT := 6 const MAX_ALERT := 6
## Maximum amount of grunk the player can carry in their tank.
@export var grunk_tank_limit := 120000
## Amount of grunk the player is currently carrying. ## Amount of grunk the player is currently carrying.
var grunk_tank := 0.0 var grunk_tank := 0.0
@ -44,6 +47,14 @@ func deposit_tank() -> void:
empty_tank() empty_tank()
func is_tank_full() -> bool:
return grunk_tank >= grunk_tank_limit
func get_tank_fill_pct() -> float:
return grunk_tank / grunk_tank_limit
## Raise the alert level, if possible. ## Raise the alert level, if possible.
func raise_alert(delta: int) -> void: func raise_alert(delta: int) -> void:
var new_value := clampi(alert_level + delta, 0, MAX_ALERT) var new_value := clampi(alert_level + delta, 0, MAX_ALERT)

View File

@ -16,7 +16,7 @@ var gravity: Vector3 = (
var selected_interactive: Interactive var selected_interactive: Interactive
var firing := false var firing := false
@onready var player_hud: PlayerHUD = %PlayerHUD @onready var hud: PlayerHUD = %PlayerHUD
@onready var camera_pivot: CameraController = %CameraPivot @onready var camera_pivot: CameraController = %CameraPivot
@ -27,6 +27,13 @@ var firing := false
@onready var wide_spray: WideSpray = %WideSpray @onready var wide_spray: WideSpray = %WideSpray
@onready var toothbrush: Tool = %Toothbrush @onready var toothbrush: Tool = %Toothbrush
## Global static access to player singleton
static var instance: Player
func _ready() -> void:
instance = self
func get_speed() -> float: func get_speed() -> float:
if is_on_floor(): if is_on_floor():
@ -51,7 +58,7 @@ func get_tool() -> Tool:
func _physics_process(delta: float) -> void: func _physics_process(delta: float) -> void:
# Will be null if no valid interactor is selected. # Will be null if no valid interactor is selected.
var interactive: Interactive = interact_ray.get_collider() as Interactive var interactive: Interactive = interact_ray.get_collider() as Interactive
player_hud.select_interactive(interactive) hud.select_interactive(interactive)
# World interaction # World interaction
if interactive and Input.is_action_just_pressed("interact"): if interactive and Input.is_action_just_pressed("interact"):

View File

@ -55,6 +55,33 @@ _surfaces = [{
blend_shape_mode = 0 blend_shape_mode = 0
shadow_mesh = SubResource("ArrayMesh_3gl0p") shadow_mesh = SubResource("ArrayMesh_3gl0p")
[sub_resource type="Animation" id="Animation_g27yp"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:mesh:surface_0/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": [12.0]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("../SpotLight3D:light_energy")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [2.0]
}
[sub_resource type="Animation" id="Animation_whqf3"] [sub_resource type="Animation" id="Animation_whqf3"]
resource_name = "flicker" resource_name = "flicker"
length = 0.01 length = 0.01
@ -85,33 +112,6 @@ tracks/1/keys = {
"values": [3.0, 2.7] "values": [3.0, 2.7]
} }
[sub_resource type="Animation" id="Animation_g27yp"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:mesh:surface_0/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": [12.0]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("../SpotLight3D:light_energy")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [2.0]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_ngq1d"] [sub_resource type="AnimationLibrary" id="AnimationLibrary_ngq1d"]
_data = { _data = {
&"RESET": SubResource("Animation_g27yp"), &"RESET": SubResource("Animation_g27yp"),

View File

@ -4,6 +4,8 @@ extends HBoxContainer
const COUNTER_BUMP_RATE := 0.15 const COUNTER_BUMP_RATE := 0.15
const COUNTER_SPINDOWN_TIME := 0.4 const COUNTER_SPINDOWN_TIME := 0.4
const TANK_WARNING_BUFFER_PCT := 0.1
@onready var counter: Label = %Counter @onready var counter: Label = %Counter
@ -14,11 +16,14 @@ func _ready() -> void:
func on_grunk_collected(delta: float) -> void: func on_grunk_collected(delta: float) -> void:
counter.text = str(int(Game.manager.grunk_tank)) counter.text = str(int(clampf(Game.manager.grunk_tank, 0.0, Game.manager.grunk_tank_limit)))
counter.scale = Vector2.ONE + Vector2.ONE * clampf(delta / 128.0, 0.1, 1.0) counter.scale = Vector2.ONE + Vector2.ONE * clampf(delta / 128.0, 0.1, 1.0)
var buffer := remap(Game.manager.get_tank_fill_pct(), 1 - TANK_WARNING_BUFFER_PCT, 1, 0, 1)
counter.modulate = Color.WHITE.lerp(Color.RED, clampf(buffer, 0, 1))
func on_grunk_emptied(amount: float) -> void: func on_grunk_emptied(amount: float) -> void:
counter.modulate = Color.WHITE
create_tween().tween_method(_set_counter, int(amount), 0, COUNTER_SPINDOWN_TIME).set_trans( create_tween().tween_method(_set_counter, int(amount), 0, COUNTER_SPINDOWN_TIME).set_trans(
Tween.TRANS_EXPO Tween.TRANS_EXPO
) )

View File

@ -23,6 +23,7 @@ text = "GRUNK: "
[node name="Counter" type="Label" parent="."] [node name="Counter" type="Label" parent="."]
unique_name_in_owner = true unique_name_in_owner = true
texture_filter = 6 texture_filter = 6
custom_minimum_size = Vector2(120, 0)
layout_mode = 2 layout_mode = 2
size_flags_horizontal = 4 size_flags_horizontal = 4
size_flags_vertical = 8 size_flags_vertical = 8

View File

@ -7,6 +7,7 @@ class_name PlayerHUD extends Control
func _ready() -> void: func _ready() -> void:
Game.manager.alert_raised.connect(_on_raise_alert) Game.manager.alert_raised.connect(_on_raise_alert)
Game.hud = self
func select_interactive(prop: Interactive) -> void: func select_interactive(prop: Interactive) -> void:
@ -15,3 +16,7 @@ func select_interactive(prop: Interactive) -> void:
func _on_raise_alert(_new_value: int) -> void: func _on_raise_alert(_new_value: int) -> void:
alert_player.play("grunk_alert") alert_player.play("grunk_alert")
func play_tank_full_alert() -> void:
alert_player.play("tank_full_alert")

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=8 format=3 uid="uid://dq1x21tq06dud"] [gd_scene load_steps=9 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="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"] [ext_resource type="Script" uid="uid://lrsv0185bfu" path="res://src/ui/hud/player_hud.gd" id="2_j6lpx"]
@ -31,6 +31,18 @@ tracks/1/keys = {
"update": 0, "update": 0,
"values": [Color(1, 1, 1, 0)] "values": [Color(1, 1, 1, 0)]
} }
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("TankAlert:modulate")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Color(1, 1, 1, 0)]
}
[sub_resource type="Animation" id="Animation_5be8f"] [sub_resource type="Animation" id="Animation_5be8f"]
resource_name = "grunk_alert" resource_name = "grunk_alert"
@ -61,10 +73,28 @@ tracks/1/keys = {
"values": [Color(1, 1, 1, 0), 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)] "values": [Color(1, 1, 1, 0), 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_ud8na"]
resource_name = "tank_full_alert"
length = 3.6
step = 0.1
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("TankAlert:modulate")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.6, 1.2, 1.8, 2.4, 3, 3.6),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1),
"update": 0,
"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="AnimationLibrary" id="AnimationLibrary_ud8na"] [sub_resource type="AnimationLibrary" id="AnimationLibrary_ud8na"]
_data = { _data = {
&"RESET": SubResource("Animation_n6jee"), &"RESET": SubResource("Animation_n6jee"),
&"grunk_alert": SubResource("Animation_5be8f") &"grunk_alert": SubResource("Animation_5be8f"),
&"tank_full_alert": SubResource("Animation_ud8na")
} }
[node name="PlayerHUD" type="Control"] [node name="PlayerHUD" type="Control"]
@ -148,6 +178,21 @@ grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
mouse_filter = 1 mouse_filter = 1
[node name="TankAlert" type="Label" parent="AlertHUD"]
modulate = Color(1, 1, 1, 0)
layout_mode = 1
anchors_preset = 5
anchor_left = 0.5
anchor_right = 0.5
offset_left = -268.0
offset_right = 268.0
offset_bottom = 88.0
grow_horizontal = 2
theme_type_variation = &"AlertLabel"
text = "TANK FULL
RETURN TO SHIP"
horizontal_alignment = 1
[node name="GrunkAlert" type="Label" parent="AlertHUD"] [node name="GrunkAlert" type="Label" parent="AlertHUD"]
modulate = Color(1, 1, 1, 0) modulate = Color(1, 1, 1, 0)
layout_mode = 1 layout_mode = 1