aka writing down how my cart works before I forget.
This is about my game, Halloween Horrors, which is here.
This game was written very much based on previous work, with functions dating all the way back to P8C-BUN, my first game. I started from the Demystify the Christmas Tree code because I wanted the kittens. It's not very token efficient at all, but I didn't come close to running out of tokens in the end (6447/8192). Originally, I was making another Christmas game - it was only very late on that my gf persuaded me to make it into something for Halloween - thus it's a little bit messy and rushed.
The unminified source is at the bottom of this post in a spoiler - it's too big to make into a cart without minification. Even after minifying, I did run out of space: v1.0.1 takes up 99.8% of the compressed cart size(!).
There are 3 sprite sheets:
The latter two are encoded in "dbi" format - i.e. the output of my Python image downsampling and compression code (dbi=="drake blue image"; I needed a name of some sort...). This will encode 4 bit PICO-8 images as 1,2 or 3 bit data if few enough colours are used, apply a couple of run length encoding schemes and encode the smallest result as 8 bit unicode for pasting into source code as a string. I wrote it for my attempt at a Dungeon Master clone at the end of last year and tweaked it since then (one day I'll finish that game too). The PICO-8 code for it unpacks this format to lua memory as a table with palette and image data. Once unpacked, the palette for the image can be set by a simple pal call, the data by using poke4(dest,unpack(data)) - very simple and, surprisingly, faster than a memcpy. I tried unpacking to the "upper memory" above 0x8000, but it was slower.
I drew the letters sheet using only 8 colours for the Christmas game which lets that image be encoded as 3 bits per pixel. I think I could have used 4 colours (i.e. 2 bit) and it would have looked fine for this game and saved up to a third of the data size.
At the end of the project I found that I'd run over the compressed size limit, but also that I hadn't used all of these two extra sprite sheets. I cropped them to the portions I was using, re-encoded and that was enough to get under the bar no code changes necessary :)
I knew I would use a separate sprite sheet for the house graphics (as opposed to the characters, decorations) so I began by making the house in a separate cart. I started off using PICO-8's sprite and map editor, but I swapped the latter for Tiled using the plugin here. This worked very well. I use Aseprite for most sprite work, but for some reason I did all drawing in PICO-8 for this game.
For the last game I'd generated the platforms by hand: add some values, run, look at a debug rectangle, repeat. That was okay for one Christmas tree, but didn't appeal for a whole house. I considered having no separate platforms and using impassable tiles, but having experimented a little with drawing the house interior already I was having enough trouble making it look as nice as I wanted without adding any more limitations. Besides, I wanted to see if it would work "off-grid".
I was already working in a separate cart to the game so I started adding code there for editing where the platforms and walls went. Then I added a simple ball sprite in position 0 (so it wouldn't be drawn by the map) so I could test the platforms. I considered adding the kitten code and encoding their graphics for it, but never got round to it.
Eventually I moved more and more into the editor as, even though it is clunky, it's still easier to work with for me than entering numbers by hand.
I liked adding the rectfill areas that paint the walls so much that I used that to draw the "paintings" instead of using more sprites. I considered adding a bunch of shadows this way, but ran out of time/patience.
PICO-8 draws rectangles so fast that this didn't seem to dent performance at all.
In retrospect, I would have liked to do one of two things:
Primarily so I could take advantage of a bigger resolution window and make the interface a bit nicer.
Incidentally, I did make a double display version of the game in PICO-8 very early on so that the two kittens could play split-screen. It worked very well, but I couldn't get the html output to work nicely with the two displays, despite a few attempted hacks (I hate web-programming) so I parked it. Might have another look at that soon especially if someone can help me hack the css to display it nicely.
Getting the platform data to save so that it could be used by the editor and the game was a bit annoying. To begin with I used printh to output to console then copied and pasted into the editor and game code separately. Yep, pretty annoying.
I worked out that I could printh to a file and then #include that file from both carts. Problem solved! Except PICO-8 didn't seem to like writing to a lua file that already existed (even though I told it to) and wrote out a .p8l file instead. I'd rename the file back to .lua to update the data. Annoying.
So I wrote a little bash script to run between saves. Less annoying.
It's kinda funny, but I only just worked out I could import the p8l file, instead of .lua and it would Just Work. Ah well, next time...
This has also made me wonder about making user-definable levels for a future game...
The big problem with putting the editor in the game would be that the editor functions obviously use tokens. It's another reason (along with test and debug code) that I would appreciate a "dev mode" in PICO-8 that blocked exporting to png, html, bin etc. but would work from .p8 files during dev time. Even if it put in a "dev mode only" banner or "over token limit" that flashes up every ten seconds or something when run like that...
Anyway, here's the editor if you're interested, with data baked in so it runs - it will still output, I guess, but I don't think it will update to use the new data. I've not tested it on here much at all and be warned: it's really not intended for use by anyone but me and even I could barely use it.
X shows platforms, walls, floors and highlights current selection for those (and the "paints").
N shows monsters, candles, dec(orations).
There's a bunch of other obscure key commands.
Worst bit: delete (-) has no "are you sure?" and there's no undo.
Interface weirdness aside, it's still been a much nicer way of working than typing the code in by hand so I would definitely use this approach again.
I pull in the two "extra" sprite sheets first ("house", "title") then store the cart's one ("game") so I can restore it from lua memory when needed. There's a few palettes for fading to black, lightning and the darker palette that's used for most of the game.
Because the game never really restarts and when you finish it the cart is just run again, the state of the music is pulled in from one of the stat values. This is the downside of that approach. The upside is that there's no need to write a reset routine and test it. It's worked okay for other game for me.
Writing this post has made me remember that switching the storm off doesn't survive restarting the game so maybe I should fix that if I find space in future.
Most of the rest is run of the mill initialising of variables and tables, except for setting up the majority of the entities in the game: the platforms, monsters, items etc.
During this project I wrote about how I was processing data stored in strings into tables: see here. I improved this a few times, but it always relied on feeding to the same constructor function that meant every entity had the same elements: x,y,r,b,c (if I remember correctly).
x and y were fine - position. But r and b (right, bottom), for instance, only made sense for the platforms and meant different things for, um, different things e.g. velocity for the bats.
I wanted to change that so I considered different constructor functions and triggering those depending on the data - that might have worked, but they'd have cost a lot of tokens and I would have needed to put those functions in a table (or mess about with _ENV) anyway and it occurred to me that I could implement what's now in the code:
This lets me describe and initialise a table of tables (or entities as I think of them) with the element names that I want like so:
The first value is the number of elements for each item, then a list of the element names and then the values themselves; for two items in this case. Add more entities by adding more numbers to the end of the string. It works for string values too of course.
That line costs 5 tokens and each table subsequently costs 4 more if you put them on the same line. You can see that the vx, and vy values burn a lot of characters - there's nothing to stop you adding those values later. I needed those elements to be non-nil so I put them in there. I might try adding them later if I need to extend the game as I'm in the weird position where I've run out of space before tokens. Of course, this string data, and the encoded images, are probably why it's got like that.
Having an editor to automatically output the large strings involved in this approach is quite helpful.
I guess the next step may be to encode the values as unicode (assuming they fit in a byte or two) to save even more space, but I haven't tried that yet and I don't know how the PICO-8 compression would react; it might not result in much of a saving.
There are three game modes: title, start and play. I re-used a set_fade function to move between these which deals with fading the palette in and out and changing the mode. You can pass it various functions and arguments to execute as soon as it's called, when it's faded to black and when it's faded up. I think. I can't remember how it works, but it seems to do what I want it to...
As with most of my carts, in the _update and _draw functions there are a few things that get done every frame, whatever the mode.
_update60: pulse and fr variables that control animation and periodic effects. I've used these since P8C-BUN, they work very well for little PICO-8 games (when trying to write bigger things e.g. using Love2D they don't and they are a pain to remove, but that's a whole different story).
Screen shake is updated here as well, inline since there's no need to call it in a function (and some token-saving habits are hard to shake ;) ):
There's no real reason not to make this separate variables instead of a table (g_ss_s vs g_ss.vx), but I never needed to do it. The conditional at the end of this snippet makes sure that the camera doesn't get "stuck" slightly off centre.
My "cam" function that wraps the PICO=8 camera() native function adds the screen shake values any time I change drawing origin and ensure that everything shakes.
There's a "shake" function that actually kicks it off.
Then it calls whatever update function is currently set.
_draw()
This resets the palette and camera and calls the current draw function. It also does the lightning - which is the same in every mode.
Randomly, a lightning strike is triggered, which consists of the screen being cleared to white, sfx triggered and countdown set. For each frame the countdown hasn't reached zero, the screen palette is set to a pre-determined set of lighter colours. Very simple, but works quite nicely. Looking at it now, I'm tempted to see if I could make the lightning fade more gradual by having more stages. I could feed the palette through the lighter map more than once, just like how the fade to black works or set up a table with gradually lighter palettes.
Most of the time, the palette is darkened to make the lightning more of a contrast and attempt to give the game a slightly more spooky atmosphere. Yellow is the exception to this (the orange is fairly bright too) so I had to be careful where I used that - it's supposed to highlight the candles that the kittens need to find and make the monster's eyes (and the pumpkin) a bit more scary.
In the menu, you can switch the storm off and that restores the normal palette and stops the lightning.
As mentioned above, I started with the DtCT code and was writing a Christmas game, so for ages this section was untouched from that. When I embarked on the Halloween project this was the first thing I played with though.
I altered the snow code to update multiple times per iteration. This makes two things happen: the raindrops appear to fall faster and makes them appear to be elongated. I tweaked the number of drops to make sure that it still ran fast enough and noticed that they were getting "caught" on the letters to the extent that the rain appeared to stop. So I hijacked the "simpler snow" (which also became rain) I'd added to the play game mode to fall constantly in the background and not interact with the letters. Speeding up the letters moving helps to hide this problem too.
There are some pal calls to make the letters a more spooky colour - I didn't change the image asset at all apart from making a K into an H and the dots on the 'i's into skulls.
For ages it still talked about Christmas after that until I could face updating the title data to be the right words...
For the previous game I'd entered this all by hand with a lot of trial and error, but having used an editor for the rest of the game I couldn't be bothered doing it by hand again. I also couldn't be bothered adding all the code to my editor that I'd need to draw the titles so instead I added it straight into the game mode and commented out the lines that move the titles about. It's pretty crude, but got the job done far faster than doing it by hand.
The code is still there, commented out.
This mode also uses the screen fade routine with one of the variants described here for added wibbliness. This is the same effect as used in PICO Space.
I pulled in the simpler rain code and screen fade for this screen too. Writing text and getting it to fit on the screen takes ages - I really should find a nicer way to edit it e.g. in PICO-8 itself. P8SCII means that the whole description is a single string. I added the control descriptions, ghosts and kitten heads at the end when I knew I wasn't short of tokens.
I implemented this constantly watching out for the moment when performance would drop enough that I'd need to do some optimisation, most likely to draw/update portions of the house at a time, instead of just updating and drawing everything every frame.
I considered various strategies to bucket entities, update on alternating frames etc.
The moment never came. The game draws and updates everything, every single frame and only rarely breaks 90% CPU, even now I stopped worrying about it.
I was disappointed and relieved at the same time :)
Also, you can see where I hacked the collision routine for the kittens (in_rect) with an unexpected "+8" because for some reason the kittens are drawn 8 pixels lower than you'd expect and I had to add that to make the collisions with the monsters work(!).
The trickiest bit of this was deciding when to swap between the house and game sprites. In the end it uses something like the following sequence, starting with the house sprites loaded into PICO-8 sprite memory:
This means there's only two loads, mid-frame. If you look closely you can see that the scores go behind the stairs, but to fix that I'd need two more loads and it'd never run at 60fps. Maybe for Picotron...
When the game ends, I use the title sprites for the "Happy Halloween" message so they need to be loaded in and that pushes the CPU just over the 60fps limit into 30fps too :( It's not too bad - you can still run about the house okay, I think - and I didn't have time to fix it. I'm not sure that I even can.
On the whole it works and people seem to like it. I could improve the code a lot and if I could work out a way to save compressed size and take advantage of the spare tokens I suspect I could add some more - maybe more options for more varied gameplay would be nice. I think I need to work on gameplay and prototyping that earlier and worry less about coding, squeezing in assets and graphics until I have that a bit more "down".
The editor worked really well and I was pleased with the data (un)packing functions.
Now I have to decide if I still want to make the Christmas game with the kittens and how I could make it better. I guess I could mahe the house/playing area even bigger. Only the background graphics are restricted by the map grid - just saying...
Warning: this is pretty messy and not v efficient. I haven't really done any token optimisation on it at all.
If you have any questions about it, please comment and we can puzzle out what on earth it does together :)
For reference only...
--returns random integer (vs float from rnd)
function rint(...) return rndr(...)&-1 end
-- rndr(t,r)==rnd(t)+r
function rndr(t,r)
return rnd(t)+(r and r or 0)
end
-- generates a random direction
function rnd_dir(m)
local angle,d=rnd(),rnd(m)
return dsin(angle),dcos(angle)
end
function buttonp(b)
local p=btnp(b)
if b==â and p then
sfx(62,3,10,2)
elseif b==ð
Ÿïž and p then
sfx(62,3,7,2)
elseif p then
sfx(62,3,11,1)
end
return p
end
function use_sprites(sprites)
if curr_spr!=sprites then
curr_spr=sprites
local data=sprites.data -- v slightly faster
poke4(0,unpack(data))
end
pal(sprites.pl)
end
decode={
function(rle)
out={}
for i=1,#rle\2 do
for j=0,rle[i2-1] do
add(out,rle[i2])
end
end
return out
end,
-- decodes data where 0s are rle only
function(rle0)
local out,i,len={},1,#rle0
while i<=len do
local data=rle0[i]
if data==0 then
local rep=rle0[i+1]
for j=0,rep do
add(out,0)
end
i+=2
else
add(out,data)
i+=1
end
end
return out
end
}
-- take list of raw pixel colour values
-- and pack into 4byte chunks for poke4
function pack_sprite_data(data)
local out,val={},0
for m,d in pairs(data) do
val=(val>>>4)|(d<<12)
if m%8==0 then
-- note horrendous swizzle to get pixels in correct order for p8
-- isn't needed below since built into decoding
-- out[(m>>3)-1]=(band(val,0xf0f0.f0f0)>>4) + (band(val,0x0f0f.0f0f)<<4)
add(out,val)
val=0
end
end
return out
end
expand8bit={
--expands 8bit data already decoded from str
[2]=function(data,ptr,d_len)
local out={}
for i=ptr,#data do
local val=data[i]
for j=3,0,-1 do
add(out,(val>>>(j2))&0x3)
d_len-=1
if d_len==0 then return out end
end
end
return out
end,
--expands 8bit data already decoded from str
[3]=function(data,ptr,d_len)
local out,val,md={},0,(ptr+2)%3
for i=ptr,#data do
val=(val<<8)+(data[i]>>8)
if i%3==md then
for j=0,7 do
add(out,(val>>>((7-j)3-8))&7)
d_len-=1
if(d_len==0) return out
end
end
end
return out
end,
--expands 8bit data already decoded from str
[4]=function(data,ptr,d_len)
local out={}
for i=ptr,#data do
add(out,(data[i]>>>4)&0xf)
add(out,data[i]&0xf)
end
return out
end
}
function unpack_dbi(dbi_data)
-- read first value to get trans
local trans, raw=ord(sub(dbi_data,1,1)),{}
for r=2,#dbi_data do
raw[r-2]=(ord(sub(dbi_data,r,r))-trans)&0xff
end
local width,height,cols,pl,ptr=raw[0],raw[1],raw[2],{},3
local bpp=(cols-8>0) and 4 or (cols-4>0) and 3 or (cols-2>0) and 2 or 1
-- printh("w:"..width.." h:"..height.." cols:"..cols)
for i=0,cols-1 do
pl[i]=raw[ptr]
ptr+=1
-- printh(pl[i])
end
local comp=raw[ptr]
ptr+=1
--16bit value for num values to extract from 8bit data
local d_len=(raw[ptr]<<8)+raw[ptr+1]
ptr+=2
-- print("d_len:"..d_len)
local d_comp = expand8bitbpp
-- debug expand 8bit
-- local d_str=''
--for d=1,#d_rle0 do
-- d_str=d_str..d_rle0[d]
--end
--printh(d_str)
-- debug rle decode
--local d_raw=decode_rle(d_rle0)
--local d_str=''
--for d=1,#d_raw do
--d_str=d_str..d_raw[d]
--end
--printh(d_str)
local sprites = {data=pack_sprite_data(decodecomp),pl=pl,w=width,h=height}
--use_sprites(sprites)
--cls()
--spr(0,0,0,16,16)
--while not btnp(â) do end
return sprites
end
function reset_dr_pal()
poke4(0x5f00,0x0302.0110,0x0706.0504,0x0b0a.0908,0x0f0e.0d0c)
end
function wait(w)
for i=0,w do flip() end
end
-- called from fade, try not to call directly
function set_upd_func(new_upd_func)
upd_func=new_upd_func
end
-- called from fade, try not to call directly
function set_dr_func(new_dr_func)
dr_func=new_dr_func
end
function set_fade(speed,
down_funcs,down_params,
up_funcs,up_params)
set_upd_func(blank)
set_dr_func(blank)
fd={
val=1,
dir=speed,
down_funcs=down_funcs,
down_params=down_params,
up_funcs=up_funcs,
up_params=up_params
}
end
function fade()
if fd.val==-10 then
return --not fading
else
if fd.val<=0 then -- end of fade
-- do changes for end of fade
if fd.up_funcs then for i in pairs(fd.up_funcs) do fd.up_funcsi end end
fd.val=-10
return
--todo: restore buttonp(â) or --skip
elseif fd.val>8 then
-- faded to black
-- so do fade down change while invisible
-- and start fade up
if fd.down_funcs then for i in pairs(fd.down_funcs) do fd.down_funcsi end end
fd.dir=-fd.dir
fd.val=8 -- make sure won't get hit again
end
-- set the colours (actual fade)
fade_pal(fd.val)
fd.val+=fd.dir
end
end
-- fades screen palette for light levels (global)
function fade_pal(lvl)
local ad=0x5f10
for c=0,15 do
-- for all colours
for i=1,lvl do
-- for requested levels
poke(ad,scpal_map[@ad])
end
ad+=1
end
end
-- gets length of printed string
-- takes into account special chars etc
-- doesn't work over multiple lines
-- or with strings that print longer than
-- 256 pixels...
-- assumes y=128 is off screen
-- be careful of camera()
function len_print(s)
print(s..'\0',0,128)
return @0x5f26
end
-- doesn't use replaced m and w for speed
function print_centre(s,y,c,out)
fun=out and pout or print
fun(s,63-len_print(s)\2,y,c)
end
function unpack_split(s)
return unpack(split(s))
end
function pout(s,x,y,c,o) -- 30 tokens, 5.7 seconds
color(o)
?'-f'..s..'\^g-h'..s..'\^g|f'..s..'\^g|h'..s,x,y
?s,x,y,c
end
-- checks if two points are in a rect with sides t and s
-- if t is not passed then treated as square
-- note the "-8" for the y axis is an enormous hack to get round
-- whatever the hell you were doing drawing the kittens
-- like you did, nowhere near their origin. This func is only
-- used for kitten collision atm so you can get away with it.
-- todo - remove the many adjustments for kitten position
function in_rect(a,b,s,t)
return abs(a.x-b.x)<s and abs(a.y-b.y-8)<(t or s)
end
--returns random integer (vs float from rnd)
function rint(...) return rndr(...)&-1 end
-- rndr(t,r)==rnd(t)+r
function rndr(t,r)
return rnd(t)+(r or 0)
end
function _update60()
pulse=(pulse+1)%192
fr=pulse\8%3
-- update_ss()
g_ss.x+=g_ss.vx
g_ss.y+=g_ss.vy
g_ss.r,g_ss.b=g_ss.vx0.6-g_ss.x/5,g_ss.vy0.6-g_ss.y/5
if abs(g_ss.vx)+abs(g_ss.vy)<0.1 then
g_ss.x,g_ss.y=0,0
end
upd_func()
end
function blank()
end
-- screen shake
function shake(d)
-- r=vx, b==vy
local x,y=rnd_dir(d)
g_ss.r+=x
g_ss.b+=y
end
function cam(x,y)
camera((x or 0)+g_ss.x,(y or 0)+g_ss.y)
end
function kit_flinch(k,e)
if k.flinch==0 then
sfx(60,3,rnd{20,24,28},4)
k.flinch=45
k.face=k.x<e.x
k.vx=k.face and -1.5 or 1.5
shake(0.2)
end
end
-- has kitten hit something
function kit_hit(k,t,w,h)
return abs(k.y-t.y-8)<(h or 16) and abs(k.x-t.x+(k.face and 18 or -10))<(w or 16)
end
function up_play()
if not fin then
-- move baddies
for g,ghost in pairs(g_ghosts) do
local newx=ghost.x+ghost.vx
if ghost.x>1000 then
ghost.vx=-1
elseif (ghost.y<128 and ghost.x<260) or ghost.x<128 then
ghost.vx=1
end
ghost.x=ghost.x+ghost.vx
ghost.y+=sin(pulse/192)/7
end
for s,spid in pairs(g_spids) do
local smin, smax
if spid.y<128 then -- upstairs spid
smin,smax=16,108
else -- downstairs spid
smin,smax=144,240
end
end
-- bats
local bat=g_bats[pulse&15]
if bat and rint(2)>0 and bat.y>20 then
bat.vy=-rint(3,1)
end
for b,bat in pairs(g_bats) do
bat.vy=min(1.5,bat.vy+0.1)
bat.y=mid(2,bat.vy0.8+bat.y,100)
bat.vx=mid(-0.8,bat.vx0.8+rndr(0.2,-0.1),0.8)
bat.x+=bat.vx
if bat.x<260 then bat.x=260 bat.vx=1 end
if bat.x>604 then bat.x=604 bat.vx=-1 end
end
end -- not fin
-- pumpkins and skulls
for p,pumpkin in pairs(g_pumpkins) do
local dist,dx,dy,kit,best_dist=32767
if not fin and abs(g_cam.x-pumpkin.hx)<100 and abs(g_cam.y-pumpkin.hy)<100 then
for pl=st_pl,end_pl do
-- find closest kitten
local f=kits[pl]
local this_dx,this_dy=f.x-pumpkin.x,f.y-pumpkin.y
local this_dist=this_dxthis_dx+this_dythis_dy
if this_dist<dist then
kit,dist,dx,dy=f,this_dist,this_dx,this_dy
end
end
else
-- send back to home
pumpkin.x+=(pumpkin.hx-pumpkin.x)0.05
pumpkin.y+=(pumpkin.hy-pumpkin.y)0.05
end
end
-- for each player's kitten 'f' for frankie
for pl=st_pl,end_pl do
-- get kitten and get 0 or 1 for current player
local f,player=kits[pl],(st_pl==end_pl) and 0 or pl-1
-- collisions with platforms
f.gr=false
if f.vy>=0 then
for pl,plat in pairs(g_plats) do
if plat.x<f.x+14 and plat.r>f.x+6 and plat.y<f.y+4 and plat.b>f.y+4 then
if btn(â¬ïž,player) and f.flinch<30 then
f.gr=false
f.vy=0.2
f.y+=2
else
f.gr=true
f.vy=0
f.y=plat.y-4
end
end
end
end
-- collisions with floors (including stairs)
-- can't go through floors from bottom
for pl=#g_floors,1,-1 do
-- for pl=4,1,-1 do
local plat=g_floors[pl]
plat.draw=nil
if plat.x<f.x+14 and plat.r>f.x+6 and plat.y<f.y+4 and plat.b>f.y+2 then
local dl,dr,dt,db=f.x+14-plat.x,plat.r-f.x+6,f.y+4-plat.y,plat.b-f.y+2
if dt<db then -- dt<db
f.gr=true
f.floor=1
f.vy=0
f.y=plat.y-4
plat.draw=1
else
f.vy=0.3
f.y=max(plat.b,f.y)
end
end
end
-- special line for stairs
-- 648,232,860,128
local sx,sy,ex,ey=unpack(g_stairs_line)
-- grad=(ey-sy)/(ex-sx)(f.x-sx)+sy
if sx<f.x+14 and ex>f.x+6 then
-- check if under line
-- todo: simplify maths
local ly=(ey-sy)/(ex-sx)(f.x-sx)+sy
-- if 634<f.x and 851>f.x then
-- local ly=-0.49760*(f.x-648)+232
if f.y<ly+4 and f.y>ly then
f.y=ly+5
f.vy=0.3
-- f.above=1
else
-- f.above=0
end
end
-- collisions with walls
for pl,plat in pairs(g_walls) do
if plat.y<f.y+4 and plat.b>f.y then
if plat.x<f.x+24 and plat.r>f.x then
f.vx=0
f.vy=max(f.vy)
if f.x-plat.x<plat.r-f.x then
f.x=plat.x-24
else
f.x=plat.r
end
end
end
end
-- "input"
-- x
local traction=(f.y>240 or not f.gr) and 0.05 or 0.2
if btn(â¬
ïž,player) and f.flinch<30 then
-- run/move left
f.vx=max(-2,f.vx-traction)
f.face=false
f.sit=0
elseif btn(â¡ïž,player) and f.flinch<30 then
-- run/move right
f.vx=min(2,f.vx+traction)
f.face=true
f.sit=0
else
f.vx*=0.9
f.sit=min(100,f.sit+1)
end
-- y
if btnp(â¬ïž,player) or btnp(ð
Ÿïž,player) and f.flinch<30 then
f.sit=0
if f.gr then
f.vy=-3.49
sfx(62,3,28,4)
else
f.vy+=0.2
end
elseif btnp(â¬ïž,player) and f.flinch<30 and f.gr and not f.floor then
f.sit=0
else
f.vy=min(3,f.vy+0.2)
end
-- hitting
if btnp(â,player) and not fin and f.flinch<30 and f.hit==0 then
f.hit=20
f.vx=0
f.sit=0
sfx(62,3,rnd{0,3},4)
end
f.hit=max(f.hit-1)
-- kitten "physics"
if st_pl==end_pl then
f.x+=f.vx
f.y+=f.vy
else
-- resolve kittens getting too far from each other
local other=pl==st_pl and kits[end_pl] or kits[st_pl]
local dx=abs(f.x+f.vx-other.x)
local dy=abs(f.y+f.vy-other.y)
if dx<120 then
f.x+=f.vx
end
if dy>120 then
f.x=other.x
f.y=other.y
else
f.y+=f.vy
end
end
-- check if kitten has hit anything
local hit
if f.hit>0 then
for c,candle in pairs(g_candles) do
if not candle.out then
if kit_hit(f,candle) then
candle.out=1
g_num_candles-=1
f.score+=10
if g_num_candles==0 then
fin=60
end
end
end
end
for s,sweet in pairs(g_sweets) do
if not sweet.hit and not sweet.dead and kit_hit(f,sweet,8,8) then
sweet.hit,hit=1,1
if sweet.spr>111 then -- double height
add(g_sweets,{x=sweet.x,y=sweet.y-8,vx=rndr(2,f.face and 0 or -2),vy=rndr(2,-1),spr=sweet.spr+48,hit=1})
end
sweet.spr+=64
sweet.vx,sweet.vy=rndr(2,f.face and 0 or -2),rndr(2,-1)
f.score+=1
g_num_broken+=1
end
end
for s,spid in pairs(g_spids) do
if kit_hit(f,spid) then
spid.vy=f.y>spid.y+6 and -2 or 2
spid.y+=spid.vy*3
hit=1
end
for g,ghost in pairs(g_ghosts) do
if kit_hit(f,ghost) then
ghost.vx=f.x>ghost.x and -1 or 1
ghost.x+=ghost.vx*5
hit=1
end
end
local function bat_hit(f,bat,w)
if kit_hit(f,bat,w) then
-- get direction away from kit
local dx,dy=bat.x-f.x,bat.y-f.y
local n,hit=sqrt(dxdx+dydy)0.1,1
bat.vx=dx/n
bat.vy=dy/n
bat.x+=bat.vx2
bat.y+=bat.vy*2
return 1
end
end
for b,bat in pairs(g_bats) do
hit=bat_hit(f,bat) or hit
end
for p,pumpkin in pairs(g_pumpkins) do
if bat_hit(f,pumpkin,pumpkin.w) then
hit=1
pumpkin.c=40
end
end
end
if hit then
sfx(62,2,rnd{12,16},4)
local px=f.face and (f.x+24) or (f.x-7)
for i=0,15 do
add(parts,{x=px+rndr(6,-3),y=f.y+rnd(5),vx=rndr(4,-2),vy=rndr(4,-3),life=rndr(30,30),
c=rnd(15)})
end
end
f.bon_cool=max(f.bon_cool-1)
if(f.bon_cool==0)f.bonus=1
-- collisions with monsters
if g_end_cool<1 then
if buttonp(â) then
set_fade(0.2,{run},{mus and 1 or 0})
end
else -- not fin
-- bats
for s,spid in pairs(g_bats) do
if in_rect(f,spid,16) then
kit_flinch(f,spid)
end
end
-- ghosts
for g,ghost in pairs(g_ghosts) do
if in_rect(f,ghost,16,12) then
kit_flinch(f,ghost)
end
end
-- spids
for s,spid in pairs(g_spids) do
if in_rect(f,spid,16) then
kit_flinch(f,spid)
end
end
for p,pumpkin in pairs(g_pumpkins) do
if in_rect(f,pumpkin,pumpkin.w) then
kit_flinch(f,pumpkin)
end
end
end -- if fin
end -- kits
-- decorations that are falling
for s,sweet in pairs(g_sweets) do
if sweet.hit then
local hit_floor
for pl,plat in pairs(g_floors) do
if plat.x-4<sweet.x and plat.r+4>sweet.x then
if plat.y-4<sweet.y and plat.b+4>sweet.y then
hit_floor=1
end
end
end
if hit_floor then
sweet.vy=-sweet.vy0.5
sfx(62,3,27,1)
if abs(sweet.vy)<0.5 then sweet.dead,sweet.hit=1 end
else
sweet.vy=min(sweet.vy+0.2,4)
end
sweet.vx=0.9
sweet.y+=sweet.vy
sweet.x+=sweet.vx
end
-- removing fallers hasn't been required so far
-- faller.life-=1
-- if faller.life<=0 then
-- -- overwrite with last faller
-- fallers[f]=fallers[#fallers]
-- fallers[#fallers]=nil
-- end
end
if fin==1 then
g_end_time=time()-g_time
end
-- bonus
-- for b=#bons,1,-1 do
-- local bon=bons[b]
-- bon.life-=1
-- if bon.life==0 then
-- bons[b]=bons[#bons]
-- bons[#bons]=nil
-- else
-- bon.y+=bon.vy
-- end
-- end
end
--function break_dec(k,baub)
-- -- spawn particles, bonuses and falling dec here
-- local decx,decy=baub.dec.x,baub.dec.y
-- if not fin then
-- k.score+=k.bonus
-- k.bon_cool=60
-- add(bons,{x=decx,y=decy,vy=-0.2,life=30,sp=65+k.bonus})
-- k.bonus=min(k.bonus+1,5)
-- end
-- local faller=add(fallers,{x=decx,y=decy,vx=k.face and rnd(2) or -rnd(2),vy=0,spr=baub.spr+80,live=true})
-- for i=0,20 do
-- add(parts,{x=decx,y=decy,vx=faller.vx+rnd(4)-2,vy=rnd(4)-2,life=rnd(30)+30,
-- c=sget((faller.spr%16)8+2+rint(4),(faller.spr\16)8+2+rint(4))})
-- end
--
--end
function _draw()
pal()
-- lightning?
dr_func()
if rint(300)==1 and not g_storm then
lightning=rint(20)+5
cls(7)
shake(1)
if not mus then sfx(rnd{61,63},0) end
elseif lightning>0 then
local lightning_cols=g_lightning_cols
for l,col in pairs(lightning_cols) do
pal(l-1,col,1)
end
else
fade()
if not g_storm and fd.val<1 then
local dark_cols=g_dark_cols
for l,col in pairs(dark_cols) do
pal(l-1,col,1)
end
if dr_func~=dr_play then pal(2,2,1) pal(8,8,1) end
end
end
lightning=max(lightning-1)
cam()
-- print(stat(0),0,112,7)
end
function dr_start()
scr_fade(pulse)
local wind=sin(pulse/433)*sin(pulse/192)/6
for i=0,2 do
for s,sno in pairs(snowback) do
sno[2]=(sno[2]+1)%128
sno[1]=(sno[1]+wind)%128
pset(sno[1],sno[2],rnd{1,5,6})
end
end
palt(15)
palt(0,1)
spr(15,pulse<20 and 1 or 0,119,1,1,pulse<20)
pal(7,6)
spr((pulse\8)%2==1 and 192 or 194,pulse-16,60+sin(pulse/192)6,2,2)
spr((pulse\8)%2==1 and 194 or 192,144-pulse,30+cos(pulse/96)6,2,2,1)
pal(7,7)
pal(5,4)
pal(6,15)
spr(15,pulse>170 and 121 or 120,119,1,1,pulse>170)
pal(5,5)
pal(6,6)
print("the fan-enily have decorated the\nhouse for hallov-eve'en tonight\nbut then gone out for food.\n|jalas, the \faspooky candles \f7they\nbought are genuinely n-enagical\nand have n-enade \f8creepy n-enonsters\f7\nappear nov-ev that it's dark.\n|jput out the candles and banish\nthe n-enonsters.\n|jand if son-ene things get broken\nit serves then-en right for\nleaving you at hon-ene alone!",3,3,7)
rectfill(54,106,54,104,13)
rectfill(55,106,70,106)
rectfill(71,104,71,106)
pout("hit",58,104,7)
rectfill(36,93,36,96,13)
rectfill(20,92,107,92)
rectfill(91,93,91,96)
line(19,93,16,94)
line(108,93,111,94)
pout("jun-enp",52,90,7)
pout('p1',1,88,7)
pout('p2',120,88,10)
print("â¬
ïž-mâ¡ïž|d-1â¬ïž-8|mâ¬ïž",1,98,6)
print(pulse<96 and "\f7+\f6ð
Ÿïž(z)\f7+\f6â" or "\f7+\f6ð
Ÿïž(n)\f7+\f6n-en",23,98)
--p2 instructions
print(pulse<96 and "â¬
ïž-mâ¡ïž|d-1â¬ïž-8|mâ¬ïž" or "s-sf|d-5e-c|md",106,98,15)
print(pulse<96 and "\ffâ\f7+\ffð
Ÿïžtab\f7+" or "\ffq\f7+\ffð
Ÿïž(v-ev)\f7+",70,98)
print('â¬
ïž \f6play frankie \ffplay philly',1,112,7+fr,1)
print('â¡ïž',120,112,10-fr,1)
print_centre('â for a 2 kitten game',122,11+fr, 1)
for i=0,3 do
for s=1,#snowfront\2 do
local sno=snowfront[s]
sno[2]=(sno[2]+1)%128
sno[1]=(sno[1]+wind)%128
pset(sno[1],sno[2],rnd{5,13,12})
end
end
if buttonp(â¬
ïž) then st_pl=1 end_pl=1 set_fade(0.2,{set_dr_func,music,decorate_house},{dr_play,mus and 22 or -1},{set_upd_func},{up_play}) end
if buttonp(â¡ïž) then st_pl=2 end_pl=2 set_fade(0.2,{set_dr_func,music,decorate_house},{dr_play,mus and 22 or -1},{set_upd_func},{up_play}) end
if buttonp(â) then st_pl=1 end_pl=2 set_fade(0.2,{set_dr_func,music,decorate_house},{dr_play,mus and 22 or -1},{set_upd_func},{up_play}) end
end
--if btnp(â¬
ïž,1) then ls[sc][g_letter][1]-=1 end
--if btnp(â¡ïž,1) then ls[sc][g_letter][1]+=1 end
--if btnp(â¬ïž,1) then g_letter=max(1,g_letter-1) end
--if btnp(â¬ïž,1) then if g_letter<#ls[sc] then g_letter+=1 else add(ls[sc],{0,0,0,2,2}) g_letter+=1 end end
scr_fade(pulse)
cool-=2.5
if cool<0 then sc=sc%(#ls-1)+1 cool=512 end
pal(title.pl)
local offset=abs(2560/(256-(cool-256)%512))/2 - 5
-- local offset=0
local wind=sin(pulse/433)*sin(pulse/192)/6
for i=0,2 do
for s,sno in pairs(snowback) do
sno[2]=(sno[2]+1)%128
sno[1]=(sno[1]+wind)%128
pset(sno[1],sno[2],6)
end
end
for lnum=1,#ls[sc] do
pal(1,2)
pal(3,8)
pal(2,1)
pal(4,1)
local l=ls[sc][lnum]
spr(l[1],l[2],l[3]+offset,l[4],l[5])
end
for i=0,2 do
for p=#snow,1,-1 do
local s=snow[p]
if s.fall then
local olds={x=s.x,y=s.y}
s.x+=wind
local pix=pget(s.x,s.y+1)
if s.y>126 then
-- fallen off bottom
-- pset(olds.x,olds.y,0)
snow[p].x=rnd(128)
snow[p].y=0
elseif pix>0 then
-- hit something
pix=pget(s.x-1,s.y+1)
if pix>0 then
local pix=pget(s.x+1,s.y+1)
if pix>0 then
s.fall=false
else
s.x+=1
snow_fall(s,olds)
end
else
s.x-=1
snow_fall(s,olds)
end
else
-- falling
snow_fall(s,olds)
end
else
-- pset(s.x,s.y,12)
if pget(s.x,s.y+1)<1 then
s.fall=true
end
end
end
end
if pulse\32%2==0 then
pout("press â ",48,122,8,2)
end
if buttonp(â) then set_fade(0.2,{set_dr_func,use_sprites},{dr_start,game},{set_upd_func},{blank}) end
--if buttonp(ð
Ÿïž) then
-- local out=''
-- for l in all(ls[sc]) do
-- out..=l[1]..','..l[2]..','..l[3]..','..l[4]..','..l[5]..','
-- end
-- printh(out)
--end
end
function snow_fall(s,olds)
-- pal(5,5)
-- pset(olds.x,olds.y,5)
s.y+=(rint(1.4,2))
pset(s.x,s.y,rnd{12,13})
end
-- formats a passed time as m:ss
function time_string(t)
local t=flr(t)
return t\60 ..":"..(t%60<10 and 0 or '')..t%60
end
function dr_play()
local ball={x=(kits[st_pl].x+kits[end_pl].x+20)\2,
y=(kits[st_pl].y+kits[end_pl].y+20)\2}
g_cam.x+=(ball.x-g_cam.x)\4
if ball.x>700 and ball.x<900 then
-- stairwell
g_cam.y=mid(62,g_cam.y+(ball.y-g_cam.y)/28,192)
else
if ball.y>129 then
-- downstairs
g_cam.x=mid(60,g_cam.x,964)
g_cam.y+=mid(-2,(193-g_cam.y)/28,2)
else
-- upstairs
g_cam.x=mid(318,g_cam.x,964)
g_cam.y+=mid(-2,(62-g_cam.y)/28,2)
end
end
cam(g_cam.x-64,g_cam.y-64)
cls()
-- rain
local wind=sin(pulse/192)/8
for i=0,2 do
for _,s in pairs(snowback) do
s[1],s[2]=(s[1]+wind)%128,(s[2]+1)%120
pset(s[1],s[2]+128,13)
end
end
-- paint walls
for p,paint in pairs(g_paints) do
rectfill(paint.x,paint.y,paint.r,paint.b,paint.c)
end
use_sprites(house)
-- floor sprites
for i=44,124 do
-- upper floor skirting boards
spr(1,i8,112,1,1)
end
for i=33,126 do
-- upper floor carpet
spr(40,i8,120,1,1)
end
for i=91,93 do
-- lower coving
spr(1,i8,136,1,1)
end
for i=104,105 do
-- lower coving
spr(1,i8,136,1,1)
end
for i=33,124 do
-- lower skirting boards
spr(1,i8,240,1,1)
end
for i=14,126 do
-- lower floorboards
spr(17,i8,248,1,1)
end
-- outlines for floors
-- rectfill(256,125,750,126,6)--1st floor
-- rectfill(840,125,1028,126)--1st floor
-- rectfill(-4,256,1028,264,6)--ground
-- background (pretty much everything apart from stairs and doorframes)
map(0,0,0,0,128,32,1)
rectfill(256,128,750,128,13)--1st floor shadow
rectfill(840,128,1028,128)--1st floor shadow
-- walls
-- rectfill(-4,-4,0,260,6)-- left wall of garden
-- rectfill(252,-4,256,128,6)-- left wall of house
-- rectfill(1024,-4,1028,255,6)--right wall
reset_dr_pal()
use_sprites(game)
-- bonus indicators
for b=1,#bons do
local bon=bons[b]
if bon.life\4%3==1 then
spr(bon.sp,bon.x,bon.y)
end
end
-- draw candles
-- draw monsters
palt(15,1)
palt(0,false)
for s,sweet in pairs(g_sweets) do
local sp=sweet.spr
if sp>111 and sp<128 then
spr(sp-16,sweet.x,sweet.y-8)
end
spr(sp,sweet.x,sweet.y)
end
for c,candle in pairs(g_candles) do
if candle.out then
pal(10,9)
pal(9,8)
end
if not candle.out then
spr(236,candle.x,candle.y,2,2)
local p=(pulse+c*7)\4
spr(46+p%2,candle.x+5,candle.y-4,1,1,fr%2==0)
else
spr(234,candle.x,candle.y,2,2)
pal(10,10)
pal(9,9)
end
end
local dim=1
if fin then
dim=flr(fin/60)
end
for s,spid in pairs(g_spids) do
local weby=spid.y<120 and 16 or 144
spr(202,spid.x-8,spid.y<120 and 16 or 144,4,2,s&1==0)-- web
rectfill(spid.x+7,weby+4,spid.x+7,spid.y+1,7)--thread
spr(230+(fin and 0 or 2(pulse\4%8<3 and 1 or 0)),spid.x,fin and (spid.y-weby)dim+weby or spid.y,2,2)-- spid
if not fin and rint(30)==0 then
add(parts,{x=spid.x+(rint(2)==0 and 6 or 9),y=spid.y+10,vx=0,vy=1,life=spid.y<128 and (128-spid.y)\3.5 or (250-spid.y)\3.5,c=11})
end
--pout(s,spid.x,spid.y,11)
end
for g,ghost in pairs(g_ghosts) do
spr(fin and 192 or 192+2(pulse\8%2),ghost.x,ghost.y,2,2,ghost.vx<0)
--rect(ghost.x,ghost.y,ghost.x+16,ghost.y+12,9)
--pout(g,ghost.x,ghost.y,7)
end
for b,bat in pairs(g_bats) do
local s=224+2((pulse\8+b)%4)
if s==230 then s=226 end
spr(fin and 226 or s,bat.x,bat.y,2,2)
--pout(b,bat.x,bat.y,8)
if not fin and rint(30)==0 then
add(parts,{x=bat.x+(rint(2)==0 and 6 or 9),y=bat.y+10,vx=0,vy=1,life=bat.y<128 and (128-bat.y)\3.5 or (250-spid.y)\3.5,c=8})
end
end
-- pumpkins and skulls
for p,pumpkin in pairs(g_pumpkins) do
spr((fin or fr%3~=1) and pumpkin.sp1 or pumpkin.sp2,pumpkin.x,pumpkin.y,pumpkin.w\8,2)
end
-- end draw monsters
if not fin or fin>0 then
-- statuses
cam()
-- candle for status
spr(236,52,11,2,2)
spr(46+fr%2,57,7,1,1,(pulse\4)%2==0)
local prog=100-flr((#g_decs-g_num_broken)/#g_decs*100)
if prog<100 then
if prog<10 then
prog=' '..prog
else
prog=' '..prog
end
end
pout((g_num_candles<10 and ' ' or '') .. g_num_candles.." "..prog.."%",47,15,fr%2==0 and 10 or 11)
-- show time elapsed
local t=time()-g_time
print_centre(time_string(t),2,10,7)
for pl=st_pl,end_pl do
local f=kits[pl]
if pl==2 then
pal(6,15)
pal(5,4)
end
-- kitten heads
cam(pl==1 and -1 or -118)
spr(15)
if pulse\8==pl*5 then
-- shifty eyes
pset(2,4,3)
pset(5,4)
pset(3,4,1)
pset(6,4)
end
rectfill(8,1,8,4,1)
cam()
pout(f.name,pl==1 and 12 or 93,2,6)
pout("score "..(f.score\100)..((f.score%100)\10)..(f.score%10),pl==1 and 2 or 91,10,f.bon_cool>1 and fr!=1 and 7 or 6)
-- local str
-- if f.above==1 then str='above' else str='below' end
-- print(str,0,100,8)
-- circ(f.x,grad,2,10)
end -- draw kittens (for pl)
pal(5,5)
pal(6,6)
cam(g_cam.x-64,g_cam.y-64)
end
-- draw kittens
for pl=st_pl,end_pl do
if pl==2 then
-- alt colours for philly
pal(5,4)
pal(6,15)
end
local f=kits[pl]
if f.flinch>0 then
f.flinch-=1
if fr!=0 then spr(38,f.x-(f.face and -4 or 8),f.y-10,3,2,f.face) end
elseif f.hit>0 then
spr(f.hit>12 and 38 or 41,f.x-(f.face and -4 or 8),f.y-10,3,2,f.face)
elseif f.gr then
if abs(f.vx)<0.1 and f.sit>10 then
-- sit
spr(9+(((pulse<48 and pl==1)or(pulse>144 and pl==2)) and fr2 or 0),f.x+(f.face and 3 or 0),f.y-8,2,2,f.face)
else
-- run
spr(fr3,f.x,f.y-10,3,2,f.face)
end
else
if f.vy<0 then
-- jump
spr(32,f.x,f.y-10,3,2,f.face)
else
-- fall
spr(35,f.x,f.y-12,3,2,f.face)
end
end
--pset(f.x,f.y,10)
end
-- dark blue->black for outlines
-- pal(1,0)
-- put palette back
pal(5,5)
pal(6,6)
palt(0,1)
palt(15,false)
for p=#parts,1,-1 do
part=parts[p]
part.life-=1
if part.life<0 then
parts[p]=parts[#parts]
parts[#parts]=nil
end
part.x+=part.vx
part.y+=part.vy
part.vy+=.2
pset(part.x,part.y,part.c)
end
-- draw stairs
use_sprites(house)
-- foreground map items
-- mostly stairs and doorframes
map(0,0,0,0,128,32,2)
reset_drpal()
-- snow
for i=0,3 do
-- local ymax=120+rint(10)
for ,s in pairs(snowfront) do
s[1],s[2]=(s[1]+wind)%112,(s[2]+1)%128
pset(s[1],s[2]+128,rnd{12,13})
end
end
-- show progress in destroying decorations
cam()
if fin==0 then
if g_end_cool<1 then
rectfill(0,118,127,124,2)
print_centre(" press â to play again",119,8+fr)
end
-- show scores
local str=''
if st_pl==end_pl and st_pl==1 then
str="frankie scores "..kits[1].score.."!"
elseif st_pl==end_pl and st_pl==2 then
str="philly scores "..kits[2].score.."!"
elseif kits[1].score>kits[2].score then
str="frankie v-evins: "..kits[1].score.." to "..kits[2].score.."!"
elseif kits[2].score>kits[1].score then
str="philly v-evins: "..kits[2].score.." to "..kits[1].score.."!"
else
str="both kittens drav-ev v-evith: "..kits[1].score.."!"
end
rectfill(0,8,127,14,9)
print_centre(str,9,10+fr)
-- show time
rectfill(0,16,127,22,11)
print_centre("your tin-ene: "..time_string(g_end_time),17,13+fr)
-- happy halloween
use_sprites(title)
pal(drpal_map)
for l in all(ls[#ls]) do
spr(l[1],l[2]+3,l[3]+3,l[4],l[5])
end
pal(title.pl)
for l,letter in pairs(ls[#ls]) do
pal(1,g_title_cols[(l+pulse\16)%3+1])
spr(letter[1],letter[2],letter[3],letter[4],letter[5])
end
g_end_cool=max(g_end_cool-1)
elseif fin then
fin-=1
end -- if fin
-- line(g_stairs_line[1],g_stairs_line[2],g_stairs_line[3],g_stairs_line[4],8)
cam()
-- print(grad,0,108,8)
end -- dr_play
-- fades a quarter of the screen at a time
-- scan line by scan line, left pixel then right pixel byte by byte
-- which line, side of pair is dictated by p
function scr_fade(p)
-- local tables seem to be faster.
-- change start line based on oddness value
local d,m=0x6000+p%2*64,p&2==0 and g80 or g81
-- for half of the 128 lines on the screen
for j=0,0x1f80,128 do
-- for every 4bytes of this line
for a=d+j,j+d+60,4 do
-- map every pair of pixels to a mapped pair
-- 4 bytes at a time
-- shorter and quicker
poke(a,m[@a],m[@(a+1)],m[@(a+2)],m[@(a+3)])
end
end
end
-- fills house with decorations for kittens to destroy
-- also init function for game
function decorate_house()
-- dump g_sweets into dec locations for the moment
g_sweets={}
for d,dec in pairs(g_decs) do
local sweet=add(g_sweets,{x=dec.x,y=dec.y,vx=0,vy=0,spr=64+rint(48)})
if sweet.spr>95 then sweet.spr+=16 end
end
g_time=time()
end
-- new unpack function
function unpack_data(raw_data)
local raw_data=split(raw_data)
local num_elements,data,names,item=raw_data[1],{},{},{}
for p=2,num_elements+2 do
add(names,raw_data[p])
end
for p=num_elements+2,#raw_data do
item[names[(p-2)%num_elements+1]]=raw_data[p]
if p%num_elements==1 then
add(data,item)
item={}
end
end
return data
end
-- init
house_dbi="ã%%ãµãããšãŠã€ããã¬ã®ã¯ãªãã²ã¡ãã«ãã£Aãµãã»ããµãâ¥â¥%ãããããããÂ¥ããã€EãŠã¡ãããã«ãŠã¡ããã ã³ãâ®ãšããããªãã€ã)ã®ããª)%ãããããããã
ãŠã¡ãŠãããã€ãâãŠã¡ãããã«ãŠã¡ããµãã« ã»ããµâ®ãšãããŸããªãã€ããã®ããª)%ãããã¡ãŠããã¡ãŠã¡ããã€ãâ¢ãŠã¡ãããã«ãŠã¡ãããã« ã¿ãã³â®ãšãããããªãã€ããã®ããª)Eã¿ãã¡ãããããã€ã¬ãã®ããŠã¡ãããã«ãŠã¡ãããã« ãã¬â®ãšããªãããã¯ããã®ããª\tãEãããã¡ãã¡ãŠã¡ãŠã¡ããã€ã¬ãã®ããŠã¡ãããã«ãŠã¡ãããã« ââ®ãšã€ããŠããã¯ããã®ããªããeãããã¡ã ãããã€ã¬ãã¯ããŠã¡ãããã«ãŠã¡ãããã«!â!ãã€ããã¯ãããã®ããªããã³ããããããã¢ã¡ãŠã¡ãµã€ã¬ãšã¯ãâãŠã¡ãããã«ãâããµã¯ã€ããµ)ã®ããªããã¬ãããããÂ¥ãEâ¢ãŠã¡ãããã«ãâãâãšãããã®ããª)ã¬ãŸãããã¬ãã®ã¬ãã€ã¬ãã€ãã#ã¡ã€ãªãããã€ã¯ã®âã«ã¿ããããã®ããª)ã³ãŸã¿ãããã¬ãã®ã¬ãã€ã¬ãã€ãããã¡ãŠããã®ã€ãžããã€ã¯ã®âãã¿ãã¿ã®ããª)ãµãŸã¿ãããã¬ãã¯ã¬ãã€ã¬ãã€ãã¯ãã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ãã¯ã®ã€ããªãâãžã€ã¯ã®âãâ ãã®ããª)ãŸãã¬ããã¬ãšã¯ã¬ãã€ã¬ãã€ãã¯ãŠã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã¯ã®ã€ãžã¢ããªãžã€ãâ¢ãã¹ãã®ããªIãããã¬ããuãã€ã¬ãã€ãã¯ãŠã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ããã€ãžãããªãžã€ããâãããšãã®ããª)ãããã¬ããuãã€ã¬ãã€ãã¯ãã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ãã€&ã€ãã€ãâã«ãããã®ããª)ãããã¬ããuãããã€ãã¯ãŠã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ããããã€ãã€ãã£ãâããã«ãã®ããª)ãããã¬ããuãã¿ããã€ãã¯ãã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã¯ã£ã¯ã€ã¯ã€ã¯ã€ã¯ãã¯%ãã€ãã€ãã€ããã®ããªããããuãããããªÂ¹Vã€ãã¯ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ãã¯Ë%ãã€ãã€ãã€ããã®ããªããããuããã!ãããžããã€ãã¯ãã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã¯ãuã%ãã€ãâ€ããããuããã¹ãªããã€ãµã€ãã€ãã¯ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ãã¯ã«ãããŠã¡ã€ããŠã¡ã€ã«ãEããâ¥ããããuããã!Vã€ãã¯ãã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã¯ãžã€ãŠã¡ã€ããŠã¡ã€ãžEãã€ãâ€ãããã%ãŸãããã!Eãã€ãã¯ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ãã¯ãžã¡ãŠã¡ã£ãŠã¡ã€ãžEãã€ãâ€ããããâµãŸã¿ã«ããããªããªãšEãã€ãã¯ãã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã¯ãã€ã¡ãŠãã¯ãã¯ãŠã¡ã&ããã€ããããããããŸã¿ãµã!Eãã€ãã¯ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ãã¯ã€ã¯ã¡ãŠã¡ãã¯ãã¯ã®ãŠãã¯+ããã€ËuããããŸãããããªã«Eãã€ãã¯ãã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã®ã¡ã¯ãã¯ã¡ãã¡ãã¡ãã¡ã¯ãâ€Hãã¹ãâµã¹ãã²ãããHãµã¹ã¬ãžããã€Eãšâ®ã¯ããã¡ãã¯ããã¡ãâ€Hãã¹ãâµã¹ãã²ãããHããã«ãã¹ã³ãžãããã€Eãšâ®ããã
ã¯ã®ã¡ãã
ã¯â€Hãã¹ãâµã¹ãã²ãããHâãµãžãããã€Eãšâ®ã¯ããã¡ãã
ãã¡ãã£â¥ã¿ã²ã³âµãã²ãããHããããŸã«ããã¬ãã€Eãšâ®ããã
ã¯ã®ã¡ãã
ã¯ã£ãâ€ãHãâµHãããHãããã«ããããã€ã¬ãã€%ãžãšâ®ã¯ããã¡ããã®ã¡ãã®ã¯ãã£ãâ€ãHãâµHãããHãµãŸããããã€ã¬ãã€âµãžã!ããã
ã¯ãµã®ã¡ã®ã¯ãµã£ãâ€ãHãâµHãããHãããã¹ããã€ã¬ãã€ããžããµãã¯ããã¡ãâã£ãâ€ãHãâµHãããHãµã¹ããã€ã¬ãã€ããžãããããã
ã¯â ãšâ-ã¬ãã¬ãã¬ãã¬ããµãËã³ããããšããšããšã®ã³ãããšãã®ãµã®ãœã®ãã ãšâ-ãã¬ãã¬ãã¬ãã¬ãµãšããã®Ëã³ãšããã®ãããšã³ã¿ãšããããã€ãã®ãã®ã¡ãã¡ãã¯ãã ãšâ-ã¬ãã¬ãã¬ãã¬ããµãšããšã®Ëã³ãšããšã®ãããšãããšãã®ãµâ¥ããšãã®ã¡ããã®ã¯ãã ãšâ-ãã¬ãã¬ãã¬ãã¬ãµããËã³ãããããšããšããã®ã¯ã®ãããšããããšãã®ã¡ãã¡ãã¯ãã ãšâ-ã¬ãã¬ãã¬ãã¬ããããšËã¬ããšãããµãšã¯ãšãããããšã®ã¯ã®ã¯ãã¯ãã¯ã®ã¯ãã¯ãããšãã®ã¡ããã®ã¯ãã ãšâ-ãã¬ãã¬ãã¬ãã¬ãããšIã)ãšãã¿ãšããã®ã¿ãã¯ãããµããšãã¯ãã¯ã®ã¯ãã¯ãã¯ã®ã¯ãããšãã®ã¡ãã¡ãã¯ãã ãšâ-ã¬ãã¬ãã¬ãã¬ããã]ãã\rããšãã€ããšã®ããµã¯ã®ããããšããããšãããããããã\"ããã¬ãã¬ãã¬ãã¬ãããšuããšã¬ããšãããEããšããããšãã®ã¡ãã
ã®ããããã€â§ãã€ãããµã€ããããšËã¬ããšã¬ããšEã¿ËEãããããã€ããvã€ãããµã€ããããšËã¬ããšã¬ããšEã»Ëã¬ããããããã€ããšãããšfã€ãããµã€ããããšã£ããŸã»ã¯ã£ã®ããšã¬ããšEã³Ëãµãžã¿ãããããã€ãã®ããšã®ã€Vã€ãããµã€ããããšâ€ãã¯ããŸã®ããšã¬ããšEãËããªããããã€ãã€ããVã€ãããµã€ããããšãâãã¯ããã®ã¯ããšã¬ããšEãâã¿ã¬#ããããã€ããfã€ãããµã€ããããšãâãã¯ããã®ã¯ããšã¬ããšãããã³âã»ã³#ããããã€â§ãã€ãããµã€ããããšãxã¿ã®ããã®ã¯ããšã¬ããšãã¡âµã»ãããµã³ãµ#ãããããâ¢ããâ¢ãããšãxã¿ã®ããã®ã¯ããšã¬ããšã¬ããš%ã¿ãI#ãã5ã«ã²ã«Eâžãã³ããšãããšâ€ããšããã®ã¯ããšããããããã«ãžãŸuãããµã©ã¯ããã¬ã€ã€ãã«ãã€ã¯ãšã®ã¯ã¬âžãã³ããšãããšâ€ãã®ããã®ã¯ããšãã«ã®ãã®ããããã¯ã¿ãŸUãããã®ã¡ãŠãã®ã¯ããããšãŸããã¯ãã¬ã®ã¯ãã£ãã£ãã³ããšãããšâã¿ã®ããã®ã¯ããšãã«ã®ããããšãã¯ãŸã¿ãŸ5ããã®ã¡ãã
ã®ããããšãã¬ãšã®ãšããšã®ãšã¬ããšã®ãããŸããããããããã®ã³ããšãxã¿ã®ããã®ã¯ããšããã²ãšãããã¹ã¿ãŸâãããã®ãã¡ãã¯ããã³ãšã¬ãã¬ãããã¬ãšã®ãšãã®ã¯ã³ãŸã¿ã£ããšããšããšããšããããšã»ãŸãããã¯ã¿ã®ã¯ããšããã²ãããã®ãã²ã¿ãŸã¬ããâ¡ã¯ãããã®ãšãã¬ãšã®ã¬ãããã®ãšã¬ãã¯ãâžãããããšã¬â¥ã¯ãã®ããšãã®ã«ã²ã«ãããã¯ããã¿ãŸã³ãããµããããã³ã®ãããšããããã®ã¯ã³âžãâãããšãã¬ã¯ãªã®ããšãã®ã«ã²ãããã¯ã8ã¿ãŸãµãã¿âµã¯ããããã²ã®ã¯ã«ã®ã€ã®ãžãã«ããâ¢ãããâ¡ããšãããŠããããžXã¿âžEããã³ã±ã«ã²âãã€ãšËã³ããã«ããããšâ¢ãµããšãããã€ãã¿Xã¿ãã¿ãÂ¥Uããã«ã«ãšããšËã³ãããµã¹ããã%ãããã¹ã²ã«ãã€ãµã¿â€ãã\nã®Eãããããã±ããã«ã²ãËããã¿ãžããããã®%ã®ãã²ãšããšãã€ã³ã¿8âããEããã²ãã«ã«ãã«ããËãµãªããããããâãã²ãšãããã¬ã¿ãâã
ãEããããã±ããããã«ã²ãšã²ãããšããšããšããšããšã#ã®ããããâãã²ãããã®ãâã¿ã²âã¡ãããšããšããšããšããããããâŽã«ãã«ã²ãããããµã€ã#ããããâã®ã«ã²ã«ãããã¯ã5ã¿ã¹âã®âµããã²ãšã²ãã²ãã²ãã±ã«ãã«ããâ§#ãšãããã«âã®ã«ã²ãããã¯ãUã¿ãŸËâã¬4ãšã¬ã#ãããããâããããããžuã¿Ëâ¢uâ€â€ãŸãâã€ãªâ¶ãªãµãªã€ãããšãã¹ãµã€ãã€ãžã¯ãžËUãŸã¿xã»xNããããªããªãžã¡ã€^ã€ã®ãããšãã¹ããã«ãžã€ãã®ãã¯ã€ãË5ãŸã¿xã¿ã¹ã¿Xããã®ã€ãªããªããããŠãã€ã®ãããšã&ããã€ã¯ãã®ËâãŸã¿xã¿ãã¿8ããªã«ãªããªã¡ã€Nãã€ã®ãããšãããŸããã«ã#ãuãŸã¿xã¿Xã¿ããŠãããã®ã€>ãžã€ã®ãããšããã«ãããã€ã®ãã®ãã€ãã¯âžã¬UãŸã¿xã¿â€ã¿ã²âã¢ã>ã¡ã€ãâããããã®ãµãšããšã®ãµãããŸãããžã€ã¯ã¬ãã¬ãã¬ãã¬ã5ãŸã¿xã¿â€ã¹ã¿ã¹ãã€ãã€ãã€ãã€>ãã¢ã®ã€ãããâãã€ã¯ã®ãšã¹ã¿ã®ã¹ãããžã¯ã®ãžã®ã〠8ã¿xã¿â€ãã¿ãŸâ¢ãã¡ã€ã.ãã€ã¯ã®ãšããã®ã¹ãµsãã9Xã¿Ëã¬ãšã«ããšãŠã¡ãªEããšã¬ããšEã®ã¡ã€ãã¢ãã€ã¯ã®ã¡Ëãã®ããªãXã¿Ëãµã¬ãšã«ããšãŠã¡ãªâµãªãããšã¬ããšEã¡ã®ã€ãáµãã€ã¯ãËãã®ããªã8ã¿Ëã³ã¬ãšã«ããšãŠã¡ãªãããšãµãªãããšã¬ããšEã®ã¡ã€ããªãããããã€ã¯ã®ã¡Ëãã®ããªããã¿Ëã¬ã¬ãšã«ããšãŠã¡ãªãããšãŠã¡ãªãããšã¬ããšEã¡ã®ã€ãáµãã€ã¯ããUããã®ããªãã²ã¿Ëâã¬ãšã«ããšãŠã¡ãªã¬ãšãããšãŠã¡ãªãããšã¬ããšEã®ã¡ã€ãâããã¯ã®ã¡ããããŠã¡ã®ããŠã¡ã®ãã¿ã®ããªãã¹ã¿Ë5ã¬ãšã«ããšãŠã¡ãªãã€ãããšãŠã¡ãªã)ãšEã¡ã®ã€ããããªããã¯ããã®ãŠã¡ã®ããŠã¡ã®ããã®ããªããŸã¿Uãµã€ã¬ã€Vã¬ãšã«ããšãŠã¡ãªã=Eã®ã¡ã€ãáµãã€ã¯ã®ã¡ãã¡ãŠã¡ã®ã¡ãŠã¡ãâ¥9uãã¬kã¬ãšã«ããšãŠã¡ãªËâã¡ã®ã€ãáµãã€ã¯ããã¡ãŠãã¯ãã¯ãŠã¡ã®ãâ¥ããµã®ãšã®ã¯ãµãËËËããã¬ã®ã¬ããã®Ëããšããšã®ãµãËËËãããã¬ããËã³ãããšãããËËËããã¬ã®ã¬ããã®Ëãã€ããšããËËËãâ®ãâ®ã®ã¬â ãâ ã®Ëãã€ããšããËËËã ã® ã®ã¬!ã®!ã®Ëãã€ããšããã³ãËËËããã¬ã®ã¬ããã®Ëã(ãã¹ããËËËâ§â§â§Ëããã³ãËËËãããËËËËËËãããËËËËËËËâµã®ãžã€ããã¯ËËËËËËËâµãã€ãËËËËËËËâµããã%ã¿ãËËËËËËâµã€ãžã€ãã€ãž[ãžãËËËËËËã¬ãµã®â§ãã€ã¯ËËËËËËã¬ãã€ãã®ãžã€ãã®ã€ããã€ã¯ËËËËËËã¬ãžã®ãã®fã€ã¯ËËËËeã€ãµãâ¶ãã¯ã¬6ã€ãã€ãã€ã®ã€ãã€ãããËËËËeã€fã¿ã¯ã¬ãã€ãžã®ãµã®ãáµããããËËËËeã€6ãã®ã¿ããâãã®ã¯ã€ãã€ã¯ã€ã¯ãã¯ã€ãËËËËeã€ãã®ãããã®ãã£ãããã®ããCããªËËËËuãFã€ãã€ãã¯ãããã®ã¯ã€ãËËËËË%ã€ãããµã¿ãã¯ã€ã¯ããã€ããªËËËËËEã€&ã€ãžã¿ãã¯ã¬ãã€ãžããã®ãËËËËËUã€ããâ¶ã€ããã¬ãµãã¯ËËuã
ããã
ããœËâœã€ãã®ãµã®ãã€ããã¯ã¬ãžã€ãããã€ã¯ËËuã¡ãŠãã¯ãŠã¡ã®ããã
ËâœãFãã¯ã¬ãµãã¯ËËuãŠã®ãã¯ã
ã®ãã®ã¯ã®ãËâœã€ãããã€ãã¿ã¯ã¬ãã€ãã¿ã¯ËËuãã®ã¯ã®ãŠã¡ãŠã¡ã®ãã®ã¯ã®ã¡Ëâœã€&ã€ãžãã¯ã¬ãã€ãžã¿ãËËuãŠãã¯ãã®ã
ã®ã¯ã®ããË5ã€ãã€6ã®ã€ããã¯ã¬ãµã®ã€ããã¯ËËuãããŠãã®ã
ããµã¡ãŠã®ã¯Ë%ã€ãã®ããã¯ã¬ãµãã¯ËËuãã¡ããã¡ã®ãã®ã
ã®ãã¡ãŠã¡ãã¯Ëâã€6ã€ãžã¿ã¯ã¬ãžã€ãžã¿ã¯ËËuããªãŠã¯ãã¯ã®ã¯ããŠã
ã®ã¯Ëâµããããµãããã®ã€ãããããã®ã€ãËËuãã
ããŠãã®ã¯ãã¡ããã®ã¯Ëã¬ã€ãžã®6ããËËËuããŠããã¡ãŠã¡ãã¯ãŠãã®ã¯ããã®ã¯Ëãã€ãã®âã¿ãËËËeã¡ãŠã
ã®ã¯ã¡ãŠã
ã¯ã
ã®ã¡ã®ã¯ã®ãã®ã¯Ëãã€ãã€âã€ãžã®ã¿ãËËËeã
ã®ã¡ããŠãã®ã¯ã®ãŠã¡ãŠã¡ããã®ãã®ã¯Ëããâ¶ããããËËËUã¡ãŠã
ããŠã¡ãŠãã¯\nã®ã¯ã®ã
ã®ã¯Ëãµã€ãã€ãµããã€ãããËËËUãã®ã¡ããŠã¡ãŠãããŠã
ã®ãã®ãã®ã
ãËãâ§ã€ãããËËË5ãŠã
ãã¢ã¡ãã¡ãããã®ãã®ãã®ã
ã®ã¯âœã€ãã&ã®ãã£ãËËËâãŠãœã®ãããŠããªãŠã®ãã3eãã€FããËËË%ãã¡ã®ã¡ã®ã¡ãŠãœããŠã¡ããããœãã¯Ëã€ãã®âã€ããã®ãËËË%ãããã
ãã¯ãŠãã®ã¯ããããœãã¯âœã€ãžãããã®ã6ã¿ã¯ËËËâµã¡ãŠã
ã®ã¯ãŠã¡ãŠãã®ã
ã®ã¡ã®ã¯ã®ãã®ã¯ã®ãœãâœãµãVã®ãžããËËËâµã
ã®ã¡ãã
ããŠã¡ãŠãã®ãã®ãã®ã¯ã®ãœã®ã¯eãµã€ã®ã€ãããµã®ã¯â¶ãËËËãã¡ãŠã
ããŠã¡ãŠãã¯\nãã¯ã
ã®ã¯ãã
ã®ã¯Eã€ã®ã€ãããžããã€ããããžã€ãËËËã³ãã®ã¡ãããŠãããŠãœã®ã¡ãã¯ã®ã
ã¯ããã®ãâã€ã®ããããã¯ã¿ãžã€ãã€ã¯ãžã€ãã€ã¯ËËËãµãŠã
ããŠã¡ãŠããŠã¡ããããã¯ã®ã
ã®ã¯ãããâµããsã£ãããã¯ËËËãŠãœã®ããã
ããããŠã¡ããªã¬ãµããµSãããµã¯ããËËË"
once_dbi="ã#âã¡ããšããŠãããããâãâlã5ãâ¬ïž5ã ããã ã#ã ã5ãã5ã ã#ã ãâã ãâgãY|ã5~â·âãŠâ®Uã±âžã¯|ã9ã«â®Uãã£YãoEã¿â+ã«ã«4,âŽTlâŽ4;ãã²ãŠã¬#ã«ã¬5ããšããhã²jãã+â·-ã«ãã+âž1ããããã+lã€Eããã¬+â1ããã³ãã1ãããjãEãã7ããã+G-ã«ãâgã)ãHã²gã%ã£âã»ããã¬+G'ã«ã»4ã¡ã1ã¿(ã¯lã»Eã¿(ã¯ãªãã³+'-ã«ã»3-ã5ã¢ãâjã¯Eãã7ãã¯Eã£âœã»ããã¬+G'ã«ã»4ã¡ã1ã¿(ã¯lã»Eã¿(ã¿ã¿Hã²ãŠã»Eã¢ãã»ããã¬+â1ããã³ãã1ããâ-ããµã¢ãã¬ãã-ãHã²jãã+â·#ãâ·3ko5ããã+'#ãã+ã¢ãŠ5ããšã¬+â1ããã³ã ã²5ãããã ã4cã)ã ãã³+â·Tãããµiã4jãã»ãᶠ9ãŠã5jã5ã â¶#lã5ã¥âŽ7ã ãT<ã9ãã1ã¿âœã»ãâ¶Y~ãã~â¶'~â®Yãã¯E~ᶠâãâ®1ãªá¶ âjãâjãâjã¯Eã¿â1ã¿â1ã¿â1ã¿â+ã«ãâjãâeã4gã5ãŠã5ãâ¬ïž5ãâ·â-ã'ã ã5ã ã1ã¿â%mã)âãª3ããYkâ¥Ykã1ã¢ãâ<ãYã«â®5ã¿â1ãŠãâkããµãŠãã»ã±ããã²ãâãšã)ã«ã€Eã²ã1ã¿â¬ïž7ãã«#ã¥ã%ã«ãã³+hã²eãã»ãã«Eã²ããããâdã1ããšãã£ã£ã²fã/ã«ã1ãã£ã²fã'ã«ã€4jãâã¡ã+kã'ã«ãã³+G5ã£â¬ïžã³ã¢ãã³+ãã¯,ãâjãEã¿(9ãã1ãã3ã¢ãTeâ®1ããã+ã1ã¿â%ã«ãããã'ã«ãã³|ãã¯ãšã1ã¿âžã¯-ããµã¿â1ãŠãâgã1ã¿ã'ã«ãâfã'ã«ã€4jãâã¡ã1ããâcãã+â1ããã+ã1ã¿â%ã«ãâãšã)ããã+â1ããããããããã²jãâ+â+ã«ãã³ããã+â1ãã3ãšã#ã ã1ã¿âã²jã²5ã¿á¶ 5ã¢ã€Eã¿â)lãšãã ³ã³ã£â1ããâhᶠâãâ®)ã«ãâgâ®'~ãŠTjãâãšã1ã¿â-ã«ãâjãâjãã³+â1ã¿âœ7ãã1ã¿â1ãã5ã ã1ã«ã5ãã5ã¿ã3,ã#lã4jã¯1ã¿âœãµ5ã¢ã»4ãã»ââ®5ãâ®YããEãžãâã¥ãTjã¯#ããâã ã5ã ãeãã+ã/ããã)ãâã»{â-ãâ¶1ã¿ãEâ®Y~ã '+ã«ã¯4eãâ+â·1ã¿â¥3ã€ã'ã ã€#ãâ'ã¡ã2ã ')ã«ã¯4eãâ+â·1ã¿hUããª3ãªâ·ãããª4jã7ãŠããã€ãšã+'/ã ã1ã«ã«4jã%ãã3ã€ãããŠã1ã¿ããµjã«5ã£ãã²ãŠã»3,ãEãã1ã±ã£3ã€ããã¢ããµãŠãâãŠã£1ã'S-ããµããããã)ãâ/~ã#d³Yã³Sã£â#ã¡ãšâo('ã«ã¯4ãšããµããã³ãã3lãâlã5ã ã5ããGã£âœãã£ãã²ãŠã¯Eã²ã7ãã\tã«ã¬7ãã«7ã¬ãã»4ã1ã±ãThã£'ã«ã¯3ã€ãã¯,ã-ã«ã«4mãã»ãã5ã ã5ã ã¯4hã9ã¿Lãª-ããµããã¯,ãã¬+ã4mãã»ããµ7ãŠã ã4ã¯4gã£ã¿ã¿âUãâ·S<ã5ã¢ãŸ5ã ã1ã«ã¯Eã¿G5c{ãŠãgeãã«Gã£â+{P+~â®Yãâ®Yãâã²ãšã-ã¡ã³ãã³ãŠ'1ã²ãTjãâjããµãã+ã«ãã¬4â¢ãŠã{ãŠãŠ(1ãŠãTjãâjããµãã+ã«ãã¬,³ããcãããTdã£ã¿ã¿âãµã ããã âµãµã¿ã1ã«ã¯Eã¿G5â¥ã³ãããã¢ããµ4â¶1ã²ã5ã¿ãeã£â·Uãã7ãã1ã¢ã[ãcããiãjãEã£â'ã ã¯4cãkã£ãã¯ãâ¥1ã«ã¯Eã¿Hãc{ãŠã{ãâŽâ¶%ã ãšâã ³5,'/ã¡ãã¿ã²ããã¢ã7ãã1ã¢ã`#3ã¬#'5jã7ã£âœãã£ã£ãã€ããã«ã9ã²ãããã1ã«ã¯Eã¿G5â§ãµãSã¯;ã¢ããµ4â¶)â·ãšãµ,Geãã£ãµâŽãšã+ã€5ã ãšâ+(ã²hã£ã¿ã#ᶠãããžãã€Eã£â5ã¢ã5\0ããµãã=â·ãšã+â®Y~ãã+(ã²hã¢ãµã ã5ã ã·âlã£1ã'Sã ã$ã '7ãŠã;ã£ãã²jã«Eããâã¡ã£ã»4ããᶠãã³ã«ãšâã 3Sã¡ã&ã (ãžãã9ããEãã4dã+ã«ã5ãã5ã ã5ã ã-ã¡ã£1ã€ã'ã«ãšã€ã¡ã'âŽãšãã ããââ·1ããã.â®Uãã£ã5ã ãã€ãâã ãTã 'slã£*ã ã·ãµã³Uã¢ããµãâ·1ã«ã¯Eããã».cããcãâŽã-ã¡ã5ã ã¯=ããTã¢Eãžãªã€EããEãã7ãã+ãhãµc3ã¬#3ãã â¶-ãš{âYã-ã¬ãšã§ã¢ãS-ãã»ããâ+(ã²ãŠã5â#ᶠã#â¶ãŠâ¶/ã ã5ã Fã»ã¢ãããŠâŽã»ãã)ãâã²ãšã5iã£ãã{ãŠã{kã£âG5ã ãããTgã³ã¿ã²ãã+â·1ã«ã¯Eã²ãšâ4³ᶠã#ᶠãã¯Tjãâã ã1ãã¯S-ãã»ããâ+(ã¯ã â¶#ã«ã³ãã³ããTdã5ã âŽ5ã ãSã¡ã1ããS-ãã»ããâ+(ã¯ãŠãâãŠã£â¬ïžãã³ãã¯9ã¿ãGã«ãšã³ã€ã9ãŠãTgã¯9ã²ãã+â·1ã«ã¯Eã¢ã1ã¡ãšãŠã{ã€ã€ã1ãŸã5áµ7<ãŠDãµã¢ãããâŽã»ãã)ãâã¯+ããµcâ·3ã€(ãâ¥ã³ãã¯=ã¿7Gã£w;ã£â·Ejã¯;ã£ãã+ãã¯,ã7ããã.ãŠ5ãâ·5ã ã5ã€ã1ã±ãTlã£)ã¬ãšâãŠã£#ã ãšãã ã5ãã5câ·+lâŽãž1{âYã¯=ã¿â¥5jã¯9ããTgã¯9ãã£+~â®5ã¿ã¬Yeᶠã³fã5ã ã5ã F1ããTo()ã ãšâã«(%{â5ã¿â/5ã ã5ã ãã¿â¬ïž7.ã;ã£â·Ejã¯;ã£â5ã¿â1ã¿â1ããTlã£)ã¬ãšâãŠã£1ãããµããâã ã5ã ãâcã9ã'Smã£1ã'Tjãâ¶ããâlã ã»-ã4jã£ã¿ã3Slã£1ã3Tjã\tâãâ,ã5ã ãeããGã£â¥efã£ãµjã€6ãªããã¢ã#ã£â-ã¡ã~â®W;ãâœ7ã¢ã5ã£âžãã£âãµã â¶#ãâ·4nãâã ãtðã¯4gã5ã ã5âŽãšã³ã ãšâ,ãTcâ·5ã â¶Tjã»7ãŠããã€ãšâlãE5ã<ãªã¬ã8ãã5ã¯âââ®Yã¿â1ã«ãšâlã£1ãã5ã ã5âŽâ¶1ã¿â1ã¿â)ã ãšâoã£1ãã]5ã ãã âŽ5ã ã5ã ã1ã ã5ã ã5ã ãšãã ã5ã ã4lã1ã3Tfã9ã'Slããã«ã ã»ãgE5ãG-ã¢ãeã£ã»4ããâŽãã».ãããªãã³ã«â¶<ãªã5ã ã5ã ã¯4á¶ã5ã ã5ã ã£(ã ã5ã ã;ãHãµjã»9ã¿âžãjãã¿ã£ã=5ã ãâŽãu,Lã5ã ãµã£â¶E\rã ã,'+ã ãšâã¬F)ã«ãšâã âµ5ã¢ãããããžãŠã»5ã£âãµgã9cããcããµããTjããã â¶;ã¢ã»7ã§ãããããžãŠã¯7ã£âã£ãã£ã¿ããã»ããeãã¢ã¿ã¿â+ã¡ãšâãâµ7.ãããããã€ãšã³4â¶1ã²ãW#ᶠã#â·edã9ã¿â+ã¬ãšââŽâµ7ã¢ãããµãããŠã£)ã«ãšâeã9#ᶠã#ᶠ5ã£ã5jãâãšã£1ã ãšã¬ã âã3ãµã/ã£)ã ãšâeã9ã³ãã³ããªã7ã£â1ããToã£-ã¡ã«ã3ãµã43Slã1ã¿ãE~ãããããµã¢ãGã£â1ããTo(-ã¬ãšã#3ã#ãã¿ããTjã€GâãããããâŽÂ³7ã¢ãâfã5ããeãã93ãµã3ã¯5ã£âžãµjãã,³ãã³ãã€ã£%ã ãšâµã ã5jã?ãã£)ã ã5fã9#3ã#3eã£â·5jããã á¶ã{ãŠãžãŠDãµ.ãE4ã¯Tdã5ã âŽ5ã ãSlã$ããŠããããfã£ã¿ã¿âãµ.ãã»ããeáµâžãiã5â·ãšâã¬ã ãKá¶ã5ã¯ã³4âã3ãµã,()ã¬ã5ã ãšâ-ã5ã ãeáµ(ãµiãwâŽãšâjãã³,âã#3ã,ã£)ã«ãG-ãšâ-ã£ã»4ããžãã9ã³ããµã â¶'ã ã5ãã4dã9ããããããã¢ã«5ã ã5ã£âãµã ã5ã ã·âµã«ãšâã ã¯TdãšEãªã%lããµã«á¶ãããŠãã«()ã¡ã¹ã4ãšâ,ãG5ã ã«cã£ãµjãkã£â¬ïžSãšãã»ããâã¡ãCãããããã¿ããTãµF'ã¬ãšâeã£ãµhããã¢ãã³+ãã¯,ããµ,³ããããããSmã£1ã¿ããµjãã³ã«ã5ã '5ã£â7ãã'ãâ¬ïž5ã¢3ã#3ãâŽãšã³ã â¶1ã²ãTjã¯@Tjᶠã ã¯Tfã'ã«ã€4dã£ããããŠããkã£â·Ejããã«â¶1ã¢ã5ã ã5ã¢ãã³+ãã¯,ããµ4³ãã#ããã¯Smã1ã¿ããjãâ·5ã ã#ã ã€ã¿âžã¯-ããµã¿ã£ãµuãããµããµã¢ã«Eã£â'ã«ãšâjãâeã'ã«ã€4dã9#3ã#'eã£â·5jããã â¶1ãã1ã¿âœ7ãã'ãâ¬ïž5.ãããµããžãŠEãµ.ãâ,ã1ã¿ãUã¿âœã²mãã»ããããã\ããã€ã€ã-ã¬ãšâeã¢ã¿ã¿â¬ïžã¯ãâ)ã ãEã²ããµã ããµã ã5ã ã¯=ã¢ã5ã¿â¬ïž5ã ã1ãã#ã ã'ãããµãâž%ãã€5ã¢ã5ã¥âµ61{âYã¯=ã¢ã¿âã¢ãâµâ{9ã¿hYãᶠã+ã£#ã«ãUãã€S~â®#~â®#iã5ã ã5ã Fãµã ãTiã5ã â¶/ãããµcããµã£ãããããµã¿â%5ã ã5ã ããã ã8ãâ·5ã ã€ã¿oã»ãžããdâ·#c³ã»ãâ¶1ã¿â1ã¿â1ã¿â){P1ã"
-- init
menuitem(1, "music on/off", function() if mus then music(-1,1000) else music(upd_func==up_play and 22 or 0)end mus=not mus end)
menuitem(2, "storm on/off", function() g_storm= not g_storm end)
g_stairs_line=split'670,231,857,138'
-- pull native sprite sheet into lua table so can be restored quickly
game={data={}}
for m=0,8192,4 do
game.data[m\4+1]=$m
end
-- set up palettes for lighting fx
scpal_map={}
local vals=split'0,129,130,131,132,133,13,6,136,137,9,139,140,1,13,143,0,0,0,1,130,128,5,10,2,4,11,3,1,2,4,142'
for i=0,15 do
scpal_map[i]=vals[i+1]
scpal_map[i+128]=vals[i+17]
end
drpal_map={[0]=0,unpack_split'0,1,1,2,1,13,6,2,4,9,3,13,5,4,14'}
g80,g81={},{}
for i=0,255 do
g80[i]=(i&0xf0)+drpal_map[i&0xf]
g81[i]=drpal_map[i\16&0xf]*16+i%16
end
fade_pal(8)
wait(20)
if sub(stat(6),1,1)!='0' then
music(0)
mus=true
else
mus=false
end
palt(0,false)
--load title data
title,house=unpack_dbi(once_dbi),unpack_dbi(house_dbi)
once_dbi,house_dbi=nil
-- unpack title sequence data (see title_gen.p8)
local title_raws={
split"163,4,6,3,4,38,28,16,2,2,69,38,16,2,2,90,48,0,2,4,7,62,16,2,2,92,65,42,3,4,89,88,36,1,4,9,95,52,2,2,7,110,52,2,2,156,35,75,3,4,69,59,85,2,2,45,69,85,3,2,7,87,85,2,2,40,97,85,1,2,220,85,107,4,1", -- drake blue games presents
split"166,13,11,3,4,38,32,19,2,2,69,42,19,2,2,3,52,19,2,2,90,64,3,2,4,15,77,19,1,2,37,76,10,1,1,7,83,19,2,2,75,52,49,2,1,169,33,71,3,4,35,56,65,2,4,15,69,81,1,2,37,68,72,1,1,89,75,65,1,4,89,83,65,1,4,71,92,81,2,3,77,70,105,4,1", -- frankie and philly in
split"128,4,16,3,4,69,26,24,2,2,89,36,8,1,4,89,44,8,1,4,13,53,24,2,2,192,65,24,3,2,7,84,24,2,2,7,94,24,2,2,3,104,24,2,2,153,93,19,1,1,128,29,57,3,4,13,51,66,2,2,38,63,66,2,2,38,73,66,2,2,13,83,66,2,2,39,97,66,2,2,38,95,66,2,2,0",-- halloween horror
--split"0,9,2,3,4,3,32,12,2,2,5,45,12,2,2,7,55,12,2,2,9,40,34,2,2,11,53,34,2,3,13,67,34,2,2,3,78,34,2,2,69,100,34,2,2,64,4,61,3,4,35,27,55,2,4,38,40,71,2,2,15,50,71,1,2,37,49,62,1,1,40,56,71,1,2,41,64,66,1,3,45,72,71,3,2,69,90,71,2,2,40,101,71,1,2,41,40,95,1,3,37,47,91,1,1,15,48,100,1,2,45,53,100,3,2,7,71,100,2,2,37,81,107,1,1,37,89,107,1,1,37,97,107,1,1",
split"128,5,35,3,4,69,28,43,2,2,11,39,43,2,3,11,53,43,2,3,71,68,43,2,3,128,9,81,3,4,69,32,91,2,2,89,42,75,1,4,89,50,75,1,4,13,59,91,2,2,192,71,91,2,2,7,88,91,2,2,7,98,91,2,2,153,97,86,1,1,3,108,91,2,2",-- happy halloween
}
ls={}
for t,title in pairs(title_raws) do
local ptr=1
ls[t]={}
repeat
local letter={}
for i=1,5 do
add(letter,title[ptr])
ptr+=1
end
add(ls[t],letter)
until ptr>=#title
end
parts,snow,bons={},{},{}
for i=0,400 do
add(snow,{x=rnd(128),y=rnd(126)})
end
pulse=0
kits={
{x=350,y=230,vx=0,vy=0,gr=true,face=true,hit=0,flinch=0,sit=30,score=0,name="frankie",bonus=1,bon_cool=0},
{x=370,y=230,vx=0,vy=0,gr=true,face=false,hit=0,flinch=0,sit=30,score=0,name="philly",bonus=1,bon_cool=0}
}
snowback,snowfront={},{}
for i=1,100 do
add(snowback,{rint(128),rint(120)})
add(snowfront,{rint(112),rint(120)})
end
g_cam,g_ss=unpack_data'2,x,y,420,60'[1],unpack_data'4,x,y,vx,vy,0,0,0,0'[1] -- between two kittens, remember to update when kitten start changes
--#include "halloween_platforms.lua"
g_floors=unpack_data('4,x,y,r,b,-4,-10,1028,0,252,122,760,130,0,253,1024,270,840,122,1028,139,824,133,852,146,664,213,682,226,680,205,698,218,696,197,714,210,712,189,730,202,728,181,746,194,744,173,776,185,760,165,792,177,776,157,808,170,792,149,824,161,808,141,840,154,647,221,667,233,640,229,647,238')
g_walls=unpack_data('4,x,y,r,b,250,-2,256,128,-4,-10,0,270,1024,-10,1028,270,200,127,204,156,112,127,116,155,584,129,588,155,880,-2,884,27,624,-2,628,28')
g_paints=unpack_data('5,x,y,r,b,c,648,0,879,7,7,278,16,647,111,8,904,0,999,7,7,256,5,277,122,8,689,16,895,111,13,624,5,642,28,13,643,13,688,31,13,945,16,1000,111,15,896,16,944,31,15,-7,240,127,255,3,200,133,223,159,2,608,144,1001,239,12,265,144,583,239,2,449,209,486,239,1,401,81,430,112,1,880,5,901,27,15,1001,5,1023,36,15,1001,86,1023,121,15,1022,122,1023,123,15,208,157,211,158,4,224,144,264,159,2,584,133,607,158,12,592,157,597,159,2,224,128,583,135,7,608,129,999,135,7,1002,133,1023,154,12,1002,214,1023,250,12,112,133,135,156,4,132,157,142,158,4,136,128,199,135,7,397,40,434,61,9,752,137,823,137,6,752,143,807,143,6,751,128,839,128,13,280,0,623,7,7,752,136,823,142,7,446,168,489,187,9,446,182,489,187,12,446,171,456,187,14,455,169,461,187,4,451,173,457,187,15,447,170,451,187,7,461,172,468,186,6,471,170,476,178,15,478,174,482,183,7,473,179,480,185,6,485,168,489,172,10,467,173,472,186,7,456,178,463,187,5,485,183,487,184,7,476,184,481,185,7,397,48,434,61,5,397,50,406,53,13,397,53,400,61,14,401,56,404,61,14,405,58,408,61,14,409,60,412,61,14,397,48,434,49,3,403,48,410,48,9,417,48,426,48,9,400,51,400,55,2,398,51,398,55,5,408,55,411,61,2,409,52,412,56,7,409,56,409,56,4,412,56,412,56,4,413,53,413,57,15,408,53,408,57,15,419,54,433,60,13,410,54,411,55,15,416,42,401,42,8,413,46,426,46,8,427,44,434,44,8,418,56,418,59,13,424,53,433,53,13,401,55,402,55,14,405,57,406,57,14,277,190,322,220,1,752,137,824,137,6')
g_plats=unpack_data('4,x,y,r,b,608,237,647,240,281,97,350,100,291,77,348,79,342,202,409,205,262,24,276,29,344,232,407,236,336,224,344,228,386,113,445,117,384,70,447,75,403,101,428,105,358,73,369,76,355,96,380,99,264,82,271,85,464,86,527,90,464,74,527,78,456,27,535,30,547,40,612,44,840,86,879,90,969,105,990,108,971,117,988,120,952,94,999,98,960,64,991,67,960,82,991,86,1008,82,1015,87,928,74,935,77,624,229,647,233,407,224,415,228,416,222,431,226,432,198,503,203,344,207,407,212,520,210,551,215,512,225,521,229,552,224,559,228,520,232,551,236,443,165,492,170,536,57,543,60,536,73,543,76,536,89,543,92,395,38,436,42,360,54,383,57,296,54,319,58,328,62,351,66,824,70,857,73,800,54,831,57,776,38,807,41,776,70,807,73,824,38,855,41,952,38,991,41,952,54,991,57,976,25,991,28,1004,34,1017,37,451,229,484,232,434,241,500,244,512,167,551,170,512,183,551,186,568,202,575,206,336,155,416,158,761,122,839,125,328,39,351,42,275,190,324,195,272,231,327,235,40,207,63,211,688,223,847,227,816,207,847,210,736,207,791,210,784,183,839,186,854,178,866,182,872,199,876,203,875,231,895,235,920,239,943,243,880,223,983,226,896,202,967,205,888,157,975,160,968,231,988,235,1008,210,1015,214,1003,153,1019,157,987,199,991,202,65,227,101,231,82,218,102,222,72,210,92,214,83,198,95,202,78,188,86,192,29,180,48,186,984,170,991,175')
g_decs=unpack_data('2,x,y,331,54,311,46,363,46,264,74,341,30,372,88,295,89,386,62,466,78,503,78,536,81,559,32,830,62,838,30,786,62,961,46,952,86,862,78,747,165,774,214,783,198,770,198,957,194,1007,202,734,214,538,158,533,174,491,190,418,214,350,194,317,222,518,174,696,189,806,214,827,30')
g_candles=unpack_data('2,x,y,294,39,430,55,941,208,908,208,594,25,780,17,952,23,810,167,980,154,515,151,433,183,273,215,30,165')
g_bats=unpack_data('4,x,y,vx,vy,600,20,0,0,309,20,0,0,493,20,0,0,293,20,0,0,417,74,1,0')
g_spids=unpack_data('3,x,y,vy,550,160,1,540,40,1,200,70,1,300,90,1,800,25,1,887,214,-1,962,156,1,924,174,1,136,154,1,157,176,1,182,200,1,663,38,1,727,95,1')
g_ghosts=unpack_data('3,x,y,vx,600,200,1,300,67,1,500,175,-1,900,23,1,965,234,1,592,104,1')
g_pumpkins=unpack_data'10,x,y,vx,vy,hx,hy,sp1,sp2,w,c,40,191,0,0,40,191,196,199,24,0,982,24,0,0,982,24,206,238,16,0,966,24,0,0,966,24,206,238,16,0'
g_num_candles=#g_candles
cool,sc,g_num_broken=512,1,0
g_title_cols=split'11,9,0'
use_sprites(title)
cls()
lightning,g_dark_cols,g_lightning_cols=0,split'0,129,130,131,132,1,13,6,136,137,10,139,140,5,4,134',split'5,12,14,10,10,7,7,7,7,7,7,7,7,7,7,7'
set_fade(0.5,{set_dr_func},{dr_title},{set_upd_func},{blank})
g_letter,g_end_cool=1,90 -- 30fps at end so 90=3 seconds