wip(0.S3): the packages migrated by ludic migrate state packages - every package test green
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
1e8b5b0523
commit
07505e7ef2
294 changed files with 14996 additions and 14675 deletions
|
|
@ -1,25 +1,25 @@
|
|||
# buy.ludic - a tier bought with money once the standing is there; the kind's item follows
|
||||
export function gear_can_buy(k: int) -> bool {
|
||||
if not gear_ok(k) or gear_best(k) or GearWorld.hidden(k) { return false }
|
||||
return GearPurse.rep() >= gear_next_rep(k) and GearPurse.money() >= gear_next_cost(k)
|
||||
export function gear_can_buy(gear_st: mut GearState, k: int) -> bool {
|
||||
if not gear_ok(k) or gear_best(gear_st, k) or GearWorld.hidden(k) { return false }
|
||||
return GearPurse.rep() >= gear_next_rep(gear_st, k) and GearPurse.money() >= gear_next_cost(gear_st, k)
|
||||
}
|
||||
|
||||
export function gear_buy(k: int) -> bool {
|
||||
if not gear_can_buy(k) { return false }
|
||||
let cost = gear_next_cost(k)
|
||||
export function gear_buy(base_st: mut BaseState, gear_st: mut GearState, k: int) -> bool {
|
||||
if not gear_can_buy(gear_st, k) { return false }
|
||||
let cost = gear_next_cost(gear_st, k)
|
||||
if not GearPurse.spend(cost) { return false }
|
||||
gear__lv[k] += 1
|
||||
gear_st.gear__lv[k] += 1
|
||||
let it = GearKinds[k].item
|
||||
if it >= 0 and GearPack.count(it) == 0 { GearPack.add(it, 1) }
|
||||
gear__fact(GEAR_BOUGHT, k, -1, cost)
|
||||
gear__fact(base_st, gear_st, GEAR_BOUGHT, k, -1, cost)
|
||||
return true
|
||||
}
|
||||
|
||||
# a kind whose item is already carried counts as its first tier
|
||||
export function gear_sync() -> void {
|
||||
gear__ensure()
|
||||
export function gear_sync(gear_st: mut GearState) -> void {
|
||||
gear__ensure(gear_st)
|
||||
for k in 0 .. GEAR_COUNT {
|
||||
let it = GearKinds[k].item
|
||||
if it >= 0 and gear__lv[k] == 0 and GearPack.count(it) > 0 { gear__lv[k] = 1 }
|
||||
if it >= 0 and gear_st.gear__lv[k] == 0 and GearPack.count(it) > 0 { gear_st.gear__lv[k] = 1 }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
# hand.ludic - what is held, and the charges: a held one runs only while it is in the hand, and
|
||||
# each burns down by the game hours while it runs
|
||||
export function gear_hand() -> int { return gear__hand }
|
||||
export function gear_hand(gear_st: GearState) -> int { return gear_st.gear__hand }
|
||||
|
||||
# a new thing in the hand (-1 empty): whatever the old one was running goes out
|
||||
export function gear_set_hand(it: int) -> void {
|
||||
gear__ensure()
|
||||
gear__hand = it
|
||||
for c in 0 .. CHARGE_COUNT { if GearCharges[c].hand { gear__on[c] = false } }
|
||||
export function gear_set_hand(gear_st: mut GearState, it: int) -> void {
|
||||
gear__ensure(gear_st)
|
||||
gear_st.gear__hand = it
|
||||
for c in 0 .. CHARGE_COUNT { if GearCharges[c].hand { gear_st.gear__on[c] = false } }
|
||||
}
|
||||
|
||||
# the charge an item carries, -1 none
|
||||
|
|
@ -15,58 +15,58 @@ export function gear_charge_of(it: int) -> int {
|
|||
return -1
|
||||
}
|
||||
|
||||
export function gear_charge(c: int) -> float {
|
||||
gear__ensure()
|
||||
return gear__left[c]
|
||||
export function gear_charge(gear_st: mut GearState, c: int) -> float {
|
||||
gear__ensure(gear_st)
|
||||
return gear_st.gear__left[c]
|
||||
}
|
||||
|
||||
export function gear_charge_set(c: int, v: float) -> void {
|
||||
gear__ensure()
|
||||
gear__left[c] = Math.clamp(v, 0.0, GearCharges[c].full)
|
||||
export function gear_charge_set(gear_st: mut GearState, c: int, v: float) -> void {
|
||||
gear__ensure(gear_st)
|
||||
gear_st.gear__left[c] = Math.clamp(v, 0.0, GearCharges[c].full)
|
||||
}
|
||||
|
||||
export function gear_charge_fill(c: int) -> void { gear_charge_set(c, GearCharges[c].full) }
|
||||
export function gear_charge_fill(gear_st: mut GearState, c: int) -> void { gear_charge_set(gear_st, c, GearCharges[c].full) }
|
||||
|
||||
export function gear_running(c: int) -> bool {
|
||||
gear__ensure()
|
||||
return gear__on[c]
|
||||
export function gear_running(gear_st: mut GearState, c: int) -> bool {
|
||||
gear__ensure(gear_st)
|
||||
return gear_st.gear__on[c]
|
||||
}
|
||||
|
||||
# on or off; false when it has nothing left, or is held and not in the hand
|
||||
export function gear_run(c: int, on: bool) -> bool {
|
||||
gear__ensure()
|
||||
export function gear_run(gear_st: mut GearState, c: int, on: bool) -> bool {
|
||||
gear__ensure(gear_st)
|
||||
if not on {
|
||||
gear__on[c] = false
|
||||
gear_st.gear__on[c] = false
|
||||
return true
|
||||
}
|
||||
if gear__left[c] < 1.0 { return false }
|
||||
if GearCharges[c].hand and GearCharges[c].item != gear__hand { return false }
|
||||
gear__on[c] = true
|
||||
if gear_st.gear__left[c] < 1.0 { return false }
|
||||
if GearCharges[c].hand and GearCharges[c].item != gear_st.gear__hand { return false }
|
||||
gear_st.gear__on[c] = true
|
||||
return true
|
||||
}
|
||||
|
||||
# the hand's own charge is running (a torch lit, a flashlight on)
|
||||
export function gear_lit() -> bool {
|
||||
if gear__hand < 0 { return false }
|
||||
let c = gear_charge_of(gear__hand)
|
||||
return c >= 0 and GearCharges[c].hand and gear_running(c)
|
||||
export function gear_lit(gear_st: mut GearState) -> bool {
|
||||
if gear_st.gear__hand < 0 { return false }
|
||||
let c = gear_charge_of(gear_st.gear__hand)
|
||||
return c >= 0 and GearCharges[c].hand and gear_running(gear_st, c)
|
||||
}
|
||||
|
||||
function gear__rate(c: int) -> float {
|
||||
function gear__rate(gear_st: mut GearState, c: int) -> float {
|
||||
let d = GearCharges[c]
|
||||
if d.rate >= 0 { return gear_value(d.rate) }
|
||||
if d.rate >= 0 { return gear_value(gear_st, d.rate) }
|
||||
return d.per_hour
|
||||
}
|
||||
|
||||
# the game hours of a tick burn every running charge; one that runs out stops and says so
|
||||
function gear__burn(hours: float) -> void {
|
||||
gear__ensure()
|
||||
function gear__burn(base_st: mut BaseState, gear_st: mut GearState, hours: float) -> void {
|
||||
gear__ensure(gear_st)
|
||||
for c in 0 .. CHARGE_COUNT {
|
||||
if not gear__on[c] { continue }
|
||||
gear__left[c] = gear__left[c] - hours * gear__rate(c)
|
||||
if gear__left[c] > 0.0 { continue }
|
||||
gear__left[c] = 0.0
|
||||
gear__on[c] = false
|
||||
gear__fact(GEAR_RAN_OUT, -1, c, 0)
|
||||
if not gear_st.gear__on[c] { continue }
|
||||
gear_st.gear__left[c] = gear_st.gear__left[c] - hours * gear__rate(gear_st, c)
|
||||
if gear_st.gear__left[c] > 0.0 { continue }
|
||||
gear_st.gear__left[c] = 0.0
|
||||
gear_st.gear__on[c] = false
|
||||
gear__fact(base_st, gear_st, GEAR_RAN_OUT, -1, c, 0)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,37 +1,39 @@
|
|||
# state.ludic - the level of each kind, the hand, each charge's units and whether it runs, the facts
|
||||
var gear__lv: []int = null
|
||||
var gear__hand: int = -1
|
||||
var gear__left: []float = null
|
||||
var gear__on: []bool = null
|
||||
var gear__q: Queue<GearFact> = null
|
||||
export state GearState {
|
||||
gear__lv: []int = null
|
||||
gear__hand: int = -1
|
||||
gear__left: []float = null
|
||||
gear__on: []bool = null
|
||||
gear__q: Queue<GearFact> = null
|
||||
}
|
||||
|
||||
function gear__ensure() -> void {
|
||||
if gear__lv != null { return }
|
||||
gear__lv = new []int
|
||||
for k in 0 .. GEAR_COUNT { push(gear__lv, GearKinds[k].start) }
|
||||
gear__left = new []float
|
||||
gear__on = new []bool
|
||||
function gear__ensure(gear_st: mut GearState) -> void {
|
||||
if gear_st.gear__lv != null { return }
|
||||
gear_st.gear__lv = new []int
|
||||
for k in 0 .. GEAR_COUNT { push(gear_st.gear__lv, GearKinds[k].start) }
|
||||
gear_st.gear__left = new []float
|
||||
gear_st.gear__on = new []bool
|
||||
for c in 0 .. CHARGE_COUNT {
|
||||
push(gear__left, GearCharges[c].full)
|
||||
push(gear__on, false)
|
||||
push(gear_st.gear__left, GearCharges[c].full)
|
||||
push(gear_st.gear__on, false)
|
||||
}
|
||||
}
|
||||
|
||||
export function gear_facts() -> Queue<GearFact> {
|
||||
if gear__q == null { gear__q = queue_new("gear.facts") }
|
||||
return gear__q
|
||||
export function gear_facts(base_st: mut BaseState, gear_st: mut GearState) -> Queue<GearFact> {
|
||||
if gear_st.gear__q == null { gear_st.gear__q = queue_new(base_st, "gear.facts") }
|
||||
return gear_st.gear__q
|
||||
}
|
||||
|
||||
function gear__fact(what: int, k: int, c: int, cost: int) -> void {
|
||||
function gear__fact(base_st: mut BaseState, gear_st: mut GearState, what: int, k: int, c: int, cost: int) -> void {
|
||||
let f = new GearFact
|
||||
f.what = what
|
||||
f.cost = cost
|
||||
f.kind = k
|
||||
f.charge = c
|
||||
if k >= 0 {
|
||||
f.level = gear__lv[k]
|
||||
f.level = gear_st.gear__lv[k]
|
||||
f.item = GearKinds[k].item
|
||||
}
|
||||
if c >= 0 { f.item = GearCharges[c].item }
|
||||
q_push(gear_facts(), f)
|
||||
q_push(base_st, gear_facts(base_st, gear_st), f)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,43 +1,43 @@
|
|||
# system.ludic - gear as a system: the burn each tick, and the levels and charges saved by key (the
|
||||
# hand is not saved: a trip opens with empty hands)
|
||||
export function gear_reset() -> void {
|
||||
gear__ensure()
|
||||
for k in 0 .. GEAR_COUNT { gear__lv[k] = GearKinds[k].start }
|
||||
export function gear_reset(base_st: mut BaseState, gear_st: mut GearState) -> void {
|
||||
gear__ensure(gear_st)
|
||||
for k in 0 .. GEAR_COUNT { gear_st.gear__lv[k] = GearKinds[k].start }
|
||||
for c in 0 .. CHARGE_COUNT {
|
||||
gear__left[c] = GearCharges[c].full
|
||||
gear__on[c] = false
|
||||
gear_st.gear__left[c] = GearCharges[c].full
|
||||
gear_st.gear__on[c] = false
|
||||
}
|
||||
gear__hand = -1
|
||||
q_clear(gear_facts())
|
||||
gear_st.gear__hand = -1
|
||||
q_clear(base_st, gear_facts(base_st, gear_st))
|
||||
}
|
||||
|
||||
export function gear_save() -> Val {
|
||||
gear__ensure()
|
||||
export function gear_save(gear_st: mut GearState) -> Val {
|
||||
gear__ensure(gear_st)
|
||||
let v = Value.object()
|
||||
let lv = Value.object()
|
||||
for k in 0 .. GEAR_COUNT { sv_put_int(lv, GearKinds[k].key, gear__lv[k]) }
|
||||
for k in 0 .. GEAR_COUNT { sv_put_int(lv, GearKinds[k].key, gear_st.gear__lv[k]) }
|
||||
Value.put(v, "levels", lv)
|
||||
let ch = Value.object()
|
||||
for c in 0 .. CHARGE_COUNT { sv_put_float(ch, GearCharges[c].key, gear__left[c]) }
|
||||
for c in 0 .. CHARGE_COUNT { sv_put_float(ch, GearCharges[c].key, gear_st.gear__left[c]) }
|
||||
Value.put(v, "charges", ch)
|
||||
return v
|
||||
}
|
||||
|
||||
# a kind the file does not name starts where a new trip does; then what the pack carries counts
|
||||
export function gear_load(v: Val, version: int) -> void {
|
||||
gear_reset()
|
||||
export function gear_load(base_st: mut BaseState, gear_st: mut GearState, v: Val, version: int) -> void {
|
||||
gear_reset(base_st, gear_st)
|
||||
if Value.has(v, "levels") != 0 {
|
||||
let lv = Value.get(v, "levels")
|
||||
for k in 0 .. GEAR_COUNT { gear__lv[k] = sv_int(lv, GearKinds[k].key, GearKinds[k].start) }
|
||||
for k in 0 .. GEAR_COUNT { gear_st.gear__lv[k] = sv_int(lv, GearKinds[k].key, GearKinds[k].start) }
|
||||
}
|
||||
if Value.has(v, "charges") != 0 {
|
||||
let ch = Value.get(v, "charges")
|
||||
for c in 0 .. CHARGE_COUNT { gear_charge_set(c, sv_float(ch, GearCharges[c].key, GearCharges[c].full)) }
|
||||
for c in 0 .. CHARGE_COUNT { gear_charge_set(gear_st, c, sv_float(ch, GearCharges[c].key, GearCharges[c].full)) }
|
||||
}
|
||||
gear_sync()
|
||||
gear_sync(gear_st)
|
||||
}
|
||||
|
||||
function gear__tick(t: Tick) -> void { gear__burn(t.hours) }
|
||||
function gear__tick(base_st: mut BaseState, gear_st: mut GearState, t: Tick) -> void { gear__burn(base_st, gear_st, t.hours) }
|
||||
|
||||
export function gear_system() -> System {
|
||||
let s = system_new("gear", PH_SIMULATE)
|
||||
|
|
|
|||
|
|
@ -17,147 +17,149 @@ program GearTest {
|
|||
def GearCharges lamp { item: IT_LAMP, full: 100.0, rate: GV_DRAIN }
|
||||
def GearCharges radio { item: 9, full: 100.0, per_hour: 5.0, hand: false }
|
||||
|
||||
var money: int = 0
|
||||
var rep: int = 0
|
||||
var pack: []int = null
|
||||
var hide_pack: bool = false
|
||||
state GeartestState {
|
||||
money: int = 0
|
||||
rep: int = 0
|
||||
pack: []int = null
|
||||
hide_pack: bool = false
|
||||
}
|
||||
|
||||
function purse_money() -> int { return money }
|
||||
function purse_spend(n: int) -> bool {
|
||||
if n > money { return false }
|
||||
money -= n
|
||||
function purse_money(geartest_st: GeartestState) -> int { return geartest_st.money }
|
||||
function purse_spend(geartest_st: mut GeartestState, n: int) -> bool {
|
||||
if n > geartest_st.money { return false }
|
||||
geartest_st.money -= n
|
||||
return true
|
||||
}
|
||||
function purse_rep() -> int { return rep }
|
||||
function pack_count(it: int) -> int { return pack[it] }
|
||||
function pack_add(it: int, n: int) -> int {
|
||||
pack[it] = pack[it] + n
|
||||
function purse_rep(geartest_st: GeartestState) -> int { return geartest_st.rep }
|
||||
function pack_count(geartest_st: GeartestState, it: int) -> int { return geartest_st.pack[it] }
|
||||
function pack_add(geartest_st: mut GeartestState, it: int, n: int) -> int {
|
||||
geartest_st.pack[it] = geartest_st.pack[it] + n
|
||||
return n
|
||||
}
|
||||
function hidden(k: int) -> bool { return hide_pack and k == GEAR_PACK }
|
||||
function hidden(geartest_st: GeartestState, k: int) -> bool { return geartest_st.hide_pack and k == GEAR_PACK }
|
||||
|
||||
bind GearPurse { money: fn purse_money, spend: fn purse_spend, rep: fn purse_rep }
|
||||
bind GearPack { count: fn pack_count, add: fn pack_add }
|
||||
bind GearWorld { hidden: fn hidden }
|
||||
|
||||
function fresh() -> void {
|
||||
money = 0
|
||||
rep = 0
|
||||
hide_pack = false
|
||||
pack = new []int
|
||||
for i in 0 .. 12 { push(pack, 0) }
|
||||
gear_reset()
|
||||
function fresh(base_st: mut BaseState, gear_st: mut GearState, geartest_st: mut GeartestState) -> void {
|
||||
geartest_st.money = 0
|
||||
geartest_st.rep = 0
|
||||
geartest_st.hide_pack = false
|
||||
geartest_st.pack = new []int
|
||||
for i in 0 .. 12 { push(geartest_st.pack, 0) }
|
||||
gear_reset(base_st, gear_st)
|
||||
}
|
||||
|
||||
function ran_out() -> int {
|
||||
let fs = q_drain(gear_facts())
|
||||
function ran_out(base_st: mut BaseState, gear_st: mut GearState) -> int {
|
||||
let fs = q_drain(base_st, gear_facts(base_st, gear_st))
|
||||
var n = -1
|
||||
for i in 0 .. len(fs) { if fs[i].what == GEAR_RAN_OUT { n = fs[i].charge } }
|
||||
return n
|
||||
}
|
||||
|
||||
test "a new trip starts where the kinds say" {
|
||||
fresh()
|
||||
expect_eq(gear_level(GEAR_ROD), 0)
|
||||
expect_eq(gear_level(GEAR_CAMERA), 1)
|
||||
expect(gear_next_name(GEAR_CAMERA) == "Zoom")
|
||||
expect_eq(gear_next_cost(GEAR_ROD), 30)
|
||||
test "a new trip starts where the kinds say" (base_st: mut BaseState, gear_st: mut GearState, geartest_st: mut GeartestState) {
|
||||
fresh(base_st, gear_st, geartest_st)
|
||||
expect_eq(gear_level(gear_st, GEAR_ROD), 0)
|
||||
expect_eq(gear_level(gear_st, GEAR_CAMERA), 1)
|
||||
expect(gear_next_name(gear_st, GEAR_CAMERA) == "Zoom")
|
||||
expect_eq(gear_next_cost(gear_st, GEAR_ROD), 30)
|
||||
}
|
||||
|
||||
test "bought with money once the standing is there, and the item follows" {
|
||||
fresh()
|
||||
expect(not gear_buy(GEAR_ROD))
|
||||
money = 200
|
||||
expect(gear_buy(GEAR_ROD))
|
||||
expect_eq(money, 170)
|
||||
expect_eq(pack[IT_ROD], 1)
|
||||
expect(not gear_can_buy(GEAR_ROD))
|
||||
rep = 10
|
||||
expect(gear_buy(GEAR_ROD))
|
||||
expect_eq(pack[IT_ROD], 1)
|
||||
let fs = q_drain(gear_facts())
|
||||
test "bought with money once the standing is there, and the item follows" (base_st: mut BaseState, gear_st: mut GearState, geartest_st: mut GeartestState) {
|
||||
fresh(base_st, gear_st, geartest_st)
|
||||
expect(not gear_buy(base_st, gear_st, GEAR_ROD))
|
||||
geartest_st.money = 200
|
||||
expect(gear_buy(base_st, gear_st, GEAR_ROD))
|
||||
expect_eq(geartest_st.money, 170)
|
||||
expect_eq(geartest_st.pack[IT_ROD], 1)
|
||||
expect(not gear_can_buy(gear_st, GEAR_ROD))
|
||||
geartest_st.rep = 10
|
||||
expect(gear_buy(base_st, gear_st, GEAR_ROD))
|
||||
expect_eq(geartest_st.pack[IT_ROD], 1)
|
||||
let fs = q_drain(base_st, gear_facts(base_st, gear_st))
|
||||
expect_eq(len(fs), 2)
|
||||
expect_eq(fs[1].what, GEAR_BOUGHT)
|
||||
expect_eq(fs[1].level, 2)
|
||||
expect_eq(fs[1].cost, 100)
|
||||
}
|
||||
|
||||
test "the best tier is the end, and a hidden kind is not for sale" {
|
||||
fresh()
|
||||
money = 1000
|
||||
rep = 50
|
||||
for i in 0 .. 5 { gear_buy(GEAR_PACK) }
|
||||
expect(gear_best(GEAR_PACK))
|
||||
expect_eq(gear_level(GEAR_PACK), 3)
|
||||
fresh()
|
||||
money = 100
|
||||
hide_pack = true
|
||||
expect(not gear_buy(GEAR_PACK))
|
||||
test "the best tier is the end, and a hidden kind is not for sale" (base_st: mut BaseState, gear_st: mut GearState, geartest_st: mut GeartestState) {
|
||||
fresh(base_st, gear_st, geartest_st)
|
||||
geartest_st.money = 1000
|
||||
geartest_st.rep = 50
|
||||
for i in 0 .. 5 { gear_buy(base_st, gear_st, GEAR_PACK) }
|
||||
expect(gear_best(gear_st, GEAR_PACK))
|
||||
expect_eq(gear_level(gear_st, GEAR_PACK), 3)
|
||||
fresh(base_st, gear_st, geartest_st)
|
||||
geartest_st.money = 100
|
||||
geartest_st.hide_pack = true
|
||||
expect(not gear_buy(base_st, gear_st, GEAR_PACK))
|
||||
expect_eq(len(gear_kinds_at(-1)), 2)
|
||||
}
|
||||
|
||||
test "a tier decides a value and a mult, and the stack's room follows" {
|
||||
fresh()
|
||||
expect_eq(gear_value(GV_BITE), 1.0)
|
||||
gear_set_level(GEAR_ROD, 3)
|
||||
expect_eq(gear_value(GV_BITE), 0.55)
|
||||
expect_eq(gear_mult(GEAR_PACK), 1.0)
|
||||
gear_set_level(GEAR_PACK, 2)
|
||||
expect_eq(gear_mult(GEAR_PACK), 1.7)
|
||||
expect_eq(gear_stack_limit(10, gear_mult(GEAR_PACK)), 17)
|
||||
test "a tier decides a value and a mult, and the stack's room follows" (base_st: mut BaseState, gear_st: mut GearState, geartest_st: mut GeartestState) {
|
||||
fresh(base_st, gear_st, geartest_st)
|
||||
expect_eq(gear_value(gear_st, GV_BITE), 1.0)
|
||||
gear_set_level(gear_st, GEAR_ROD, 3)
|
||||
expect_eq(gear_value(gear_st, GV_BITE), 0.55)
|
||||
expect_eq(gear_mult(gear_st, GEAR_PACK), 1.0)
|
||||
gear_set_level(gear_st, GEAR_PACK, 2)
|
||||
expect_eq(gear_mult(gear_st, GEAR_PACK), 1.7)
|
||||
expect_eq(gear_stack_limit(10, gear_mult(gear_st, GEAR_PACK)), 17)
|
||||
expect_eq(gear_stack_limit(1, 3.0), 1)
|
||||
expect_eq(gear_stack_limit(4, 0.1), 1)
|
||||
expect_eq(gear_mult(GEAR_ROD), 1.0)
|
||||
expect_eq(gear_mult(gear_st, GEAR_ROD), 1.0)
|
||||
}
|
||||
|
||||
test "a carried item counts as the first tier" {
|
||||
fresh()
|
||||
pack[IT_ROD] = 1
|
||||
gear_sync()
|
||||
expect_eq(gear_level(GEAR_ROD), 1)
|
||||
test "a carried item counts as the first tier" (base_st: mut BaseState, gear_st: mut GearState, geartest_st: mut GeartestState) {
|
||||
fresh(base_st, gear_st, geartest_st)
|
||||
geartest_st.pack[IT_ROD] = 1
|
||||
gear_sync(gear_st)
|
||||
expect_eq(gear_level(gear_st, GEAR_ROD), 1)
|
||||
}
|
||||
|
||||
test "a held charge runs only in the hand, burns by the hour and runs out" {
|
||||
fresh()
|
||||
test "a held charge runs only in the hand, burns by the hour and runs out" (base_st: mut BaseState, gear_st: mut GearState, geartest_st: mut GeartestState) {
|
||||
fresh(base_st, gear_st, geartest_st)
|
||||
let t = CHARGE_TORCH
|
||||
expect(not gear_run(t, true))
|
||||
gear_set_hand(IT_TORCH)
|
||||
expect(gear_run(t, true))
|
||||
expect(gear_lit())
|
||||
expect(not gear_run(gear_st, t, true))
|
||||
gear_set_hand(gear_st, IT_TORCH)
|
||||
expect(gear_run(gear_st, t, true))
|
||||
expect(gear_lit(gear_st))
|
||||
gear_system().tick(tick_new(0.1, 1, 0.5))
|
||||
expect_eq(gear_charge(t), 30.0)
|
||||
expect_eq(gear_charge(gear_st, t), 30.0)
|
||||
gear_system().tick(tick_new(0.1, 2, 0.6))
|
||||
expect_eq(gear_charge(t), 0.0)
|
||||
expect(not gear_lit())
|
||||
expect_eq(ran_out(), t)
|
||||
expect(not gear_run(t, true))
|
||||
expect_eq(gear_charge(gear_st, t), 0.0)
|
||||
expect(not gear_lit(gear_st))
|
||||
expect_eq(ran_out(base_st, gear_st), t)
|
||||
expect(not gear_run(gear_st, t, true))
|
||||
}
|
||||
|
||||
test "a charge's rate can be its tier's, and a new hand puts the light out" {
|
||||
fresh()
|
||||
gear_set_hand(IT_LAMP)
|
||||
gear_run(CHARGE_LAMP, true)
|
||||
test "a charge's rate can be its tier's, and a new hand puts the light out" (base_st: mut BaseState, gear_st: mut GearState, geartest_st: mut GeartestState) {
|
||||
fresh(base_st, gear_st, geartest_st)
|
||||
gear_set_hand(gear_st, IT_LAMP)
|
||||
gear_run(gear_st, CHARGE_LAMP, true)
|
||||
gear_system().tick(tick_new(0.1, 1, 1.0))
|
||||
expect_eq(gear_charge(CHARGE_LAMP), 86.0)
|
||||
gear_set_level(GEAR_CAMERA, 2)
|
||||
expect_eq(gear_charge(gear_st, CHARGE_LAMP), 86.0)
|
||||
gear_set_level(gear_st, GEAR_CAMERA, 2)
|
||||
gear_system().tick(tick_new(0.1, 2, 1.0))
|
||||
expect_eq(gear_charge(CHARGE_LAMP), 78.0)
|
||||
gear_run(CHARGE_RADIO, true)
|
||||
gear_set_hand(-1)
|
||||
expect(not gear_running(CHARGE_LAMP))
|
||||
expect(gear_running(CHARGE_RADIO))
|
||||
expect_eq(gear_charge(gear_st, CHARGE_LAMP), 78.0)
|
||||
gear_run(gear_st, CHARGE_RADIO, true)
|
||||
gear_set_hand(gear_st, -1)
|
||||
expect(not gear_running(gear_st, CHARGE_LAMP))
|
||||
expect(gear_running(gear_st, CHARGE_RADIO))
|
||||
}
|
||||
|
||||
test "levels and charges are saved by key" {
|
||||
fresh()
|
||||
gear_set_level(GEAR_ROD, 2)
|
||||
gear_charge_set(CHARGE_TORCH, 12.5)
|
||||
let v = gear_save()
|
||||
fresh()
|
||||
gear_load(v, 1)
|
||||
expect_eq(gear_level(GEAR_ROD), 2)
|
||||
expect_eq(gear_level(GEAR_CAMERA), 1)
|
||||
expect_eq(gear_charge(CHARGE_TORCH), 12.5)
|
||||
expect_eq(gear_charge(CHARGE_LAMP), 100.0)
|
||||
test "levels and charges are saved by key" (base_st: mut BaseState, gear_st: mut GearState, geartest_st: mut GeartestState) {
|
||||
fresh(base_st, gear_st, geartest_st)
|
||||
gear_set_level(gear_st, GEAR_ROD, 2)
|
||||
gear_charge_set(gear_st, CHARGE_TORCH, 12.5)
|
||||
let v = gear_save(gear_st)
|
||||
fresh(base_st, gear_st, geartest_st)
|
||||
gear_load(base_st, gear_st, v, 1)
|
||||
expect_eq(gear_level(gear_st, GEAR_ROD), 2)
|
||||
expect_eq(gear_level(gear_st, GEAR_CAMERA), 1)
|
||||
expect_eq(gear_charge(gear_st, CHARGE_TORCH), 12.5)
|
||||
expect_eq(gear_charge(gear_st, CHARGE_LAMP), 100.0)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,20 @@
|
|||
# tiers.ludic - what is owned and what a tier is worth
|
||||
export function gear_ok(k: int) -> bool { return k >= 0 and k < GEAR_COUNT }
|
||||
|
||||
export function gear_level(k: int) -> int {
|
||||
gear__ensure()
|
||||
return gear__lv[k]
|
||||
export function gear_level(gear_st: mut GearState, k: int) -> int {
|
||||
gear__ensure(gear_st)
|
||||
return gear_st.gear__lv[k]
|
||||
}
|
||||
|
||||
# outright: staging, a test, a camera handed over with the trip
|
||||
export function gear_set_level(k: int, lv: int) -> void {
|
||||
gear__ensure()
|
||||
gear__lv[k] = lv
|
||||
export function gear_set_level(gear_st: mut GearState, k: int, lv: int) -> void {
|
||||
gear__ensure(gear_st)
|
||||
gear_st.gear__lv[k] = lv
|
||||
}
|
||||
|
||||
export function gear_owned(k: int) -> bool { return gear_level(k) > 0 }
|
||||
export function gear_owned(gear_st: mut GearState, k: int) -> bool { return gear_level(gear_st, k) > 0 }
|
||||
|
||||
export function gear_best(k: int) -> bool { return gear_level(k) >= GearKinds[k].tiers }
|
||||
export function gear_best(gear_st: mut GearState, k: int) -> bool { return gear_level(gear_st, k) >= GearKinds[k].tiers }
|
||||
|
||||
# a tier's name, "" for none
|
||||
export function gear_level_name(k: int, lv: int) -> string {
|
||||
|
|
@ -23,16 +23,16 @@ export function gear_level_name(k: int, lv: int) -> string {
|
|||
}
|
||||
|
||||
# the tier on offer next: its name, cost and the standing it wants
|
||||
export function gear_next_name(k: int) -> string { return gear_level_name(k, gear_level(k) + 1) }
|
||||
export function gear_next_name(gear_st: mut GearState, k: int) -> string { return gear_level_name(k, gear_level(gear_st, k) + 1) }
|
||||
|
||||
export function gear_next_cost(k: int) -> int {
|
||||
if gear_best(k) { return 0 }
|
||||
return GearKinds[k].cost[gear_level(k)]
|
||||
export function gear_next_cost(gear_st: mut GearState, k: int) -> int {
|
||||
if gear_best(gear_st, k) { return 0 }
|
||||
return GearKinds[k].cost[gear_level(gear_st, k)]
|
||||
}
|
||||
|
||||
export function gear_next_rep(k: int) -> int {
|
||||
if gear_best(k) { return 0 }
|
||||
return GearKinds[k].rep[gear_level(k)]
|
||||
export function gear_next_rep(gear_st: mut GearState, k: int) -> int {
|
||||
if gear_best(gear_st, k) { return 0 }
|
||||
return GearKinds[k].rep[gear_level(gear_st, k)]
|
||||
}
|
||||
|
||||
function gear__pick(xs: []float, lv: int, fallback: float) -> float {
|
||||
|
|
@ -43,12 +43,12 @@ function gear__pick(xs: []float, lv: int, fallback: float) -> float {
|
|||
}
|
||||
|
||||
# the kind's own number at its level (1.0 when it has none)
|
||||
export function gear_mult(k: int) -> float { return gear__pick(GearKinds[k].mult, gear_level(k), 1.0) }
|
||||
export function gear_mult(gear_st: mut GearState, k: int) -> float { return gear__pick(GearKinds[k].mult, gear_level(gear_st, k), 1.0) }
|
||||
|
||||
# a value its kind's tier decides
|
||||
export function gear_value(v: int) -> float {
|
||||
export function gear_value(gear_st: mut GearState, v: int) -> float {
|
||||
let d = GearValues[v]
|
||||
return gear__pick(d.at, gear_level(d.gear), 0.0)
|
||||
return gear__pick(d.at, gear_level(gear_st, d.gear), 0.0)
|
||||
}
|
||||
|
||||
# the room for a thing whose base stack is `base`, scaled: a single thing stays single, and a
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue