Add planet setups as authored resources (#42)
PlanetSetup/PlanetSetupSpawn define a curated capture-point/enemy layout for a surface profile; PlanetSetups scans res://PlanetSetups/ at first use (not a hardcoded preload table) so dropping in a new .tres is the only step needed to add one, and resolves the same setup for the same planet deterministically, same pattern as WorldGen.planet_data_at_chunk. PlanetSurfaceController composes a PlanetSetupHost onto the landed surface alongside the existing resource-provider feature scene. Ships two starter setups (rocky_default, gas_default) with placeholder capture-point markers; #43 replaces the markers with the real CapturePoint scene through the same apply_setup() entry point. Part of the #40 conquest-mechanic breakdown.
This commit is contained in:
parent
a1ad6cc844
commit
5326852807
17 changed files with 350 additions and 4 deletions
69
PlanetSetups.gd
Normal file
69
PlanetSetups.gd
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
class_name PlanetSetups
|
||||
extends RefCounted
|
||||
|
||||
# Registry of authored PlanetSetup resources. Deliberately scans
|
||||
# res://PlanetSetups/ at first use instead of a hardcoded preload
|
||||
# dictionary (contrast PlanetDefinitions.gd), so dropping a new .tres in
|
||||
# that folder is the only step needed to add a setup - the map editor
|
||||
# (#48) writes there directly.
|
||||
|
||||
const SETUPS_DIR: String = "res://PlanetSetups"
|
||||
# Compared against get_script() rather than an `is PlanetSetup` check - the
|
||||
# same load-order hazard as PlanetSurfaceController's setup_host: a global
|
||||
# class_name identifier can be looked up before an import pass has
|
||||
# registered it, while a direct script preload never depends on that cache.
|
||||
const PLANET_SETUP_SCRIPT: Script = preload("res://PlanetSetup.gd")
|
||||
|
||||
static var _all: Array = []
|
||||
static var _scanned: bool = false
|
||||
|
||||
|
||||
static func _ensure_scanned() -> void:
|
||||
if _scanned:
|
||||
return
|
||||
_scanned = true
|
||||
var dir: DirAccess = DirAccess.open(SETUPS_DIR)
|
||||
if dir == null:
|
||||
return
|
||||
dir.list_dir_begin()
|
||||
var file_name: String = dir.get_next()
|
||||
while file_name != "":
|
||||
if not dir.current_is_dir() and file_name.ends_with(".tres"):
|
||||
var res: Resource = load(SETUPS_DIR + "/" + file_name)
|
||||
if res != null and res.get_script() == PLANET_SETUP_SCRIPT:
|
||||
_all.append(res)
|
||||
file_name = dir.get_next()
|
||||
dir.list_dir_end()
|
||||
|
||||
|
||||
static func rescan() -> void:
|
||||
# The map editor calls this after saving so a freshly written setup is
|
||||
# visible without restarting the process.
|
||||
_all = []
|
||||
_scanned = false
|
||||
_ensure_scanned()
|
||||
|
||||
|
||||
static func all() -> Array:
|
||||
_ensure_scanned()
|
||||
return _all
|
||||
|
||||
|
||||
static func setups_for_profile(profile_id: String) -> Array:
|
||||
var result: Array = []
|
||||
for setup in all():
|
||||
if setup.surface_profile_id == profile_id:
|
||||
result.append(setup)
|
||||
return result
|
||||
|
||||
|
||||
static func setup_for_planet(planet_id: String, profile_id: String) -> Resource:
|
||||
# Same pattern as WorldGen.planet_data_at_chunk: seeded purely from the
|
||||
# planet's own stable id, so the same planet always resolves to the
|
||||
# same setup from anywhere, with nothing stored.
|
||||
var candidates: Array = setups_for_profile(profile_id)
|
||||
if candidates.is_empty():
|
||||
return null
|
||||
var rng: RandomNumberGenerator = RandomNumberGenerator.new()
|
||||
rng.seed = hash(planet_id)
|
||||
return candidates[rng.randi() % candidates.size()]
|
||||
Loading…
Reference in a new issue