OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-tps / scenes / maps / sky_defaults.gd

56 lines · gd ref:
extends RefCounted
class_name SkyDefaults
## WHICH SKY DEFAULTS A MAP MAY APPLY — hyper-games #42 P1.
##
## A map opens with a look it wants: map_dc_terrain asks for morning, map_dc_level
## for daylight. That is right for a room that has never been dressed, and wrong
## for one that has: a room with a saved sky is a world someone authored, and
## forcing noon over it makes the time slider pointless on every map that inherits
## from it.
##
## THE RULE IS "SAVED WINS", and map_dc_level already had it — this is that check,
## made shared and made complete. Two gaps it closes:
##
##   1. map_dc_terrain had NO guard at all. It set current_time and minutes_per_day
##      unconditionally in _ready, so entering it clobbered whatever the room had
##      saved. That is the reported symptom: set the sky, change map, lose it.
##   2. map_dc_level guarded ONE property. A map that also sets minutes_per_day —
##      as map_dc_terrain does — had that half unguarded even where the check ran.
##
## Why the arrival-order framing in the old comments is not the whole story: the
## panel restores saved values at setup and again on state_changed, so a map whose
## _ready runs AFTER that simply overwrites them. It is not a race that a longer
## timer wins, it is a writer with no business writing. SETTLE_DELAY in
## sky_debug_panel re-asserts 1.5 s later and is what made this survivable; it stays
## as a backstop, but it should no longer be the thing doing the work.
##
## Pure and static over key strings, so the rule is assertable without a room, a
## peer or a GameState — the same reason TerrainEditOrder is its own file.

const PREFIX := "world:sky:"


## The subset of `props` the room has NOT saved, in the order given.
##
## `saved_keys` is what GameState.keys_with_prefix(PREFIX) returns: unscoped keys
## for the CURRENT map, since map scoping is applied on the way to the store.
static func unsaved(props: Array[String], saved_keys: Array[String]) -> Array[String]:
	var have: Dictionary = {}
	for k: String in saved_keys:
		if k.begins_with(PREFIX):
			have[k.substr(PREFIX.length())] = true
	var out: Array[String] = []
	for p: String in props:
		if not have.has(p):
			out.append(p)
	return out


## True when the room has saved nothing at all about the sky — a map may then
## apply its whole opening look without checking property by property.
static func is_undressed(saved_keys: Array[String]) -> bool:
	for k: String in saved_keys:
		if k.begins_with(PREFIX):
			return false
	return true