Compare commits

...

38 Commits

Author SHA1 Message Date
2507a3f218 Final tutorial improvements 2024-02-14 18:17:19 -08:00
89dcee996f Add better cover 2024-02-14 18:03:31 -08:00
55eb61825e Add a tips page 2024-02-14 17:51:57 -08:00
184ce112bd Fix a crash 2024-02-14 17:32:27 -08:00
c2a978e315 Grabbed cards float 2024-02-14 16:29:49 -08:00
93161c6465 Stacked moves 2024-02-14 15:55:00 -08:00
7f87814d35 Remove unused code 2024-02-14 14:10:19 -08:00
a7697fa1b2 Don't undo during restart animation 2024-02-13 19:15:19 -08:00
0912e90510 Change undo behavior
- Undo while holding a card drops it
- Undo can be redone
2024-02-13 19:09:35 -08:00
119155a903 Update rood 2024-02-12 17:50:38 -08:00
e3bc5a0dc6 Add content warning 2024-02-12 16:34:26 -08:00
dd46a76f54 Improve pickup/drop 2024-02-12 15:03:55 -08:00
ff1c59adf3 Add image to cart 2024-02-11 21:54:32 -08:00
2085ba5a63 Complete the rood 2024-02-11 21:53:19 -08:00
4747e297b4 Add sounds 2024-02-11 20:54:01 -08:00
bb2cfdd6af Add QOL features 2024-02-11 20:40:30 -08:00
3b9c61329b Add music manager 2024-02-11 20:18:01 -08:00
da41929613 Add some music 2024-02-11 20:12:49 -08:00
2cca0cd857 Don't show a menu on restart 2024-02-11 18:04:51 -08:00
6949abc2fb Final win screen! 2024-02-11 17:58:34 -08:00
4a61d8afd3 Archaeology feature 2024-02-11 17:28:41 -08:00
21d0ed432d Get rid of old unneeded file 2024-02-11 16:48:22 -08:00
172fd30ad0 Tiling menu 2024-02-11 16:48:11 -08:00
f30b7d6023 Misc bugfixes 2024-02-11 15:58:40 -08:00
343e4a2ea9 Cart data reset, excavate button 2024-02-11 15:51:56 -08:00
c4b11071e5 Add menu 2024-02-11 14:59:20 -08:00
cdaedc8be3 Improve a line of liturgy 2024-02-11 13:52:34 -08:00
1f8a937107 Add liturgy 2024-02-11 13:44:45 -08:00
a06ea160b2 Track whether the player hsa completed the tutorial 2024-02-10 22:19:54 -08:00
d7d91dd3a7 Restart menu 2024-02-10 22:01:05 -08:00
8b23695945 Restart level animation 2024-02-10 21:41:48 -08:00
b4f4b8cbb5 Improve layout 2024-02-10 21:02:31 -08:00
6998d614a9 Better board/cursor graphics 2024-02-10 20:56:48 -08:00
e184552458 Tutorial: improved 2024-02-10 20:40:12 -08:00
15e86c7940 Tutorial code 1 2024-02-10 19:42:38 -08:00
2ad6a0bc3a Add state manager and ironman mode 2024-02-10 17:44:38 -08:00
59de5962dc Use a seed list for level 7 2024-02-10 16:35:57 -08:00
917f50370b Undo feature 2024-02-09 22:35:55 -08:00
36 changed files with 25209 additions and 1084 deletions

View File

@ -1,11 +1,15 @@
board=klass()
function board:init(ruleset)
function board:init(w)
local ruleset=w.ruleset
self.watcher=w
self.ruleset=ruleset
self.cursor=cursor:new(self)
self.animator=animator:new()
self.checkpoint=nil
self.slots={}
self.wells={}
self.restart_progress=0
-- board slots
-- ...n_slots: normal
@ -35,16 +39,29 @@ function board:init(ruleset)
if (not lst) return new.rank==0
return new.rank==lst.rank+1
end))
self.wells[#self.wells].obscured_by_last_well=true
-- n_suits+2: arcana descending
add(self.wells,well:new(self.ruleset,function(lst,new)
if (new.suit!='a') return
if (not lst) return new.rank==self.ruleset.n_arcana-1
return new.rank==lst.rank-1
end))
self.wells[#self.wells].obscured_by_last_well=true
-- top arcana
add(self.wells,well:new(self.ruleset,function(lst,new)
local w1=self.wells[self.ruleset.n_suits+1]
local w2=self.wells[self.ruleset.n_suits+2]
if (#w1.contents + #w2.contents != self.ruleset.n_arcana-1) return
return new.suit=='a'
end))
local seed=seeds:choose(self.ruleset.pool)
printh("chosen seed: "..tostr(seed,2))
self:deal(seeds:choose(self.ruleset.pool))
self:deal(w.seed or seeds:choose(self.ruleset.pool))
end
function board:get_endgame_card()
local last_arcana=self.wells[#self.wells]:peek()
if (last_arcana) return last_arcana
return self.last_card or 1
end
function board:deal(seed)
@ -67,24 +84,54 @@ function board:deal(seed)
end
end
function board:set_restart_progress(progress)
self.restart_progress=progress
end
function board:get_completion_level()
return self.ruleset.completion_level
end
function board:undo()
if (not self.checkpoint) return
if (not self.watcher:intercept("undo")) sounds:dire() return
sounds:menu()
local current_checkpoint=checkpoint:new(self,self.checkpoint.card)
self.checkpoint:apply(self)
self.checkpoint=current_checkpoint
end
function board:on_idle()
self:find_automove()
end
function board:pre_move(card)
self.checkpoint=checkpoint:new(self,card)
end
function board:on_move()
-- TODO: Make checkpoint
self:find_automove()
end
function board:is_won()
if (not self:can_take_input()) return false
for s=1,#self.slots do
if (self.slots[s]:peek()) return false
end
return true
end
function board:find_automove()
for s=1,#self.slots do
local top=self.slots[s]:peek()
if top then
for w=1,#self.wells do
for w=#self.wells,1,-1 do
if w<=self.ruleset.n_suits and self.slots[self.ruleset.n_slots+1]:peek()!=nil then
-- the top wells are blocked
elseif self.wells[w]:would_accept(top) then
self.cursor:drop_grab_silent()
self:animate_and_move_to_well(s,w)
self.last_card=top
return true
end
@ -104,32 +151,40 @@ function board:update()
if (not was_idle and is_idle) then
self:on_idle()
end
if (is_idle) self.cursor:update()
end
function board:draw()
local extra_slot_full=self.slots[self.ruleset.n_slots+1]:peek()!=nil
local last_well_full=self.wells[#self.wells]:peek()!=nil
for w_ix=1,#self.wells do
local w=self.wells[w_ix]
local l=self.ruleset.layouts:well(w_ix)
local shadowed=nil
if w.obscured_by_last_well and last_well_full then
shadowed=true
end
if w.obscured_by_extra_slot and extra_slot_full then
shadowed=true
end
for i=1,#w.contents do
local x,y=l:place_card(i)
self.ruleset.deck:draw_card(x,y,w.contents[i],{shadowed=shadowed})
self.ruleset.deck:draw_card(x,y,w.contents[i],{rotate=l.rotated,shadowed=shadowed})
end
end
local grabs={}
for s_ix in all(self.cursor.grabbed_slots) do
grabs[s_ix]=(grabs[s_ix] or 0)+1
end
local function forall_slots(cb)
for s_ix=1,#self.slots do
local s=self.slots[s_ix]
local l=self.ruleset.layouts:slot(s_ix)
local n=#s.contents
if (self.cursor.grabbed==s_ix) n-=1
local n=#s.contents-(grabs[s_ix] or 0)
cb(x,y,s_ix,s,l,n)
end
@ -142,17 +197,25 @@ function board:draw()
end
end)
if self.checkpoint then
local cpl=self.ruleset.layouts:checkpoint()
local x,y=cpl:place_card(0)
self.ruleset.deck:draw_card(x,y,self.checkpoint.card,{shadowed=true})
end
self.animator:draw()
if self.animator:idle() then
self.watcher:draw(self)
local hover_slot=self.cursor:hover_slot()
forall_slots(function(x,y,s_ix,s,l,n)
if hover_slot==s_ix then
local x,y=l:place_card(n+1)
self.cursor:draw_at(l,x,y)
self.cursor:draw_at(l,n)
end
end)
end
democrap:distort_screen(self.restart_progress)
end
slot=klass()
@ -174,8 +237,8 @@ end
function slot:add(card)
add(self.contents,card)
end
function slot:peek()
return self.contents[#self.contents]
function slot:peek(depth)
return self.contents[#self.contents-(depth or 0)]
end
function slot:pop()
return deli(self.contents,#self.contents)
@ -200,4 +263,7 @@ function well:add(card)
end
function well:clear()
self.contents={}
end
function well:peek()
return self.contents[#self.contents]
end

View File

@ -55,7 +55,7 @@ function board:_animate_move_card(card,on_end,start_x,start_y,compute_end)
if (frame==0) end_x,end_y=compute_end()
frame+=1
progress=frame/7
if (progress>=1.0) on_end() return false
if (progress>=1.0) sounds:deal_card() on_end() return false
return true
end
function anim_obj:draw()

40
checkpoint.lua Normal file
View File

@ -0,0 +1,40 @@
checkpoint=klass()
function checkpoint:init(board,card)
self.card=card
self.slots={}
self.wells={}
for s=1,#board.slots do
local cnt={}
for c in all(board.slots[s].contents) do
add(cnt,c)
end
self.slots[s]=cnt
end
for w=1,#board.wells do
local cnt={}
for c in all(board.wells[w].contents) do
add(cnt,c)
end
self.wells[w]=cnt
end
end
function checkpoint:apply(board)
for s=1,#board.slots do
while #board.slots[s].contents>0 do
deli(board.slots[s].contents)
end
for i in all(self.slots[s]) do
add(board.slots[s].contents,i)
end
end
for w=1,#board.wells do
while #board.wells[w].contents>0 do
deli(board.wells[w].contents)
end
for i in all(self.wells[w]) do
add(board.wells[w].contents,i)
end
end
board.cursor:drop_grab()
end

67
completion_tracker.lua Normal file
View File

@ -0,0 +1,67 @@
completion_tracker={}
add(modules,completion_tracker)
function completion_tracker:init()
cartdata("pyrex_fortunesfoundation_1")
end
function completion_tracker:reset()
for i=0,63 do
if (i!=59) dset(i,0) -- don't clear music pref flag
end
end
function completion_tracker:get_metascore()
local b0=dget"60"
local b1=dget"61"
local b2=dget"62"
local b3=dget"63"
return (b0<<8)+b1+(b2>>8)+(b3>>16)
end
function completion_tracker:incr_metascore()
local ms=self:get_metascore()
ms+=0x0.0001
dset(60,(ms>>8)&0xff)
dset(61,(ms)&0xff)
dset(62,(ms<<8)&0xff)
dset(63,(ms<<16)&0xff)
end
function completion_tracker:get_completion_level()
return dget(0)
end
function completion_tracker:advance_completion_level(clevel)
dset(0,max(dget(0), clevel))
end
function completion_tracker:get_music_preference()
return dget(59)==0
end
function completion_tracker:set_music_preference()
if (dget(59)==0) dset(59,1) return
dset(59,0)
end
-- TODO: Bitfield instead
function completion_tracker:mark_seen(text_id)
local ix,bit=self:_unpack_text_id(text_id)
dset(ix,dget(ix)|bit)
end
function completion_tracker:was_seen(text_id)
local ix,bit=self:_unpack_text_id(text_id)
return dget(ix)&bit !=0
end
function completion_tracker:_unpack_text_id(text_id)
assert(text_id>0)
assert(text_id<120) -- max 120 texts for now
-- using bytes 1 through 15
local ix,bit=1+text_id\8,text_id%8
assert(ix<16)
return ix,1<<bit
end
function completion_tracker:should_show_tutorial()
return self:get_completion_level() < tutorial.completion_stage
end

BIN
cover.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -10,16 +10,18 @@ function cursor:init(board)
self.board=board
self.hover_x=self.ruleset.n_slots\2
self.hover_y=1
self.grabbed=nil
self.saved_hover_x_y=nil
self.grabbed_slots={}
end
function cursor:acceptance_state()
if self.grabbed then
local hover=self:hover_slot()
if hover==self.grabbed then
local hover=self:hover_slot()
local slot=self:grabbed_slot()
if slot then
if hover==slot then
return acceptance_state.no_move
end
local source=self.board.slots[self.grabbed]
local source=self.board.slots[slot]
local target=self.board.slots[self:hover_slot()]
local card=source:peek()
if target:would_accept(card) then
@ -28,35 +30,115 @@ function cursor:acceptance_state()
return acceptance_state.would_not_accept
end
else
return acceptance_state.not_grabbed
if (self.board.slots[hover]:peek()) return acceptance_state.not_grabbed
return acceptance_state.would_not_accept
end
end
function cursor:save_hover()
self.saved_hover_x_y={self.hover_x,self.hover_y}
end
--[[
function cursor:restore_hover()
self.wants_to_restore_hover=true
end
]]
--[[
function cursor:actually_restore_hover()
if (not self.saved_hover_x_y) return
-- self.wants_to_restore_hover=false
-- try restoring hover x
local old_hover_x,old_hover_y=self.hover_x,self.hover_y
self.hover_x,self.hover_y=unpack(self.saved_hover_x_y)
-- try very hard to be in a valid spot
for i in all{
function() self.hover_x,self.hover_y=old_hover_x,old_hover_y end,
function() self:move_x(-1) end,
function() self:move_y(1) end,
function() self:move_x(-1) end,
function() self:move_y(-1) end
} do
if (self:acceptance_state()!=acceptance_state.would_not_accept) return
i()
end
end
]]--
function cursor:toggle_grab()
local acc,src,tar=self:acceptance_state()
local slot=self:hover_slot()
if acc==acceptance_state.not_grabbed then
if (self.board.slots[self:hover_slot()]:peek()) self.grabbed=self:hover_slot()
if (not self.board.watcher:intercept("grab",slot)) sounds:dire() return
if (self.board.slots[slot]:peek()) self.grabbed_slots={slot}
self:save_hover()
sounds:menu()
elseif acc==acceptance_state.would_accept then
local card=src:pop()
tar:add(card)
self.grabbed=nil
self.board:on_move(card)
if (not self.board.watcher:intercept("drop",slot)) sounds:dire() return
self.board:pre_move(src:peek())
while self:acceptance_state() == acceptance_state.would_accept do
local card=src:pop()
tar:add(card)
deli(self.grabbed_slots)
end
self.grabbed_slots={}
self.board:on_move()
-- if (#self.grabbed_slots == 0) self:restore_hover()
sounds:menu()
elseif acc==acceptance_state.no_move or acc==acceptance_state.would_not_accept then
self.grabbed=nil
self:drop_grab()
else
assert(false,"invalid acceptance state")
end
end
function cursor:incr_grab()
local slot=self:hover_slot()
if (slot!=self:grabbed_slot()) return
if (not self.board.watcher:intercept("incr_grab",slot)) sounds:dire() return
local new_card = self.board.slots[slot]:peek(#self.grabbed_slots)
if (not new_card) return
local old_card = self.board.slots[slot]:peek(#self.grabbed_slots-1)
if (not self:_can_incr_grab(old_card,new_card)) return
add(self.grabbed_slots,slot)
sounds:menu()
end
function cursor:drop_grab_silent()
self.grabbed_slots={}
end
function cursor:drop_grab()
if (not self.board.watcher:intercept("cancel")) sounds:dire() return
self.grabbed_slots={}
-- self:restore_hover()
sounds:menu()
end
function cursor:update()
-- if (self.wants_to_restore_hover) self:actually_restore_hover()
end
function cursor:move_x(dx)
if (self.hover_y==0) return
self.hover_x+=dx
self.hover_x%=self.ruleset.n_slots -- TODO: Don't hard-code
if (dx==0) return
local orig_x=self.hover_x
while true do
self.hover_x+=dx
self.hover_x%=self.ruleset.n_slots
if (self.hover_x==orig_x) return
if (self:acceptance_state()!=acceptance_state.would_not_accept) return true
end
return
end
function cursor:move_y(dy)
local old_y=self.hover_y
if (self.hover_y==0 and dy==1) self.hover_y=1
if (self.hover_y==1 and dy==-1) self.hover_y=0
if (self.hover_y==1 and dy==-1 and #self.grabbed_slots<2) self.hover_y=0
if (self:acceptance_state()==acceptance_state.would_not_accept) if (not self:move_x(-1)) self.hover_y=old_y
end
function cursor:hover_slot()
@ -64,50 +146,42 @@ function cursor:hover_slot()
return self.hover_x+1
end
function cursor:grabbed_slot()
return self.grabbed_slots[#self.grabbed_slots]
end
function cursor:grabbed_card()
if self.grabbed then
local slot=self.board.slots[self.grabbed]
return slot:peek()
local grabbed_slot=self:grabbed_slot()
if grabbed_slot then
return self.board.slots[grabbed_slot]:peek()
end
return nil
end
function cursor:draw_at(l,x,y)
local card=self:grabbed_card()
local acc=self:acceptance_state()
function cursor:draw_at(l,i)
local slot=self:grabbed_slot()
if card and acc!=acceptance_state.would_accept and acc!=acceptance_state.no_move then
x+=sin(time()/2)*2+0.5
y+=sin(time()/4)+0.5+1
end
x=flr(x)
y=flr(y)
local function draw_surround_box(fg)
if (not fg) return
if l.rotated then
rect(x-4,y+6,x+13,y+16,fg)
else
rect(x-1,y-1,x+9,y+16,fg)
end
if not slot then
local filled=false
if (i<1) i=1 filled=true
draw_layout_hint(l,i,12,filled)
return
end
local function draw_overlapping_box(fg)
if (l.obscured) draw_surround_box(fg) return
if l.rotated then
rectfill(x-3,y+7,x+12,y+15,fg)
else
rectfill(x,y,x+8,y+15,fg)
end
end
local not_moving=self:acceptance_state()==acceptance_state.no_move
for i2=1,#self.grabbed_slots do
local ix=i2-1
if (not_moving) ix=#self.grabbed_slots-i2
local card=self.board.slots[slot]:peek(ix)
if card then
local x,y=l:place_card(i+i2+1)
local card_fg=self.ruleset.deck:draw_card(x,y,card,{rotate=l.rotated})
local fg=card_fg
if (acc==acceptance_state.would_accept) fg=9
draw_surround_box(fg)
else
draw_overlapping_box(9)
if (i2==1) draw_layout_hint(l,i+i2+1,9,false)
end
end
function cursor:_can_incr_grab(c0,c1)
c0=self.board.ruleset.deck.cards[c0]
c1=self.board.ruleset.deck.cards[c1]
if (c0.suit!=c1.suit) return false
return c0.rank==c1.rank+1 or c1.rank==c0.rank+1
end

35
democrap.lua Normal file
View File

@ -0,0 +1,35 @@
democrap={
patterns={
0b1111111111111111,
0b1111111111111111,
0b1111111111111111,
0b1111111111111111,
0b1111111111111111,
0b1111111111111111,
0b1111111111111111,
0b1111111111111100,
0b1111111111110000,
0b1111110011110000,
0b1111000011110000,
0b1111000011000000,
0b1111000000000000,
0b1100000000000000,
0b0000000000000000
}
}
function democrap:distort_screen(progress)
if (progress <= 0) return
progress=min(progress,1)
for src=0x6004,0x7fc4,64 do
dst=src+sin(t()+src/0x800)*(4*progress)+0.5
memcpy(dst,src,56)
end
local ps=democrap.patterns
local p=ps[1+flr(progress*#ps)] or ps[#ps]
fillp(p)
local old=@0x5333
poke(0x5f33,1)
rectfill(0,0,127,127,13)
poke(0x5f33,old)
fillp()
end

View File

@ -2,7 +2,6 @@
modules={}
function _init()
-- printh("restarting")
_doall("init")
end
@ -33,43 +32,10 @@ function klass()
return k
end
function alives(tbl)
local tbl2={}
for i in all(tbl) do
if (not i.dead) add(tbl2,i)
end
return tbl2
end
function trunc4(x)
if (x < 0) return -trunc4(-x)
return x\0.25/4
end
function stepstep(by,x0,x1,f)
local x=x0
if (x==x1) return
if x0>x1 then
return stepstep(by,-x0,-x1,function(x) return f(-x) end)
end
x=x\by*by
while true do
x+=by
if (x>=x1) f(x1) break
if (not f(x)) break
end
end
function lerp(x,x0,x1)
return x0+x*(x1-x0)
end
function csv(s)
function gsv(s)
local ret=split(s,"\n")
for i,v in ipairs(ret) do
ret[i] = type(v) == "string" and split(v) or {v} end
ret[i] = type(v) == "string" and split(v,"`") or {v} end
return ret
end

37
layout_hint.lua Normal file
View File

@ -0,0 +1,37 @@
function draw_layout_hint(l,i,fg,filled,tut_border)
-- layout, index
local x,y=l:place_card(i)
if (l.obscured) filled=false
if filled then
if l.rotated then
rectfill(x-3,y+7,x+12,y+15,fg)
else
rectfill(x,y,x+8,y+15,fg)
end
else
if tut_border then
local exclude=1+flr(time()*3)%3
pal(1,14)
pal(2,14)
pal(3,14)
palt(13,true)
pal(exclude,13)
if l.rotated then
spr(32,x-5,y+5,3,2)
else
-- rect(x-3,y-3,x+11,y+18,13)
spr(14,x-2,y-2,2,3)
end
pal()
palt()
return
end
if l.rotated then
rect(x-4,y+6,x+13,y+16,fg)
else
rect(x-1,y-1,x+9,y+16,fg)
end
end
end

151
liturgy.lua Normal file
View File

@ -0,0 +1,151 @@
liturgy={
holy_book=gsv[[rood 1`1,2,3
rood 2`4,5,6,7
rood 3`8,9,10
rood 4`11,12,13
rood 5`14,15,16,17,18
rood 6`19,20
rood 7`21,22,23
rood 8`24,25,26]],
sacred_text_lines=gsv
[[1`one meerkat, one day
1`stood on two legs. it said:
1`'come into this thicket.
1` i have a bright wreath.
1` my laurel is vibrant.'
2`all sweet things tolerated,
2`those who came when called
2`were sheared of their fur.
2`this was the first day:
2`the dandelions blown.
3`the hollow,
3`which opens to a key: music.
3`the meerkats were led there.
3`where they stood.
4`now even the water
4`knows how to talk.
4`their leader, first to stand,
4`calls them to choir.
5`a dulcimer's sweet harmony and,
5`pretending to weep,
5`it announces the title of
5`a scroll: 'the fate.'
6`now they are a regiment.
6`gather them.
6`pour oil.
7`catching a leaf, ride it.
7`suture its veins.
7`scatter glass in the vineyard.
8`lanias came in silver.
8`he milled the wheat and barley.
8`he took oranges from the trees.
8`meerkats dashed to the ferns.
8`he raised his bow and screamed.
9`the bolt became the wind.
9`the silver sails lashed.
9`the silver ospreys swarmed.
9`the silver shadow wailed.
10`burning oil from bay to sky.
10`scampering keas in bags!
10`there was no one in the field.
10`lanias came and went in silver.
11`ravens are an old people.
11`but the mandate is new.
11`the spry one turns in the egg.
12`it reads 'the fate':
12`'man is woman'
12`'a house in heaven
12` is bought on earth.'
12`and not by hatching.
13`the egg turns. it cracks.
13`a meerkat tumbles out.
13`cold, it breathes its last.
14`when lanias drags down stars
14`in his net, he cannot
14`take down one: beauty.
15`he cannot envy the vain,
15`so lanias wrote this rood:
15`the vain will not have it.
16`no longer is 'the fate':
16`there are many fates.
16`the music is over now.
16`it is quiet in the garden.
17`where are you? a small bird,
17`divine. you are in the fences.
17`you are seedling, little one.
17`the gorgeous lily blooms.
18`a star in the sky shines
18`and you are born.
18`accept its blessing: caw,
18`do not sing.
19`you have your room.
19`i have mine.
19`let's dig a river,
19`and build a bridge.
20`let's dig a trap.
20`let's line it with spikes.
20`let's cover it with a sheet,
20`and bury it in soil.
21`a cuckoo stole an egg.
21`in the nest it left its young.
21`the summer was so lean
21`and the snow so deep.
22`it was plump as a berry
22`and it hatched.
22`meerkats were in the trees.
23`lanias said: old men suffer
23`and die for nothing. listen:
23`when you grow: you won't
23`understand it. you want what
23`you cannot have.
24`night is here.
24`you're asleep.
24`you leave this body.
24`you won't want to come back.
25`cross your eyes: 'the fate'
25`is in them, their tears,
25`their music, their silence.
26`our rood is the final one.
26`those we killed have been
26`planted like seeds. this rood,
26`like this city, will not
26`be destroyed.]]
}
function liturgy:init()
local verse_lines={}
for line in all(self.sacred_text_lines) do
local verse=tonum(line[1])
if (not verse_lines[verse]) verse_lines[verse]={}
add(verse_lines[verse], line[2])
end
local annotated_verses={}
for bookdata in all(self.holy_book) do
local name=bookdata[1]
local ix=1
for verse in all(split(bookdata[2])) do
local annotated_verse_name=name
local lines=verse_lines[verse]
annotated_verse_name..=":"..ix.."-"
ix+=#lines
annotated_verse_name..=ix-1
local annotated_verse=""
for l in all(lines) do
if (annotated_verse!="") annotated_verse..="\n"
annotated_verse..=l
end
annotated_verses[verse]={annotated_verse_name,annotated_verse}
end
end
self.annotated_verses=annotated_verses
end
liturgy:init()
function liturgy:suggest_verse(ruleset,card)
local meta=ruleset.deck.cards[card]
local i=2+meta.rank
if (meta.suit!="a") i=ruleset.preferred_verse or i
return i, unpack(liturgy.annotated_verses[i])
end

View File

@ -3,36 +3,23 @@ add(modules,main)
function main:init()
extcmd("rec")
self.board=board:new(progression[1])
self.state_manager=state_manager:new() -- instantiate one global
self.state_manager:push(state_menu:new())
--[[
local b=board:new(watcher:new(progression[#progression],1,{}))
b.last_card=75
self.state_manager:push(state_wonround:new(b))
]]--
if (completion_tracker:should_show_tutorial()) self.state_manager:push(state_ironman:new(tutorial)) self.state_manager:push(state_content_warning:new())
end
function main:update()
self.board:update()
if self.board:can_take_input() then
if (btnp(0)) self.board.cursor:move_x(-1)
if (btnp(1)) self.board.cursor:move_x(1)
if (btnp(2)) self.board.cursor:move_y(-1)
if (btnp(3)) self.board.cursor:move_y(1)
if (btnp(4)) self.board.cursor:toggle_grab()
end
self.state_manager:update()
end
function main:draw()
cls(13)
self.board:draw()
-- bg
pal(13,-3,1)
-- arcana
-- pal(1,0,1)
pal(15,-9,1)
-- suits
pal(4,-11,1) -- first suit
pal(12,12,1)
pal(2,-8,1)
pal(3,-5,1)
-- pal(8,-9,1)
-- pal(14,8,1)
self.state_manager:draw()
apply_palette()
end

409
main.p8
View File

@ -1,90 +1,107 @@
pico-8 cartridge // http://www.pico-8.com
version 41
__lua__
-- raven's rood
-- by pyrex and nyeo
#include engine.lua
#include palette.lua
#include animator.lua
#include board.lua
#include board_animations.lua
#include checkpoint.lua
#include completion_tracker.lua
#include dealer.lua
#include democrap.lua
#include cursor.lua
#include layout.lua
#include layout_hint.lua
#include liturgy.lua
#include music_manager.lua
#include ruleset.lua
#include palette.lua
#include progression.lua
#include seed_constants.lua
#include seeds.lua
#include sounds.lua
#include state_archaeology.lua
#include state_content_warning.lua
#include state_excavate_menu.lua
#include state_manager.lua
#include state_menu.lua
#include state_gameround.lua
#include state_ironman.lua
#include state_reset_menu.lua
#include state_wonironman.lua
#include state_wonround.lua
#include tutorial.lua
#include text.lua
#include watcher.lua
#include main.lua
--[[
srand(2)
for i=1,10 do
print(tostr(rnd(),2))
end
stop()]]
__gfx__
00000000000000000000000000000000777770000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000007000000777000000070000700070000707070000000000000000000000000000000000000000000000000000000000000000000000000000000000
07070000007000000777000000700000707070000077770000000000000000000000000000000000000000000000000000000000000000000000000000000000
00700000007000000777000000700000707070000770700000000000000000000000000000000000000000000000000000000000000000000000000000000000
07070000077700000070000007000000777070000077777000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000007000000777000007000000700070000700777000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000707770000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000070000000700000007000000000000000000000000000000000000000000000000000
00000000000070000000700000700070007000700070007000700070007000700070007000700070070707000707070007070700000000000000000000000000
00000000000000000000000000000000000000000000000000000000000070000000700000007000007777000077770000777700000000000000000000000000
00007000000000000000700000000000000070000070007000707070000000000070007000700070077070000770700007707000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000070000000000000007000007777700077777000777770000000000000000000000000
00000000000070000000700000700070007000700070007000700070007000700070007000700070070077700700777007007770000000000000000000000000
00000000000000000000000000000000000000000000000000000000000070000000700000007000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000077777000000000000000000000000000000000000000000000000000000000000000000000000000ddddddddddddd000
0000000000700000077700000007000070007000070707000000000000000000000000000000000000000000000000000000000000000000d31231231231d000
0707000000700000077700000070000070707000007777000000000000000000000000000000000000000000000000000000000000000000d20000000002d000
0070000000700000077700000070000070707000077070000000000000000000000000000000000000000000000000000000000000000000d10000000003d000
0707000007770000007000000700000077707000007777700000000000000000000000000000000000000000000000000000000000000000d30000000001d000
0000000000700000077700000700000070007000070077700000000000000000000000000000000000000000000000000000000000000000d20000000002d000
0000000000000000000000000000000070777000000000000000000000000000000000000000000000000000000000000000000000000000d10000000003d000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d30000000001d000
0000000000000000000000000000000000000000000000000000000000007000000070000000700000000000000000000000000000000000d20000000002d000
0000000000007000000070000070007000700070007000700070007000700070007000700070007007070700070707000707070000000000d10000000003d000
0000000000000000000000000000000000000000000000000000000000007000000070000000700000777700007777000077770000000000d30000000001d000
0000700000000000000070000000000000007000007000700070707000000000007000700070007007707000077070000770700000000000d20000000002d000
0000000000000000000000000000000000000000000000000000000000007000000000000000700000777770007777700077777000000000d10000000003d000
0000000000007000000070000070007000700070007000700070007000700070007000700070007007007770070077700700777000000000d30000000001d000
0000000000000000000000000000000000000000000000000000000000007000000070000000700000000000000000000000000000000000d20000000002d000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d10000000003d000
dddddddddddddddddddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d30000000001d000
d123123123123123123d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d20000000002d000
d300000000000000001d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d13213213213d000
d200000000000000002d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ddddddddddddd000
d100000000000000003d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
d300000000000000001d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
d200000000000000002d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
d100000000000000003d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
d300000000000000001d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
d200000000000000002d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
d100000000000000003d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
d321321321321321321d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
dddddddddddddddddddd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
fffffffff000000000000000000000000000000000000ff00000000000000000000000a000000000000000000000000000000000000000000000000000000000
0ff0000fff00000000000000000000000000000000000ff00000000000fff000900009aa0000a000000000000000000000000000000000000000000000000000
0ff00000ff000ffff00ffff00fff00ffff000ff0fff00f00fffff000000fff00999009aa00aaa000000000000000000000000000000000000000000000000000
0ff0000ff000f000ff00ff0000f00f000ff0ffff00ff000ff000f00000fff000099999aaaaaa0000000000000000000000000000000000000000000770000000
0ff0fff000000000ff00ff0000f0ff000ff00ff000ff000ff000000000000000099999aaaaaa0000000000000000000000000000000000000000777700000000
0ff00ff000000fffff000ff00f00fffffff00ff000ff000ffff0000000000000099999aaaaaa0000000000000000000000000000000000000777777700000000
0ff000ff0000f000ff000ff00f00ff0000000ff000ff00000ffff00000000000009999aaaaa00000000000000000000000000000000000007777777700000000
0ff0000ff00ff000ff0000f0f000ff0000000ff000ff0000000ff00000000000009999aaaaa00000000000000000000000000000000000777777777000000000
0ff00000ff0ff00fff0000fff0000ff000f00ff000ff000f000ff000000000000000000000000000000000000000000000000000000007777777700000000000
ffff0000fff0fff0fff0000f000000ffff00ffff00fff00fffff0000000000000000000000000000000000000000000000000000000077777777000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000777777770000000000000
fffffffff0000000000000000000000000fff0000000000000000000000000000000000000000000000000000000000000000000007777777700000dd0000000
0ff0000fff0000000000000000000000000ff000000000000000000000000000000000000000000000000000000000000000000000777777700000ddd0000000
0ff00000ff000ffff00000ffff00000fff0ff0000000000000000000000000000000000000000000000000000000000000000000077777770000dddddd000000
0ff0000ff000ff00ff000ff00ff000ff00fff00000000000000000000000000000000000000000000000000000000000000000000777777700ddddddd0000000
0ff0fff0000ff0000ff0ff0000ff0ff0000ff0000000000000000000000000000000000000000000000000000000000000000000777777770ddddddd00000000
0ff00ff0000ff0000ff0ff0000ff0ff0000ff0000000000000000000000000000000000000000000000000000000000000000000777777777dddddd000000000
0ff000ff000ff0000ff0ff0000ff0ff0000ff000000000000000000000000000000000000000000000000000000000000000000077777777dddddd0000000000
0ff0000ff00ff0000ff0ff0000ff0ff0000ff000000000000000000000000000000000000000000000000000000000000000000077777777ddddd00000777000
0ff00000ff00ff00ff000ff00ff000ff00fff000000000000000000000000000000000000000000000000000000000000000000077777777dddd000007777770
ffff0000fff00ffff00000ffff00000fff0fff0000000000000000000000000000000000000000000000000000000000000000077777777dddd0000077777777
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000777777dd7ddd7770777777700
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000777777d7777777777777777000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007777777777777777777777777000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000777777777777777777777777777700
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007777777777777777777770000777700
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000077707777777777777777000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000077777777777777777770000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000077777777777777777770000700000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000077770000007777777700000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000077700000000077770000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000
c9311100fc009820e4509a50ca603c90a3a009a0d5b00dd055f027215d21a531e531d6319831e8317931277132a5120a007276821161320416d14631d331e862
7462511341324319b5779502eb05d82194423941818023885111644669aa2a169110a1561bb28201632467214103762f4812302241975603a9799117a3111c31
54224678216131332299517613113822a1a81b2191451b9d4a12444e2146331121146b18a623a1212143b4414461930716662c10145931ca52421046d1d46453
@ -149,6 +166,136 @@ fa1da3a42c14300b02d04505c8f103471874735968bb1cd203743347342fd27240c1b61350475064
00113043464471777326217676060195001268be8381430c862a1c2b0265a4234a69635140318597cb49370643550c2a314e33781b490095f73245600a00de12
041497c80550a4701604144259018e4314582680b0bb8a28b4061216010d3063521c666031d4460d1412012e2547030e2389252b19e9da341623912035220923
220d61f5d10673575950d15619fb7355715a214d604411ab425c28017fa0069204b0663402432027a2205515603021b5012178664215329112a53b219206035f
__label__
5555gggggggggggggggggg55555555555555555555555555555555555555gggggggg55gggggg5555555555555555gggggggggggggggggggggggggggggggggggg
5555gggggggggggggggggg55555555555555555555555555555555555555gggggggg55gggggg5555555555555555gggggggggggggggggggggggggggggggggggg
55gggggggggggggggggggg55555555gggggggggggg5555555555555555gggggggggggggggg5555555555555555gggggggggg5555gggggggggggggggggggggg55
55gggggggggggggggggggg55555555gggggggggggg5555555555555555gggggggggggggggg5555555555555555gggggggggg5555gggggggggggggggggggggg55
gggggggggg555555gggggg555555gggggggggggggggggg55555555gggggggggggggggggggg55555555555555gggggggggg555555gggggggggggggggggg555555
gggggggggg555555gggggg555555gggggggggggggggggg55555555gggggggggggggggggggg55555555555555gggggggggg555555gggggggggggggggggg555555
gggggggg555555555555gg55gggggggggggggggggggggggggggggggggggggggggggggggg55555555555555gggggggg555555555555gggggggggggggg55555555
gggggggg555555555555gg55gggggggggggggggggggggggggggggggggggggggggggggggg55555555555555gggggggg555555555555gggggggggggggg55555555
gggggg5555555555555555gggggggggggggggggggggggggggggggggggggggggggggggggg55555555555555gggg55555555555555gggggggggggggg555555gg55
gggggg5555555555555555gggggggggggggggggggggggggggggggggggggggggggggggggg55555555555555gggg55555555555555gggggggggggggg555555gg55
55gg55555555555555gggggggggggggggggg5555gggggggggggggggggggggggggggggg5555555555555555gg55555555555555gggggggggggggggg5555555555
55gg55555555555555gggggggggggggggggg5555gggggggggggggggggggggggggggggg5555555555555555gg55555555555555gggggggggggggggg5555555555
5555555555555555gggggggggggggg55555555gggggggggggggggggggggggggggggggg555555555555555555555555555555gggggggggggggggggg5555555555
5555555555555555gggggggggggggg55555555gggggggggggggggggggggggggggggggg555555555555555555555555555555gggggggggggggggggg5555555555
5555555555555555gggggggg55555555555555gggggggggggggggggggggggggggggggg5555555555555555555555555555gggggggggggggggggggg55555555gg
5555555555555555gggggggg55555555555555gggggggggggggggggggggggggggggggg5555555555555555555555555555gggggggggggggggggggg55555555gg
555555555555555555gggg5555555555555555gggggggggggggggggggggggggggggggg55555555555555555555555555gggggggggg555555gggggg555555gggg
555555555555555555gggg5555555555555555gggggggggggggggggggggggggggggggg55555555555555555555555555gggggggggg555555gggggg555555gggg
55gggggggg55555555555555555555555555gggggggggggggggggggggggggggggggggg555555555555555555555555gggggggggg555555555555gg55gggggggg
55gggggggg55555555555555555555555555gggggggggggggggggggggggggggggggggg555555555555555555555555gggggggggg555555555555gg55gggggggg
gggggggggggggggg5555555555555555gggggggggggggggggggggggggggggggggggg555555555555555555555555gggggggggg5555555555555555gggggggggg
gggggggggggggggg5555555555555555gggggggggggggggggggggggggggggggggggg555555555555555555555555gggggggggg5555555555555555gggggggggg
gggggggggggggg5555555555555555gggggggggggggggggggggggggggggggggggggg555555555555555555555555555555gg55555555555555gggggggggggggg
gggggggggggggg5555555555555555gggggggggggggggggggggggggggggggggggggg555555555555555555555555555555gg55555555555555gggggggggggggg
gggg55gggggg5555555555555555gggggggggggggggggggggggggggggggggggggg5555555555555555555555555555555555555555555555gggggggggggggg55
gggg55gggggg5555555555555555gggggggggggggggggggggggggggggggggggggg5555555555555555555555555555555555555555555555gggggggggggggg55
gggggggggg5555555555555555gggggggggg5555gggggggggggggggggggggg55555555555555555555555555555555555555555555555555gggggggg55555555
gggggggggg5555555555555555gggggggggg5555gggggggggggggggggggggg55555555555555555555555555555555555555555555555555gggggggg55555555
gggggggggg55555555555555gggggggggg555555gggggggggggggggggg55555555555555555555555555555555555555555555555555555555gggg5555555555
gggggggggg55555555555555gggggggggg555555gggggggggggggggggg55555555555555555555555555555555555555555555555555555555gggg5555555555
gggggggg55555555555555gggggggg555555555555gggggggggggggg555555555555555555555555555555555555555555gggggggg5555555555555555555555
gggggggg55555555555555gggggggg555555555555gggggggggggggg555555555555555555555555555555555555555555gggggggg5555555555555555555555
gggggggg55555555555555gggg55555555555555gggggggggggggg555555gg55555555555555555555555555555555gggggggggggggggggg5555555555555555
gggggggg55555555555555gggg55555555555555gggggggggggggg555555gg55555555555555555555555555555555gggggggggggggggggg5555555555555555
gggggg5555555555555555gg55555555555555gggggggggggggggg55555555555555555555555555555555555555gggggggggggggggggg5555555555555555gg
gggggg5555555555555555gg55555555555555gggggggggggggggg55555555555555555555555555555555555555gggggggggggggggggg5555555555555555gg
gggggg555555555555555555555555555555gggggggggggggggggg55555555555555555555555555555555555555gggggggg55gggggg5555555555555555gggg
gggggg555555555555555555555555555555gggggggggggggggggg55555555555555555555555555555555555555gggggggg55gggggg5555555555555555gggg
gggggg5555555555555555555555555555gggggggggggggggggggg55555555gggggggggggg5555555555555555gggggggggggggggg5555555555555555gggggg
gggggg5555555555555555555555555555gggggggggggggggggggg55555555gggggggggggg5555555555555555gggggggggggggggg5555555555555555gggggg
gggggg55555555555555555555555555gggggggggg555555gggggg555555gggggggggggggggggg55555555gggggggggggggggggggg55555555555555gggggggg
gggggg55555555555555555555555555gggggggggg555555gggggg555555gggggggggggggggggg55555555gggggggggggggggggggg55555555555555gggggggg
gggggg555555555555555555555555gggggggggg555555555555gg55gggggggggggggggggggggggggggggggggggggggggggggggg55555555555555gggggggg55
gggggg555555555555555555555555gggggggggg555555555555gg55gggggggggggggggggggggggggggggggggggggggggggggggg55555555555555gggggggg55
gggg555555nnnnnnnnnnnnnnnnnngggggggggg5555555555555555ggggggggggggggggggggggggggggggggggggggggggggggnnnn55555555555555gggg555555
gggg555555nnnnnnnnnnnnnnnnnngggggggggg5555555555555555ggggggggggggggggggggggggggggggggggggggggggggggnnnn55555555555555gggg555555
gggg55555555nnnn55555555nnnnnn5555gg55555555555555gggggggggggggggggg5555ggggggggggggggggggggggggggggnnnn55555555555555gg55555555
gggg55555555nnnn55555555nnnnnn5555gg55555555555555gggggggggggggggggg5555ggggggggggggggggggggggggggggnnnn55555555555555gg55555555
gg5555555555nnnn5555555555nnnn555555nnnnnnnn5555nnnnnnnnggggnnnnnn5555nnnnnnnnggggggnnnnggnnnnnnggggnn5555nnnnnnnnnn555555555555
gg5555555555nnnn5555555555nnnn555555nnnnnnnn5555nnnnnnnnggggnnnnnn5555nnnnnnnnggggggnnnnggnnnnnnggggnn5555nnnnnnnnnn555555555555
555555555555nnnn55555555nnnn555555nn555555nnnn55ggnnnngg555555nn5555nnggggggnnnnggnnnnnnnnggggnnnngggg55nnnn555555nn555555555555
555555555555nnnn55555555nnnn555555nn555555nnnn55ggnnnngg555555nn5555nnggggggnnnnggnnnnnnnnggggnnnngggg55nnnn555555nn555555555555
555555555555nnnn55nnnnnn555555555555555555nnnn5555nnnn55555555nn55nnnnggggggnnnnggggnnnnggggggnnnngggg55nnnn55555555555555555555
555555555555nnnn55nnnnnn555555555555555555nnnn5555nnnn55555555nn55nnnnggggggnnnnggggnnnnggggggnnnngggg55nnnn55555555555555555555
555555555555nnnn5555nnnn5555555555ggnnnnnnnnnn555555nnnn5555nn5555nnnnnnnnnnnnnnggggnnnnggggggnnnngggg55nnnnnnnn55555555555555gg
555555555555nnnn5555nnnn5555555555ggnnnnnnnnnn555555nnnn5555nn5555nnnnnnnnnnnnnnggggnnnnggggggnnnngggg55nnnnnnnn55555555555555gg
555555555555nnnn555555nnnn5555ggggnnggggggnnnngg5555nnnn5555nn55ggnnnnggggggggggggggnnnnggggggnnnngg55555555nnnnnnnn55555555gggg
555555555555nnnn555555nnnn5555ggggnnggggggnnnngg5555nnnn5555nn55ggnnnnggggggggggggggnnnnggggggnnnngg55555555nnnnnnnn55555555gggg
555555555555nnnn55555555nnnnggggnnnnggggggnnnn55555555nn55nn55ggggnnnnggggggggggggggnnnnggggggnnnngg555555555555nnnn555555555555
555555555555nnnn55555555nnnnggggnnnnggggggnnnn55555555nn55nn55ggggnnnnggggggggggggggnnnnggggggnnnngg555555555555nnnn555555555555
555555555555nnnn5555555555nnnnggnnnn55ggnnnnnn55555555nnnnnnggggggggnnnnggggggnnggggnnnnggggggnnnn555555nn555555nnnn555555555555
555555555555nnnn5555555555nnnnggnnnn55ggnnnnnn55555555nnnnnnggggggggnnnnggggggnnggggnnnnggggggnnnn555555nn555555nnnn555555555555
ggggggggggnnnnnnnn55555555nnnnnnggnnnnnnggnnnnnn55555555nngggggggggg55nnnnnnnnggggnnnnnnnnggggnnnnnn5555nnnnnnnnnn55555555555555
ggggggggggnnnnnnnn55555555nnnnnnggnnnnnnggnnnnnn55555555nngggggggggg55nnnnnnnnggggnnnnnnnnggggnnnnnn5555nnnnnnnnnn55555555555555
gggggggggggggg55555555gggggggggggggggggggg55555555555555gggggggggg555555gggggggggggggggggg55555555555555555555555555555555555555
gggggggggggggg55555555gggggggggggggggggggg55555555555555gggggggggg555555gggggggggggggggggg55555555555555555555555555555555555555
ggggggggggnnnnnnnnnnnnnnnnnngggggggggggg55555555555555gggggggg555555555555ggggnnnnnngggg5555555555555555555555555555555555555555
ggggggggggnnnnnnnnnnnnnnnnnngggggggggggg55555555555555gggggggg555555555555ggggnnnnnngggg5555555555555555555555555555555555555555
ggggggggggggnnnnggggggggnnnnnngggggggggg55555555555555gggg55555555555555ggggggggnnnngg555555gg55555555555555555555555555555555gg
ggggggggggggnnnnggggggggnnnnnngggggggggg55555555555555gggg55555555555555ggggggggnnnngg555555gg55555555555555555555555555555555gg
gggg5555ggggnnnnggggggggggnnnnggggggnnnnnnnn5555555555nnnnnnnn55555555ggnnnnnnggnnnngg55555555555555555555555555555555555555gggg
gggg5555ggggnnnnggggggggggnnnnggggggnnnnnnnn5555555555nnnnnnnn55555555ggnnnnnnggnnnngg55555555555555555555555555555555555555gggg
555555ggggggnnnnggggggggnnnnggggggnnnn5555nnnn555555nnnn5555nnnn5555ggnnnnggggnnnnnngg55555555555555555555555555555555555555gggg
555555ggggggnnnnggggggggnnnnggggggnnnn5555nnnn555555nnnn5555nnnn5555ggnnnnggggnnnnnngg55555555555555555555555555555555555555gggg
555555ggggggnnnnggnnnnnnggggggggnnnngg555555nnnn55nnnn55555555nnnnggnnnnggggggggnnnngg55555555gggggggggggg5555555555555555gggggg
555555ggggggnnnnggnnnnnnggggggggnnnngg555555nnnn55nnnn55555555nnnnggnnnnggggggggnnnngg55555555gggggggggggg5555555555555555gggggg
555555ggggggnnnnggggnnnnggggggggnnnngg555555nnnn55nnnn55555555nnnnggnnnngg555555nnnngg555555gggggggggggggggggg55555555gggggggggg
555555ggggggnnnnggggnnnnggggggggnnnngg555555nnnn55nnnn55555555nnnnggnnnngg555555nnnngg555555gggggggggggggggggg55555555gggggggggg
5555ggggggggnnnnggggggnnnnggggggnnnngg555555nnnn55nnnn55555555nnnnggnnnn55555555nnnngg55gggggggggggggggggggggggggggggggggggggggg
5555ggggggggnnnnggggggnnnnggggggnnnngg555555nnnn55nnnn55555555nnnnggnnnn55555555nnnngg55gggggggggggggggggggggggggggggggggggggggg
ggggggggggggnnnnggggggggnnnnggggnnnn55555555nnnn55nnnn555555ggnnnnggnnnn55555555nnnn55gggggggggggggggggggggggggggggggggggggggggg
ggggggggggggnnnnggggggggnnnnggggnnnn55555555nnnn55nnnn555555ggnnnnggnnnn55555555nnnn55gggggggggggggggggggggggggggggggggggggggggg
ggggggggggggnnnnggggggggggnnnnggggnnnn5555nnnn555555nnnn5555nnnn55gg55nnnn5555nnnnnngggggggggggggggg5555gggggggggggggggggggggggg
ggggggggggggnnnnggggggggggnnnnggggnnnn5555nnnn555555nnnn5555nnnn55gg55nnnn5555nnnnnngggggggggggggggg5555gggggggggggggggggggggggg
ggggggggggnnnnnnnnggggggggnnnnnngg55nnnnnnnn5555555555nnnnnnnn5555555555nnnnnn55nnnnnngggggggg55555555gggggggggggggggggggggggggg
ggggggggggnnnnnnnnggggggggnnnnnngg55nnnnnnnn5555555555nnnnnnnn5555555555nnnnnn55nnnnnngggggggg55555555gggggggggggggggggggggggggg
gggg5555gggggggggggggggggggggg55555555555555555555555555555555555555555555555555gggggggg55555555555555gggggggggggggggggggggggggg
gggg5555gggggggggggggggggggggg55555555555555555555555555555555555555555555555555gggggggg55555555555555gggggggggggggggggggggggggg
gg555555gggggggggggggggggg55555555555555555555555555555555555555555555555555555555gggg5555555555555555gggggggggggggggggggggggggg
gg555555gggggggggggggggggg55555555555555555555555555555555555555555555555555555555gggg5555555555555555gggggggggggggggggggggggggg
5555555555gggggggggggggg555555555555555555555555555555555555555555gggggggg55555555555555555555555555gggggggggggggggggggggggggggg
5555555555gggggggggggggg555555555555555555555555555555555555555555gggggggg55555555555555555555555555gggggggggggggggggggggggggggg
55555555gggggggggggggg555555gg55555555555555555555555555555555gggggggggggggggggg5555555555555555gggggggggggggggggggggggggggggggg
55555555gggggggggggggg555555gg55555555555555555555555555555555gggggggggggggggggg5555555555555555gggggggggggggggggggggggggggggggg
555555gggggggggggggggg55555555555555555555555555555555555555gggggggggggggggggg5555555555555555gggggggggggggggggggggggggggggggggg
555555gggggggggggggggg55555555555555555555555555555555555555gggggggggggggggggg5555555555555555gggggggggggggggggggggggggggggggggg
5555gggggggggggggggggg55555555555555555555555555555555555555gggggggg55gggggg5555555555555555gggggggggggggggggggggggggggggggggggg
5555gggggggggggggggggg55555555555555555555555555555555555555gggggggg55gggggg5555555555555555gggggggggggggggggggggggggggggggggggg
55gggggggggggggggggggg55555555gggggggggggg5555555555555555gggggggggggggggg5555555555555555gggggggggg5555gggggggggggggggggggggg55
55gggggggggggggggggggg55555555gggggggggggg5555555555555555gggggggggggggggg5555555555555555gggggggggg5555gggggggggggggggggggggg55
gggggggggg555555gggggg555555gggggggggggggggggg55555555gggggggggggggggggggg55555555555555gggggggggg555555gggggggggggggggggg555555
gggggggggg555555gggggg555555gggggggggggggggggg55555555gggggggggggggggggggg55555555555555gggggggggg555555gggggggggggggggggg555555
gggggggg555555555555gg55gggggggggggggggggggggggggggggggggggggggggggggggg55555555555555gggggggg555555555555gggggggggggggg55555555
gggggggg555555555555gg55gggggggggggggggggggggggggggggggggggggggggggggggg55555555555555gggggggg555555555555gggggggggggggg55555555
gggggg5555555555555555gggggggggggggggggggggggggggggggggggggggggggggggggg55555555555555gggg55555555555555gggggggggggggg555555gg55
gggggg5555555555555555gggggggggggggggggggggggggggggggggggggggggggggggggg55555555555555gggg55555555555555gggggggggggggg555555gg55
55gg55555555555555gggggggggggggggggg5555gggggggggggggggggggggggggggggg5555555555555555gg55555555555555gggggggggggggggg5555555555
55gg55555555555555gggggggggggggggggg5555gggggggggggggggggggggggggggggg5555555555555555gg55555555555555gggggggggggggggg5555555555
5555555555555555gggggggggggggg55555555gggggggggggggggggggggggggggggggg555555555555555555555555555555gggggggggggggggggg5555555555
5555555555555555gggggggggggggg55555555gggggggggggggggggggggggggggggggg555555555555555555555555555555gggggggggggggggggg5555555555
5555555555555555gggggggg55555555555555gggggggggggggggggggggggggggggggg5555555555555555555555555555gggggggggggggggggggg55555555gg
5555555555555555gggggggg55555555555555gggggggggggggggggggggggggggggggg5555555555555555555555555555gggggggggggggggggggg55555555gg
555555555555555555gggg5555555555555555gggggggggggggggggggggggggggggggg55555555555555555555555555gggggggggg555555gggggg555555gggg
555555555555555555gggg5555555555555555gggggggggggggggggggggggggggggggg55555555555555555555555555gggggggggg555555gggggg555555gggg
55gggggggg55555555555555555555555555gggggggggggggggggggggggggggggggggg555555555555555555555555gggggggggg555555555555gg55gggggggg
55gggggggg55555555555555555555555555gggggggggggggggggggggggggggggggggg555555555555555555555555gggggggggg555555555555gg55gggggggg
gggggggggggggggg5555555555555555gggggggggggggggggggggggggggggggggggg555555555555555555555555gggggggggg5555555555555555gggggggggg
gggggggggggggggg5555555555555555gggggggggggggggggggggggggggggggggggg555555555555555555555555gggggggggg5555555555555555gggggggggg
gggggggggggggg5555555555555555gggggggggggggggggggggggggggggggggggggg555555555555555555555555555555gg55555555555555gggggggggggggg
gggggggggggggg5555555555555555gggggggggggggggggggggggggggggggggggggg555555555555555555555555555555gg55555555555555gggggggggggggg
gggg55gggggg5555555555555555gggggggggggggggggggggggggggggggggggggg5555555555555555555555555555555555555555555555gggggggggggggg55
gggg55gggggg5555555555555555gggggggggggggggggggggggggggggggggggggg5555555555555555555555555555555555555555555555gggggggggggggg55
gggggggggg5555555555555555gggggggggg5555gggggggggggggggggggggg55555555555555555555555555555555555555555555555555gggggggg55555555
gggggggggg5555555555555555gggggggggg5555gggggggggggggggggggggg55555555555555555555555555555555555555555555555555gggggggg55555555
gggggggggg55555555555555gggggggggg555555gggggggggggggggggg55555555555555555555555555555555555555555555555555555555gggg5555555555
gggggggggg55555555555555gggggggggg555555gggggggggggggggggg55555555555555555555555555555555555555555555555555555555gggg5555555555
gggggggg55555555555555gggggggg555555555555gggggggggggggg555555555555555555555555555555555555555555gggggggg5555555555555555555555
gggggggg55555555555555gggggggg555555555555gggggggggggggg555555555555555555555555555555555555555555gggggggg5555555555555555555555
__map__
c30111e665c2b118f005bb151891000098020109634a06445a66afc5d3572f39d001b11430e3e61748055e3fd2637052131f2002560d516492b5020f990002b002f021f560105023b02d203145db2173d6341920c04b96902a31290d662d910e2752f9c05504756d0fb298534135a1a47803080f05360051613425132229001a
d505aa3b118eb2f2c4333549a23b566224356131b5834961e12254034233120950235312522720922fb5e63672625833f9076b7242ca37d4bf5993aa1801f4c7346c2135300a0b625c674b2153531e33641560011046633b111045225280117720054d3a8f2619caed2015d3591418114689412040f632155d3331095f836644
@ -157,19 +304,113 @@ d505aa3b118eb2f2c4333549a23b566224356131b5834961e1225403423312095023531252272092
70954c1817109352c5410681966841290376240ba3f26050311a12110340a2505703112022c0023da045850c514513424822930514b06403532e235a783717104760256632d9a212272711306328d47551b51b4c8610acf67a11171810339055e1331841200028a2611a977291bc0633572201044ba2d638db0dc860213021c3
d112540c847a3d2b88693720504c31e4c2a055431ea47602f804e4f405ea10be68d639ab9642a1a0f9744232be8b125319405159f512649d3402d0f79b242cc8070585421956f10584116d681c448868019160838b3092e51133c11263b7e4a313b74352a3a46110ad32d144b302e26975019463487231002d09c89c9840767c
1233002a63a4119274ca950163625513502e12302efaa1f0da9bd420612524a1633109a700f00006686083c205503d7474030070402a080b771442d79631632280e071b7d0fbb7412f13543919c4033e083182299b4330060551235013a835620e5a550325022a2d7b6250b34740163bde22730861f407910271937553c120b5
c744206292856e00177230131e46015d219b307ea03d1374224f339b0332ac1d305462d2072b67cc2b2c719fd41b6d7055c4034638560aa482d0b4174a44155203a5f26b03e1c4050a061bb02125530606752302412b605a53d7031508303520ee7358104b094101782e0da82aa965130b220f5118784700058771bb09c1848a
84e32894119c8c830111590f933415202a40e60104443520d85821d00105399c0423922c8a8c60c600a333716c6097531112330c7bb050227f550833742371ac8e2e2312dd34e095107d34612049251a3deb6208401203151a43a27a118cf1a03f760708847432034f246608904943930431780a3ed102d070346a8180e40001
b5fba3451b167353e0ab21fec20653f18161b035200815132041a5511b50c80cb8ec658516319143950f05932c71460162439bb00c35530113be243271389c083c73c731106070335009dd0051113622908990265b11472516044a777d4707da0a9053504030942690db86053408221540300221a1b223d201403440048d1f48
4031617635e060621524e87647400b86740349c001590791270282f1305f32609b70132269a2e523f29108033096e310074312114a134e52922a29092b23421793346149671bd491176025541256501109144457253663a3041a394b173931169515f337ae26330c801902d2354d51a0d502f19a68088df41a38841f83044202
165400107b081e045b2d911211a8712289a63102323b2a767022341116b34c639c0304052bc382e21905427000630d0344c8516c4665925034920b9e82e6539039736e020647801142321b12b421352743f871c100440b6f531b020113e6371140020437a921126a05779678c4402151412281754c4778ca02ac432553e12607
330d3b1af86533a032400724969268734f760a27f45001fc40174422188a161d2b20289007145394e66022a840575b320200f8407e833275018515844490ad0274093119b1a8010367323f2135ad8338806974bdcf944424070b0100c95446014320023a08347f77b21f31872f09139552112c417007140f63fcb520a4112016
0295260120027224b5b87554902044101506154406128150c06446423260ca5002317a18f37405043057165158a6084708c515050021be292a811208283572c826a2810977302ec94a55ff919502b2a33442144b74715544716219300212f37011e813c08fd56608a386131e44f220902515151bc569b305210218c1e545826c
4d34323500a9431391130198127276500440b220a1422b6b58b6a6367635e10b61808b7002313e52053a146635275f70118a2339ba62046d760b5000d3bd0012687814013f87a2a306831030325632662132df101a5135900a7f1b3300e00860033081ec4010c00204b14440037253060c2451d45409e76d349560b2593b3365
32459905b00864008c262420078270533013221a930d612db04c05a42fb620419293885f24e59110d0005c320075cd4841a019089c63f521d6b8c92babf6430b48030084324d0025af206b02e0300bf8854a07666b0423108028201456180b4216287129020549401639a610ba03231030662131c41543d3b070208d0a123230
71431b689680b02410030f304bfb6684a31fc6017605041745581335b0749863260429ad11e061ed6e25a287895137ef20b21260418041d2a04408aa5b960a230a1b522000b325e270a090811741436d45572801621c4496bd57895524875309220b5187209a1b20519b253842509224b56812a2910935501f1d040a008a2460
155508248600254795b5b16ea19227d1778a7880d91843084837f450a85c0013035505588001e0718000312c7340025143107c3f1e39c5515151621712018f7700112d8117095613020005794534d3241ab897b0d1bd287c0020012b01f0008d4b05418a400af2271362259c660a090391020222c0df12e86b3440000584050c
5637072006bf05e801b465c2621967083d0b0398115119a8a3035b04210310cba70b9aa852730f100d307b00062fb003b20767442823f233303082432338c029c70e761c3814180802150300df070980c19b3745ea37f075717622a530a08765450627000082080a0054706b6695b73832b009290054e7001c98404c2be41203
aa5d07675526e306a49c50e220e7350148d085070623116528350f05003090f21400007d0047c035240273124800700339218809070000b43005252e00371000840c048e01ea2084000d5530c12756ac1d93d0d5c060c70004d0106720b8c800b0d8e0038000504108d78577810481533ba0f0c804000c07005205760000b850
02f76081e1020f00d0d01e9a14224e1e4078186105860002404003070950000090001f430910009b0300290de050d6d02077c01400f00400048d00e050060c500c87060000020d00c0006540d290002100586000a0d00d00b14a00000a00f044f9002800600003a0400af00b0409580d040070670c0005000009e80500000020
0000070000080678000300600009000b00d06000000f0d77e0000000000400c000009610d00000000000a050000000000000080000a0d0000a60d805000000080000026000b00000000060c0e000000000000080500004000009e0000306000000000000000000000706700000000050d0600000906000b00000900c00000000
00030d00c0050000090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
c744206292856e00177230131e4664132299e1cb25282d52b13828222771226595220403221d43773619434346126c3567c96af1356d483de56b331814220046b94129728703d0161517aa693313119c341152942202213d0f1f3f26e9332496232652160c514733116f421606531606104212d4a953269428a1125134a1d912
0eb422597b26350120a171e349612134c9142d146749443a140164485321c32601712ac41553453c214fb331161a65e2311177e8260325372426315b61313431198737c765a021231371d1125145133556411898141f522524f242365433456f33d1c3851221d8856206221266a11902860574f2c2f669925566e1111414c216
17383d226bb8043e7225a85d2a54a253020293660733115946a1320927aad3b3062216247d464736831c541a55e3111133321844817061314233552193ff90261b2115c3311b0f11394d112c4b50b226832392a1800362e0af2112964d51c62e7438138044111251527392453356127117a4411e248128543533430112251446
83645030104244478b155ca4692124a7218533bd53d241a2285d231014c2404d8a4a3893e5311961125b8ca4c05718918a6a22fa37133a16443366c0ef85111113c11455a33f14751e14158c1329235342037e4851a118373e8123318690513322191542512c343211e12364535642522d851577d5031131a138388026281d23
4117175b245135513316154f5128b77794216263421a2343431311a184232183197d861324702222405412743042d311014272164277061d76144351142869112287525947671572332141e8951123821203a5e0862b4b354e1fb26a21728815247d154173b42354321b79e552161b41b2503203182e4b6082e414b233331639
121334545121215928201243496b6827120283421a11100245161641634b91b514137d1812ecd1513b2472615615311681783ad325b945b4402636f2a56321125051546183466a11312e64cd91263281da08321132af727a3e726714219329984c2120046523493343415c42fa969b3316921b6514d5ab2a0cd5135342353425
d206c1895317208b2de9282306212575c00233774525443c0f812116531c830224481114144a3118d210c21473403c7953773536496c23a222eb02829461138291c63113276135357d001236316101010251e6a72aab5343410243d6e1125a2f492f7d1ed486627333559362436e472c1a042a12671a7e251133fe725e521653
41e913524751c3037713931886122a5333192129a3315f390f11425f81141ae11e4594146216cd26424bb52d79115100267010503862403941458b52b259527d235a1335a84153811735631359012d74206d3e5a45b18341301102252980647329127411134317ac232312825c9042920c262a80231434551040439991d68e22
5efb5b7c040b81037c5d437350ac1f44137816585262514866a35c3a9152504d17191410113001133d217b45132e34c192124951696506b11e2422425013a9a360248c25142471a6d50192401265c5024523301244541421018c52247191a0233975403812111e9433531727325171432918580310b03159411130221834a212
3111b7d0849034ed18467546445e2b3167255e79165432a331705302731704321109454d0341e61812b6d42eb5771922c28bc22620063780836e81622b135d31b1622aab15522382156322d23113536643231643a5a49e1371693151622649ac561598477102584c601212b15813b504231351813239eb237622c0321896153c
3486b40b2d4231d242282e36a1e6726a12a1302d14f3d1400529e2f19643207240ee304011231952567133651e2143621739061162108bd51f232358514e3135122d1122a5138418f8233354401121281234913781f031213346a1b43342303127d243318931023a5e01a2233b448d644462444261412323233e21f217a31429
741114111131124046148334d11335112223525ff4471301199555613413565326933b1d2102a1140711c14188c365261222f18d107519116014231709e5059181b33791143555116381a05b3279b533316c582838377716c23065147444329d137295fd8790264c18f77014161053362d18631d0d5a42120689912c9c553846
1571b752651e1b3173befa40215c1574f082332ca51e482d510a9419e91132166214903271193c61a7c6153378111241021461a03053455311d2244115a33a11362646e44b31134b1015c179e1c2f843134912233e71566542713761111de19c893725541e4195112a9a5a384411e53519553312f2911c20e00695b237944452
228256512f66243b14c0414a12b915a17485cc1336a41d166571b39272251b38136142846559e2d46316031b4711044f43625867974535a87348160882162355c71339439562e22421253266289a3a26092643ac631c33c08414b933102370392411193533719733230f3b0314e48435460612326b20904515919322e3639d43
8a074c50428115e11322211931133e1355519a21a26981d96042210a12d323c32884d6e833c4756b1c311773352367394025473561809122110b56042330b1231427854c724d64492359a112343295360a204808598543044d522c2b5696152456b11416325124319121427124836b0daa2917131b3135441335e2217ca2029f
564011f57a1036357762523322096ff25183883a59305548245832cc32a55583cf1184202161a751e4a709034223344852a19456db41a634823171345c77122a4a1d11402b462e430546171aa413a85247b6a45286074a211536282332323936a327243333a62724248a537216143720e16041107f0612f413611222e3421001
5604b1d04e19331b34405b2542811616221019132cdb2e36c302371801ad521931840fb4213110c59645731821c7731101d506c1930202623f524a033165112133369272d2548f23821580662142151432933910316146ac3231b73875510283462a23216868111f2ea042641358deb33e24488161388a70d91313115d634003
c492289b5141433d10374b16ac6712152316072551b722065a5283281a38c5231917332655ba5132645398212681682366db513652522963701fe6723a24511d01384ce43011451847018f145627a209222c220271255a694633a9051ccd817d5637235922660701b13a672095b2180038bd21e40a215147541542a093157131
11815492467355afc91233693c11353858911a9435472621655585113bb221b41231b7503d446362128922324731c7464641d6621824a229a261503263221082a3c16342933fe47632531159b36121c4c2617387d2981056ada6034141238333442c30816334d66a12841135335e3614732211ea451553443241434600a51605
ac49a4516135e231316332ea30311c4262420391515020b57bd441827626ac3121117111e314397621634cb3447532223145c52549d3474b525a1c989c31b862b1326188144227333515131111fc3b65b224f64bd1527f81533141132c0400436907b5a141116192500377c52a4204cb5b1443093181151372271275a5c21543
0213443436179d540a0421b1332362702b151242c2450e1821020294022d139137116a265363201a417e6bc5e1a31234223159790027b329244251720d751333b1252336219722c103e2724730b622fb01376883122163095251130106632831c48231207c9502184135264193b2424137132e90260124b61613235227611101
13712081357d5710d54533453922517613848b628b3b641f43a7663345121216810362b2c7156715654325282652161c51606571a9496a031289a2214237520b1418c711153501152334053265f63459171a382d422ca31647d14515b66413354007a217748646555a90432161424550847b2265129382112252243570e43c51
65c36534685711e9102895112512419d21062604c95c130841452445322376286c511128422626915a101d1784631830017c530411332960ae66b0413c47d931b13c711089060157a17361523352b25d1361221c656591611341ab14204a11439732663150620112032a4302036325e8322eb5573042a212431b18cf56578e33
01447a75130226312881342247810740351d14141305239e12a4a2a05f13240a271933164e873663574b18d11154b2a2c2b508bd1139611c011433129273356283427d6691126215131a293225461533e0141302912a4014a0a339c5412251367842eb475112a2161c3053660c4165f0088114571448943b44b0213366192131
3595095320212d4246bb3525231d3b3234458d54831ad803236b13b2846895482785e36db149044cb33736ca3e121195567012831f4015944f3b1e536b19875925733040180b521901843ca07c561341e32205335aa1312525119424621210263825580964765b25958843f318b4b51518289837551312e812d22097226242e0
__sfx__
911300001305013031130321303213032130321105011031110321103211032110321505215031150321503215032150321503215032150321503215032150321503215032150321503215032150321503215032
911300001305013031130321303213032130321303213032130321303013030130301303013032130321303215050150311503015030150321503215032150301503015030150301503215032150321503215030
911300001605016031160301603016032160321805018031180301803018030180301105011031110301103011030110301103011030110321103211032130501505015031150321305011050110311103013052
911300001005210052100520905009031090300905009031090300903009030090300903009032090320903215050150311503015030150301503015030150301503015030150321503215032150301503015030
911300001806018031180301803218032180321606016031160301603216032160321a0601a0411a0401a0421a0421a0421a0401a0401a0401a0421a0421a0421a0421a0421a0511a0501a0501a0521a0521a052
91130000180501803118030180301803018030180321803218032180321803218032180321803218032180321a0601a0411a0401a0401a0401a0401a0421a0421a0421a0421a0421a0421a0421a0421a0421a040
911300001b0501b0311b0301b0321b0321b0321d0501d0311d0301d0321d0321d0321605016031160301603016030160301603216032160321603216032180501a0501a0311a0301805016050160311603218052
911300001505015031150300e0500e0310e0300e0500e0310e0300e0300e0300e0300e0300e0300e0300e0301a0501a0311a0301a0301a0301a0301a0301a0301a0301a0301a0301a0301a0301a0301a0301a030
91130000190511a0311a0301a0301a0301a0301805018031180301803018030180301c0511c0311c0301c0301c0301c0301c0301c0301c0301c0301c0301c0301c0301c0301c0301c0301c0301c0301c0301b031
911300001a0501a0311a0301a0301a0301a0301a0301a0301a0301a0301a0301a0301a0301a0301a0301a0301a0301a0301a0301a0301a0301a0301a0301a0301a0301a0301a0301a0301a0301a0301a0301a030
011300000c7530000007050070211a643000000000000000050500502105025000001a643000000a0500a0500c7530000000000000001a643000000a0500a0210a02500000000001a60302050020210102500000
011300000c7530000000050000211a643000000000000000000500002100025000001a6430000000000000000c7530000005050050501a643000000000000000050500505005025000001a643000000000000000
0113000000000000000c0500c0210c0250000000000000000a0500a0210a0250000000000000000f0500f0210f02500000000000000000000000000f0500f0210f02500000000000000007050070210602500000
011300000c753050000502505021050250000000000000000c753050000502505021050250000000000000000c7530a0000a0250a0210a0250000000000000000c7530a0000a0250a0210c753000000a0250a021
011300000c7530c0210c0200c0200c0200c0200c0200c0200c7530a0210a0200a0200a0200a0200a0200a0200c7530f0210f0200f0200f0200f0200f0500f0210c7530f0200f0200f02007050070210702006021
011300000c753050000502005020040250000000000000000c753050000502005020050200502005020050200c753000000a0500a0210a0250000000000000000c7530a0000a0200a0200a0200a0200a02500000
1513000000000000001a5552155521215265551a215000001b5552255522215275551b215000001a5552155521215265551a215000001a2051a2051a205000000c7530000000000000001a643000001a64300000
1513000000000000001c5552155521215285551c215000001c5552155521215285551c215000001d5552155521215295551d2150000000000000001d5552155521215295551d2150000000000000000000000000
1513000000000000001f52026520265212b5202b5202b5202052027520275212c5202c5202c5201f52026520265202b5202b5212b5222b5222b5202b5202b5202b5202b5202b5202b5202b5202b5202b5202b520
151300002b5202b5211f52526520265212b5202b5212b5202052527520275212c5202c5212c5221f52526520265212b5202b5222b5222b5222b5222b5222b5222b5222b5222b5222b5222b5222b5222b5222b522
151300002b5202b5222152026520265222d5202d5222d5222152026520265222d5202d5222d5222252026520265202e5202e5222e5222e5222e5202e5202e5202e5202e5202252026520265202f5202f5202f520
011300000c7530000000000000001a6430000000000000000c7530000000000000001a6430000000000000000c7530000000000000001a6430000000000000000c7530000000000000001a643000000000000000
011300000c7000000000000000001a6030000000000000000c7530000000000000001a6030000000000000000c7000000000000000001a6030000000000000000c7530000000000000001a643000000000000000
151300003053030530305303053030530305302e5302e5302e5202e5202e5202e5203252032520325203252032520325203052030520305203052030520305213051030510305103051030511305103051030510
a51300003051030510305103051030510305103051030510305103051030510305103051030510305103051524500245002450024500245002450024500245002450024500245002450024500245002450024500
011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
930a00003766437625000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
954a00002b66518000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
010400000c25512255232550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0108000013335113000c3000c3050c305000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
__music__
01 00551544
00 01551544
00 020a1644
00 030b1644
00 000a1644
00 010b1644
00 020a1644
00 030b1644
00 000a1044
00 010b1044
00 020a1044
00 030b1144
00 040c1244
00 050d1344
00 060e1344
00 070f1444
00 08171544
02 09181544

19
music_manager.lua Normal file
View File

@ -0,0 +1,19 @@
music_manager={}
add(modules,music_manager)
function music_manager:init()
self._allow=true
end
function music_manager:allow(a)
self._allow=a
end
function music_manager:update()
if (not self._allow) music(-1,0) return
local is_playing = stat(54) != -1
local should_be_playing = completion_tracker:get_music_preference()
if (is_playing and not should_be_playing) music(-1,500)
if (not is_playing and should_be_playing) music(0)
local label,pref="start music",true
if (should_be_playing) label,pref="stop music",false
menuitem(1,label,function() completion_tracker:set_music_preference(pref) end)
end

17
palette.lua Normal file
View File

@ -0,0 +1,17 @@
function apply_palette()
-- bg
pal(13,-3,1)
-- arcana
-- pal(1,0,1)
pal(15,-9,1)
-- suits
pal(4,-11,1) -- first suit
pal(12,12,1)
pal(2,-8,1)
pal(3,-5,1)
-- pal(8,-9,1)
-- pal(14,8,1)
end

View File

@ -1,17 +1,16 @@
progression={
ruleset:new(11,5,10,25),
-- level 1
ruleset:new(5,1,9,0), -- by test: always winnable
ruleset:new(1,5,1,9,0,nil,1), -- by test: always winnable
-- level 2
ruleset:new(5,2,9,0), -- by test: always winnable
ruleset:new(2,5,2,9,0,nil,2), -- by test: always winnable
-- level 3
ruleset:new(7,2,9,8), -- by test: always winnable
ruleset:new(3,7,2,9,8), -- by test: always winnable
-- level 4 (first challenging)
ruleset:new(9,3,9,16, "l4"),
ruleset:new(4,9,3,9,16, "l4"),
-- level 5
ruleset:new(9,3,11,18, "l5"),
ruleset:new(5,9,3,11,18, "l5"),
-- fortune's foundation
ruleset:new(11,4,13,22,"ff"),
ruleset:new(6,11,4,13,22,"ff"),
-- harder than fortune's foundation
ruleset:new(11,5,10,25)
ruleset:new(7,11,5,10,25,"l7")
}

View File

@ -1,5 +1,6 @@
ruleset=klass()
function ruleset:init(
completion_level,
-- Number of unlocked slots (up to 11)
-- Includes the one in the middle
-- For Fortune's Foundation: 11
@ -17,13 +18,16 @@ function ruleset:init(
-- Number of arcana (unbounded)
-- For Fortune's Foundation: 22
n_arcana,
pool
pool,
preferred_verse
)
self.completion_level=completion_level
self.n_slots=n_slots
self.n_suits=n_suits
self.n_cards_per_suit=n_cards_per_suit
self.n_arcana=n_arcana
self.pool=pool
self.preferred_verse=preferred_verse
assert(self.n_slots<=11)
assert(self.n_suits<=5)
assert(self.n_cards_per_suit<=13)
@ -164,24 +168,31 @@ function ruleset:generate_layouts()
local ruleset=self
local width=ruleset.n_slots*10
local x=(128-width)\2
local y=9 -- 1 is also fine
function layouts:well(i)
if i<=ruleset.n_suits then
local wx=width-ruleset.n_suits*10+(i-1)*10
return layout:new(x+wx,1,layout_mode.obscured)
return layout:new(x+wx,y,layout_mode.obscured)
end
i-=ruleset.n_suits
if (i==1) return layout:new(x,1,layout_mode.obscured)
if (i==2) return layout:new(x+10,1,layout_mode.obscured)
if (i==1) return layout:new(x,y,layout_mode.obscured)
if (i==2) return layout:new(x+10,y,layout_mode.obscured)
if (i==3) return layout:new(x+5,y,layout_mode.rotated)
assert(false,"unknown well")
end
function layouts:checkpoint()
local wx=(ruleset.n_slots\2)*10
return layout:new(x+wx,y,layout_mode.obscured)
end
function layouts:slot(i)
if i<=ruleset.n_slots then
local sx=(i-1)*10
return layout:new(x+sx,18,layout_mode.vertical)
return layout:new(x+sx,y+17,layout_mode.vertical)
end
if (i==ruleset.n_slots+1) return layout:new(x+width-ruleset.n_suits*5-5,1,layout_mode.rotated)
if (i==ruleset.n_slots+1) return layout:new(x+width-ruleset.n_suits*5-5,y,layout_mode.rotated)
assert(false, "unknown slot")
end
end

View File

@ -15,15 +15,16 @@ def main():
# analyze(level_4)
level_5 = load_seeds("input/level_5.txt")[:5000]
# analyze(level_5)
ff = load_seeds("input/fortunes_foundation.txt")
ff = load_seeds("input/fortunes_foundation.txt")[:7578]
# analyze(ff)
# level_7 = load_seeds("input/level_7.txt")[:5000]
level_7 = load_seeds("input/level_7.txt")[:6000]
# analyze(level_7)
level_4_data = negencode_16b(level_4)
level_5_data = negencode_delta_4b(level_5)
ff_data = delta_4b(ff)
level_7_data = delta_4b(level_7)
all_data = b""
@ -31,19 +32,19 @@ def main():
for block, data in [
("l4", level_4_data),
("l5", level_5_data),
("ff", ff_data)
("ff", ff_data),
("l7", level_7_data),
]:
offsets[f"{block}_start"] = len(all_data)
all_data += data
offsets[f"{block}_end"] = len(all_data)
augment_map("../main.p8", "../seed_constants.lua", all_data, offsets)
def augment_map(target, constants_file, binary, offsets):
assert isinstance(binary, bytes) and len(binary) < 8192 # length of mapdata
print(f"Length of basic extra map data: {len(binary)}")
assert isinstance(binary, bytes) and len(binary) <= 8192 # length of mapdata
mapdata = (binary + bytes([0] * 8192))[:8192]
cart = Pico8Cart.load(target)

File diff suppressed because it is too large Load Diff

View File

@ -4,5 +4,7 @@ seed_constants={
l5_start=4138,
l5_end=4679,
ff_start=4679,
ff_end=11017
ff_end=9102,
l7_start=9102,
l7_end=12288
}

View File

@ -4,6 +4,7 @@ function seeds:init()
self.l4=seed_pool:new(seed_constants.l4_start,seed_constants.l4_end,_naive_16b,true)
self.l5=seed_pool:new(seed_constants.l5_start,seed_constants.l5_end,_delta_4b,true)
self.ff=seed_pool:new(seed_constants.ff_start,seed_constants.ff_end,_delta_4b)
self.l7=seed_pool:new(seed_constants.l7_start,seed_constants.l7_end,_delta_4b)
end
function seeds:choose(pool)
if (pool) return self[pool]:choose()

View File

@ -1,854 +0,0 @@
81
11
124
76
10
111
128
63
106
136
50
150
6
152
74
27
113
91
171
18
167
16
125
51
148
198
93
146
200
219
196
83
177
14
237
36
262
239
276
169
285
138
242
241
259
299
302
279
182
166
191
159
306
255
320
309
295
328
313
373
269
348
340
388
286
354
428
382
398
322
441
343
469
319
453
488
456
520
525
414
508
361
529
527
521
494
569
563
417
580
589
594
614
605
422
596
505
593
676
511
682
660
413
512
483
716
722
731
629
696
741
445
743
683
688
706
771
734
773
647
778
789
752
612
764
820
622
689
814
833
793
797
863
737
767
742
738
795
816
772
897
928
879
940
949
882
934
960
957
968
973
780
864
962
976
899
982
1019
919
931
936
1009
1033
905
1034
1026
1068
1014
1015
1029
1097
975
1104
1032
1059
1040
1089
1125
1147
1126
1061
1167
1062
1148
1055
1145
1094
1215
817
1098
1186
1211
1177
1196
1239
1235
1245
1225
1263
1237
955
1163
1217
1194
1202
1276
1334
1252
1150
1191
1285
1368
1336
1328
1332
1370
1384
1376
1400
1341
1244
1288
1379
1262
1427
1236
1457
1248
1473
1466
1475
1472
1436
1428
1495
1286
1504
1509
1483
1453
1476
1317
1479
1511
1350
1535
1357
1529
1505
1555
1542
1559
1563
1576
1581
1525
1577
1603
1607
1630
1619
1546
1450
1524
1435
1669
1647
1597
1689
1629
1566
1677
1705
1701
1624
1402
1676
1642
1723
1719
1743
1611
1711
1679
1745
1782
1627
1779
1765
1716
1750
1807
1812
1653
1776
1728
1831
1731
1801
1784
1848
1832
1783
1826
1878
1706
1790
1791
1746
1862
1896
1828
1872
1903
1915
1921
1906
1947
1931
1919
1930
1936
1833
1841
1968
1645
1994
1997
1954
1970
1979
2016
1913
1957
2034
1898
2004
1927
2061
2044
1834
2068
2079
1987
1870
1953
2096
2078
2101
2106
1965
1958
2134
1969
2029
2139
2092
1961
2128
2123
2140
2064
2062
2071
2067
2195
2102
2200
2148
2111
2023
2138
2223
2165
2232
2115
2247
2112
2157
2257
2118
2206
2229
2191
2171
2268
2302
2283
2221
2331
2094
2318
2289
2186
2250
2350
2170
2243
2366
2337
2193
2286
2303
2400
2377
2332
2358
2227
2336
2253
2166
2404
2262
2093
2413
2202
2440
2371
2457
2379
2429
2491
2402
2238
2405
2315
2502
2431
2465
2531
2326
2519
2419
2430
2569
2533
2596
2602
2471
2616
2554
2590
2517
2560
2548
2407
2643
2580
2618
2498
2619
2617
2650
2334
2641
2689
2706
2685
2585
2717
2658
2644
2695
2744
2578
2687
2672
2768
2661
2651
2772
2669
2620
2795
2770
2787
2761
2629
2813
2851
2854
2725
2800
2888
2900
2844
2625
2897
2815
2934
2940
2942
2937
2947
2834
2846
2825
2830
2624
2777
2980
2747
2906
2871
3006
2956
3051
3090
3048
3065
3088
2977
2941
2912
3025
3062
3103
3133
3086
2960
3153
3127
3165
3137
3147
3008
3177
3123
3110
2976
3197
3015
3164
3144
3035
3221
3225
3207
3224
3237
2982
3239
3240
3248
3097
3182
3186
3161
3099
2966
3264
3091
3256
3202
3293
3265
3272
3252
3298
3310
3228
3227
3297
3322
3320
3365
3234
3350
3332
3187
3307
3409
3226
3413
3418
3391
3430
3294
3397
3323
3438
3436
3315
3433
3398
3449
3302
3480
3530
3481
3304
3493
3541
3511
3574
3479
3576
3412
3411
3231
3510
3598
3572
3437
3335
3374
3582
3593
3619
3620
3590
3609
3667
3683
3607
3669
3484
3497
3546
3725
3628
3726
3738
3514
3723
3526
3727
3766
3748
3767
3779
3785
3661
3761
3824
3729
3812
3708
3854
3808
3595
3835
3827
3801
3858
3823
3886
3883
3512
3861
3860
3897
3863
3874
3876
3912
3906
3901
3909
3744
3895
3869
3787
3962
3934
3961
3960
3993
3859
3942
3917
3976
3868
4010
3923
4031
3935
4058
3978
4062
3956
3933
4028
4013
4018
3952
4083
4089
4066
4116
4132
4021
3815
4006
4153
4093
3924
4047
4024
4057
4001
4165
4180
4072
3926
4172
4161
4197
4192
4098
4052
4157
4224
3982
4202
4191
4080
4234
4252
4228
4048
4269
4272
4243
3991
4214
4246
4245
4271
4050
4320
4336
4285
4355
4357
4262
4248
4338
4315
4302
4343
4291
4385
4388
4280
3990
4389
4342
4383
4353
4423
4288
4427
4365
4409
4459
4467
4421
4477
4151
4370
4502
4511
4481
4528
4494
4446
4547
4533
4537
4323
4554
4555
4491
4593
4538
4562
4536
4603
4619
4553
4639
4573
4514
4646
4664
4665
4581
4655
4673
4647
4405
4683
4731
4607
4703
4699
4745
4742
4739
4755
4782
4557
4776
4800
4766
4701
4762
4829
4852
4738
4773
4788
4728
4756
4862
4859
4860
4718
4877
4689
4903
4879
4865
4925
4844
4888
4770
4929
4956
4957
4858
4961
4857
4924
4861
4878
4962
4909
4883
4993
4967
4991
5004
5021
5039
4893
4975
5019
4936
5060
5002
5046
5015

File diff suppressed because it is too large Load Diff

13
sounds.lua Normal file
View File

@ -0,0 +1,13 @@
sounds={}
function sounds:menu()
sfx(63,3)
end
function sounds:deal_card()
sfx(60,3)
end
function sounds:dire()
sfx(62,3)
end
function sounds:win()
sfx(61,3)
end

94
state_archaeology.lua Normal file
View File

@ -0,0 +1,94 @@
state_archaeology=klass()
function state_archaeology:init(tips_mode)
self.tips_mode=tips_mode
self.n_holy_books=#liturgy.holy_book
self:select_book(1)
end
function state_archaeology:enter() end
function state_archaeology:exit(new_top) end
function state_archaeology:reenter() end
function state_archaeology:suspend() end
function state_archaeology:select_book(n)
self.selection=n
if (self.tips_mode) self.title="tips" self.full_text=archaeology_tips return
local lines={}
local hb=liturgy.holy_book[self.selection]
self.title=hb[1]
printh()
for source in all(split(hb[2])) do
for line in all(liturgy.sacred_text_lines) do
if (line[1]==source) add(lines,self:_censor(source,line[2]))
end
end
self.full_text=""
for i=1,#lines do
if (i>1) self.full_text..="\n"
self.full_text..=lines[i]
end
end
function state_archaeology:_censor(src,line)
if (completion_tracker:was_seen(src)) return line
local line2=""
for i=1,#line do
local c=sub(line,i,i)
if ("a"<=c and c<="z") c="?"
line2..=c
end
return "\f6"..line2.."\ff"
end
function state_archaeology:update()
local vel=0
if (btnp(0)) vel-=1
if (btnp(1)) vel+=1
if (btnp(5)) sounds:menu() self.done=true
if (vel!=0) sounds:menu() self:select_book((self.selection+vel-1)%self.n_holy_books+1)
end
function state_archaeology:draw()
local fullw,fullh=measure_text(self.full_text)
local total_height=fullh+16
cls(13)
local y=64-total_height\2
local tw=measure_text(self.title)-1
local x=64-tw\2
local tx=x
print(self.title,x,y,15)
y+=6
line(x,y,x+tw-1,y,15)
y+=3
local x=64-fullw\2
rectfill(x-1,y-1,x+fullw,y+fullh-1,4)
print(self.full_text,x,y,15)
y+=fullh+1
line(tx,y,tx+tw-1,y,15)
y+=2
if not self.tips_mode then
print("⬅️",tx,y)
print("➡️",tx+tw-7,y)
end
print("❎ go back",1,122,15)
end
archaeology_tips=[[
wise archaeologists know these
secrets:
- hold ❎ to get a new board.
- hold 🅾️ to pick up more than
one card.
- updates and other games by
pyrex and nyeo are
available at nyeogmi.itch.io
and lexaloffle.
only diligent research can
uncover sacred mysteries!
- p & n]]

42
state_content_warning.lua Normal file
View File

@ -0,0 +1,42 @@
state_content_warning=klass()
function state_content_warning:init(prior_menu)
self.prior_menu=prior_menu
self.frame=0
self.frames=4
self.progress=0
end
function state_content_warning:enter() music_manager:allow(false) end
function state_content_warning:exit(new_top) music_manager:allow(true) end
function state_content_warning:reenter() end
function state_content_warning:suspend() end
function state_content_warning:update()
for i=0,6 do
if (btnp(i)) self.done=true
end
end
function state_content_warning:draw()
cls(0)
print([[
raven's rood explores post-
colonial subject matter,
including violent conflict
leading to genocide.
these themes are artistically
essential and inseparable from
the overall content of the game.
we understand all games are not
suitable for every individual.
we hope you enjoy our game
despite the bleak nature of its
subject matter.
once you continue, the tutorial
will begin, and you will not
encounter this message again.
]],2,2,6)
print("🅾️ continue",2,121,15)
end

23
state_excavate_menu.lua Normal file
View File

@ -0,0 +1,23 @@
-- todo: actually display a level picker or something
state_excavate_menu=klass()
function state_excavate_menu:init(prior_menu)
self.prior_menu=prior_menu
self.frame=0
self.frames=4
self.progress=0
end
function state_excavate_menu:enter() end
function state_excavate_menu:exit(new_top) end
function state_excavate_menu:reenter() end
function state_excavate_menu:suspend() end
function state_excavate_menu:update()
self.frame+=1
self.progress=self.frame/self.frames
if (self.progress>1) self.done=true main.state_manager:push(state_ironman:new(non_tutorial))
end
function state_excavate_menu:draw()
self.prior_menu:draw()
democrap:distort_screen(self.progress)
end

75
state_gameround.lua Normal file
View File

@ -0,0 +1,75 @@
state_gameround=klass()
function state_gameround:init(watcher,ruleset)
self.board=board:new(watcher,ruleset)
self.outcome=nil
self.grab_frames=0
self.restart_frames=0
self.picking_up=false
end
function state_gameround:enter() self:add_menu() end
function state_gameround:exit() self:remove_menu() end
function state_gameround:reenter() self:add_menu() end
function state_gameround:suspend() self:remove_menu() end
function state_gameround:add_menu()
menuitem(4,"restart",function() self.outcome="restart" self.done=true end)
menuitem(5,"go to menu",function() self.outcome="menu" self.done=true end)
end
function state_gameround:remove_menu()
menuitem(4)
menuitem(5)
end
function state_gameround:update()
self.board:update()
if btn(4) then
self.grab_frames+=1
else
self.grab_frames=0
end
if btn(5) then
self.restart_frames+=1
else
self.restart_frames=0
end
local restart_progress=self.restart_frames/60
self.board:set_restart_progress(restart_progress)
if restart_progress>=1.0 then
self.outcome="restart"
self.done=true
return
end
if self.board:can_take_input() then
if (btnp(0)) self.board.cursor:move_x(-1) self.picking_up=false
if (btnp(1)) self.board.cursor:move_x(1) self.picking_up=false
if (btnp(2)) self.board.cursor:move_y(-1) self.picking_up=false
if (btnp(3)) self.board.cursor:move_y(1) self.picking_up=false
if btnp(4) then
if self.grab_frames<4 then
self.board.cursor:toggle_grab()
self.picking_up=true
else
self.board.cursor:incr_grab()
end
end
if btnp(5) and self.restart_frames < 4 then
if self.board.cursor:grabbed_card() then
self.board.cursor:drop_grab()
else
self.board:undo()
self.picking_up=false
end
end
end
if (self.board:is_won()) self.outcome="win" self.done=true main.state_manager:push(state_wonround:new(self.board))
end
function state_gameround:draw()
cls(13)
self.board:draw()
end

41
state_ironman.lua Normal file
View File

@ -0,0 +1,41 @@
state_ironman=klass()
function state_ironman:init(sequence)
self.sequence=sequence
self.level=1
end
function state_ironman:enter() self:on_enter() end
function state_ironman:exit() end
function state_ironman:reenter(round)
if round.outcome=="win" then
self.level+=1
elseif round.outcome=="menu" then
self.done=true
elseif round.outcome=="restart" then
else
assert(false,"unrecognized outcome: "..round.outcome)
end
self:on_enter()
end
function state_ironman:suspend() end
function state_ironman:on_enter()
local level=self.level
if (self.done) return
if level <= #self.sequence then
local w=self.sequence[level]()
main.state_manager:push(state_gameround:new(w))
else
main.state_manager:push(state_wonironman:new())
self.done=true
end
end
function state_ironman:update()
assert(false,"wtf")
end
function state_ironman:draw()
assert(false,"wtf2")
end

34
state_manager.lua Normal file
View File

@ -0,0 +1,34 @@
state_manager=klass()
function state_manager:init()
self._states={}
end
function state_manager:push(state)
local top=self:peek()
add(self._states,state)
if (top) top:suspend(state)
state:enter(top)
end
function state_manager:pop()
local top=deli(self._states,#self._states)
if (not top) return
local new_top=self:peek()
top:exit(new_top)
if (new_top) new_top:reenter(top)
return top
end
function state_manager:peek()
return self._states[#self._states]
end
function state_manager:update()
local state=self:peek()
if (state) state:update()
while true do
local state=self:peek()
if state and state.done then self:pop() else break end
end
end
function state_manager:draw()
local state=self:peek()
if (state) state:draw()
end

117
state_menu.lua Normal file
View File

@ -0,0 +1,117 @@
state_menu=klass()
function state_menu:init()
self.selection=1
self.frame=0
local function plain_opt(n,s,a)
return menu_option:new(function() return n end,function()
main.state_manager:push(s:new(a))
end)
end
self.options={
plain_opt("excavate",state_excavate_menu,self),
plain_opt("archaeology",state_archaeology),
menu_option:new(),
menu_option:new(function()
local pref=completion_tracker:get_music_preference()
if (pref) return "stop music"
return "start music"
end,function()
completion_tracker:set_music_preference(not completion_tracker:get_music_preference())
end),
plain_opt("reset data",state_reset_menu,self),
plain_opt("tips",state_archaeology,true)
}
end
function state_menu:enter() end
function state_menu:exit() end
function state_menu:reenter()
self.selection=1
end
function state_menu:suspend()
self.selection=nil
end
function state_menu:update()
self.frame+=1
self.frame%=1024
if (btnp(1) or btnp(4)) sounds:menu() self.options[self.selection]:cb() return
local vel=0
if (btnp(2)) vel-=1
if (btnp(3)) vel+=1
if vel!=0 then
while true do
self.selection=(self.selection+vel-1)%#self.options+1
if (self.options[self.selection].cb!=nil) break
end
end
end
function state_menu:draw()
cls(13)
self:draw_bg()
local optionsh=1
for o in all(self.options) do
optionsh+=2
if (o.cb) optionsh+=4
end
local totalh=optionsh+32
local y=128-totalh-1--64-totalh\2
-- rectfill(68,y,126,y+totalh-1,13)
local y0=y
spr(64,68,y,7,3)
y+=22
line(68,y,126,y,15)
y+=2
local optionsy=y+1
rectfill(68,y,126,y+optionsh-1,4)
y+=optionsh+1
line(68,y,126,y,15)
y+=2
print("by pyrex & nyeo",68,y,15)
local y1=y
local x=69
y=optionsy
for i=1,#self.options do
local o=self.options[i]
if (self.selection==i) spr(71,x-7+cos(time())*0.5,y)
local fg=13
if (o.cb) fg=15
if o.name then
print(o.name(),x,y,fg)
y+=6
else
line(x-1,y,x+57,y,fg)
y+=2
end
end
-- metascore
local metascore=completion_tracker:get_metascore()
if metascore>0 then
spr(72,66,y0-9,2,1)
print("="..tostr(metascore,2),79,y0-6,6)
end
end
function state_menu:draw_bg()
pal(7,1)
pal(13,1)
local m=128-(self.frame/2)%128
for col=-8,7 do
for row=-3,7 do
local realx=flr(col*32-row*16)+m
local realy=flr(row*30-col*12)
spr(76,realx,realy,4,4)
end
end
pal()
end
menu_option=klass()
function menu_option:init(name,cb)
self.name=name
self.cb=cb
end

62
state_reset_menu.lua Normal file
View File

@ -0,0 +1,62 @@
state_reset_menu=klass()
function state_reset_menu:init(prior_menu)
self.prior_menu=prior_menu
self.options="⬅️➡️⬆️⬇️🅾️"
self.code={}
self.code_i=1
for i=1,5 do
local i=flr(rnd(#self.options))
add(self.code,i)
end
end
function state_reset_menu:enter() end
function state_reset_menu:exit(new_top) end
function state_reset_menu:reenter() end
function state_reset_menu:suspend() end
function state_reset_menu:update()
for o=0,5 do
if btnp(o) then
if self.code_i>#self.code then
run()
end
if self.code[self.code_i]==o then
sounds:dire()
self.code_i+=1
if (self.code_i>#self.code) completion_tracker:reset()
else
self.done=true
end
return
end
end
end
function state_reset_menu:caption()
if (self.code_i > #self.code) return "savedata reset!"
local caption="to reset your\nsavedata, type\nthis code\n\n"
local code="\f7"
for i=1,#self.code do
local o=self.code[i]+1
local c=sub(self.options,o,o)
if (i-1<self.code_i and i>=self.code_i) code..="\ff"
if (i!=1) code..=" "
code..=c
end
return caption..code
end
function state_reset_menu:draw()
self.prior_menu:draw()
local caption=self:caption()
local w,h=measure_text(caption)
h-=1
local x=64-w\2
local y=64-h\2
rect(x-2,y-2,x+w+1,y+h+1,15)
rectfill(x-1,y-1,x+w,y+h,4)
print(caption,x,y,15)
end

31
state_wonironman.lua Normal file
View File

@ -0,0 +1,31 @@
state_wonironman=klass()
function state_wonironman:init()
end
function state_wonironman:enter()
sounds:win()
completion_tracker:incr_metascore()
end
function state_wonironman:exit(new_top) end
function state_wonironman:reenter() end
function state_wonironman:suspend() end
function state_wonironman:update()
if (btnp(4)) sounds:menu() self.done=true self.outcome="menu"
end
function state_wonironman:draw()
cls(13)
local msg="you have reached the bottom\n\nreceive one majestic kroner"
local w,h=measure_text(msg)
local x=64-w\2
local y=64-h\2
line(64-7,y-3,64+7,y-3,15)
line(64-7,y+h+1,64+7,y+h+1,15)
rectfill(x-1,y-1,x+w,y+h-1,4)
print(msg,x,y,15)
y+=h+3
spr(72,64-6,y,2,1)
line(64-7,y+9,64+7,y+9,15)
print("next",57,y+11,15)
print("(🅾️)",57,y+17,15)
end

76
state_wonround.lua Normal file
View File

@ -0,0 +1,76 @@
state_wonround=klass()
function state_wonround:init(board)
self.board=board
self.frame=0
self.frames=30
self.progress=0.0
self.card=self.board:get_endgame_card()
self.verse_id,self.verse_name,self.verse=liturgy:suggest_verse(self.board.ruleset,self.card)
end
seen_tip_this_session=false
function state_wonround:enter()
sounds:win()
completion_tracker:mark_seen(self.verse_id)
completion_tracker:advance_completion_level(self.board:get_completion_level())
if (self.board.watcher:allow_tips()) self.tip=deli(_won_round_tips,1) add(_won_round_tips,self.tip)
end
function state_wonround:exit(new_top) end
function state_wonround:reenter() end
function state_wonround:suspend() end
function state_wonround:update()
self.frame=min(self.frame+1,self.frames)
self.progress=self.frame/self.frames
self.board:set_restart_progress(self.progress)
if (self.progress<1.0) return
if (btnp(4)) sounds:menu() self.done=true
end
function state_wonround:draw()
cls(13)
if self.progress<1.0 then
self.board:draw()
return
end
self.board.ruleset.deck:draw_card(0,0,self.card,{})
poke(0x5f54,0x60)
-- blow it up
sspr(0,0,9,16,55,28+sin(time())+0.5,18,32)
poke(0x5f54,0x00)
rectfill(0,0,8,15,13)
local w,_=measure_text(self.verse_name)
local x=64-w\2
-- rectfill(x,64,x+w-2,70,4)
print(self.verse_name,x,64,15)
line(x,70,x+w-2,70,15)
local oldx,oldw=x,w
local y=73
local w,h=measure_text(self.verse)
local x=64-w\2
rectfill(x-1,y-1,x+w,y+h-1,4)
print(self.verse,x,y,15)
--[[
for line in all(split(self.verse,"\n")) do
local w,_=measure_text(line)
print(line,64-w\2,y,7)
y+=6
end
]]--
y+=h+1
line(oldx,y,oldx+oldw-2,y,15)
print("next",57,y+2,15)
print("(🅾️)",57,y+8,15)
if self.tip then
local w=measure_text(self.tip)
print(self.tip,64-w\2,122,15)
end
end
_won_round_tips={
"tip: hold ❎ to restart",
"tip: hold 🅾️ to stack cards"
}

9
text.lua Normal file
View File

@ -0,0 +1,9 @@
function measure_text(s)
local w=0
local lines=split(s,"\n")
for l in all(lines) do
w=max(w,print(l,0,128))
end
local h=#lines*6
return w,h
end

48
tutorial.lua Normal file
View File

@ -0,0 +1,48 @@
standard_watcher_cb=function(i) return function() return watcher:new(progression[i]) end end
tutorial={
-- function() return watcher:new(progression[6]) end,
function()
return watcher:new(progression[1], 10,{
tutorial_grab:new(1,4,"stack cards ascending..."),
tutorial_grab:new(5,1,"... or descending."),
tutorial_grab:new(4,3),
tutorial_grab:new(2,4,"fill the wells."),
})
end,
function()
return watcher:new(progression[2], 10,{
tutorial_grab:new(1,6,"use the extra slot."),
tutorial_grab:new(1,2,"it blocks the wells."),
tutorial_grab:new(1,5,"it blocks the wells."),
tutorial_grab:new(1,5,"it blocks the wells."),
tutorial_grab:new(2,1,"it blocks the wells."),
tutorial_grab:new(2,1,"it blocks the wells."),
tutorial_grab:new(6,1,"drag it down."),
})
end,
function()
return watcher:new(progression[3],3,{
tutorial_grab:new(7,6,"here are more cards."),
tutorial_undo:new("undo. (or hold to restart.)"),
tutorial_grab:new(6,7),
tutorial_grab:new(6,8,"they have their own well."),
tutorial_grab:new(2,6,"it can't be blocked."),
tutorial_grab:new(2,4,"stack ascending or descending."),
tutorial_grab:new(3,1,"collect the last card\nto read a scroll!"),
})
end,
standard_watcher_cb(4),
standard_watcher_cb(5),
standard_watcher_cb(6),
standard_watcher_cb(7),
completion_stage=3
}
non_tutorial={
standard_watcher_cb(3),
standard_watcher_cb(4),
standard_watcher_cb(5),
standard_watcher_cb(6),
standard_watcher_cb(7)
}

100
watcher.lua Normal file
View File

@ -0,0 +1,100 @@
watcher=klass()
function watcher:init(ruleset,seed,stages)
self.ruleset=ruleset
self.seed=seed
self._stages=stages or {}
self._allow_tips=#self._stages == 0
end
function watcher:allow_tips()
return self._allow_tips
end
function watcher:active_stage(board)
local stage=self._stages[1]
if (stage and stage:active()) return stage
end
function watcher:intercept(x,arg)
local stage=self:active_stage()
if (not stage) return true
local allowed,drop=stage:intercept(x,arg)
if (drop) deli(self._stages,1)
return allowed
end
function watcher:draw(board)
local stage=self:active_stage()
if (not stage) return
local layouts=board.ruleset.layouts
local layout,i,x,y,text
layout,i,text=stage:draw(board,layouts)
x,y=layout:place_card(i)
local w,h=measure_text(text)
x+=1
y+=20
local lx=x+3
rectfill(x-2,y-2,x+w,y+h,1)
rect(x-2,y-2,x+w,y+h,15)
print(text,x,y,15)
local note=stage.note
if (not note) return
local w,h=measure_text(note)
local x=64-w\2
local y=88
rectfill(x-1,y-1,x+w-1,y+h-1,1)
rect(x-2,y-2,x+w,y+h,15)
print(note,x,y,15)
end
tutorial_grab=klass()
function tutorial_grab:init(src,dst,note)
self.src=src
self.dst=dst
self.note=note
end
function tutorial_grab:active()
return true
end
function tutorial_grab:intercept(x, slot)
if (x=="grab" and slot==self.src) return true,false
if (x=="drop" and slot==self.dst) return true,true
end
function tutorial_grab:draw(board,layouts)
local layout,i,text
if board.cursor:grabbed_card() == nil then
-- show a hint for grabbing
layout=layouts:slot(self.src)
i=#board.slots[self.src].contents
draw_layout_hint(layout,i,15,false,true)
text="🅾️"
else
layout=layouts:slot(self.dst)
i=#board.slots[self.dst].contents+2
draw_layout_hint(layout,i,15,false,true)
text="🅾️"
end
return layout,i,text
end
tutorial_undo=klass()
function tutorial_undo:init(note)
self.note=note
end
function tutorial_undo:active()
return true
end
function tutorial_undo:intercept(x)
if (x=="undo") return true,true
end
function tutorial_undo:draw(board,layouts)
local layout,i,text
layout=layouts:checkpoint()
draw_layout_hint(layout,0,15,false,true)
text=""
return layout,i,text
end
-- todo: restart?