# demand.ludic - what each vendor is short of this week, and the one thing it is full of: rolled # from the shop's own dice, seeded by the week, so it never moves anyone else's rolls # how many things a vendor wants a week, what that pays and what a glut pays, the week, the seed export function shop_config_demand(shop_st: mut ShopState, wants: int, want_mult: float, glut_mult: float, days: int, seed: int) -> void { shop_st.shop_wants_n = wants shop_st.shop_want_mult = want_mult shop_st.shop_glut_mult = glut_mult shop_st.shop_week_days = days shop_st.shop_seed = seed shop_st.shop_week_rolled = -1 } export function shop_week(shop_st: ShopState) -> int { return (ShopWorld.day() - 1) / shop_st.shop_week_days } function shop_pick_one(shop_st: ShopState, v: int, taken: []int) -> int { for t in 0 .. 200 { let it = rng_between(shop_st.shop_dice, 0, shop_items(shop_st) - 1) if not shop_buys(shop_st, v, it) { continue } var dup = false for k in 0 .. len(taken) { if taken[k] == it { dup = true } } if not dup { return it } } return -1 } function shop_roll_vendor(shop_st: mut ShopState, v: int) -> void { let taken = shop_st.shop_taken List.clear(taken) for k in 0 .. shop_st.shop_wants_n { let it = shop_pick_one(shop_st, v, taken) shop_st.shop_want_list[v * shop_st.shop_wants_n + k] = it if it >= 0 { kept_push(taken, it) } } shop_st.shop_full_list[v] = shop_pick_one(shop_st, v, taken) } # the week's lists, rolled again only when the week turns export function shop_roll(shop_st: mut ShopState) -> void { let week = shop_week(shop_st) if week == shop_st.shop_week_rolled and shop_st.shop_want_list != null { return } shop_st.shop_week_rolled = week rng_seed(shop_st.shop_dice, shop_st.shop_seed + week * 37) shop_lists_empty(shop_st) if shop_items(shop_st) == 0 { return } for v in 0 .. shop_vendors(shop_st) { shop_roll_vendor(shop_st, v) } } export function shop_wants(shop_st: ShopState, v: int, it: int) -> bool { if not shop_vendor_ok(shop_st, v) or shop_st.shop_want_list == null { return false } for k in 0 .. shop_st.shop_wants_n { if shop_st.shop_want_list[v * shop_st.shop_wants_n + k] == it { return true } } return false } export function shop_glutted(shop_st: ShopState, v: int, it: int) -> bool { if not shop_vendor_ok(shop_st, v) or shop_st.shop_full_list == null { return false } return shop_st.shop_full_list[v] == it } # what a vendor wants this week, in its order export function shop_wanted(shop_st: ShopState, v: int) -> []int { let out = new []int if not shop_vendor_ok(shop_st, v) or shop_st.shop_want_list == null { return out } for k in 0 .. shop_st.shop_wants_n { let it = shop_st.shop_want_list[v * shop_st.shop_wants_n + k] if it >= 0 { push(out, it) } } return out } # the week's multiplier on what `v` pays for `it` (1 with no vendor) export function shop_demand_mult(shop_st: ShopState, v: int, it: int) -> float { if shop_wants(shop_st, v, it) { return shop_st.shop_want_mult } if shop_glutted(shop_st, v, it) { return shop_st.shop_glut_mult } return 1.0 } # this week, `v` wants `it` (a test, staging, a board that says so) export function shop_set_want(shop_st: mut ShopState, v: int, it: int) -> void { if not shop_vendor_ok(shop_st, v) { return } shop_roll(shop_st) shop_st.shop_want_list[v * shop_st.shop_wants_n] = it if shop_st.shop_full_list[v] == it { shop_st.shop_full_list[v] = -1 } } function shop_demand_reset(shop_st: mut ShopState) -> void { shop_st.shop_week_rolled = -1 shop_st.shop_want_list = null shop_st.shop_full_list = null }