Guest User

Untitled

a guest
Oct 2nd, 2023
48
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 60.06 KB | Source Code | 0 0
  1. pico-8 cartridge // http://www.pico-8.com
  2. version 41
  3. __lua__
  4. --vestal's path
  5. --by senator myth
  6.  
  7. --enums+globals
  8. --[[
  9.     jumpy thing -done
  10.         -jump short distances
  11.     freezey -done
  12.         -freeze water, moving objects
  13.         -in a line
  14.     shovel -done
  15.         -dig things, or refill holes
  16.     sapling
  17.         -can be planted, used as target
  18.     hookshot -done
  19.         -c:
  20.     keys
  21.         -can be used to unlock doors
  22.    
  23.     teleporter 
  24. --]]
  25.  
  26. --globals and enums
  27.  
  28. modes = {
  29.     gameplay  = 0,
  30.     inventory = 1,
  31.     hookshot  = 2,
  32.     victory   = 3,
  33.     wait      = 4,
  34. }
  35.  
  36. flags = {
  37.     can_be_picked_up = 0,
  38.     is_solid = 1,
  39.     is_pit   = 4
  40. }
  41.  
  42. normals = {
  43.     up    = {x=0, y=-1},
  44.     down  = {x=0, y=1 },
  45.     left  = {x=-1,y=0 },
  46.     right = {x=1 ,y=0 },
  47. }
  48.  
  49. tiles = {
  50.     none        = 0,
  51.     hole        = 81,
  52.     filled_hole = 82,
  53.     tree        = 83,
  54.     water       = 100,
  55.     ice         = 101,
  56.     gate_y      = 106,
  57.     gate_r      = 107,
  58.     gate_b      = 108,
  59.     cold_hearth = 93,
  60.     lit_hearth  = 77,
  61. }
  62.  
  63. items = {
  64.     none   = 0,
  65.     ball   = 2,
  66.     shovel = 68,
  67.     hookshot = 69,
  68.     horseshoe = 71,
  69.     icerod = 70,
  70.     torch = 78,
  71.     key_y       = 90,
  72.     key_r       = 91,
  73.     key_b       = 92,
  74. }
  75.  
  76. item_names = {
  77.     [items.shovel]    = "shovel",
  78.     [items.hookshot]  = "hookshot",
  79.     [items.horseshoe] = "alicorn shoe",
  80.     [items.torch]     = "sacred fire",
  81.     [items.icerod]    = "ice wand",
  82.     [items.key_y]     = "gold key",
  83.     [items.key_r]     = "red key",
  84.     [items.key_b]     = "blue key"
  85. }
  86.  
  87. secrets = {
  88. --  {x=13, y=28,
  89. --      item = items.ball}
  90. }
  91.  
  92. secrets_found = {}
  93.  
  94. debug1, debug2 = "🅾️", "hi!"
  95.  
  96. mode = modes.gameplay
  97. pickup_enabled = true
  98. last_map_x = nil
  99. last_map_y = nil
  100.  
  101. safe_x = 0
  102. safe_y = 0
  103.  
  104. hs_range = 49
  105. hs_pos = {x=0,y=0}
  106. hs_retracting = false
  107. hooked = false
  108.  
  109. ice_proj = nil
  110.  
  111. jumping = false
  112. jump_height = 6
  113. jump_speed = 1
  114.  
  115. p = {}
  116. inv = {0,0}
  117. sel = 1
  118. lvl = 1
  119.  
  120. --in tile/map space
  121. spawns = {
  122.     {x=2,y=3},
  123.     {x=21,y=7},
  124.     {x=14,y=27},
  125.     {x=30,y=19},
  126.     {x=36,y=10},--5
  127.     {x=57,y=10},
  128.     {x=67,y=14},
  129.     {x=66,y=20},
  130.     {x=83,y=28},
  131.     {x=97, y=22},--{x=81,y=7},--10
  132.     {x=37,y=26},
  133.     {x=102,y=07},
  134. }
  135.  
  136. descriptions = {
  137.     "level 1 - \nstart",
  138.     "level 2 - \nisland",
  139.     "level 3 - \npeninsula",
  140.     "level 4 - \nforest paths",
  141.     "level 5 - \nford the river",
  142.     "level 6 - \ndelta",
  143.     "level 7 - \nquiet mere",
  144.     "level 8 - \nnorth forest",
  145.     "level 9 - \nfrozen lake",
  146.     "level 10 - \nrivers",
  147.     "level 11 - \nisthmus",
  148.     "level 12 - \nfinale",
  149. }
  150.  
  151. hints = {
  152.     "",
  153.     "",
  154.     {[[press z
  155. to use items.]],
  156.         8,16,7
  157.     },
  158.     {[[press x to open inventory.
  159. inventory space limit is 2.]],
  160.         8,98,7
  161.     },
  162.     {[[press enter to
  163. restart level.]],
  164.         65,108,7
  165.     },
  166.     "",
  167.     "",
  168.     "",
  169.     "",
  170.     "",
  171.     "",
  172.    
  173.  
  174.    
  175. }
  176.  
  177. function _init()
  178.     sp = spawns[lvl]
  179.     p=entity("player", 4+sp.x*8, 4+sp.y*8, 1, normals.down)
  180.     cls(11)
  181.     music(0)
  182.     menuitem(1,"restart level",reload_level)
  183. end
  184.  
  185. function entity(
  186.         name,
  187.         x,
  188.         y,
  189.         sprite,
  190.         normal,
  191.         update)
  192.         return {
  193.             name   = name,
  194.             x      = x,
  195.             y      = y,
  196.             sprite = sprite,
  197.             n      = normal,
  198.             h      = 0,
  199.             update = update,
  200.             born   = time(),
  201.             age    = 0,
  202.     }
  203. end
  204. -->8
  205. --update
  206. function _update()
  207.     if
  208.         mode == modes.gameplay then
  209.             update_gameplay()
  210. --          update_hookshot()
  211.     elseif
  212.         mode == modes.inventory then
  213.             update_inventory()
  214.     elseif
  215.         mode == modes.hookshot then
  216.             update_hookshot()  
  217.     elseif
  218.         mode == modes.victory then
  219.             update_victory()
  220.     elseif
  221.         mode == modes.wait then
  222.             update_wait()
  223.     else
  224.         assert(false, "no mode!")
  225.     end
  226. end
  227.  
  228. function update_gameplay()
  229.     if btnp(❎) and lvl>=4 then
  230.         mode = modes.inventory
  231.         return
  232.     end
  233.     if btnp(🅾️) then
  234.         use()
  235.         return
  236.     end
  237.    
  238.     stx,sty = p.x,p.y
  239.     start_tile = tile_at(stx,sty)
  240.    
  241.     if btn(⬆️) then
  242.         p.y-=1
  243.         p.n=normals.up
  244.     end
  245.     if btn(⬇️) then
  246.         p.y+=1
  247.         p.n=normals.down
  248.     end
  249.     if btn(⬅️) then
  250.         p.x-=1
  251.         p.n=normals.left
  252.     end
  253.     if btn(➡️) then
  254.         p.x+=1
  255.         p.n=normals.right
  256.     end
  257.    
  258.     tile_here = tile_at(p.x,p.y)
  259.     if is_gate(tile_here) then
  260.         open_gate_at(p.x,p.y)
  261.     end
  262.     if tile_here==tiles.cold_hearth then
  263.         light_hearth_at(p.x,p.y)
  264.         return
  265.     end
  266.     if is_solid(tile_here) then
  267.         p.x,p.y = stx,sty
  268.     elseif is_pit(tile_here) and
  269.                                 p.h==0 then
  270.         p.x,p.y = stx,sty
  271.     end
  272.    
  273.     map_x, map_y = world_2_map(p.x,p.y)
  274.     if map_x ~= last_map_x or
  275.                 map_y ~= last_map_y then
  276.                 pickup_enabled = true
  277.     end
  278.    
  279.     if jumping then
  280.         p.h += jump_speed
  281.         if p.h >= jump_height then
  282.             jumping = false
  283.         end
  284.     elseif p.h > 0 then
  285.         p.h -= jump_speed
  286.         if p.h <= 0 then --jic...
  287.             p.h = 0
  288.             tile_here = tile_at(p.x,p.y)
  289.             if is_pit(tile_here) then
  290.                 p.x,p.y = safe_x, safe_y
  291.             end
  292.         end
  293.     end
  294.    
  295.     last_map_x,last_map_y =
  296.         map_x, map_y
  297.    
  298.     pickup()
  299.    
  300.     if ice_proj then
  301.         ice_proj:update()
  302.     end
  303. end
  304.  
  305. function update_inventory()
  306.     if btnp(➡️) then sel += 1 end
  307.     if btnp(⬅️) then sel -= 1 end
  308.     if sel==3 then sel=1 end
  309.     if sel==0 then sel=2 end
  310.     if btnp(⬇️) then drop() end
  311.     if btnp(❎) or btnp(🅾️) then
  312.         mode = modes.gameplay
  313.     end
  314. end
  315.  
  316. function update_hookshot()
  317.     old_x, old_y = hs_pos.x,
  318.                                                              hs_pos.y
  319.     if not hs_retracting then
  320.         hs_pos.x += p.n.x * 3
  321.         hs_pos.y += p.n.y * 3
  322.         tile_here = tile_at(
  323.             hs_pos.x,
  324.             hs_pos.y   
  325.         )
  326.         if is_solid(tile_here) then
  327.             hs_pos.x,
  328.             hs_pos.y = old_x, old_y
  329.             hs_retracting = true
  330.             if tile_here == tiles.tree then
  331.                 sfx(7)
  332.                 hooked = true
  333.             end
  334.         end
  335.         if abs(hs_pos.x - p.x) +
  336.                     abs(hs_pos.y - p.y) >=
  337.                                     hs_range then
  338.             hs_retracting = true                           
  339.         end
  340.     else
  341.         if hooked then
  342.             p.x += p.n.x * 3
  343.             p.y += p.n.y * 3
  344.             pickup()
  345.         else
  346.             hs_pos.x -= p.n.x * 3
  347.             hs_pos.y -= p.n.y * 3
  348.         end
  349.     end
  350.    
  351.     if hs_pos.x == p.x and
  352.                 hs_pos.y == p.y and
  353.                 hs_retracting == true
  354.     then
  355.         tile_here = tile_at(p.x,p.y)
  356.         if is_solid(tile_here) or
  357.                     is_pit(tile_here)   then
  358.             p.x,p.y=safe_x,safe_y
  359.         end
  360.         mode=modes.gameplay
  361.     end
  362. end
  363.  
  364. function update_victory()
  365.     if lvl == 12 then return end
  366.     if btnp(❎) or btnp(🅾️) then
  367.         sfx(0)
  368.         ice_proj = nil
  369.         load_level(lvl+1)
  370.         mode = modes.wait
  371.     end
  372. end
  373.  
  374. function update_wait()
  375.     if btnp(❎) or btnp(🅾️) then
  376.         mode = modes.gameplay
  377.     end
  378. end
  379.  
  380. function inv2str()
  381.     return tostr(inv[1]).." , " ..tostr(inv[2])
  382. end
  383.  
  384. function load_level(level)
  385.     lvl= level
  386.     inv= {0,0}
  387.     sp = spawns[lvl]
  388.     p=entity("player", 4+sp.x*8, 4+sp.y*8, 1, normals.down)
  389.     reload(0x2000, 0x2000, 0x1000)
  390. end
  391.  
  392. function reload_level()
  393.     load_level(lvl)
  394. end
  395. -->8
  396. --draw
  397.  
  398. function _draw()
  399.     cls(3)
  400.     camera_to_player_screen()
  401.     map()
  402.     camera()
  403.     draw_hints()
  404.     camera_to_player_screen()
  405.     draw_player()
  406.  
  407.     if ice_proj then
  408.         draw_entity(ice_proj)
  409.     end
  410.     fx,fy= flr(p.x/8)+p.n.x, flr(p.y/8)+p.n.y
  411. --  hilight_tile(flr(p.x/8),flr(p.y/8),10)
  412. --  hilight_tile(fx,fy,10)
  413.    
  414.     if mode == modes.inventory then
  415.         draw_inventory()
  416.     elseif mode == modes.hookshot then
  417.         draw_hookshot(p.x,p.y,hs_pos.x, hs_pos.y)
  418.     elseif mode == modes.victory then
  419.         draw_victory()
  420.     elseif mode == modes.wait then
  421.         draw_wait()
  422.     end
  423.    
  424.     camera()
  425. end
  426.  
  427. function my_rect(x,y,w,h,col)
  428.     rectfill(x,y,x+w,y+h,col)
  429. end
  430.  
  431. function draw_inventory()
  432.     camera()
  433.     color(2)
  434.     rectfill(0,0,128, 128 * 1/8, 0)
  435.     print(sel_name(), 50 ,0, 6)
  436.     print("⬅️➡️-equip ⬇️-drop", 50, 8,6)
  437.    
  438.     for k,v in pairs(inv) do
  439.         spr(v,k*11,2)
  440.     end
  441.    
  442.     i=sel-1
  443.     rect(9+i*11,0,(9+i*11)+11,11,10+i)
  444.    
  445.     color()
  446.     cursor(0)
  447. end
  448.  
  449. function draw_hookshot(sx,sy,ex,ey)
  450.     camera_to_player_screen()
  451.     for i=1,5 do
  452.         x = lerp(sx,ex,i/5)
  453.         y = lerp(sy,ey,i/5)
  454.         spr(67,x-4,y-4)
  455.     end
  456. end
  457.  
  458. function draw_victory()
  459.     if lvl ~= 12 then
  460.         cls(1)
  461.         camera()
  462.         spr(77,32,62)
  463.         print("hearth restored.",41,64,7)
  464.     else
  465.         cls(1)
  466.         camera(0,48*8)
  467.         map()
  468.         camera()
  469.         print("all hearths restored.\nthanks for playing!",20,68,7)
  470.     end
  471. end
  472.  
  473. function draw_wait()
  474.     cls(1)
  475.     camera()
  476.     spr(93,32,62)
  477.     print(descriptions[lvl],41,64,7)
  478. end
  479.  
  480. function draw_entity(e)
  481.     spr(e.sprite, e.x-4, e.y-4)
  482. end
  483.  
  484. function draw_player()
  485.     if p.h ~= 0 then
  486.         circfill(p.x, p.y+3,2,1)
  487.     end
  488.     pspr = get_player_sprite()
  489.     spr(pspr, p.x-4, p.y-4-p.h)
  490. end
  491.  
  492. function hilight_tile(tx,ty,col)
  493.     s,e = tx*8, ty*8
  494.     rect(s,e,s+8,e+8,col)
  495. end
  496.  
  497.  
  498. function draw_hints()
  499.     if lvl >= 6 then return end
  500.     hint = hints[lvl]
  501.     if hint == "" then return end
  502.     print(hint[1], hint[2],
  503.         hint[3],hint[4])
  504.     cursor()
  505. end
  506.  
  507. function get_player_sprite()
  508.     if
  509.         p.n == normals.up then
  510.         return 1
  511.     elseif
  512.         p.n == normals.down then
  513.         return 1+16
  514.     elseif
  515.         p.n == normals.left then
  516.         return 1+32
  517.     elseif
  518.         p.n == normals.right then
  519.         return 1+48
  520.     end
  521. end
  522.  
  523. function sel_name()
  524.     result = item_names[inv[sel]]
  525.     if result == nil then
  526.         result = "none"
  527.     end
  528.     return result
  529. end
  530. -->8
  531. --helpers
  532.  
  533. --function current_map_coords()
  534. --  return flr(p.x/8),flr(p.y/8)
  535. --end
  536. --
  537. --function facing_map_coords()
  538. --  return flr(p.x/8)+p.n.x, flr(p.y/8)+p.n.y
  539. --end
  540.  
  541. function facing_pos()
  542.     return p.x+p.n.x*8,p.y+p.n.y*8
  543. end
  544.  
  545. function tile_at(x,y)
  546.     return mget(x/8, y/8)
  547. end
  548.  
  549. function set_tile_at(x,y,t)
  550.     mset(x/8, y/8, t)
  551. end
  552.  
  553. function world_2_map(x,y)
  554.     return flr(x/8), flr(y/8)
  555. end
  556.  
  557. function is_pickupable(t)
  558.     return fget(t,flags.can_be_picked_up)
  559. end
  560.  
  561. function is_solid(t)
  562.     return fget(t,flags.is_solid)
  563. end
  564.  
  565. function is_pit(t)
  566.     return fget(t,flags.is_pit)
  567. end
  568.  
  569. function is_gate(t)
  570.     return
  571.         t==tiles.gate_y or
  572.         t==tiles.gate_r or
  573.         t==tiles.gate_b
  574. end
  575.  
  576. function lerp(a,b,t)
  577.     return a * (1-t) + b * t
  578. end
  579.  
  580. function camera_to_player_screen()
  581.     camera(flr(p.x/128)*128, flr(p.y/128)*128)
  582. end
  583. -->8
  584. --actions
  585.  
  586. function drop()
  587.     tile_here = tile_at(p.x,p.y)
  588.     fx,fy = facing_pos()
  589.     tile_facing = tile_at(fx,fy)
  590.     if tile_here == 0 or
  591.                 tile_here == tiles.filled_hole then
  592.         set_tile_at(p.x,p.y, inv[sel])
  593.         inv[sel]=0
  594.         pickup_enabled = false
  595.     elseif tile_facing == 0 or
  596.                 tile_here == tiles.filled_hole then
  597.         set_tile_at(fx,fy, inv[sel])
  598.         inv[sel]=0
  599.     end
  600. end
  601.  
  602. function pickup()
  603.     if not pickup_enabled then return end
  604.     tile_here = tile_at(p.x,p.y)
  605.     if is_pickupable(tile_here) then
  606.         for k,v in pairs(inv) do
  607.             if v == 0 then
  608.                 inv[k] = tile_here
  609.                 set_tile_at(p.x,p.y,0)
  610.                 sfx(1)
  611.                 break
  612.             end
  613.         end
  614.     end
  615. end
  616.  
  617. function use()
  618.     item = inv[sel]
  619.     if item ==
  620.         items.shovel then
  621.             dig()
  622.     elseif item ==
  623.         items.hookshot then
  624.             fire_hookshot()    
  625.     elseif item ==
  626.         items.horseshoe then
  627.             jump()
  628.     elseif item ==
  629.         items.icerod then
  630.             cast_ice()
  631.     end
  632. end
  633.  
  634. function dig()
  635.     tile_here = tile_at(p.x,p.y)
  636.     if tile_here == tiles.ice then
  637.         return
  638.     end
  639.     fx,fy = facing_pos()
  640.     tile = tile_at(fx,fy)
  641.     if tile == tiles.none or
  642.                 tile == tiles.filled_hole then
  643.         item = get_secret(fx,fy)
  644.         if item ~= nil then
  645.             spawn_item(fx,fy,p.n.x,p.n.y,item)
  646.         end
  647.         set_tile_at(fx,fy,tiles.hole)
  648.         sfx(2)
  649.     elseif tile == tiles.hole then
  650.         set_tile_at(fx,fy,tiles.filled_hole)
  651.         sfx(3)
  652.     end
  653. end
  654.  
  655. function fire_hookshot()
  656.     sfx(6)
  657.     safe_x, safe_y = p.x, p.y
  658.     hs_pos = {x=p.x, y=p.y}
  659.     hs_retracting = false
  660.     hooked = false
  661.     mode = modes.hookshot
  662. end
  663.  
  664. function jump()
  665.     if p.h ~= 0 then return end
  666.     if p.n.y == -1 then
  667.         jump_height = 9
  668.         jump_speed = 1.5
  669.     else
  670.         jump_height = 6
  671.         jump_speed = 1
  672.     end
  673.     safe_x, safe_y = p.x,p.y
  674.     jumping = true
  675.     sfx(5)
  676. end
  677.  
  678. function cast_ice()
  679.     p_tile = tile_at(p.x,p.y)
  680.     if p_tile == tiles.ice then
  681.         return
  682.     end
  683.     for x=0,128 do
  684.         for y=0,64 do
  685.             if mget(x,y) == tiles.ice then
  686.                 mset(x,y,tiles.water)
  687.             end
  688.         end
  689.     end
  690.     sfx(8)
  691.     ice_proj = entity(
  692.         "ice_proj",
  693.         p.x,
  694.         p.y,
  695.                 3,
  696.         p.n,
  697.         ice_proj_update
  698.     )
  699. end
  700.  
  701. function ice_proj_update(s)
  702.     s.age+=1/30
  703.     s.x+=s.n.x
  704.     s.y+=s.n.y
  705.    
  706.     tile_here = tile_at(s.x,s.y)
  707.     if tile_here == tiles.water then
  708. --      sfx(9)
  709.         set_tile_at(s.x,s.y,tiles.ice)
  710.     end
  711.    
  712.     if s.age >= 4 then
  713.         ice_proj = nil
  714.     end
  715.    
  716.     if s.sprite==3 then
  717.         s.sprite=19
  718.     else s.sprite=3
  719.     end
  720. end
  721.  
  722. function open_gate_at(x,y)
  723.     gate = tile_at(x,y)
  724.     for k,v in pairs(inv) do
  725.         --abuse sprite offset
  726.         if v==gate-16 then
  727.             set_tile_at(x,y,0)
  728.             inv[k]=items.none
  729.             sfx(10)
  730.         end
  731.     end
  732. end
  733.  
  734. function light_hearth_at(x,y)
  735.     for k,v in pairs(inv) do
  736.         if v==items.torch then
  737.             set_tile_at(x,y,tiles.lit_hearth)
  738.             inv[k]=items.none
  739.             sfx(4)
  740.             mode = modes.victory
  741. --          load_level(lvl+1)
  742.  
Advertisement
Add Comment
Please, Sign In to add comment