pico-8 cartridge // http://www.pico-8.com version 8 __lua__ -- isaac's descent -- by eevee -- note: in order to fit within -- the pico-8's arduous size -- constraints, all comments -- have been stripped from this -- cartridge. sorry! original -- unmolested source code -- available at: -- https://c.eev.ee/isaacs-descent/isaac.p8 animframedelay = 4 minfrac = 0.0000152587890625 function ceil(n) return flr(n + 1 - minfrac) end function merge(a, b) for k, v in pairs(b) do a[k] = v end return a end function sort(list, keyfunc) local keys = {} keyfunc = keyfunc or function(v) return v end for i = 1, #list do keys[i] = keyfunc(list[i]) end for i = 2, #list do local j = i while j > 1 and keys[j - 1] > keys[j] do keys[j], keys[j - 1] = keys[j - 1], keys[j] list[j], list[j - 1] = list[j - 1], list[j] j -= 1 end end end font_height = 6 font_width = 4 widechars = {} for _ch in all{ "‹", "‘", "”", "ƒ", "Ž", "—", "\135", "\138", } do widechars[_ch] = true end function printat(lines, anchor, align, color, bordercolor, bgcolor) local valign = sub(align, 1, 1) local halign = sub(align, 2, 2) local vm = ({t=0, m=0.5, b=1})[valign] local hm = ({l=0, m=0.5, r=1})[halign] if type(lines) == "string" then lines = {lines} end local th = #lines * font_height - 1 local y = anchor.y - flr(th * vm) linewidths = {} for line in all(lines) do local lw = 0 for n = 1, #line do lw += font_width if widechars[sub(line, n, n)] then lw += font_width end end add(linewidths, lw - 1) end if bordercolor or bgcolor then local maxw = 0 for lw in all(linewidths) do maxw = max(maxw, lw) end local x = anchor.x - flr(maxw * hm) local rx, ry, rw, rh = x - 4, y - 4, x + maxw + 3, y + th + 3 if bgcolor then rectfill(rx, ry, rw, rh, bgcolor) end if bordercolor then rect(rx, ry, rw, rh, bordercolor) end end for l, line in pairs(lines) do local x = ( anchor.x - flr(linewidths[l] * hm)) print(line, x, y, color) y += font_height end end function class(base, proto) proto = proto or {} proto.__index = proto local meta = {} setmetatable(proto, meta) if base then meta.__index = base end function meta:__call(...) local this = setmetatable({}, self) if this.init then this:init(...) end return this end return proto end vec2 = class() function vec2:init(x, y) self.x = x or 0 self.y = y or 0 end function vec2:copy() return vec2(self.x, self.y) end function vec2:__eq(other) return self.x == other.x and self.y == other.y end function vec2:__add(other) return vec2( self.x + other.x, self.y + other.y) end function vec2:__mul(n) return vec2( self.x * n, self.y * n) end function vec2:__sub(other) return self + other * -1 end function vec2:elemx(other) return vec2( self.x * other.x, self.y * other.y) end function vec2:at(anchor) return box( anchor.x, anchor.y, self.x, self.y) end box = class() function box:init(l, t, w, h) if w < 0 then l += w w *= -1 end if h < 0 then t += h h *= -1 end self.l = l self.t = t self.w = w self.h = h end function box.__index(self, key) if key == "r" then return self.l + self.w elseif key == "b" then return self.t + self.h else return box[key] end end function box:__add(offset) return box(self.l + offset.x, self.t + offset.y, self.w, self.h) end function box:overlaps(other) return ( self.l < other.r and self.r > other.l and self.t < other.b and self.b > other.t ) end function box:touches(other) return ( self.l <= other.r and self.r >= other.l and self.t <= other.b and self.b >= other.t ) end actor = class{ __name = "actor", enabled = true, poses = {}, shape = box(0, 0, 1, 1), z = 0, } function actor:init(pos) self.pos = pos self:reset() end function actor:reset() self:set_pose("default") end function actor:blocks(actor, d) local t = self.sprite:current() if fget(t, 7) then if fget(t, 5) then return d.y > 0 end return true end end function actor:coll() return self.shape + self.pos end function actor:oncollide(other, delta) end function actor:update() end function actor:draw() end function actor:set_pose(pose) if pose ~= self.pose and self.poses[pose] then self.pose = pose self:set_sprite(self.poses[pose]) end end function actor:set_sprite(s) self.sprite = to_sprite(s) end mobactor = class(actor, { __name = "mobactor", is_mobile = true, height = 1, width = 1, z = 100, min_speed = 0.015625, -- 1/64 max_speed = 0.25, -- 1/4 friction = 0.625, }) function mobactor:init(pos) self.pos0 = self.pos0 or pos:copy() actor.init(self, pos) end function mobactor:reset() actor.reset(self) self.pos = self.pos0:copy() self.vel = vec2() self.sprite_time = 0 self.facing_right = false self.ground = true end function mobactor:blocks() return true end gravity = 1/32 terminal_velocity = 7/8 function mobactor:update() self.sprite_time += 1 self.touching_mechanism = nil local abs, vec2 = abs, vec2 local vel = self.vel local friction = self.friction if not self.ground then friction = 1 - (1 - friction) / 2 end vel.x *= friction if abs(vel.x) > self.max_speed then vel.x = sgn(vel.x) * self.max_speed elseif abs(vel.x) < self.min_speed then vel.x = 0 end if not self.floating then vel.y = min( vel.y + gravity, terminal_velocity) end local prevx = self._prevx or 0 self._prevx = vel.x if vel.x ~= 0 then self.facing_right = vel.x < 0 end self.ground = false local move = vel:copy() if abs(vel.x) < abs(prevx) then local goalx = self.pos.x + move.x local d1 = goalx - flr(goalx + 0.5) if abs(d1) < 1/16 then move.x -= d1 end end local coll = self:coll() local delta = vec2( abs(move.x), abs(move.y)) local sign = vec2( sgn(move.x), sgn(move.y)) local nearx, farx, neary, fary = "l", "r", "t", "b" if sign.x > 0 then nearx, farx = farx, nearx end if sign.y > 0 then neary, fary = fary, neary end local boundx = abs(curzone.box[nearx] - coll[nearx]) if delta.x > boundx then delta.x = boundx vel.x = 0 end local boundy = abs(curzone.box[neary] - coll[neary]) if delta.y > boundy then if vel.y > 0 then self.ground = true end delta.y = boundy vel.y = 0 end local blockers = {} local moverange = box(coll.l, coll.t, coll.w + delta.x, coll.h + delta.y) if sign.x < 0 then moverange.l -= delta.x end if sign.y < 0 then moverange.t -= delta.y end local function add_blocker(other) if not other.enabled then return end if other.oncollide == actor.oncollide and not other:blocks(self, vel) then return end local otherbox = other:coll() if coll:overlaps(otherbox) then if self.is_player and other.is_usable then self.touching_mechanism = other end elseif moverange:overlaps(otherbox) then local dist = vec2( sign.x * (otherbox[farx] - coll[nearx]), sign.y * (otherbox[fary] - coll[neary])) local order = max(0, dist.x) * delta.y + max(dist.y) * delta.x add(blockers, { actor = other, dist = dist, order = order, coll = otherbox, }) end end for actor in all(curzone.mobs) do if actor ~= self and abs(self.pos.x - actor.pos.x) + abs(self.pos.y - actor.pos.y) <= 8 then add_blocker(actor) end end for x = flr(moverange.l), ceil(moverange.r) do for y = flr(moverange.t), ceil(moverange.b) do add_blocker(curzone:tile(vec2(x, y))) end end sort(blockers, function (blocker) return blocker.order end) local movedby = vec2() for blocker in all(blockers) do local dist = blocker.dist - movedby dist.x = min(max(0, dist.x), delta.x) dist.y = min(max(0, dist.y), delta.y) local ymult = delta.y * dist.x local xmult = delta.x * dist.y local step = dist:copy() if dist.x == 0 or dist.y == 0 then elseif ymult > xmult then step.y = delta.y * dist.x / delta.x elseif xmult > ymult then step.x = delta.x * dist.y / delta.y end delta -= step movedby += step coll += (step:elemx(sign)) if coll:touches(blocker.coll) then local touchx = coll[nearx] == blocker.coll[farx] local touchy = coll[neary] == blocker.coll[fary] if touchx and touchy then if delta.x > delta.y then touchx = false else touchy = false end end local force = move:copy() if not touchx or delta.x == 0 then force.x = 0 end if not touchy or delta.y == 0 then force.y = 0 end blocker.actor:oncollide(self, force) if blocker.actor:blocks(self, force) then if touchx then delta.x = 0 vel.x = 0 else delta.y = 0 if vel.y > 0 then self.ground = true end vel.y = 0 end end end end movedby += delta self.pos += (movedby:elemx(sign)) local pose = "default" if self.is_dead then pose = self.pose elseif not self.ground then if vel.y <= 0 then pose = "jumping" else pose = "falling" end elseif vel.x ~= 0 then pose = "walking" end self:set_pose(pose) end function mobactor:draw() local p = self.pos:copy() if self.floating then p.y += 0.25 * (sin(curtime % 90 / 90) - 1) end self.sprite:drawat(p, self.sprite_time, self.facing_right) end function mobactor:set_sprite(s) actor.set_sprite(self, s) self.sprite_time = 0 end playeractor = class(mobactor, { __name = "playeractor", is_player = true, z = 1000, xaccel = 0.125, -- 1/8 max_jump_time = 4, yaccel = 7/64, aircontrol = 0.5, }) function playeractor:reset() self.is_dead = false mobactor.reset(self) self.jumptime = 0 end function playeractor:update() if self.is_dead then mobactor.update(self) return end local xmult = 1 if not self.ground then xmult = self.aircontrol end if btn(0) then self.vel.x -= self.xaccel * xmult elseif btn(1) then self.vel.x += self.xaccel * xmult end if btn(5) then -- — progress.seenjumphint = true if self.floating then sfx(19) self.floating = false end if self.jumptime < self.max_jump_time then self.vel.y -= self.yaccel if self.jumptime == 0 then sfx(0) end self.jumptime += 1 end elseif self.ground then self.jumptime = 0 else self.jumptime = 999 end mobactor.update(self) if self.floating and rnd() < 0.1 then curzone:add_actor(particle( self.pos + vec2(rnd(1), 2), 7, rnd(10) + 10, vec2(0, -0.0625))) end if btnp(2) then -- ” progress.seeninvhint = true progress.curitem -= 1 if progress.curitem == 0 then progress.curitem = #progress.inventory end elseif btnp(3) then -- ƒ progress.seeninvhint = true progress.curitem += 1 if progress.curitem > #progress.inventory then progress.curitem = 1 end elseif btnp(4) then -- Ž if self.touching_mechanism then progress.seenusehint = true self.touching_mechanism:onactivate() else local item = progress.inventory[progress.curitem] if item then item:use(self) end end end end firstjump = box(2, 7, 1, 1) firststaff = box(8, 7, 2, 1) function playeractor:draw() mobactor.draw(self) local hint = nil if not progress.seenjumphint and self:coll():overlaps(firstjump) then hint = "—" elseif not progress.seenstaffhint and self:coll():overlaps(firststaff) then hint = "Ž" elseif not progress.seenusehint and self.touching_mechanism then hint = "Ž" elseif not progress.seeninvhint and #progress.inventory > 1 then hint = "”ƒ" end if hint then local ax = self.pos.x * 8 local ay = self.pos.y * 8 circfill(ax + 4, ay - 1, 1, 7) circfill(ax + 8, ay - 5, 1, 7) local cx, cy = ax + 4, ay - 13 circfill(cx + 5, cy - 0, 4, 7) circfill(cx - 5, cy + 0, 4, 7) circfill(cx - 0, cy - 2, 4, 7) circfill(cx + 0, cy + 2, 4, 7) printat({hint}, vec2(cx, cy), "mm") end end function playeractor:die() if self.is_dead then return end self.is_dead = true self:set_pose"dying" game:die(self) end transientactor = class(actor, { is_transient = true, }) function transientactor:init(...) actor.init(self, ...) if not self.sprite then self.sprite = to_sprite( mget(self.pos.x, self.pos.y)) end end _tiledefs = {} function declare_tile(data) if data.sprite then data.sprite = to_sprite(data.sprite) end if data.poses then for name, sprref in pairs(data.poses) do data.poses[name] = to_sprite(sprref) end end local sprite = data.sprite or (data.poses and data.poses.default) local for_tiles = data.for_tiles or sprite:get_tiles() local cls = data.class data.class = nil if cls then elseif data.reset or data.update or data.draw or data.poses or (sprite and sprite.is_animated) then cls = decoractor else cls = transientactor end local newcls = class(cls, data) for _key, tileno in pairs(for_tiles) do if not _tiledefs[tileno] then _tiledefs[tileno] = class( data, { sprite = to_sprite(tileno) }) end end return newcls end _oneoff_actors = {} function oneoff_actor(data) setmetatable(data, data.class or actor) add(_oneoff_actors, data) return data end decoractor = class(actor, { __name = "decoractor", is_decor = true, _sprchange = false, }) function decoractor:set_sprite(s) actor.set_sprite(self, s) mset(self.pos.x, self.pos.y, self.sprite:current()) self._sprchange = true end function decoractor:reset() local t = 0 if self.enabled then t = self.sprite:current() end mset(self.pos.x, self.pos.y, t) end function decoractor:update() if curtime % animframedelay == 0 or self._sprchange then mset(self.pos.x, self.pos.y, self.sprite:current()) self._sprchange = false end end particle = class(actor, { init = function(self, pos, col, ttl, vel) actor.init(self, pos) self.col = col self.ttl = ttl self.vel = vel or vec2() end, update = function(self) self.ttl -= 1 if self.ttl <= 0 then curzone:del_actor(self) end self.pos += self.vel end, draw = function(self) local p = self.pos * 8 pset(p.x, p.y, self.col) end, }) _tiletrans = {} function declare_transparency(tiles) local trans = tiles.trans for tileno in all(tiles) do _tiletrans[tileno] = trans end end _spritedefs = {} sprite = class() function sprite:init(frames, skip) self.frames = frames self.skip = skip or 0 self.width = 1 self.height = 1 if type(frames[1]) == "table" then self.height = #frames else self.frames = {frames} end self.size = self.width * self.height self.is_animated = false for frames in all(self.frames) do if #frames > 1 then self.is_animated = true break end end end function sprite:get_tiles() local seen = {} local ret = {} for frames in all(self.frames) do for tileno in all(frames) do if not seen[tileno] then seen[tileno] = true add(ret, tileno) end end end return ret end function sprite:current(n, dt) n = n or 1 dt = dt or curtime local frames = self.frames[n] local animlen = #frames * animframedelay local time = dt % animlen local frame = flr(time / animframedelay) + 1 if self.frames.stop and dt >= animlen then frame = #frames end frame += self.skip if frame > #frames then frame -= #frames end return frames[frame] end function sprite:drawat(pos, dt, hflip, vflip) for n = 1, self.size do local tileno = self:current(n, dt) local trans = _tiletrans[tileno] if trans then palt(0, false) for color in all(trans) do palt(color, true) end end spr(tileno, pos.x * 8, (pos.y + n - 1) * 8, 1, 1, hflip, vflip) if trans then palt() end end end function declare_sprite(args) local skip = 0 for tileno in all(args) do _spritedefs[tileno] = sprite( args, skip) if args.name then _spritedefs[args.name] = _spritedefs[tileno] end skip += 1 end return _spritedefs[args[1]] end function declare_sprites(defs) foreach(defs, declare_sprite) end function to_sprite(val) if type(val) == "number" then return _spritedefs[val] or declare_sprite{val} elseif type(val) == "string" then return _spritedefs[val] elseif #val > 0 then return declare_sprite(val) else return val end end function to_ramp(conv) local ret = {} for color = 0, 15 do local ramp = {} ret[color + 1] = ramp while color do add(ramp, color) color = conv[color + 1] end end return ret end blackramp = to_ramp{ nil, 0, 0, 1, 2, 1, 5, 6, 2, 8, 9, 3, 13, 5, 8, 14, } greenramp = to_ramp{ 1, 3, 3, 11, 3, 1, 10, 10, 9, 10, 11, nil, 11, 12, 9, 9, } function apply_ramp_fade(ramp, proportion, mode) mode = mode or 1 pal() for color = 0, 15 do local colorramp = ramp[color + 1] local slot = flr(#colorramp * proportion + 1) pal(color, colorramp[slot], mode) end end mapzone = class() function mapzone:init(...) self.box = box(...) self.actors = {} self.mobs = {} self.decor = {} end function mapzone:tile(pos) local decor = self.decor[pos.y * 128 + pos.x] if decor then return decor end local tileno = mget(pos.x, pos.y) if _tiledefs[tileno] then return _tiledefs[tileno](pos) end return transientactor(pos) end function mapzone:add_actor(actor) add(self.actors, actor) if actor.is_decor then self.decor[actor.pos.y * 128 + actor.pos.x] = actor elseif actor.is_mobile then add(self.mobs, actor) end if actor.is_player then player = actor end end function mapzone:del_actor(actor) del(self.actors, actor) if actor.is_decor then local x, y = actor.pos.x, actor.pos.y self.decor[y * 128 + x] = nil mset(x, y, 0) elseif actor.is_mobile then del(self.mobs, actor) end end function mapzone:reset() local mset, vec2 = mset, vec2 if not self.inited then self.inited = true cam.l, cam.t = self.box.l, self.box.t for x = self.box.l, self.box.r - 1 do for y = self.box.t, self.box.b - 1 do local tilecls = _tiledefs[mget(x, y)] if tilecls and not tilecls.is_transient then local actor = tilecls( vec2(x, y)) self:add_actor(actor) if actor.is_mobile then mset(x, y, 0) end end end end for actor in all(_oneoff_actors) do self:add_actor(actor) end end end function mapzone:draw(cam, flag) flag = flag or 0 camera(cam.l * 8, cam.t * 8) local x = flr(cam.l) local y = flr(cam.t) map(x, y, x * 8, y * 8, 17, 17, flag) end scene = class{ onenter = function() end, onexit = function() end, get_music = function() end, } function scene:init(obj) merge(self, obj or {}) end curtime = 0 function scene:update() curtime = (curtime + 1) % 20160 for layer in all(self.layers) do if layer.update then layer:update() end end end function scene:draw(nocls) local pal, camera = pal, camera if not nocls then cls() end for layer in all(self.layers) do pal() camera() layer:draw() end end scenefader = class(scene) function scenefader:init(newscene, duration, ramp, onbetween) self.newscene = newscene self.oldscene = game.scene self.timer = 1 self.duration = duration self.ramp = ramp or blackramp self.onbetween = onbetween if self.oldscene then game:changemus(nil, self.duration) else self:doreverse() end end function scenefader:doreverse() self.reverse = true self.timer = 1 game:changemus(self.newscene:get_music(), self.duration) if self.onbetween then self:onbetween() end end function scenefader:onenter() end function scenefader:update() self.timer += 1 if self.timer >= self.duration then if not self.reverse then self:doreverse() elseif self.timer > 0 then self.timer -= 1 game:set_scene(self.newscene) end end end function scenefader:draw() rectfill(0, 0, 128, 128, 9) if self.reverse then self.newscene:draw() else self.oldscene:draw() end local prop = self.timer / self.duration if self.reverse then prop = 1 - prop end apply_ramp_fade(self.ramp, prop) end cam = box(0, 0, 16, 16) margin = 6 map_layer = { update_camera = function(self) local bounds = curzone.box local focus = player:coll() cam.l = max( min(cam.l, max(bounds.l, focus.l - margin)), min(bounds.r, focus.r + margin) - cam.w) cam.t = max( min(cam.t, max(bounds.t, focus.t - margin)), min(bounds.b, focus.b + margin) - cam.h) end, reset = function(self) curzone:reset() for actor in all(curzone.actors) do actor:reset() end self:update_camera() progress.savepoint = nil progress:backup() end, update = function(self) for actor in all(curzone.actors) do if actor.enabled then actor:update() end end self:update_camera() if player:coll().r == curzone.box.r then game:set_scene(scenefader( mainscene, 20, blackramp, function() curzonen += 1 curzone = zones[curzonen] map_layer:reset() end )) end end, draw = function(self) curzone:draw(cam) pal() sort( curzone.actors, function (actor) return actor.z end) for actor in all(curzone.actors) do if actor.enabled and actor:coll():overlaps(cam) then actor:draw() end end end, } deadscene = class(scene) function deadscene:init(wrapped) self.wrapped = wrapped end function deadscene:update() if btn(4) then game:doreset() elseif btn(5) and progress.savepoint then game:doresurrect() else self.wrapped:update() end end function deadscene:draw() self.wrapped:draw() pal() palt() local msg = {"Ž reset "} if progress.savepoint then add(msg, "— resurrect") end printat(msg, vec2(64, 64), "mm", 7, 7, 0) end game = { pending_scene = nil, scene = nil, curmusic = -1, taskhdl = 1, tasks = {}, pending_tasks = {}, } function game:initialize() if self.curmusic then self:_music(self.curmusic) end for tileno, def in pairs(_spritedefs) do if type(tileno) == "number" and not _tiledefs[tileno] and (def.is_animated or _tiletrans[tileno]) then declare_tile{ class = decoractor, sprite = def, } end end map_layer:reset() end function game:schedule(tics, callback) local handle = self.taskhdl self.taskhdl += 1 self.pending_tasks[handle] = { time = tics, callback = callback, } return handle end function game:update() for handle, task in pairs(self.tasks) do task.time -= 1 if task.time <= 0 then task.callback() self.tasks[handle] = nil end end if self.pending_scene then if self.scene then self.scene:onexit() end self.scene = self.pending_scene self.pending_scene = nil self.scene:onenter() end self.scene:update() merge(self.tasks, self.pending_tasks) self.pending_tasks = {} end function game:draw() self.scene:draw() end function game:set_scene(scene) self.pending_scene = scene end function game:changemus(track, fadelen) track = track or -1 if track == self.curmusic then return end if self.curmusic ~= -1 and track ~= -1 then self:_music(-1, fadelen) self:schedule(fadelen, function() self:_music(track, fadelen) end) else self:_music(track, fadelen) end self.curmusic = track end function game:_music(track, fadelen) if fadelen then fadelen = fadelen * 100 / 3 end music(track, fadelen) end function game:die() self:changemus(nil, 0) sfx(2) self:schedule(45, function() self:set_scene(deadscene(self.scene)) end) end function game:doresurrect() if not progress.savepoint then return end sfx(3) self:changemus(nil) self:set_scene(scenefader( mainscene, 10, greenramp, function() player.pos = progress.savepoint.pos player.is_dead = false player:set_pose"default" map_layer:update_camera() end )) end function game:doreset() self:changemus(nil) self:set_scene(scenefader( mainscene, 20, blackramp, function() progress:restore() map_layer:reset() end )) end function game:win() self:set_scene(winscene( self.scene)) end function _init() game:initialize() end function _update() game:update() end function _draw() game:draw() end mainscene = scene{ layers = { { update = function(self) end, draw = function(self) camera() rectfill(0, 0, 128, 128, 0) end, }, map_layer, { draw = function(self) local gizmo = player.touching_mechanism if gizmo then color(isaaccolors[isaaccolor][3]) else color(7) end local t, l = 2, 2 rect(t + 1, l, t + 12, l + 13) rect(t, l + 1, t + 13, l + 12) rectfill(t + 2, l + 2, t + 11, l + 11, 0) local iconpos = vec2(t + 3, l + 3) * 0.125 if gizmo then if gizmo.usesprite:current() == 2 then pal( isaaccolors[1][1], isaaccolors[isaaccolor][1]) end gizmo.usesprite:drawat(iconpos) pal() else item = progress.inventory[progress.curitem] if item then item.sprite:drawat(iconpos) end end end, }, }, } function mainscene:get_music() return 0 end titlescene = scene{ slowwalk = declare_sprite{ {1}, {16, 16, 16, 16, 17, 17, 17, 17}}, update = function(self) scene.update(self) if btn(4) or btn(5) then game:set_scene(scenefader( mainscene, 30, blackramp)) end end, draw = function(self) cls() pal(5, isaaccolors[isaaccolor][4]) sspr(64, 96, 64, 32, 0, 16, 128, 64) pal() for i = 1, 4 do pal( isaaccolors[1][i], isaaccolors[isaaccolor][i]) end self.slowwalk:drawat(vec2(0.5, 6)) pal() to_sprite(24):drawat(vec2(14.5, 6.5)) printat( {"ld36 edition"}, vec2(64, 72), "tm", isaaccolors[isaaccolor][4]) printat( {"press Ž or —"}, vec2(64, 96), "mm", 7) printat( {"Ž = z — = x enter for menu"}, vec2(64, 128), "bm", 5) end, get_music = function() return 20 end, onenter = function(self) game:changemus(self:get_music()) end, } game:set_scene(titlescene) winscene = class(scene, { init = function(self, wrapped) self.wrapped = wrapped scene.init(self) end, onenter = function(self) game:changemus(nil) sfx(9) game:schedule(60, function() game:set_scene(scenefader( endscene, 60, blackramp)) end) end, draw = function(self) self.wrapped:draw() end, }) endscene = scene{ timer = 0, onenter = function() game:changemus(30) end, update = function(self) self.timer += 1 end, draw = function(self) cls() printat({ "you did it, isaac!", "", "you found the flurry, the", "legendary enchanted sabre.", "", "now you just need to, ah,", "get back out of here.", "", "good luck with that!", }, vec2(64, 8), "tm", 7) printat( {"\135 thanks for playing! \135"}, vec2(64, 80), "mm", 14, 2, 2) sspr(120, 48, 8, 16, 4, 108) printat( {"hastily made by eevee", "@eevee", "\138 http://eev.ee/"}, vec2(16, 124), "bl", 12) end, } menuitem(1, "reset room", function() game:doreset() end) items = { staff = { sprite = declare_sprite{48}, use = function(self, player) progress.seenstaffhint = true local pos = player.pos:copy() local tile = curzone:tile(pos) if tile.sprite:current() ~= 0 then return end if progress.savepoint then curzone:del_actor(progress.savepoint) progress.savepoint = nil end progress.savepoint = savepointactor(pos) curzone:add_actor(progress.savepoint) sfx(1) for angle = 0.125, 1, 0.125 do curzone:add_actor(particle( player.pos + vec2(0.5, 0.5), 11, 8, vec2(cos(angle), sin(angle)) * 0.125 )) end end, }, spellbook = { sprite = declare_sprite{50}, use = function(self, player) if player.floating then sfx(19) player.floating = false elseif player.ground then sfx(8) player.floating = true end end, } } progress = { inventory = {items.staff}, curitem = 1, savepoint = nil, backup = function(self) self.savestate = { inventory = merge({}, self.inventory), curitem = self.curitem, } end, restore = function(self) self.inventory = merge({}, self.savestate.inventory) self.curitem = self.savestate.curitem self.savepoint = nil end, } gravity = 1/32 terminal_velocity = 1 zones = { mapzone(0, 0, 24, 16), mapzone(24, 0, 16, 16), mapzone(40, 0, 40, 24), mapzone(80, 0, 16, 24), mapzone(96, 0, 32, 24), mapzone(0, 16, 24, 32), mapzone(24, 16, 16, 16), mapzone(24, 32, 16, 16), mapzone(40, 24, 40, 24), mapzone(80, 24, 32, 24), mapzone(112, 24, 16, 24), } curzonen = 1 curzone = zones[curzonen] declare_tile{ class = playeractor, shape = box(0, 0.5, 1, 1.5), height = 2, poses = { default = {{1}, {17}}, walking = {{1}, {16, 17}}, jumping = {{1}, {16}}, falling = {{1}, {16}}, dying = {{1, 3, 4, 5, 6}, {17, 19, 20, 21, 22}, stop = true}, }, draw = function(self) for i = 1, 4 do pal( isaaccolors[1][i], isaaccolors[isaaccolor][i]) end playeractor.draw(self) pal() end, } isaaccolors = { {13, 2, 12, 1}, -- purple + blue {13, 2, 14, 2}, -- purple + pink {12, 1, 11, 3}, -- blue + green {15, 9, 14, 2}, -- peach + pink {11, 3, 10, 9}, -- green + yellow {6, 5, 7, 6}, -- silver + white {9, 4, 13, 2}, -- orange + purple {1, 1, 8, 2}, -- navy + red } isaaccolor = flr(rnd(#isaaccolors)) + 1 savepointactor = class(actor, { sprite = declare_sprite{ 24, 24, 24, 24, 24, 25, 26, 27, 28, 29, }, is_savepoint = true, draw = function(self) self.sprite:drawat( self.pos + vec2(0, 0.5), self.sprite_time, self.facing_right) end, reset = function(self) curzone:del_actor(self) end, }) declare_tile{ sprite = 8, shape = box(0, 0.75, 1, 0.25), oncollide = function(self, actor, d) if d.y > 0 and actor.is_player then actor:die() end end, } declare_tile{ poses = { default = {56}, switched = {57}, }, usesprite = declare_sprite{2}, oncollide = function() end, is_usable = true, reset = function(self) self.is_usable = true self:set_pose"default" end, onactivate = function(self) sfx(4) for _pos, decor in pairs(curzone.decor) do if decor.onuselever then decor:onuselever(true) end end self:set_pose"switched" self.is_usable = false end, } declare_tile{ sprite = 42, shape = box(0, 0, 1, 0.25), timer = 0, reset = function(self) self.enabled = false decoractor.reset(self) end, onuselever = function(self) self.enabled = true self.timer = 25 end, update = function(self) decoractor.update(self) if not self.enabled or self.timer <= 0 then return end self.timer -= 1 if self.timer == 10 then sfx(5) end if self.timer <= 10 then end end, draw = function(self) if self.timer > 0 then apply_ramp_fade(blackramp, self.timer / 10, 0) self.sprite:drawat(self.pos) pal() end end, } declare_tile{ class = mobactor, poses = { default = {58}, awake = {59}, }, reset = function(self) mobactor.reset(self) self:sleep() end, sleep = function(self) self.sleep_timer = 0 self:set_pose"default" if self.laser then curzone:del_actor(self.laser) self.laser = nil end end, update = function(self) local pcoll = player:coll() local scoll = self:coll() local px = pcoll.l + pcoll.w / 2 local sx = scoll.l + scoll.w / 2 if abs(px - sx) < 2 then self:set_pose"awake" self.sleep_timer = 150 if not self.laser then self.laser = laseractor(self.pos + vec2(0, 1)) curzone:add_actor(self.laser) end elseif self.pose == "awake" then self.sleep_timer -= 1 if self.sleep_timer <= 0 then self:sleep() end end if self.pose == "awake" then local dx = 0.125 local d0 = self.pos.x - self.pos0.x if d0 > 4 then self.reverse = true elseif d0 < -4 then self.reverse = false end if self.reverse then dx *= -1 end self.pos.x += dx if self.laser then self.laser.pos.x += dx end end end, } laseractor = class(actor, { init = function(self, pos) actor.init(self, pos) local bottom = pos:copy() while pos.y < curzone.box.b - 1 do bottom.y += 1 local tile = curzone:tile(bottom) if tile:blocks(self) then break end end self.shape = box( 0.375, 0, 0.25, bottom.y - pos.y) end, update = function(self) local coll = self:coll() if curtime % 10 == 0 then local ang = rnd() * 0.5 curzone:add_actor(particle( vec2(coll.l, coll.b), 8, 8, vec2(cos(ang), sin(ang)) * 0.125)) end if coll:overlaps(player:coll()) then player:die() end end, draw = function(self) local coll = self:coll() rectfill(coll.l * 8, coll.t * 8, coll.r * 8 - 1, coll.b * 8 - 1, 8) end, }) declare_tile{ poses = { default = {62}, turning = {62, 63}, }, usesprite = declare_sprite{2}, oncollide = function() end, is_usable = true, update = function(self) if self.turning_timer then self.turning_timer -= 1 if self.turning_timer <= 0 then self.turning_timer = nil self:reset() end end decoractor.update(self) end, reset = function(self) self.is_usable = true self:set_pose"default" end, onactivate = function(self) sfx(18) for actor in all(curzone.actors) do if actor.onusewheel then actor:onusewheel(true) end end self:set_pose"turning" self.is_usable = false self.turning_timer = 30 end, } declare_tile{ class = mobactor, sprite = 39, reset = function(self) mobactor.reset(self) local x, y = self.pos0.x, self.pos0.y local h = 1 while y > 0 do if curzone:tile(vec2(x, y - 1)).sprite:current() == 38 then h += 1 y -= 1 else break end end self.pos = vec2(x, y) self.shape = box(0, 0, 1, h) end, update = function(self) if self.direction and curtime % 3 == 0 then local coll = self:coll() if self.direction > 0 and coll.b == flr(coll.b) and curzone:tile(vec2(coll.l, coll.b)):blocks(self) then self.direction = nil return end if self.direction < 0 and coll.h <= 1 then self.direction = nil self.close_timer = 120 return end self.shape.h += self.direction self.shape.b += self.direction elseif self.close_timer then self.close_timer -= 1 if self.close_timer <= 0 then self.close_timer = nil sfx(7) self.direction = 0.125 end end end, draw = function(self) local sx = self.pos.x * 8 local coll = self:coll() local sy = coll.b * 8 - 8 spr(39, sx, sy) local h = coll.h * 8 - 8 while h >= 8 do sy -= 8 h -= 8 spr(38, sx, sy) end if h > 0 then sspr(6*8, 24 - h, 8, h, sx, sy - h) end end, onusewheel = function(self) if not self.direction and not self.close_timer then sfx(7) self.direction = -0.125 end end, } declare_tile{ class = decoractor, sprite = 38, enabled = false, } declare_tile{ sprite = 47, shape = box(0, 0.375, 1, 0.625), } declare_tile{ class = mobactor, sprite = 50, shape = box(0.25, 0.25, 0.5, 0.5), floating = true, reset = function(self) mobactor.reset(self) self.enabled = true end, oncollide = function(self, actor, d) if actor.is_player then sfx(6) add(progress.inventory, items.spellbook) self.enabled = false end end } declare_tile{ class = mobactor, sprite = 53, shape = box(0.25, 0.25, 0.5, 0.5), floating = true, oncollide = function(self, actor, d) if actor.is_player then game:win() end end, } __gfx__ 00000000c0000000000ddd0000000000000000000000000000000000000000000000000044440444000000000000000000000000000000000044444022242242 00000000ca0000000ddddd00c0000000000000000000000000000000000000000000000004444440000000000000000000000000000000004444444424224224 007007001ccc0000dddd0000ca000000000000000000000000000000000000000000000000000000000000000000000000000000000000004424424422424224 000770001accc000dddddddd1ccc0000c000000000000000001cc000000000000000000000000000000000000000000000000000000000002442242422422424 0007700001caca00dddddddd1accc0000ca000000ccca0000001cca0000000000080000000000000000000000000000000000000000000004224242242242422 00700700041cccc0dddd000001caca0001ccc00001cccc000001cccc000000000060002000000000000000000000000000000000000000002424222224242222 000000000117dd000ddddd00041cccc001accc00001accc00001accc000000000566006000000000000000000000000000000000000000002422422424224224 00000000022dddd0000ddd00011ddd00001caca0001ccac00001ccac000000005556655600000000000000000000000000000000000000002242242222422422 002dddd0002dddd0002dddd0002dddd0041cccc0004ccca000041cca00000000033333000333330003333300033333000bb33300033bb30003333b0000000000 0011cc000011cc000011cc000011cc00011dddd0002dddd000121ccc00000000330003303300033033000330bb0003303300033033000b30330003b000000000 011ccdc0011ccdc0011ccdc00111cd000011cc000012ddd00012dddd000000003003003330030033b003003330030033300b0033300300b33003003b00000000 21ccdd1c211ccdc0211ccdc0011ccdc00111cd000011cd000011cdd0000000003033303330333033b033303330bb30333033b033303330bb3033303300000000 1cc2dd1c11ccdd1c11ccdd1c111ccdc0011ccdc00111cd000111cd000000000003300030033000300bb0003003300030033000b0033000300330003000000000 1cc2ddc01cc2dd1c1cc2dd1c11ccdd1c111ccdc0011ccdc00111cdc0000000000000333000003330000033300000bb30000033b0000033300000333000000000 020000d000200d000002d00000200d0011ccdd1c11ccdd1c111ccdc0000000000003300000033000000bb0000003300000033000000330000003300000000000 2000000d00200d00000d200000200d000220dd0011c0dd1c11ccdd1c0000000000030000000b0000000300000003000000030000000300000003000000000000 044444404444422244444224444444440444044455555555056d6650056d665006760600055505000effffe00000000000000000555555554444422265000056 424422442444224404444440444400402424242426d666650566665005666650606007075050050502eeee20000000000000000066d666652444224407655670 22242444222424440000000004400400222022202226d66505d66d5005d66d5000700606005005050000000000000000000000006666d6652224244400766700 2222444422224444000000000040004000000000222266d5056d6650056d665007000060050000500022220000000000000000006d6666d522224444eeeeeeee 422422444224224400000000000000000000000042246d650566665005666650000600000005000000000000000000000000000066666d6542662d44ef2222fe 4244222442442224000000000000000000000000424426650566d6500566d6506760076055500550000000000ffffff000000000666d66654d66d66402ffff20 4244422242444222000000000000000000000000424442d505d6665005d666507070760650505505000000002e7eeee22ffffff26d66d6d556d666d502feef20 24444222244442220000000000000000000000002444422505666d50005555000060070700500505000000002e7eeee22e7eeee2666666655555555502feef20 00004440077777701cccccc00ff00000000000000000000600000000000000000000000000000000444444444444444400000000000000000002000000000020 000442447757557711c33cc09f9f0e00000000000000006000000000000000004000000000000004446666444466664450000000000000050004000020000400 00042444777777771cccc3c099fffe00000000000000060000000000000000004400000000000044462222644622226455000000000000550020420004204200 00444240775575771cc3ccc0fffffeee00000000090060000000000000000000040000000000004062244226622ee22605000000000000500044404200444000 004400000777777011cc33c00fffeff00000000000960000000000000000000000500000000005002244442222eeee2200600000000006002404440000044400 04400000000077001cccccc0000effff0000000004490000555555555555555500252200002252002222222222e88e2200262200002262000024020000240240 44000000000070001ffffff00000ffff00000000440f90006d666d666d666d660244442002444420022442200228822002444420024444200000400000400002 40000000000700001111111000000ff00000000044f0000066666666666666662444444224444442002222000022220024444442244444420000200002000000 66666666606566660000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 60000000066550600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 60000000000605060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 60000000000650550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 66666666000066560000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00006000000000650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00006000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00006000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200200 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002202200 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024e2400 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eee4400 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e414100 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004444e40 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000444400 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ff4f00 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffff0 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fffff0 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004fff40 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024f420 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004244420 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ff442400 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ff42400 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040400 12020000000032121212121212121212121212000000001212121212121212121212121212121212121202000000000000000022321212121212000012120000 00000000000002121200000012121212120200000000000032221212120200003232323232000000000000000000001212520000000000000000000012121212 12120000000000221212122232e23232121212808002021212121212121212121212121212121212121212000000000000000000002222322212000012320000 00000000020212121200000012121212121202020000000000002212121200000000000000000000000000000000021212120000000000000000000012121212 12120200000000001212220000620000221212121212121212121212121212121212121212121212121212420000000000000000000000000012000032000000 00000202121212121200000012121212121212120202020000000012121202020000000002020202000000e30000121212120000000000000000000212121212 12121200000000001222000000620000002212121212121212121232223222e22232121212121212121212000000000000000000000000000022000000000000 02021212121212121202000012121212121212121212120242424212121212120000000012121212020000000002121212120000000000000000001212121212 12121202000000001200000000720000000032121212121212123200000000620000222212121212121212424200000000000000000000000000000000000202 12121212121212121212000022121212121212121212121200000012121212120000000022121212120202020212121212125200000000000000001212121212 12121212000000021200000002020202000000221212121212120000000000620000000032121212121212000000000000000000000000000000000000021212 12121212121212121212000000121212121212121212122200000212121212120000000000121212121212121212121212121200000000000000001212121212 12121222000000121202000022121212020000002212121212220000000000620000000000221212121212024242000000000000000000000000000202121222 22323222121212121212000000121212121212121232220000001212121212220000000000141212121212121212121212121200000000000000001412121212 12123200000002121212000000223212120200000012121212000000000000620000000000001212121212120000000000000000000000000000002222322200 00000000221212121212020000121212121212222200000000021212121212000000000000001212e23222121212121212121200000000000000000012121212 12320000000012121212020000000022121200000032121212000000a20000620000000200002212121212120200000000000000000000000000000000000000 0000e300001212121212120000121212121222000000000002121212121232000000000000003222620000221412121212121252000000000000000014121212 12000000000212121212120000000000121202000000121212020000000000620000001200000012121212121200000000000000000000000000000000000000 00000000003212121212120000321212121200000000000212121212122200000000000000000000620000000022141212121212000000000000000000121212 12000000021212121212120200000000121212000000221212120000000000620000001200000012121212121252000000000000000000000000000000000000 00000000000012121212120000001212123200000000002232323222220000000000000000000000720000000000001212121212000000000000000000321212 12020000223212121212122200000002121212020000003222120200000000620000001202000012121212121212000000000000000000000000000000000000 00000000000012121212120200002212220000000200000000000000000000000000000000000000020202520000001412121212520000000000000000001212 12120000000022322232320000000012121212120000000000121202000000620000001212000032121212121212020000000000000000000000020200000000 00000000000012121212121200000012100000021202020000000000000000000000000000000002121212125200000012121212120000000000000000021212 1212020000000000000000000000021212121212000000001022223200e300720000831212000000121212121212120200000000000000000202121202020200 00000000000212121212121202000032000002121212120202000000000000000000000000000012121212121252000012121212125200000000530000121212 12121202020000000000000002021212121212120202000000000000000000020000121212020000121212121212121202028080800202021212121212121202 02020202021212121212121212020000020212121212121212020202020000008080800000000012121212121212520012121212121200000000f20002121212 12121212120202020202020212121212121212121212020202020202020202120202121212120202121212121212121212121212121212121212121212121212 12121212121212121212121212120202121212121212121212121212120202021212120202020212121212121212125212121212121252d2d2d2d2d212121212 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007700000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000770000000000000000000000000000000000005700000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000770000000000000000000000000000000000007500000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000550000777000007777000007777000000777005000777000000000 00000000000000000000000000000000000000000000000000000000000000000000000007770007777700077777700077777700007777700007777700000000 00000000000000000000000000000000000000000000000000000000000000000000000005770007775500055557700055557700077755700007775500000000 00000000000000000000000000000000000000000000000000000000000000000000000000770005777000007777700007777700077500500005777000000000 00000000000000000000000000000000000000000000000000000000000000000000000000770000577700077557700077557700077700000000577700000000 00000000000000000000000000000000000000000000000000000000000000000000000000770007777700077777700077777700057777700007777700000000 00000000000000000000000000000000000000000000000000000000000000000000000007777005777500057777770057777770005777500005777500000000 00000000000000000000000000000000000000000000000000000000000000000000000005555000555000005555550005555550000555000000555000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000070000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000070000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000070000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000777700000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000777700077700077700777000777007077700575500000000000 00000000000000000000000000000000000000000000000000000000000000000000000000007555700755570755507555707555705755570070000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000007000700777750577007000507777500700070070000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000007000700755500055707000707555000700070070000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000005777570577700777505777505777000700070057700000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000555050055500555000555000555000500050005500000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 __gff__ 000000000000000000000000000080800000000000000000000000000000000080804040a080008000008000008080800000000000000000000080800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 __map__ 21212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121222300003a0000222321212121212121212121212121212121 2121212121212121212121212121212121212121212121212121212121212121212121212121212121212222222222222221212123232222222322222221212121222223232223222222222222212121222223222221212121212121212121212121212223222200000000000000000022222121212121212121212121212121 2121212121212121212121212121212121212121212121212121212121212121212121212121212122220000000000000022212200000000000000000022232321000000000000000000000000232121010000000023212121212121212121212121220000000000000000000000000000002223222221212121212121212121 2121212121212121212121212121212121212121212121212121232223223a22232222212121212100000000000000000000210000000000000000000000000021000000000000000000000000002121000000000000222121212121212121212121000000000000000000000000000000000000000022222121212121212121 2121222322222121212121212121212121212121212121232222000000000000000000222223212101000000000000000000210000000000000020200000000022000000000000002a20000000002121202000000000002121212121212121212123000000202000000000000000000020202020242424242121212121212121 22220000000022222321212121222223222121212323220001000000000000000000000000002221000000000000202000002200200000000000222300000000000000000000002a0021000000002121212100000000002221212121212121212100000020212120202020202020202021212121000000002221212121212121 010000000000000000222322220000000023222200000000000000000000000000000000000000212020200000002222000000002200000000000000000000000000000000002a000021200000002121212100000000000021212121212121212100000022232121212121212121212323232121202024242421212121212121 0000002020000000000000000000000000000000000020202020202020202020202020000000002121212100000000000000002000000000000000000000000020200000002000000021210000002221212120000000000023212121212121212100000000002321212121212323230000002222222200000021212121212121 2020202121202000000000000000000020202020202021212121212121212121212121200000002121212300000000000000002200000000000000000000000023220000002300000021210000000021212121000000000000222121212121212100320000000023232323230000000000000000000000002021212121212121 21212121212121202020202a2a2a2a2a212121212121212121212121212121212121212100000021212100000000000000002000000000000000000000000000000000000000000000212100000000212121210000000000000021212121212121002f0000000000000000000000000020000000000000202121212121212121 21212121212121212121210000000000212121212121212121212121212121212121212120000021212100000000000000002300000000000000000000000000000000000000000000212100000000212121212a2a2a2a2a2a2a2121212121212120212020080808080808080808082021000000002020212121212121212121 2121212121232322212121000000000021212121212121212121212121212121212121212100002321210000000000000000000000000000000000000000000000000000000000000022210000000021212121000000000000002222222322232121212121212121212121212121212122000020202121212121212121212121 2121212222000000222322000000202021212121212121212121212121212121212121212100000021210000000000000000000000000000000000000000000000000000000000000000210000000021212121000000000000000000000000002121212121212121212122232222222200002021212121212121212121212121 2121230000003800000000000020212121212121212121212121212121212121212121212120000021210000000000000000000000000000000000000000000000000000000000000000212000000021212121000000000000000000000000002121212121212122222200000000000000202121212121212121212121212121 212108080820212020202020202121212121212121212121212121212121212121212121212120202121000000000000000000000000000000000000000000000000000000000000000021210000002121212100000000000000002a202020202121212121222200000000002020202020212121212121212121212121212121 2121212121212121212121212121212121212121212121212121212121212121212121212121212121230000000000000000000000000000000000000000000000000000000000000000212100000021212121000000000000002a08212121212121212223000000000020202121212121212121212121212121212121212121 21212121212121212121212121212121212121212121212121212121212121212121212121212121210000000000000000000000000000000000000000000000000000000000000000002121000000212121212a2a2a2a2a2a2a0821212121212121220000000000202021212121212223222121212121212121212222222221 2121212122222221212122222322212121212121212121212323232223212121212121212121212121000000000000000000000000000000000000000000000000000000000000000008212100000021212121000000000000002121212121212121000000000020212121212222230000002223222323222223220000000021 21222322000000232e2200000000222223212121212121210100000000222121212121212121212121000000000000000000000000000000000000000000000000000000000000000021212100000022212121000000000000002121212121212123000000000022222322220000000000000000000000000000000000000022 220000000000000026000000000000000022222e23212121000000000000222e23222e222221212121000000000000000000000000000000000000000000000000080808000000000821212100000000212121080000000000002121212121212200000020000000000000000000000020000000000000000000000820000000 0100003e00000000260000000000000000000026002221212000000000000026000026000023212121000008080000000000000000000000000000000000000808212121080000082121212120000000212121210000000000002121212121210100002021202008080000000008082021202008080000000008082121200000 00000000000000002700000000000000000000260000212121200000003e0026000026000000222121003821210800080808000000000000080000080008082121212121210808212121212121000000212121210000380000082121212121210000202121212121210808080821212121212121210808080821212121212000 2020202020000020202020200820082020000027000023212121200000000026000027000000002121082121212108212121080808080808210808210821212121212121212121212121212121002020212121210820212008212121212121212020212121212121212121212121212121212121212121212121212121212120 2121212121202021212121202020202121202020000000212121212020202026202020202000002121212121212121212121212121212121212121212121212121212121212121212121212121202121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121 212121212121212123222323222223222e22222200000021212121212121212621212121220000212121212121212121212e21212121212121212121212e212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121 2121212122232322000000000000000026000000000000212121212121212126212121230000202121212121222222232226222121212121212121212226222121222223222223232222212121212121212121212222232222232322222223222321212121212121212121212121212121212121232341212121212121212121 21212222000000000000000000003e0026000000000000212121212121212126212121000020212122222323000000000026002222212121212123220026002223000000000000000000212121212121212121220000000000000000000000000023212121212121212121212121212123232323000000232321212121212121 2123000000000000000000000000000027000000000020212121212122222226212122000021212101000000000000000026000000222323222200000026000000000000000000000000232121212121212123000000000000000000000000000000212121212121212121212121212101000000000000000021212121212121 2100000000000000202020202020202020200000002021212121212300000027212100000022222200000000000000000026000000000000000000000026000000000000000000200000002121212121212200000000202008080808080000080808212121212121212222232321212100000000000000000041212121212121 210000000020202021212121212121212121200000232321212121080808202121212020000000002000000000000000002700000000000000000000002738000000000000002a210000002121212121210000000020212121212121210000212121212121212122230000000022212125000000000000000000232121212121 2100000020212121212121212121212121212100000000212121212121212121212121212020000021000000242424000020202020202000000000002020210000000000000000210000002221212121210000242421212121212121210000222121212121212200000000000000232121000000000000000000002121212121 2100000022222121212121212121212121212100003e00212121212121212121212121212121202021200000000000000022222121212120202000002121230000000000000000212000000021212121210000000022232221212121210000002121212121220000000000000000002121000000000000000000004121212121 __sfx__ 010200000c0700c070110701307000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 010c00001f3751c375233752330523305233050030500305003050030500305003050030500305003050030500305003050030500305003050030500305003050030500305003050030500305003050030500305 0108000017070170701707017070110701107011070110700e0700c0700e0710e0710e0710e0710e0710e07100000000000000000000000000000000000000000000000000000000000000000000000000000000 01020000186111861118621186211d631216312364126641296412d64130641346413764137641376413764137641376413764137641296412964124641246411d6411d641186311863111621116210c6110c611 01100000136550065000655006050c605006050060500605006050060500605006050060500605006050060500605006050060500605006050060500605006050060500605006050060500605006050060500605 01040000115741a504135741557415570005040050400504005040050400504005040050400504005040050400504005040050400504005040050400504005040050400504005040050400504005040050400504 0108000028075260752d0751700513005040050000500005000050000500005000050000500005000050000500005000050000500005000050000500005000050000500005000050000500005000050000500005 010c0000246102b6102f61000616246102b6102f61000616006060060600606006060060600606006060060600606006060060600606006060060600606006060060600606006060060600606006060060600606 010c00000e774107740e7741377413770137701377013770007040070400704007040070400704007040070400704007040070400704007040070400704007040070400704007040070400704007040070400704 010c0000217701c7001d7701f770217701a70021770007001f7702177023770217002477024770247702477023700237002370023700237002370023700237000070000700007000070000700007000070000700 0110000005070050700507005070070700707005070050700b0700b0700b0700b0700907009070090700907005070050700507005070040700407002070020700707007070050700507002070020700007000070 011000001c0021c0021c0521c0521c0021c0021c0521c052000020000200002000021f0521f0521f0521f05200002000021d0521d0521f0521f05219002180021f0521f0521f0521d05218052180521800218002 01100000050700507005000050000407004070050000500007070070700707007070187430900007000070000907009070040700407005070050700200002000040700407004070040701a743187430000000000 01100000077430670305703057030c743077030070300703057030570305743057030c743057030b70300703077430670305703057030c743077030070300703057030570305743007430c743057030b70300703 01100000180521a0521f0521f0021f0521f0021f0521f0521f0021f0021f0521f0521d0521d0521f0521c05218052180021805218002180521a0521d0521a0521805218052180520e0021a0521a0521a05205002 011000000707007070070700707007070070700707007070050700507005070050700407004070020700207007070070700907009070050700507007070070700507005070050700507002070020700207002070 001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 010c00003b0740000429074000043b0740000429074000043b0740000429074000040000400004000040000400004000040000400004000040000400004000040000400004000040000400004000040000400004 0106000013770107700c7700c7700c7700c7751370013700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 011000001103500005000050000513035110051103500005150301503500005000051303013035000050000510030100301003010035000050000500005000051003010030100301003500005000050000500005 011000001103500000000000000013035000001103500000150301503500000000001303013035000000000010035100351003510035130351303513035130351703517035170351703511035110351103511035 011000001703511035130350000017035110351303500000100301003500000000001003010035000000000017035110351303500000170351103513035000001003010035000000000010030100350000000000 011000001703511035130350000018035150351703500000170351103513035000001803515035170350000018035150351303511035170351303517035130051803515035130351103517035130351703513005 001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 011000001c770007002170021700217702177021770007001d7001d7001f7001c7001d7701f7001f7701f7001d7701d7001a7701a7701a7001a7001a7001a70021770007001d770007001c7701c7700070000700 011000001a770007001c770007001d7701d77000700007001f7701f7001c770007001f7701c7001d770007001f7701f7701f7701f7701c7001c7000070000700187701a770187701877018770187701877018770 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 __music__ 01 0a424344 00 0c424d44 00 0c420d44 00 0a4b0d44 00 0f4b0d44 00 0f4e0d44 02 0c4e0d44 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 01 14424344 00 15424344 00 14424344 00 16424344 02 17424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 01 1e424344 04 1f424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344 00 41424344