M1c: weather, snap building, shelter, beds and regrowth
- Seeded weather (clear/cloudy/rain/storm, snow and blizzards on cold days and above the snowline), lightning, synthesised rain/wind/thunder sound - Rain/snow particles stopped by roofs; wet ground, settled snow and wind via global shader uniforms - Snap-together wood floor, wall, door, roof and gable with structural support, collapse and X to dismantle - Shelter detection: dry under a roof, warmer and Rested inside with a fire; rain burns an uncovered campfire faster - Bed sets the spawn point and lets you sleep through the night - Trees, boulders and ground pickups regrow; timers saved - Grass cleared under floors; shorter HUD hint - New test_weather_building suite (62 checks) and tests/run_all.sh, which also fails on script errors
This commit is contained in:
@@ -15,6 +15,8 @@ var _fx: Array[CPUParticles3D] = []
|
||||
var _t := 0.0
|
||||
var _noise := FastNoiseLite.new()
|
||||
var _lit := true
|
||||
var _roofed_cache := -1.0 ## -1 unknown, 0 open sky, 1 under a roof
|
||||
var _roof_timer := 0.0
|
||||
|
||||
func _build() -> void:
|
||||
add_to_group("station:campfire")
|
||||
@@ -64,19 +66,44 @@ func interact_prompt(player: Node) -> String:
|
||||
var has_fuel: bool = player.inventory.count("wood") + player.inventory.count("stick") > 0
|
||||
if _lit:
|
||||
var left := "%d:%02d" % [int(fuel) / 60, int(fuel) % 60]
|
||||
return "Campfire (%s left)%s" % [left, " [E] Add fuel" if has_fuel else " (add wood or sticks)"]
|
||||
var hiss := ", hissing in the rain" if burn_rate() > 1.2 else ""
|
||||
return "Campfire (%s left%s)%s" % [left, hiss, " [E] Add fuel" if has_fuel else " (add wood or sticks)"]
|
||||
return "Campfire (out)%s" % (" [E] Add fuel to light" if has_fuel else " (needs wood or sticks)")
|
||||
|
||||
func interact(player: Node) -> void:
|
||||
Actions.add_fuel(player, self)
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
## How much faster fuel burns right now: rain on an uncovered fire makes it
|
||||
## hiss and eat through its wood (up to 4x in a storm). A roof stops that.
|
||||
func burn_rate() -> float:
|
||||
var w: Node = get_parent().get_parent() if get_parent() != null else null
|
||||
if w == null or w.get("weather") == null:
|
||||
return 1.0
|
||||
var rain: float = w.weather.rain_at(global_position)
|
||||
if rain <= 0.05:
|
||||
_roofed_cache = -1.0
|
||||
return 1.0
|
||||
if _roofed_cache < 0.0:
|
||||
_roofed_cache = 1.0 if w.build.roofed_at(global_position) else 0.0
|
||||
return 1.0 if _roofed_cache > 0.5 else 1.0 + 3.0 * rain
|
||||
|
||||
func burn(seconds: float) -> void:
|
||||
if not _lit:
|
||||
return
|
||||
fuel -= delta
|
||||
fuel -= seconds * burn_rate()
|
||||
if fuel <= 0.0:
|
||||
fuel = 0.0
|
||||
_set_lit(false)
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if not _lit:
|
||||
return
|
||||
_roof_timer -= delta
|
||||
if _roof_timer <= 0.0:
|
||||
_roof_timer = 2.0
|
||||
_roofed_cache = -1.0 # re-check the roof now and then (you may build one)
|
||||
burn(delta)
|
||||
if not _lit:
|
||||
return
|
||||
_t += delta
|
||||
var f := _noise.get_noise_1d(_t * 10.0)
|
||||
|
||||
Reference in New Issue
Block a user