ludic/packages/ludic.effects/system.ludic
Orkuncakilkaya d0ad364ad4 feat(ludic.effects): timed modifiers as a mechanic package; ludic.base's q_new is queue_new
ludic.effects: effects_add / effects_add_after / effects_clear / effects_run,
effects_sum / effects_has / effects_at / effects_live, an EffectEnded queue
(ran out, pushed out by the bonus cap, crowded out of a full ring) and a
System with its own save section. Nine test blocks in tests/effects_test.ludic.

ludic.base: q_new collided with render3d's quaternion q_new the moment a game
imported both, so the queue constructor is queue_new.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 04:14:09 +03:00

52 lines
1.4 KiB
Text

# system.ludic - the effects as a system: reset, a tick in game hours, and its own save section
export function effects_reset() -> void {
effects_clear()
q_clear(effects_ended())
}
function effects_tick(t: Tick) -> void { effects_run(t.hours * 60.0) }
export function effects_save() -> Val {
let l = Value.list()
let all = ef_all()
for i in 0 .. len(all) {
let o = Value.object()
sv_put_int(o, "k", all[i].kind)
sv_put_float(o, "m", all[i].mag)
sv_put_float(o, "t", all[i].left)
sv_put_float(o, "d", all[i].delay)
sv_put_bool(o, "b", all[i].bonus)
sv_put_str(o, "l", all[i].label)
Value.add(l, o)
}
let v = Value.object()
Value.put(v, "list", l)
return v
}
export function effects_load(v: Val, version: int) -> void {
effects_clear()
if Value.has(v, "list") == 0 { return }
let l = Value.get(v, "list")
for i in 0 .. Value.count(l) {
if len(ef_all()) >= ef_max { break }
let o = Value.at(l, i)
let e = new Effect
e.kind = sv_int(o, "k", 0)
e.mag = sv_float(o, "m", 0.0)
e.left = sv_float(o, "t", 0.0)
e.delay = sv_float(o, "d", 0.0)
e.bonus = sv_bool(o, "b", false)
e.label = sv_str(o, "l", "")
push(ef_all(), e)
}
}
export function effects_system() -> System {
let s = system_new("effects", PH_SIMULATE)
s.reset = fn effects_reset
s.tick = fn effects_tick
s.save = fn effects_save
s.load = fn effects_load
return s
}