Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- pico-8 cartridge // http://www.pico-8.com
- version 41
- __lua__
- --vestal's path
- --by senator myth
- --enums+globals
- --[[
- jumpy thing -done
- -jump short distances
- freezey -done
- -freeze water, moving objects
- -in a line
- shovel -done
- -dig things, or refill holes
- sapling
- -can be planted, used as target
- hookshot -done
- -c:
- keys
- -can be used to unlock doors
- teleporter
- --]]
- --globals and enums
- modes = {
- gameplay = 0,
- inventory = 1,
- hookshot = 2,
- victory = 3,
- wait = 4,
- }
- flags = {
- can_be_picked_up = 0,
- is_solid = 1,
- is_pit = 4
- }
- normals = {
- up = {x=0, y=-1},
- down = {x=0, y=1 },
- left = {x=-1,y=0 },
- right = {x=1 ,y=0 },
- }
- tiles = {
- none = 0,
- hole = 81,
- filled_hole = 82,
- tree = 83,
- water = 100,
- ice = 101,
- gate_y = 106,
- gate_r = 107,
- gate_b = 108,
- cold_hearth = 93,
- lit_hearth = 77,
- }
- items = {
- none = 0,
- ball = 2,
- shovel = 68,
- hookshot = 69,
- horseshoe = 71,
- icerod = 70,
- torch = 78,
- key_y = 90,
- key_r = 91,
- key_b = 92,
- }
- item_names = {
- [items.shovel] = "shovel",
- [items.hookshot] = "hookshot",
- [items.horseshoe] = "alicorn shoe",
- [items.torch] = "sacred fire",
- [items.icerod] = "ice wand",
- [items.key_y] = "gold key",
- [items.key_r] = "red key",
- [items.key_b] = "blue key"
- }
- secrets = {
- -- {x=13, y=28,
- -- item = items.ball}
- }
- secrets_found = {}
- debug1, debug2 = "🅾️", "hi!"
- mode = modes.gameplay
- pickup_enabled = true
- last_map_x = nil
- last_map_y = nil
- safe_x = 0
- safe_y = 0
- hs_range = 49
- hs_pos = {x=0,y=0}
- hs_retracting = false
- hooked = false
- ice_proj = nil
- jumping = false
- jump_height = 6
- jump_speed = 1
- p = {}
- inv = {0,0}
- sel = 1
- lvl = 1
- --in tile/map space
- spawns = {
- {x=2,y=3},
- {x=21,y=7},
- {x=14,y=27},
- {x=30,y=19},
- {x=36,y=10},--5
- {x=57,y=10},
- {x=67,y=14},
- {x=66,y=20},
- {x=83,y=28},
- {x=97, y=22},--{x=81,y=7},--10
- {x=37,y=26},
- {x=102,y=07},
- }
- descriptions = {
- "level 1 - \nstart",
- "level 2 - \nisland",
- "level 3 - \npeninsula",
- "level 4 - \nforest paths",
- "level 5 - \nford the river",
- "level 6 - \ndelta",
- "level 7 - \nquiet mere",
- "level 8 - \nnorth forest",
- "level 9 - \nfrozen lake",
- "level 10 - \nrivers",
- "level 11 - \nisthmus",
- "level 12 - \nfinale",
- }
- hints = {
- "",
- "",
- {[[press z
- to use items.]],
- 8,16,7
- },
- {[[press x to open inventory.
- inventory space limit is 2.]],
- 8,98,7
- },
- {[[press enter to
- restart level.]],
- 65,108,7
- },
- "",
- "",
- "",
- "",
- "",
- "",
- }
- function _init()
- sp = spawns[lvl]
- p=entity("player", 4+sp.x*8, 4+sp.y*8, 1, normals.down)
- cls(11)
- music(0)
- menuitem(1,"restart level",reload_level)
- end
- function entity(
- name,
- x,
- y,
- sprite,
- normal,
- update)
- return {
- name = name,
- x = x,
- y = y,
- sprite = sprite,
- n = normal,
- h = 0,
- update = update,
- born = time(),
- age = 0,
- }
- end
- -->8
- --update
- function _update()
- if
- mode == modes.gameplay then
- update_gameplay()
- -- update_hookshot()
- elseif
- mode == modes.inventory then
- update_inventory()
- elseif
- mode == modes.hookshot then
- update_hookshot()
- elseif
- mode == modes.victory then
- update_victory()
- elseif
- mode == modes.wait then
- update_wait()
- else
- assert(false, "no mode!")
- end
- end
- function update_gameplay()
- if btnp(❎) and lvl>=4 then
- mode = modes.inventory
- return
- end
- if btnp(🅾️) then
- use()
- return
- end
- stx,sty = p.x,p.y
- start_tile = tile_at(stx,sty)
- if btn(⬆️) then
- p.y-=1
- p.n=normals.up
- end
- if btn(⬇️) then
- p.y+=1
- p.n=normals.down
- end
- if btn(⬅️) then
- p.x-=1
- p.n=normals.left
- end
- if btn(➡️) then
- p.x+=1
- p.n=normals.right
- end
- tile_here = tile_at(p.x,p.y)
- if is_gate(tile_here) then
- open_gate_at(p.x,p.y)
- end
- if tile_here==tiles.cold_hearth then
- light_hearth_at(p.x,p.y)
- return
- end
- if is_solid(tile_here) then
- p.x,p.y = stx,sty
- elseif is_pit(tile_here) and
- p.h==0 then
- p.x,p.y = stx,sty
- end
- map_x, map_y = world_2_map(p.x,p.y)
- if map_x ~= last_map_x or
- map_y ~= last_map_y then
- pickup_enabled = true
- end
- if jumping then
- p.h += jump_speed
- if p.h >= jump_height then
- jumping = false
- end
- elseif p.h > 0 then
- p.h -= jump_speed
- if p.h <= 0 then --jic...
- p.h = 0
- tile_here = tile_at(p.x,p.y)
- if is_pit(tile_here) then
- p.x,p.y = safe_x, safe_y
- end
- end
- end
- last_map_x,last_map_y =
- map_x, map_y
- pickup()
- if ice_proj then
- ice_proj:update()
- end
- end
- function update_inventory()
- if btnp(➡️) then sel += 1 end
- if btnp(⬅️) then sel -= 1 end
- if sel==3 then sel=1 end
- if sel==0 then sel=2 end
- if btnp(⬇️) then drop() end
- if btnp(❎) or btnp(🅾️) then
- mode = modes.gameplay
- end
- end
- function update_hookshot()
- old_x, old_y = hs_pos.x,
- hs_pos.y
- if not hs_retracting then
- hs_pos.x += p.n.x * 3
- hs_pos.y += p.n.y * 3
- tile_here = tile_at(
- hs_pos.x,
- hs_pos.y
- )
- if is_solid(tile_here) then
- hs_pos.x,
- hs_pos.y = old_x, old_y
- hs_retracting = true
- if tile_here == tiles.tree then
- sfx(7)
- hooked = true
- end
- end
- if abs(hs_pos.x - p.x) +
- abs(hs_pos.y - p.y) >=
- hs_range then
- hs_retracting = true
- end
- else
- if hooked then
- p.x += p.n.x * 3
- p.y += p.n.y * 3
- pickup()
- else
- hs_pos.x -= p.n.x * 3
- hs_pos.y -= p.n.y * 3
- end
- end
- if hs_pos.x == p.x and
- hs_pos.y == p.y and
- hs_retracting == true
- then
- tile_here = tile_at(p.x,p.y)
- if is_solid(tile_here) or
- is_pit(tile_here) then
- p.x,p.y=safe_x,safe_y
- end
- mode=modes.gameplay
- end
- end
- function update_victory()
- if lvl == 12 then return end
- if btnp(❎) or btnp(🅾️) then
- sfx(0)
- ice_proj = nil
- load_level(lvl+1)
- mode = modes.wait
- end
- end
- function update_wait()
- if btnp(❎) or btnp(🅾️) then
- mode = modes.gameplay
- end
- end
- function inv2str()
- return tostr(inv[1]).." , " ..tostr(inv[2])
- end
- function load_level(level)
- lvl= level
- inv= {0,0}
- sp = spawns[lvl]
- p=entity("player", 4+sp.x*8, 4+sp.y*8, 1, normals.down)
- reload(0x2000, 0x2000, 0x1000)
- end
- function reload_level()
- load_level(lvl)
- end
- -->8
- --draw
- function _draw()
- cls(3)
- camera_to_player_screen()
- map()
- camera()
- draw_hints()
- camera_to_player_screen()
- draw_player()
- if ice_proj then
- draw_entity(ice_proj)
- end
- fx,fy= flr(p.x/8)+p.n.x, flr(p.y/8)+p.n.y
- -- hilight_tile(flr(p.x/8),flr(p.y/8),10)
- -- hilight_tile(fx,fy,10)
- if mode == modes.inventory then
- draw_inventory()
- elseif mode == modes.hookshot then
- draw_hookshot(p.x,p.y,hs_pos.x, hs_pos.y)
- elseif mode == modes.victory then
- draw_victory()
- elseif mode == modes.wait then
- draw_wait()
- end
- camera()
- end
- function my_rect(x,y,w,h,col)
- rectfill(x,y,x+w,y+h,col)
- end
- function draw_inventory()
- camera()
- color(2)
- rectfill(0,0,128, 128 * 1/8, 0)
- print(sel_name(), 50 ,0, 6)
- print("⬅️➡️-equip ⬇️-drop", 50, 8,6)
- for k,v in pairs(inv) do
- spr(v,k*11,2)
- end
- i=sel-1
- rect(9+i*11,0,(9+i*11)+11,11,10+i)
- color()
- cursor(0)
- end
- function draw_hookshot(sx,sy,ex,ey)
- camera_to_player_screen()
- for i=1,5 do
- x = lerp(sx,ex,i/5)
- y = lerp(sy,ey,i/5)
- spr(67,x-4,y-4)
- end
- end
- function draw_victory()
- if lvl ~= 12 then
- cls(1)
- camera()
- spr(77,32,62)
- print("hearth restored.",41,64,7)
- else
- cls(1)
- camera(0,48*8)
- map()
- camera()
- print("all hearths restored.\nthanks for playing!",20,68,7)
- end
- end
- function draw_wait()
- cls(1)
- camera()
- spr(93,32,62)
- print(descriptions[lvl],41,64,7)
- end
- function draw_entity(e)
- spr(e.sprite, e.x-4, e.y-4)
- end
- function draw_player()
- if p.h ~= 0 then
- circfill(p.x, p.y+3,2,1)
- end
- pspr = get_player_sprite()
- spr(pspr, p.x-4, p.y-4-p.h)
- end
- function hilight_tile(tx,ty,col)
- s,e = tx*8, ty*8
- rect(s,e,s+8,e+8,col)
- end
- function draw_hints()
- if lvl >= 6 then return end
- hint = hints[lvl]
- if hint == "" then return end
- print(hint[1], hint[2],
- hint[3],hint[4])
- cursor()
- end
- function get_player_sprite()
- if
- p.n == normals.up then
- return 1
- elseif
- p.n == normals.down then
- return 1+16
- elseif
- p.n == normals.left then
- return 1+32
- elseif
- p.n == normals.right then
- return 1+48
- end
- end
- function sel_name()
- result = item_names[inv[sel]]
- if result == nil then
- result = "none"
- end
- return result
- end
- -->8
- --helpers
- --function current_map_coords()
- -- return flr(p.x/8),flr(p.y/8)
- --end
- --
- --function facing_map_coords()
- -- return flr(p.x/8)+p.n.x, flr(p.y/8)+p.n.y
- --end
- function facing_pos()
- return p.x+p.n.x*8,p.y+p.n.y*8
- end
- function tile_at(x,y)
- return mget(x/8, y/8)
- end
- function set_tile_at(x,y,t)
- mset(x/8, y/8, t)
- end
- function world_2_map(x,y)
- return flr(x/8), flr(y/8)
- end
- function is_pickupable(t)
- return fget(t,flags.can_be_picked_up)
- end
- function is_solid(t)
- return fget(t,flags.is_solid)
- end
- function is_pit(t)
- return fget(t,flags.is_pit)
- end
- function is_gate(t)
- return
- t==tiles.gate_y or
- t==tiles.gate_r or
- t==tiles.gate_b
- end
- function lerp(a,b,t)
- return a * (1-t) + b * t
- end
- function camera_to_player_screen()
- camera(flr(p.x/128)*128, flr(p.y/128)*128)
- end
- -->8
- --actions
- function drop()
- tile_here = tile_at(p.x,p.y)
- fx,fy = facing_pos()
- tile_facing = tile_at(fx,fy)
- if tile_here == 0 or
- tile_here == tiles.filled_hole then
- set_tile_at(p.x,p.y, inv[sel])
- inv[sel]=0
- pickup_enabled = false
- elseif tile_facing == 0 or
- tile_here == tiles.filled_hole then
- set_tile_at(fx,fy, inv[sel])
- inv[sel]=0
- end
- end
- function pickup()
- if not pickup_enabled then return end
- tile_here = tile_at(p.x,p.y)
- if is_pickupable(tile_here) then
- for k,v in pairs(inv) do
- if v == 0 then
- inv[k] = tile_here
- set_tile_at(p.x,p.y,0)
- sfx(1)
- break
- end
- end
- end
- end
- function use()
- item = inv[sel]
- if item ==
- items.shovel then
- dig()
- elseif item ==
- items.hookshot then
- fire_hookshot()
- elseif item ==
- items.horseshoe then
- jump()
- elseif item ==
- items.icerod then
- cast_ice()
- end
- end
- function dig()
- tile_here = tile_at(p.x,p.y)
- if tile_here == tiles.ice then
- return
- end
- fx,fy = facing_pos()
- tile = tile_at(fx,fy)
- if tile == tiles.none or
- tile == tiles.filled_hole then
- item = get_secret(fx,fy)
- if item ~= nil then
- spawn_item(fx,fy,p.n.x,p.n.y,item)
- end
- set_tile_at(fx,fy,tiles.hole)
- sfx(2)
- elseif tile == tiles.hole then
- set_tile_at(fx,fy,tiles.filled_hole)
- sfx(3)
- end
- end
- function fire_hookshot()
- sfx(6)
- safe_x, safe_y = p.x, p.y
- hs_pos = {x=p.x, y=p.y}
- hs_retracting = false
- hooked = false
- mode = modes.hookshot
- end
- function jump()
- if p.h ~= 0 then return end
- if p.n.y == -1 then
- jump_height = 9
- jump_speed = 1.5
- else
- jump_height = 6
- jump_speed = 1
- end
- safe_x, safe_y = p.x,p.y
- jumping = true
- sfx(5)
- end
- function cast_ice()
- p_tile = tile_at(p.x,p.y)
- if p_tile == tiles.ice then
- return
- end
- for x=0,128 do
- for y=0,64 do
- if mget(x,y) == tiles.ice then
- mset(x,y,tiles.water)
- end
- end
- end
- sfx(8)
- ice_proj = entity(
- "ice_proj",
- p.x,
- p.y,
- 3,
- p.n,
- ice_proj_update
- )
- end
- function ice_proj_update(s)
- s.age+=1/30
- s.x+=s.n.x
- s.y+=s.n.y
- tile_here = tile_at(s.x,s.y)
- if tile_here == tiles.water then
- -- sfx(9)
- set_tile_at(s.x,s.y,tiles.ice)
- end
- if s.age >= 4 then
- ice_proj = nil
- end
- if s.sprite==3 then
- s.sprite=19
- else s.sprite=3
- end
- end
- function open_gate_at(x,y)
- gate = tile_at(x,y)
- for k,v in pairs(inv) do
- --abuse sprite offset
- if v==gate-16 then
- set_tile_at(x,y,0)
- inv[k]=items.none
- sfx(10)
- end
- end
- end
- function light_hearth_at(x,y)
- for k,v in pairs(inv) do
- if v==items.torch then
- set_tile_at(x,y,tiles.lit_hearth)
- inv[k]=items.none
- sfx(4)
- mode = modes.victory
- -- load_level(lvl+1)
Advertisement
Add Comment
Please, Sign In to add comment