Visual pass: grid materials, corridor lights, emissive props, target marker, objectives
Portal-style triplanar grid on all structure, omni lighting per segment, emissive glow on every interactable, floating look-target marker, socket gets a visible empty-ring slot, HUD gains an OBJECTIVE tracker line. Integration playthrough still 19/19. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
d414ccd6e4
commit
5f67b3c6b0
@ -19,6 +19,9 @@ class Door extends StaticBody3D:
|
|||||||
mi.position.y = height / 2.0
|
mi.position.y = height / 2.0
|
||||||
var mat := StandardMaterial3D.new()
|
var mat := StandardMaterial3D.new()
|
||||||
mat.albedo_color = tint
|
mat.albedo_color = tint
|
||||||
|
mat.emission_enabled = true
|
||||||
|
mat.emission = tint
|
||||||
|
mat.emission_energy_multiplier = 0.3
|
||||||
mi.material_override = mat
|
mi.material_override = mat
|
||||||
add_child(mi)
|
add_child(mi)
|
||||||
var col := CollisionShape3D.new()
|
var col := CollisionShape3D.new()
|
||||||
@ -61,6 +64,9 @@ class Pickup extends Node3D:
|
|||||||
mi.mesh = m
|
mi.mesh = m
|
||||||
var mat := StandardMaterial3D.new()
|
var mat := StandardMaterial3D.new()
|
||||||
mat.albedo_color = tint
|
mat.albedo_color = tint
|
||||||
|
mat.emission_enabled = true
|
||||||
|
mat.emission = tint
|
||||||
|
mat.emission_energy_multiplier = 0.6
|
||||||
mi.material_override = mat
|
mi.material_override = mat
|
||||||
add_child(mi)
|
add_child(mi)
|
||||||
|
|
||||||
@ -93,6 +99,9 @@ class Bucket extends Node3D:
|
|||||||
mi.position.y = 0.21
|
mi.position.y = 0.21
|
||||||
var mat := StandardMaterial3D.new()
|
var mat := StandardMaterial3D.new()
|
||||||
mat.albedo_color = Color(0.35, 0.4, 0.5)
|
mat.albedo_color = Color(0.35, 0.4, 0.5)
|
||||||
|
mat.emission_enabled = true
|
||||||
|
mat.emission = Color(0.35, 0.5, 0.8)
|
||||||
|
mat.emission_energy_multiplier = 0.5
|
||||||
mi.material_override = mat
|
mi.material_override = mat
|
||||||
add_child(mi)
|
add_child(mi)
|
||||||
# the leaky bucket IS just a decaying exposable state (GDD)
|
# the leaky bucket IS just a decaying exposable state (GDD)
|
||||||
@ -115,12 +124,26 @@ class Socket extends Node3D:
|
|||||||
add_to_group("interactable")
|
add_to_group("interactable")
|
||||||
var mi := MeshInstance3D.new()
|
var mi := MeshInstance3D.new()
|
||||||
var m := BoxMesh.new()
|
var m := BoxMesh.new()
|
||||||
m.size = Vector3(0.5, 0.5, 0.25)
|
m.size = Vector3(0.8, 0.8, 0.15)
|
||||||
mi.mesh = m
|
mi.mesh = m
|
||||||
var mat := StandardMaterial3D.new()
|
var mat := StandardMaterial3D.new()
|
||||||
mat.albedo_color = Color(0.1, 0.1, 0.12)
|
mat.albedo_color = Color(0.2, 0.2, 0.24)
|
||||||
mi.material_override = mat
|
mi.material_override = mat
|
||||||
add_child(mi)
|
add_child(mi)
|
||||||
|
var ring := MeshInstance3D.new()
|
||||||
|
var t := TorusMesh.new()
|
||||||
|
t.inner_radius = 0.16
|
||||||
|
t.outer_radius = 0.26
|
||||||
|
ring.mesh = t
|
||||||
|
ring.rotation.x = PI / 2.0
|
||||||
|
ring.position.z = -0.1
|
||||||
|
var rmat := StandardMaterial3D.new()
|
||||||
|
rmat.albedo_color = Color(0.95, 0.55, 0.1)
|
||||||
|
rmat.emission_enabled = true
|
||||||
|
rmat.emission = Color(0.95, 0.55, 0.1)
|
||||||
|
rmat.emission_energy_multiplier = 1.4
|
||||||
|
ring.material_override = rmat
|
||||||
|
add_child(ring)
|
||||||
|
|
||||||
func interact(droid: Node3D) -> void:
|
func interact(droid: Node3D) -> void:
|
||||||
if filled:
|
if filled:
|
||||||
@ -137,7 +160,7 @@ class Socket extends Node3D:
|
|||||||
m.height = 0.12
|
m.height = 0.12
|
||||||
mi.mesh = m
|
mi.mesh = m
|
||||||
mi.rotation.x = PI / 2.0
|
mi.rotation.x = PI / 2.0
|
||||||
mi.position.z = 0.18
|
mi.position.z = -0.18
|
||||||
add_child(mi)
|
add_child(mi)
|
||||||
door.open()
|
door.open()
|
||||||
droid.toast("WHEEL DONATED. DOOR BUS COMPLETE. MOBILITY REDUCED.")
|
droid.toast("WHEEL DONATED. DOOR BUS COMPLETE. MOBILITY REDUCED.")
|
||||||
@ -161,6 +184,9 @@ class Tank extends Node3D:
|
|||||||
mi.position.y = 0.6
|
mi.position.y = 0.6
|
||||||
var mat := StandardMaterial3D.new()
|
var mat := StandardMaterial3D.new()
|
||||||
mat.albedo_color = Color(0.2, 0.3, 0.45)
|
mat.albedo_color = Color(0.2, 0.3, 0.45)
|
||||||
|
mat.emission_enabled = true
|
||||||
|
mat.emission = Color(0.2, 0.4, 0.7)
|
||||||
|
mat.emission_energy_multiplier = 0.5
|
||||||
mi.material_override = mat
|
mi.material_override = mat
|
||||||
add_child(mi)
|
add_child(mi)
|
||||||
|
|
||||||
@ -192,6 +218,9 @@ class Plate extends Node3D:
|
|||||||
mi.mesh = m
|
mi.mesh = m
|
||||||
var mat := StandardMaterial3D.new()
|
var mat := StandardMaterial3D.new()
|
||||||
mat.albedo_color = Color(0.6, 0.55, 0.2)
|
mat.albedo_color = Color(0.6, 0.55, 0.2)
|
||||||
|
mat.emission_enabled = true
|
||||||
|
mat.emission = Color(0.8, 0.7, 0.2)
|
||||||
|
mat.emission_energy_multiplier = 0.6
|
||||||
mi.material_override = mat
|
mi.material_override = mat
|
||||||
add_child(mi)
|
add_child(mi)
|
||||||
|
|
||||||
|
|||||||
165
src/main.gd
165
src/main.gd
@ -29,6 +29,7 @@ var sun_light: DirectionalLight3D
|
|||||||
|
|
||||||
var drum: Node3D
|
var drum: Node3D
|
||||||
var drum_turned := false
|
var drum_turned := false
|
||||||
|
var _marker: Label3D
|
||||||
|
|
||||||
var t_sol := 10.0 # start mid-day
|
var t_sol := 10.0 # start mid-day
|
||||||
var is_day := true
|
var is_day := true
|
||||||
@ -45,6 +46,28 @@ func _ready() -> void:
|
|||||||
_build_objects()
|
_build_objects()
|
||||||
_build_droid()
|
_build_droid()
|
||||||
_build_hud()
|
_build_hud()
|
||||||
|
if "--shot" in OS.get_cmdline_user_args():
|
||||||
|
_photo_tour()
|
||||||
|
|
||||||
|
|
||||||
|
func _photo_tour() -> void:
|
||||||
|
var spots := [
|
||||||
|
[Vector3(0, 0.2, 2), PI], # spawn, facing door1
|
||||||
|
[Vector3(1.4, 0.2, 6.2), PI], # socket close-up
|
||||||
|
[Vector3(0, 0.2, 9), PI], # segment B: post + bus gap
|
||||||
|
[Vector3(-0.5, 0.2, 17.5), PI], # segment C: drum bay + puddle
|
||||||
|
[Vector3(-1.5, 0.2, 27), PI], # segment D: valve + tank
|
||||||
|
[Vector3(0, 0.2, 35), PI], # segment E: skylight + solar
|
||||||
|
]
|
||||||
|
for i in spots.size():
|
||||||
|
droid.global_position = spots[i][0]
|
||||||
|
droid.rotation.y = spots[i][1]
|
||||||
|
for f in 20:
|
||||||
|
await get_tree().process_frame
|
||||||
|
await RenderingServer.frame_post_draw
|
||||||
|
var img := get_viewport().get_texture().get_image()
|
||||||
|
img.save_png("/tmp/exposure_shot_%d.png" % i)
|
||||||
|
get_tree().quit()
|
||||||
|
|
||||||
|
|
||||||
# ---------- input ----------
|
# ---------- input ----------
|
||||||
@ -65,6 +88,20 @@ func _init_input() -> void:
|
|||||||
|
|
||||||
# ---------- construction helpers ----------
|
# ---------- construction helpers ----------
|
||||||
|
|
||||||
|
var _grid_tex: ImageTexture
|
||||||
|
|
||||||
|
|
||||||
|
func grid_tex() -> ImageTexture:
|
||||||
|
if not _grid_tex:
|
||||||
|
var img := Image.create(64, 64, false, Image.FORMAT_RGB8)
|
||||||
|
for y in 64:
|
||||||
|
for x in 64:
|
||||||
|
var line := x % 16 == 0 or y % 16 == 0
|
||||||
|
img.set_pixel(x, y, Color(0.5, 0.5, 0.5) if line else Color(0.92, 0.92, 0.92))
|
||||||
|
_grid_tex = ImageTexture.create_from_image(img)
|
||||||
|
return _grid_tex
|
||||||
|
|
||||||
|
|
||||||
func mat(col: Color) -> StandardMaterial3D:
|
func mat(col: Color) -> StandardMaterial3D:
|
||||||
if not _mats.has(col):
|
if not _mats.has(col):
|
||||||
var m := StandardMaterial3D.new()
|
var m := StandardMaterial3D.new()
|
||||||
@ -73,12 +110,36 @@ func mat(col: Color) -> StandardMaterial3D:
|
|||||||
return _mats[col]
|
return _mats[col]
|
||||||
|
|
||||||
|
|
||||||
func box(pos: Vector3, size: Vector3, col: Color, parent: Node3D = null) -> CSGBox3D:
|
func struct_mat(col: Color) -> StandardMaterial3D:
|
||||||
|
var key := "g" + str(col)
|
||||||
|
if not _mats.has(key):
|
||||||
|
var m := StandardMaterial3D.new()
|
||||||
|
m.albedo_color = col
|
||||||
|
m.albedo_texture = grid_tex()
|
||||||
|
m.uv1_triplanar = true
|
||||||
|
m.uv1_scale = Vector3(0.25, 0.25, 0.25) # 1m grid cells
|
||||||
|
_mats[key] = m
|
||||||
|
return _mats[key]
|
||||||
|
|
||||||
|
|
||||||
|
func glow(col: Color, energy := 0.7) -> StandardMaterial3D:
|
||||||
|
var key := "e" + str(col) + str(energy)
|
||||||
|
if not _mats.has(key):
|
||||||
|
var m := StandardMaterial3D.new()
|
||||||
|
m.albedo_color = col
|
||||||
|
m.emission_enabled = true
|
||||||
|
m.emission = col
|
||||||
|
m.emission_energy_multiplier = energy
|
||||||
|
_mats[key] = m
|
||||||
|
return _mats[key]
|
||||||
|
|
||||||
|
|
||||||
|
func box(pos: Vector3, size: Vector3, col: Color, parent: Node3D = null, grid := false) -> CSGBox3D:
|
||||||
var b := CSGBox3D.new()
|
var b := CSGBox3D.new()
|
||||||
b.size = size
|
b.size = size
|
||||||
b.position = pos
|
b.position = pos
|
||||||
b.use_collision = true
|
b.use_collision = true
|
||||||
b.material = mat(col)
|
b.material = struct_mat(col) if grid else mat(col)
|
||||||
(parent if parent else self).add_child(b)
|
(parent if parent else self).add_child(b)
|
||||||
return b
|
return b
|
||||||
|
|
||||||
@ -95,10 +156,10 @@ func sign3d(text: String, pos: Vector3, rot_y := PI, size := 30, col := Color(0.
|
|||||||
|
|
||||||
|
|
||||||
func divider(z: float) -> void:
|
func divider(z: float) -> void:
|
||||||
var c := Color(0.3, 0.3, 0.34)
|
var c := Color(0.45, 0.46, 0.52)
|
||||||
box(Vector3(-2.6, 2, z), Vector3(2.8, 4, 0.3), c)
|
box(Vector3(-2.6, 2, z), Vector3(2.8, 4, 0.3), c, null, true)
|
||||||
box(Vector3(2.6, 2, z), Vector3(2.8, 4, 0.3), c)
|
box(Vector3(2.6, 2, z), Vector3(2.8, 4, 0.3), c, null, true)
|
||||||
box(Vector3(0, 3.5, z), Vector3(2.4, 1, 0.3), c)
|
box(Vector3(0, 3.5, z), Vector3(2.4, 1, 0.3), c, null, true)
|
||||||
|
|
||||||
|
|
||||||
func make_door(z: float) -> Node3D:
|
func make_door(z: float) -> Node3D:
|
||||||
@ -133,35 +194,50 @@ func _build_env() -> void:
|
|||||||
sun_light.light_energy = 1.2
|
sun_light.light_energy = 1.2
|
||||||
add_child(sun_light)
|
add_child(sun_light)
|
||||||
|
|
||||||
|
# corridor lighting — segments feel lit, not fog-grey
|
||||||
|
for z in [4.0, 12.0, 18.5, 24.0, 30.0, 37.0, 42.5]:
|
||||||
|
var o := OmniLight3D.new()
|
||||||
|
o.position = Vector3(0, 3.4, z)
|
||||||
|
o.omni_range = 10.0
|
||||||
|
o.light_energy = 1.1
|
||||||
|
o.light_color = Color(1.0, 0.96, 0.88)
|
||||||
|
add_child(o)
|
||||||
|
for p in [Vector3(8, 6.5, 22), Vector3(6.4, 3.2, 25.8), Vector3(-5.0, 3.0, 24)]:
|
||||||
|
var o := OmniLight3D.new()
|
||||||
|
o.position = p
|
||||||
|
o.omni_range = 8.0
|
||||||
|
o.light_energy = 1.0
|
||||||
|
add_child(o)
|
||||||
|
|
||||||
|
|
||||||
func _build_geometry() -> void:
|
func _build_geometry() -> void:
|
||||||
var wall := Color(0.28, 0.29, 0.33)
|
var wall := Color(0.5, 0.52, 0.58)
|
||||||
# floor
|
# floor
|
||||||
box(Vector3(3, -0.15, 22.5), Vector3(18.6, 0.3, 46), Color(0.36, 0.36, 0.38))
|
box(Vector3(3, -0.15, 22.5), Vector3(18.6, 0.3, 46), Color(0.62, 0.62, 0.65), null, true)
|
||||||
# left wall x=-4.15, niche gap z 23.4..24.6
|
# left wall x=-4.15, niche gap z 23.4..24.6
|
||||||
box(Vector3(-4.15, 2, 11.45), Vector3(0.3, 4, 23.9), wall)
|
box(Vector3(-4.15, 2, 11.45), Vector3(0.3, 4, 23.9), wall, null, true)
|
||||||
box(Vector3(-4.15, 2, 33.55), Vector3(0.3, 4, 17.9), wall)
|
box(Vector3(-4.15, 2, 33.55), Vector3(0.3, 4, 17.9), wall, null, true)
|
||||||
# relay niche (behind left wall) + bars
|
# relay niche (behind left wall) + bars
|
||||||
box(Vector3(-5.8, 2, 24), Vector3(0.3, 4, 1.6), wall)
|
box(Vector3(-5.8, 2, 24), Vector3(0.3, 4, 1.6), wall, null, true)
|
||||||
box(Vector3(-5.0, 2, 23.4), Vector3(1.6, 4, 0.3), wall)
|
box(Vector3(-5.0, 2, 23.4), Vector3(1.6, 4, 0.3), wall, null, true)
|
||||||
box(Vector3(-5.0, 2, 24.6), Vector3(1.6, 4, 0.3), wall)
|
box(Vector3(-5.0, 2, 24.6), Vector3(1.6, 4, 0.3), wall, null, true)
|
||||||
box(Vector3(-4.15, 1, 23.8), Vector3(0.1, 2, 0.1), Color(0.15, 0.15, 0.15))
|
box(Vector3(-4.15, 1, 23.8), Vector3(0.1, 2, 0.1), Color(0.15, 0.15, 0.15))
|
||||||
box(Vector3(-4.15, 1, 24.2), Vector3(0.1, 2, 0.1), Color(0.15, 0.15, 0.15))
|
box(Vector3(-4.15, 1, 24.2), Vector3(0.1, 2, 0.1), Color(0.15, 0.15, 0.15))
|
||||||
# right wall x=4.15: gaps for drum bay (z 20..24) and bonus bay (z 25..26.6)
|
# right wall x=4.15: gaps for drum bay (z 20..24) and bonus bay (z 25..26.6)
|
||||||
box(Vector3(4.15, 2, 9.75), Vector3(0.3, 4, 20.5), wall)
|
box(Vector3(4.15, 2, 9.75), Vector3(0.3, 4, 20.5), wall, null, true)
|
||||||
box(Vector3(4.15, 2, 24.5), Vector3(0.3, 4, 1.0), wall)
|
box(Vector3(4.15, 2, 24.5), Vector3(0.3, 4, 1.0), wall, null, true)
|
||||||
box(Vector3(4.15, 2, 34.55), Vector3(0.3, 4, 15.9), wall)
|
box(Vector3(4.15, 2, 34.55), Vector3(0.3, 4, 15.9), wall, null, true)
|
||||||
# bonus bay shell
|
# bonus bay shell
|
||||||
box(Vector3(8.65, 2, 25.8), Vector3(0.3, 4, 3.0), wall)
|
box(Vector3(8.65, 2, 25.8), Vector3(0.3, 4, 3.0), wall, null, true)
|
||||||
box(Vector3(6.4, 2, 24.9), Vector3(4.4, 4, 0.3), wall)
|
box(Vector3(6.4, 2, 24.9), Vector3(4.4, 4, 0.3), wall, null, true)
|
||||||
box(Vector3(6.4, 2, 26.7), Vector3(4.4, 4, 0.3), wall)
|
box(Vector3(6.4, 2, 26.7), Vector3(4.4, 4, 0.3), wall, null, true)
|
||||||
# drum bay outer shell
|
# drum bay outer shell
|
||||||
box(Vector3(12.15, 3.5, 22), Vector3(0.3, 8, 6), wall)
|
box(Vector3(12.15, 3.5, 22), Vector3(0.3, 8, 6), wall, null, true)
|
||||||
box(Vector3(8, 3.5, 19.3), Vector3(8, 8, 0.3), wall)
|
box(Vector3(8, 3.5, 19.3), Vector3(8, 8, 0.3), wall, null, true)
|
||||||
box(Vector3(8, 3.5, 24.7), Vector3(8, 8, 0.3), wall)
|
box(Vector3(8, 3.5, 24.7), Vector3(8, 8, 0.3), wall, null, true)
|
||||||
# end walls
|
# end walls
|
||||||
box(Vector3(0, 2, -0.5), Vector3(8.6, 4, 0.3), wall)
|
box(Vector3(0, 2, -0.5), Vector3(8.6, 4, 0.3), wall, null, true)
|
||||||
box(Vector3(0, 2, 44.5), Vector3(8.6, 4, 0.3), wall)
|
box(Vector3(0, 2, 44.5), Vector3(8.6, 4, 0.3), wall, null, true)
|
||||||
# dividers + doors
|
# dividers + doors
|
||||||
for z in [8.0, 16.0, 26.0, 34.0, 40.0]:
|
for z in [8.0, 16.0, 26.0, 34.0, 40.0]:
|
||||||
divider(z)
|
divider(z)
|
||||||
@ -189,14 +265,14 @@ func _build_objects() -> void:
|
|||||||
Vector3(-2.0, 2.2, 4.0), PI, 22, Color(1.0, 0.75, 0.3))
|
Vector3(-2.0, 2.2, 4.0), PI, 22, Color(1.0, 0.75, 0.3))
|
||||||
|
|
||||||
# --- segment B: charge post + be-the-wire gap ---
|
# --- segment B: charge post + be-the-wire gap ---
|
||||||
box(Vector3(-2.5, 0.9, 10.5), Vector3(0.5, 1.8, 0.5), Color(0.2, 0.5, 0.6))
|
box(Vector3(-2.5, 0.9, 10.5), Vector3(0.5, 1.8, 0.5), Color(0.2, 0.5, 0.6)).material = glow(Color(0.15, 0.7, 0.85))
|
||||||
var post1 := ElementField.make("electricity", 1.3, Color(0.3, 1.0, 1.0, 0.12))
|
var post1 := ElementField.make("electricity", 1.3, Color(0.3, 1.0, 1.0, 0.12))
|
||||||
post1.position = Vector3(-2.5, 0.9, 10.5)
|
post1.position = Vector3(-2.5, 0.9, 10.5)
|
||||||
add_child(post1)
|
add_child(post1)
|
||||||
sign3d("CHARGE POST", Vector3(-2.5, 2.3, 10.2))
|
sign3d("CHARGE POST", Vector3(-2.5, 2.3, 10.2))
|
||||||
|
|
||||||
for x in [-1.0, 1.0]:
|
for x in [-1.0, 1.0]:
|
||||||
box(Vector3(x, 1.0, 15.3), Vector3(0.25, 2.0, 0.25), Color(0.55, 0.55, 0.6))
|
box(Vector3(x, 1.0, 15.3), Vector3(0.25, 2.0, 0.25), Color(0.55, 0.55, 0.6)).material = glow(Color(0.8, 0.8, 0.5), 0.5)
|
||||||
var contact_trans := [{"from": "idle", "to": "hot", "element": "electricity",
|
var contact_trans := [{"from": "idle", "to": "hot", "element": "electricity",
|
||||||
"duration": 0.15, "decay_to": "idle", "decay_s": 0.6}]
|
"duration": 0.15, "decay_to": "idle", "decay_s": 0.6}]
|
||||||
contact_a = make_exposable("BUS CONTACT A", "idle", contact_trans.duplicate(true), Vector3(-1.0, 1.0, 15.3))
|
contact_a = make_exposable("BUS CONTACT A", "idle", contact_trans.duplicate(true), Vector3(-1.0, 1.0, 15.3))
|
||||||
@ -211,7 +287,7 @@ func _build_objects() -> void:
|
|||||||
sign3d("SPARE MOBILITY UNIT — GC CAT. 6601-W", Vector3(2.5, 1.4, 17.8))
|
sign3d("SPARE MOBILITY UNIT — GC CAT. 6601-W", Vector3(2.5, 1.4, 17.8))
|
||||||
|
|
||||||
# --- segment C: post 2, drum bay, puddle + relay ---
|
# --- segment C: post 2, drum bay, puddle + relay ---
|
||||||
box(Vector3(-2.8, 0.9, 20.5), Vector3(0.5, 1.8, 0.5), Color(0.2, 0.5, 0.6))
|
box(Vector3(-2.8, 0.9, 20.5), Vector3(0.5, 1.8, 0.5), Color(0.2, 0.5, 0.6)).material = glow(Color(0.15, 0.7, 0.85))
|
||||||
var post2 := ElementField.make("electricity", 1.3, Color(0.3, 1.0, 1.0, 0.12))
|
var post2 := ElementField.make("electricity", 1.3, Color(0.3, 1.0, 1.0, 0.12))
|
||||||
post2.position = Vector3(-2.8, 0.9, 20.5)
|
post2.position = Vector3(-2.8, 0.9, 20.5)
|
||||||
add_child(post2)
|
add_child(post2)
|
||||||
@ -236,7 +312,7 @@ func _build_objects() -> void:
|
|||||||
crate.position = Vector3(-2.6, 2.65, 0)
|
crate.position = Vector3(-2.6, 2.65, 0)
|
||||||
drum.add_child(crate)
|
drum.add_child(crate)
|
||||||
|
|
||||||
box(Vector3(3.7, 0.7, 18.6), Vector3(0.3, 1.4, 0.3), Color(0.5, 0.4, 0.2))
|
box(Vector3(3.7, 0.7, 18.6), Vector3(0.3, 1.4, 0.3), Color(0.5, 0.4, 0.2)).material = glow(Color(0.9, 0.6, 0.15), 0.5)
|
||||||
drum_switch = make_exposable("DRUM MOTOR BUS", "idle",
|
drum_switch = make_exposable("DRUM MOTOR BUS", "idle",
|
||||||
[{"from": "idle", "to": "active", "element": "electricity",
|
[{"from": "idle", "to": "active", "element": "electricity",
|
||||||
"duration": 0.8, "permanent": true}],
|
"duration": 0.8, "permanent": true}],
|
||||||
@ -261,7 +337,7 @@ func _build_objects() -> void:
|
|||||||
puddle_live.enabled = false
|
puddle_live.enabled = false
|
||||||
add_child(puddle_live)
|
add_child(puddle_live)
|
||||||
|
|
||||||
box(Vector3(-5.0, 1.0, 24), Vector3(0.4, 0.4, 0.4), Color(0.6, 0.3, 0.3))
|
box(Vector3(-5.0, 1.0, 24), Vector3(0.4, 0.4, 0.4), Color(0.6, 0.3, 0.3)).material = glow(Color(0.9, 0.25, 0.2), 0.6)
|
||||||
relay = make_exposable("SLUICE RELAY", "open",
|
relay = make_exposable("SLUICE RELAY", "open",
|
||||||
[{"from": "open", "to": "tripped", "element": "electricity",
|
[{"from": "open", "to": "tripped", "element": "electricity",
|
||||||
"duration": 1.0, "permanent": true}],
|
"duration": 1.0, "permanent": true}],
|
||||||
@ -287,8 +363,8 @@ func _build_objects() -> void:
|
|||||||
Vector3(7.2, 2.0, 25.8), PI / 2.0, 24, Color(1.0, 0.75, 0.3))
|
Vector3(7.2, 2.0, 25.8), PI / 2.0, 24, Color(1.0, 0.75, 0.3))
|
||||||
|
|
||||||
# --- segment D: valve, bucket, tank ---
|
# --- segment D: valve, bucket, tank ---
|
||||||
box(Vector3(-3.8, 1.4, 28), Vector3(0.5, 0.5, 0.5), Color(0.3, 0.5, 0.7))
|
box(Vector3(-3.8, 1.4, 28), Vector3(0.5, 0.5, 0.5), Color(0.3, 0.5, 0.7)).material = glow(Color(0.25, 0.5, 0.9), 0.5)
|
||||||
box(Vector3(-3.4, 0.9, 28), Vector3(0.12, 1.6, 0.12), Color(0.3, 0.5, 0.9)) # stream
|
box(Vector3(-3.4, 0.9, 28), Vector3(0.12, 1.6, 0.12), Color(0.3, 0.5, 0.9)).material = glow(Color(0.3, 0.55, 1.0), 0.9) # stream
|
||||||
var valve := ElementField.make("water", 1.3, Color(0.2, 0.4, 1.0, 0.10))
|
var valve := ElementField.make("water", 1.3, Color(0.2, 0.4, 1.0, 0.10))
|
||||||
valve.position = Vector3(-3.3, 0.8, 28)
|
valve.position = Vector3(-3.3, 0.8, 28)
|
||||||
add_child(valve)
|
add_child(valve)
|
||||||
@ -310,6 +386,7 @@ func _build_objects() -> void:
|
|||||||
sun_field.position = Vector3(0, 2.2, 37)
|
sun_field.position = Vector3(0, 2.2, 37)
|
||||||
add_child(sun_field)
|
add_child(sun_field)
|
||||||
var panel := box(Vector3(1.5, 1.5, 37.3), Vector3(1.2, 0.8, 0.1), Color(0.1, 0.15, 0.4))
|
var panel := box(Vector3(1.5, 1.5, 37.3), Vector3(1.2, 0.8, 0.1), Color(0.1, 0.15, 0.4))
|
||||||
|
panel.material = glow(Color(0.15, 0.25, 0.7), 0.5)
|
||||||
panel.rotation.x = -0.5
|
panel.rotation.x = -0.5
|
||||||
solar = make_exposable("SOLAR CELL", "unpowered",
|
solar = make_exposable("SOLAR CELL", "unpowered",
|
||||||
[{"from": "unpowered", "to": "powered", "element": "light",
|
[{"from": "unpowered", "to": "powered", "element": "light",
|
||||||
@ -354,6 +431,15 @@ func _build_hud() -> void:
|
|||||||
cross.add_theme_color_override("font_color", Color(0.55, 1.0, 0.6, 0.7))
|
cross.add_theme_color_override("font_color", Color(0.55, 1.0, 0.6, 0.7))
|
||||||
cl.add_child(cross)
|
cl.add_child(cross)
|
||||||
|
|
||||||
|
_marker = Label3D.new()
|
||||||
|
_marker.text = "▼"
|
||||||
|
_marker.font_size = 72
|
||||||
|
_marker.modulate = Color(0.55, 1.0, 0.6)
|
||||||
|
_marker.billboard = BaseMaterial3D.BILLBOARD_ENABLED
|
||||||
|
_marker.no_depth_test = true
|
||||||
|
_marker.visible = false
|
||||||
|
add_child(_marker)
|
||||||
|
|
||||||
|
|
||||||
# ---------- rules ----------
|
# ---------- rules ----------
|
||||||
|
|
||||||
@ -425,12 +511,25 @@ func _process(_delta: float) -> void:
|
|||||||
holding += " [%s%s]" % [ex.state.to_upper(),
|
holding += " [%s%s]" % [ex.state.to_upper(),
|
||||||
" %ds" % ceil(ex.decay_remaining()) if ex.decay_remaining() > 0 else ""]
|
" %ds" % ceil(ex.decay_remaining()) if ex.decay_remaining() > 0 else ""]
|
||||||
|
|
||||||
|
var obj := "WALK OUT THE EXIT."
|
||||||
|
if not door1.is_open:
|
||||||
|
obj = "DOOR 1 BUS IS MISSING A COMPONENT. YOU ARE MADE OF COMPONENTS."
|
||||||
|
elif not door2.is_open:
|
||||||
|
obj = "BUS GAP AHEAD — GET CHARGED AT THE POST, STAND IN THE GAP."
|
||||||
|
elif not door3.is_open:
|
||||||
|
obj = "SEALED BAY — RELAY IS BEHIND THE BARS. READ THE CAUTION SIGN. DISOBEY IT."
|
||||||
|
elif not door4.is_open:
|
||||||
|
obj = "GRAV TANK NEEDS 2 POURS. THE BUCKET LEAKS. HUSTLE."
|
||||||
|
elif not won:
|
||||||
|
obj = "EXIT RUNS ON SUNLIGHT. CHECK THE SOL CLOCK."
|
||||||
|
|
||||||
var lines := [
|
var lines := [
|
||||||
"GENERAL COMPONENT™ — UNIT-77 — MISSION: RESTORE ASSET. RETURN ASSET.",
|
"GENERAL COMPONENT™ — UNIT-77 — MISSION: RESTORE ASSET. RETURN ASSET.",
|
||||||
"SOL: %s%s" % [sol, " ★ ROOM RESTORED — PHASE 0 COMPLETE" if won else ""],
|
"SOL: %s%s" % [sol, " ★ ROOM RESTORED — PHASE 0 COMPLETE" if won else ""],
|
||||||
"SHELL: %s | CORE: %s | WHEELS: %d | SPARES: %d | PORT 00: NO COMPONENT SPECIFIED"
|
"SHELL: %s | CORE: %s | WHEELS: %d | SPARES: %d | PORT 00: NO COMPONENT SPECIFIED"
|
||||||
% [shell_s, core_s, droid.wheels, droid.spare_wheels],
|
% [shell_s, core_s, droid.wheels, droid.spare_wheels],
|
||||||
"HOLDING: %s" % holding,
|
"HOLDING: %s" % holding,
|
||||||
|
"OBJECTIVE: %s" % obj,
|
||||||
]
|
]
|
||||||
|
|
||||||
var scan := droid.best_target(["exposable"], 8.0, 0.93)
|
var scan := droid.best_target(["exposable"], 8.0, 0.93)
|
||||||
@ -445,6 +544,10 @@ func _process(_delta: float) -> void:
|
|||||||
var target := droid.best_target(["interactable"], 3.0, 0.7)
|
var target := droid.best_target(["interactable"], 3.0, 0.7)
|
||||||
if target:
|
if target:
|
||||||
lines.append("[E] %s" % target.get("prompt_text"))
|
lines.append("[E] %s" % target.get("prompt_text"))
|
||||||
|
_marker.visible = true
|
||||||
|
_marker.global_position = target.global_position + Vector3(0, 1.1 + 0.12 * sin(t_sol * 5.0), 0)
|
||||||
|
else:
|
||||||
|
_marker.visible = false
|
||||||
if droid.stun > 0:
|
if droid.stun > 0:
|
||||||
lines.append(">>> REBOOTING <<<")
|
lines.append(">>> REBOOTING <<<")
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user