# party.ludic - with company every player reports what THEY have toward each step of the current # chapter (steps_mine) and the owner of the story answers the step from the lot. Held per seat, # so a player who leaves takes their column with them; seat 0 is this machine, read live. # how many seats a party has export function steps_config(steps_st: mut StepsState, players: int) -> void { steps_st.steps__players = players steps_st.steps__col = null } @alloc_ok("the party's columns: once a chapter, and when the party changes") function steps__party_clear(steps_st: mut StepsState) -> void { steps_st.steps__col = new []int for i in 0 .. steps_st.steps__players * STEPS_PER_CHAPTER { push(steps_st.steps__col, 0) } steps_st.steps__col_ch = steps_st.steps__cur } # a party over (or a new one): every column forgotten export function steps_party_reset(steps_st: mut StepsState) -> void { steps_st.steps__col = null } # the columns, emptied when the chapter they were about is not this one (before a teammate's go in) function steps__cols(steps_st: mut StepsState) -> void { if steps_st.steps__col == null or steps_st.steps__col_ch != steps_st.steps__cur { steps__party_clear(steps_st) } } # seat p's share of step i: seat 0 read live, a teammate's as they sent it for this chapter function steps__share(steps_st: StepsState, p: int, i: int) -> int { let ch = steps_st.steps__cur if p == 0 { if steps_finished(steps_st) or i >= steps_in(steps_st, ch) { return 0 } return steps_mine(steps_st, steps_kind(steps_st, ch, i), steps_param(steps_st, ch, i), steps_need(steps_st, ch, i)) } let k = p * STEPS_PER_CHAPTER + i if steps_st.steps__col == null or steps_st.steps__col_ch != ch or k >= len(steps_st.steps__col) { return 0 } return steps_st.steps__col[k] } # this machine's shares for the current chapter, to send to whoever owns the story # the same into a list the caller keeps (a guest checks its shares every tick) export function steps_my_shares_into(steps_st: StepsState, out: []int) -> void { List.clear(out) @alloc_ok("into the caller's kept list, at most STEPS_PER_CHAPTER") for i in 0 .. STEPS_PER_CHAPTER { push(out, steps__share(steps_st, 0, i)) } } export function steps_my_shares(steps_st: StepsState) -> []int { let out = new []int for i in 0 .. STEPS_PER_CHAPTER { push(out, steps__share(steps_st, 0, i)) } return out } # a teammate's shares, as they sent them; ignored when they were about another chapter export function steps_share(steps_st: mut StepsState, p: int, ch: int, shares: []int) -> void { if p <= 0 or p >= steps_st.steps__players or ch != steps_st.steps__cur { return } steps__cols(steps_st) for i in 0 .. min(len(shares), STEPS_PER_CHAPTER) { steps_st.steps__col[p * STEPS_PER_CHAPTER + i] = shares[i] } } export function steps_share_of(steps_st: StepsState, p: int, i: int) -> int { return steps__share(steps_st, p, i) } # a seat emptied: what it had goes with it export function steps_leave(steps_st: mut StepsState, p: int) -> void { if steps_st.steps__col == null or p <= 0 or p >= steps_st.steps__players { return } for i in 0 .. STEPS_PER_CHAPTER { steps_st.steps__col[p * STEPS_PER_CHAPTER + i] = 0 } } # the shares of every seat taken, combined as the pool says (seat 0 is the start) function steps__combined(steps_st: StepsState, i: int, how: int) -> int { var v = steps__share(steps_st, 0, i) for p in 1 .. steps_st.steps__players { if not StepsWorld.present(p) { continue } let c = steps__share(steps_st, p, i) if how == STEPS_POOL_ANY or how == STEPS_POOL_OR { v = v | c } else if how == STEPS_POOL_SUM { v += c } else if how == STEPS_POOL_MAX { if c > v { v = c } } } return v } # the answer to step i of the current chapter: solo this is steps_eval and nothing more export function steps_met(steps_st: StepsState, i: int) -> bool { let ch = steps_st.steps__cur let kind = steps_kind(steps_st, ch, i) if not StepsWorld.party() { return steps_eval(steps_st, kind, steps_param(steps_st, ch, i), steps_need(steps_st, ch, i)) } let how = steps_pool(steps_st, kind) if how == STEPS_POOL_WORLD { return steps_eval(steps_st, kind, steps_param(steps_st, ch, i), steps_need(steps_st, ch, i)) } return steps_from(steps_st, kind, steps_param(steps_st, ch, i), steps_need(steps_st, ch, i), steps__combined(steps_st, i, how), steps_players(steps_st), steps_each(steps_st, i)) } # the party's count for step i of the current chapter, -1 for one that is not a tally export function steps_party_got(steps_st: StepsState, i: int) -> int { let ch = steps_st.steps__cur let kind = steps_kind(steps_st, ch, i) let param = steps_param(steps_st, ch, i) if steps_got(steps_st, kind, param) < 0 { return -1 } let how = steps_pool(steps_st, kind) if not StepsWorld.party() or how == STEPS_POOL_WORLD or how == STEPS_POOL_ANY or how == STEPS_POOL_EACH { return steps_got(steps_st, kind, param) } return steps_got_from(steps_st, kind, param, steps__combined(steps_st, i, how)) }