generated from krampus/template-godot4
88 lines
2.1 KiB
GDScript
88 lines
2.1 KiB
GDScript
extends AudioStreamPlayer
|
|
|
|
const MUTE_VOLUME := -80.0
|
|
|
|
@export var volume_increment := 0.618
|
|
@export var base_volume := -18.0
|
|
@export var boosted_volume := -2.0
|
|
|
|
@export_category("Beast Proximity Boost")
|
|
@export var proximity_cutoff := 20.0
|
|
@export var proximity_scale := 17.0
|
|
|
|
var target_volume := MUTE_VOLUME
|
|
var suppressed := false
|
|
var boosted := false
|
|
|
|
|
|
func _ready() -> void:
|
|
Game.manager.alert_raised.connect(_on_alert_raised)
|
|
|
|
|
|
func get_target_volume() -> float:
|
|
if suppressed:
|
|
return MUTE_VOLUME
|
|
if boosted:
|
|
return boosted_volume
|
|
return target_volume + beast_proximity_boost(closest_beast_distance())
|
|
|
|
|
|
## Calculate the volume gain from proximity to a beast
|
|
func beast_proximity_boost(distance: float) -> float:
|
|
return max(0.0, proximity_scale * (proximity_cutoff - distance) / proximity_cutoff)
|
|
|
|
|
|
## Get the distance from the player to the closest beast
|
|
func closest_beast_distance() -> float:
|
|
if not is_instance_valid(Player.instance):
|
|
return INF
|
|
|
|
var min_dist_sq := INF
|
|
var nodes := get_tree().get_nodes_in_group("GrunkBeast")
|
|
for node: Node in nodes:
|
|
var n3d := node as Node3D
|
|
if is_instance_valid(n3d):
|
|
var dist_sq := n3d.global_position.distance_squared_to(Player.instance.global_position)
|
|
if dist_sq < min_dist_sq:
|
|
min_dist_sq = dist_sq
|
|
return sqrt(min_dist_sq)
|
|
|
|
|
|
## Temporarily suppress ambience
|
|
func suppress(time: float = 5.0) -> void:
|
|
suppressed = true
|
|
get_tree().create_timer(time).timeout.connect(_unsuppress)
|
|
|
|
|
|
## Temporarily boost ambience
|
|
func boost(time: float = 5.0) -> void:
|
|
boosted = true
|
|
get_tree().create_timer(time).timeout.connect(_unboost)
|
|
|
|
|
|
func _unsuppress() -> void:
|
|
suppressed = false
|
|
|
|
|
|
func _unboost() -> void:
|
|
boosted = false
|
|
|
|
|
|
func _process(delta: float) -> void:
|
|
volume_db = lerpf(volume_db, get_target_volume(), volume_increment * delta)
|
|
|
|
|
|
func _on_player_enters_ship(_body: Node3D) -> void:
|
|
target_volume = MUTE_VOLUME
|
|
|
|
|
|
func _on_player_exits_ship(_body: Node3D) -> void:
|
|
target_volume = base_volume
|
|
|
|
|
|
func _on_alert_raised(new_level: int) -> void:
|
|
if new_level == Game.manager.MAX_ALERT:
|
|
suppress(30)
|
|
else:
|
|
boost(10.0)
|