Lights to place indoors (tallow candle, torch stand); docs brought up to date; the journey plan; sticky teleports in net tests; protocol 15
This commit is contained in:
64
scripts/building/lamp.gd
Normal file
64
scripts/building/lamp.gd
Normal file
@@ -0,0 +1,64 @@
|
||||
extends "res://scripts/building/piece.gd"
|
||||
## A light to place indoors (or anywhere): a tallow candle or a torch stand.
|
||||
## Always lit, no fuel. Its item's "lamp" says how: {"range", "energy",
|
||||
## "height" (of the flame), "flicker" (0 = steady), "color"}.
|
||||
## Flames are a small additive glow; the light itself is an OmniLight3D.
|
||||
|
||||
var _light: OmniLight3D
|
||||
var _flame: MeshInstance3D
|
||||
var _noise := FastNoiseLite.new()
|
||||
var _t := 0.0
|
||||
var _base := 1.0
|
||||
var _flicker := 0.0
|
||||
var _h := 0.5
|
||||
|
||||
func _build() -> void:
|
||||
add_to_group("lamp")
|
||||
var l: Dictionary = def.get("lamp", {})
|
||||
_base = float(l.get("energy", 1.0))
|
||||
_flicker = float(l.get("flicker", 0.2))
|
||||
_h = float(l.get("height", 0.5))
|
||||
_noise.seed = int(get_instance_id() % 1000)
|
||||
_noise.frequency = 2.0
|
||||
_t = randf() * 100.0
|
||||
_light = OmniLight3D.new()
|
||||
var c: Array = l.get("color", [1.0, 0.7, 0.4])
|
||||
_light.light_color = Color(c[0], c[1], c[2])
|
||||
_light.light_energy = _base
|
||||
_light.omni_range = float(l.get("range", 6.0))
|
||||
_light.omni_attenuation = 1.3
|
||||
_light.shadow_enabled = bool(l.get("shadows", false))
|
||||
_light.position = Vector3(0, _h + 0.05, 0)
|
||||
add_child(_light)
|
||||
# The flame: a small glowing teardrop at the wick.
|
||||
var m := StandardMaterial3D.new()
|
||||
m.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
|
||||
m.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
|
||||
m.blend_mode = BaseMaterial3D.BLEND_MODE_ADD
|
||||
m.albedo_color = Color(1.0, 0.72, 0.32, 0.85)
|
||||
var s := SphereMesh.new()
|
||||
var fr := float(l.get("flame", 0.03))
|
||||
s.radius = fr
|
||||
s.height = fr * 3.2
|
||||
s.radial_segments = 8
|
||||
s.rings = 4
|
||||
s.material = m
|
||||
_flame = MeshInstance3D.new()
|
||||
_flame.mesh = s
|
||||
_flame.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
|
||||
_flame.position = Vector3(0, _h, 0)
|
||||
add_child(_flame)
|
||||
|
||||
func display_name() -> String:
|
||||
return String(def.get("name", "Light"))
|
||||
|
||||
func interact_prompt(_player: Node) -> String:
|
||||
return "%s (X to take it up)" % display_name()
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if _flicker <= 0.0 or _light == null:
|
||||
return
|
||||
_t += delta
|
||||
var f := _noise.get_noise_1d(_t * 9.0)
|
||||
_light.light_energy = _base * (1.0 + f * _flicker)
|
||||
_flame.scale = Vector3.ONE * (1.0 + f * _flicker * 0.8)
|
||||
Reference in New Issue
Block a user