Map 1: rebuild Hollywood as the El Capitan landmark
Replace the generic boulevard facade with a stylized 6840 Hollywood Blvd block: six Ionic columns, eight stone steps, Masonic frieze/medallions, event banners, side doors, El Capitan Theatre and retail neighbours, Ovation Hollywood arcade, Walk of Fame and four-lane street markings. Add the Day and Night Hollywood venue-menu rows. Night uses a phase-time offset so a full-length shift stays in LATE while the clock starts at zero; late routine traffic keeps the street populated and the offset round-trips through checkpoint restore. Retune local-light falloff to linear attenuation, add a cool north sky fill, and use the smooth limestone facade texture. Refresh the staged gallery and map references; add geometry-budget, menu, night-offset and late-traffic tests.
This commit is contained in:
1 parent
3f335481d6
commit
74dc1fdc1d
50 files changed
+1176
-100
No files matched your search
@@ -45,9 +45,14 @@ var body_camera_on := false
|
||||
var coordinator: ShiftCoordinator = null
|
||||
var guard: GuardController = null
|
||||
var _sun: DirectionalLight3D = null
|
||||
var _fill: DirectionalLight3D = null
|
||||
var _env_node: WorldEnvironment = null
|
||||
var _sky: ProceduralSkyMaterial = null
|
||||
var _last_phase: int = -1
|
||||
## Menu-only alias for the night scenery variant; it resolves to the Hollywood
|
||||
## scenario with a LATE phase offset.
|
||||
const HOLLYWOOD_NIGHT_ID := "hollywood_building_night"
|
||||
var _start_phase_override: int = -1
|
||||
|
||||
## Per-phase lighting looks for the sun, sky, and ambient (PLAN.md: shift
|
||||
## structure — phase-based lighting). Night phases switch street lamps on.
|
||||
@@ -58,7 +63,7 @@ const PHASE_LIGHTING := {
|
||||
"sky_ground": Color(0.45, 0.5, 0.55), "ambient": Color(0.75, 0.78, 0.85), "night": false,
|
||||
"exposure": 0.6, "glow": 0.45, "fog_color": Color(0.87, 0.83, 0.76),
|
||||
"fog_density": 0.0034, "fog_energy": 0.5, "contrast": 1.05, "saturation": 1.04,
|
||||
"ambient_energy": 0.1, "volumetric_density": 0.004, "volumetric_energy": 0.0,
|
||||
"ambient_energy": 0.1, "fill_energy": 0.22, "volumetric_density": 0.004, "volumetric_energy": 0.0,
|
||||
},
|
||||
Rules.Phase.MIDDAY: {
|
||||
"sun_energy": 1.0, "sun_angle": -62.0, "sun_yaw": -30.0, "sun_color": Color(1.0, 0.99, 0.96),
|
||||
@@ -66,7 +71,7 @@ const PHASE_LIGHTING := {
|
||||
"sky_ground": Color(0.5, 0.54, 0.58), "ambient": Color(0.85, 0.88, 0.95), "night": false,
|
||||
"exposure": 0.6, "glow": 0.4, "fog_color": Color(0.88, 0.87, 0.83),
|
||||
"fog_density": 0.0028, "fog_energy": 0.5, "contrast": 1.06, "saturation": 1.04,
|
||||
"ambient_energy": 0.28, "volumetric_density": 0.003, "volumetric_energy": 0.0,
|
||||
"ambient_energy": 0.28, "fill_energy": 0.18, "volumetric_density": 0.003, "volumetric_energy": 0.0,
|
||||
},
|
||||
# Evening is dusk, not a bright sunset: the sun is almost down and the street
|
||||
# is carried by the marquee, the lamps and the lit windows (realism pass).
|
||||
@@ -76,7 +81,7 @@ const PHASE_LIGHTING := {
|
||||
"sky_ground": Color(0.1, 0.09, 0.12), "ambient": Color(0.2, 0.19, 0.26), "night": true,
|
||||
"exposure": 0.72, "glow": 0.8, "fog_color": Color(0.34, 0.27, 0.3),
|
||||
"fog_density": 0.0026, "fog_energy": 0.45, "contrast": 1.1, "saturation": 1.05,
|
||||
"ambient_energy": 0.12, "volumetric_density": 0.014, "volumetric_energy": 0.10,
|
||||
"ambient_energy": 0.12, "fill_energy": 0.10, "volumetric_density": 0.014, "volumetric_energy": 0.10,
|
||||
},
|
||||
Rules.Phase.LATE: {
|
||||
"sun_energy": 0.02, "sun_angle": -8.0, "sun_color": Color(0.3, 0.35, 0.5),
|
||||
@@ -84,7 +89,7 @@ const PHASE_LIGHTING := {
|
||||
"sky_ground": Color(0.03, 0.03, 0.05), "ambient": Color(0.06, 0.07, 0.12), "night": true,
|
||||
"exposure": 0.95, "glow": 1.15, "fog_color": Color(0.08, 0.1, 0.2),
|
||||
"fog_density": 0.0028, "fog_energy": 0.45, "contrast": 1.12, "saturation": 1.0,
|
||||
"ambient_energy": 0.22, "volumetric_density": 0.020, "volumetric_energy": 0.14,
|
||||
"ambient_energy": 0.30, "fill_energy": 0.06, "volumetric_density": 0.020, "volumetric_energy": 0.14,
|
||||
},
|
||||
}
|
||||
var hud: Hud = null
|
||||
@@ -222,7 +227,7 @@ func _build_guard() -> GuardController:
|
||||
flashlight.spot_range = 30.0 if Materials.modern_light_falloff() else 20.0
|
||||
flashlight.spot_angle = 14.0
|
||||
flashlight.light_energy = 4.2
|
||||
flashlight.spot_attenuation = 0.0 if Materials.modern_light_falloff() else 0.9
|
||||
flashlight.spot_attenuation = 1.0
|
||||
flashlight.spot_angle_attenuation = 0.9
|
||||
# The volumetric shaft is a Forward+ (desktop HQ) effect. Compatibility and
|
||||
# headless builds leave the light non-volumetric, so their look is unchanged.
|
||||
@@ -265,6 +270,7 @@ func _build_scenario(id: String) -> VenueScenario:
|
||||
return ScenarioFactory.hollywood_building()
|
||||
|
||||
func switch_scenario(id: String) -> void:
|
||||
_start_phase_override = -1
|
||||
active_scenario_id = id
|
||||
selected_scenario = _build_scenario(id)
|
||||
_rebuild_world_for_venue(id)
|
||||
@@ -315,6 +321,9 @@ func _reset_shift_state() -> void:
|
||||
hud.set_body_camera(false)
|
||||
scenario_duration_s = selected_scenario.shift_duration_s
|
||||
coordinator.setup(selected_scenario, scenario_duration_s, 4242)
|
||||
if _start_phase_override >= 0:
|
||||
coordinator.phase_offset_s = _phase_start_s(_start_phase_override)
|
||||
coordinator.current_phase = coordinator._phase_for_time(0.0)
|
||||
coordinator.scheduler.spawn_rate_multiplier = float(_difficulty()["spawn"])
|
||||
_connect_radio()
|
||||
_connect_crowd()
|
||||
@@ -336,6 +345,11 @@ func _start_shift() -> void:
|
||||
# opens and closes.
|
||||
_refresh_freeze()
|
||||
|
||||
func _phase_start_s(phase: int) -> float:
|
||||
if selected_scenario == null:
|
||||
return 0.0
|
||||
return float((selected_scenario.shift_phases.get(phase, {}) as Dictionary).get("start_s", 0.0))
|
||||
|
||||
func _show_start_menu() -> void:
|
||||
_shift_running = false
|
||||
if pause_overlay:
|
||||
@@ -353,6 +367,10 @@ func _on_venue_selected(scenario_id: String) -> void:
|
||||
start_menu.close()
|
||||
if not _resuming and Save:
|
||||
Save.clear_shift_state()
|
||||
_start_phase_override = -1
|
||||
if scenario_id == HOLLYWOOD_NIGHT_ID:
|
||||
_start_phase_override = Rules.Phase.LATE
|
||||
scenario_id = "hollywood_building"
|
||||
active_scenario_id = scenario_id
|
||||
_venue_index = maxi(0, VENUE_ORDER.find(scenario_id))
|
||||
selected_scenario = _build_scenario(scenario_id)
|
||||
@@ -715,6 +733,15 @@ func _ensure_lighting() -> void:
|
||||
_sun.directional_shadow_mode = DirectionalLight3D.SHADOW_PARALLEL_4_SPLITS
|
||||
_sun.directional_shadow_max_distance = 60.0
|
||||
scene_root.add_child(_sun)
|
||||
# A soft sky-bounce fill from the north keeps the shaded Ovation frontage
|
||||
# readable without adding a second set of hard shadows.
|
||||
_fill = DirectionalLight3D.new()
|
||||
_fill.name = "SkyFill"
|
||||
_fill.rotation_degrees = Vector3(-24, 180, 0)
|
||||
_fill.light_energy = 0.2
|
||||
_fill.light_color = Color(0.62, 0.72, 0.9)
|
||||
_fill.shadow_enabled = false
|
||||
scene_root.add_child(_fill)
|
||||
_env_node = WorldEnvironment.new()
|
||||
var env := Environment.new()
|
||||
env.background_mode = Environment.BG_SKY
|
||||
@@ -741,6 +768,8 @@ func _apply_phase_lighting() -> void:
|
||||
# entrance view reads as shade when the sun is off the facade.
|
||||
_sun.rotation_degrees = Vector3(float(cfg.get("sun_angle", -50.0)),
|
||||
float(cfg.get("sun_yaw", -30.0)), 0)
|
||||
if _fill:
|
||||
_fill.light_energy = float(cfg.get("fill_energy", 0.16))
|
||||
if _sky:
|
||||
_sky.sky_top_color = cfg.get("sky_top", Color.BLUE)
|
||||
_sky.sky_horizon_color = cfg.get("sky_horizon", Color.WHITE)
|
||||
@@ -1981,7 +2010,8 @@ func _physics_process(delta: float) -> void:
|
||||
hud.log("Objective: %s — keep the entrance clear and verify access." % str(
|
||||
Rules.PHASE_NAMES.get(coordinator.current_phase, "Early")))
|
||||
hud.set_shift_state(coordinator, selected_scenario)
|
||||
var preview := coordinator.scheduler.preview(coordinator.elapsed_s, coordinator.current_phase)
|
||||
var preview := coordinator.scheduler.preview(coordinator.schedule_time_s(),
|
||||
coordinator.current_phase)
|
||||
hud.refresh_debug(coordinator, npcs, preview)
|
||||
_perception_pass()
|
||||
|
||||
|
||||
Reference in new issue
Block a user