0,]']>S}Wup8d%qy)6o;]AsVl3 6789:;<=>%%FGHIJKLMN&'()*+,-FGHIJKLMN#%%VWXYZ[\]^)*+,6789:;<=VWXYZ[\^#%fghijklmn9:;&'()*+,-.#%GHIJKLMN()*+-&'()*+,6789:;<=>#$%WXYZ[\]^89:;<=6789:;@APP```pppppppppppp@w&B`````````````````````````````` '  C        // / / / ////////////////c  P !$*-------------------------.! tttttt ttt t tttt t ttt tt t Ttttt ttt Ttttt ttttt t t t tt ttt t t t t tt ttt t t t t tt ttt t t t t tt tt t t tt t t t uUUuuUUkuuuuuu uuUUuUUUUU UuUU UuUUuuUUuuuuuu uuUUuUUUUU UuUU UuumUmUkuoumUmUdubBBbbBBbBBbbBBbbbbbb bbbbbbb bbBBbbBBbBBbbBBbbbbbb bbbbbbbP0p@`@`qqN?  ~                         `        >L-- title: The Moon Pool -- author: Daniel Griffin -- desc: Moonlander World Demake -- script: lua -- game state control STATE_INIT = 5 STATE_START = 8 STATE_INTRO = 9 STATE_CONTINUE = 10 STATE_PLAY = 12 STATE_MAP = 13 STATE_SHIP_KILLED = 14 STATE_SHIP_KILL_DELAY = 16 STATE_WAIT_RESPAWN = 18 STATE_NEW_LEVEL_DELAY = 20 STATE_END = 22 gameState = STATE_INIT t=0 x=0 y=0 up = 4.71238897 sx=0 sy=0 cx=0 cy=0 mj = 0 -- mapscreen y counter fuel =1 doubleFuel = 0 grav = 1 landedPads = {} totalLanded=0 timeSinceMapPressed =0--deBounce timer playerShip = { position = { x = sx, y = sy }, velocity = { speed = grav, direction = up }, acceleration = 0.01, deceleration = 0.002, rotation =up, rotationSpeed = 0.07, radius = 10, points = { {x=5,y=0, colour = 12}, {x=3,y=2, colour = 12}, {x=0,y=2, colour = 12}, {x=-1,y=3, colour = 12}, {x=-4,y=3, colour = 12}, {x=-2,y=0, colour = 12}, {x=-2,y=0, colour = 12}, {x=-4,y=-3, colour = 12}, {x=-1,y=-3, colour = 12}, {x=0,y=-2, colour = 12}, {x=3,y=-2, colour = 12}, {x=5,y=0, colour = 12} } } particles = {} smokeColours = {12,13,14,08} playerThrustOffset = { x=-5, y=0 } function set(ls) local s={} for _,l in ipairs(ls) do s[l]=true end function s.contains(s,e) return s[e]==true end function s:add(e) s[e]=true end function s:remove(e) s[e]=nil end return s end terrainTilesOuter =set({1,2,17,18,3,4,5,19,21,35,36,37,50,51,66,67,96,97,129,130,131,132,133,160,161,227,228,229,230,231,232,225,240,152,155,168,171,184,187,176}) landingPadTiles = set({212,213,214,215}) gateTiles = set({140,156,157,172,173,188}) upgradeTiles = set({82,83,98,99}) trussTiles = set({48,49,64,65,80,81,153,154,169,170,185,186}) gatesRemoved=false --Gates by landing count requirement: --[req]"blocX,blocY,blockX,blockY,etc" gateBlocks = {} gateBlocks[2]="03,33,04,33,05,33" gateBlocks[5]="138,13,138,14,138,15,138,16,138,17" gateBlocks[10]="125,63,125,64,125,65,125,66,125,67" gateBlocks[20]="78,39,79,39,80,39,104,62,104,63,104,64,104,65,104,66,104,67,88,62,88,63,134,42,134,43,134,44,134,45" gateBlocks[30]="166,106,166,107,166,108,166,109,166,110,205,63,206,63,207,63,205,77,206,77,207,77" --Landing Pad Text Dictionary --["RoomX.0RoomY.0"] = "Flavour text" lpDict = {} lpDict["0.00.0"] = "I - The Thing on the Moon Path" lpDict["0.01.0"] = "II - Dead! All Dead!" lpDict["1.03.0"] = "III - The Moon Rock" lpDict["1.01.0"] = "IV - The First Vanishings" lpDict["1.00.0"] = "V - xx" lpDict["2.01.0"] = "VI - The Shining Devil Took Them!" lpDict["1.02.0"] = "VII - A Lost Page of Earth" lpDict["2.03.0"] = "VIII - The Moon Pool" lpDict["2.00.0"] = "IX - The Flame-Tipped Shadows" lpDict["5.00.0"] = "X - Yolara, Priestess of the Shining One" lpDict["5.01.0"] = "XI - The Justice of Lora" lpDict["5.02.0"] = "XII - The Angry, Whispering Globe" lpDict["6.01.0"] = "XIII - The Amphitheatre of Jet" lpDict["6.00.0"] = "XIV - The Madness of Olaf" lpDict["6.02.0"] = "XV - The Casting of the Shadow" lpDict["6.03.0"] = "XVI - Dragon Worm and Moss Death" lpDict["5.03.0"] = "XVII - In the Lair of the Dweller" lpDict["7.03.0"] = "XVIII - The Three Silent Ones" lpDict["4.01.0"] = "XIX - The Wooing of Lakla" lpDict["7.00.0"] = "XX - The Coming of Yolara" lpDict["4.04.0"] = "XXI - The Crimson Sea" lpDict["2.04.0"] = "XXII - The Shaping of the Shining One" lpDict["4.05.0"] = "XXIII - The Building of the Moon Pool" lpDict["5.04.0"] = "XXIV - Your Love; Your Lives; Your Souls!" lpDict["5.06.0"] = "XXV - The Meeting of Titans" lpDict["4.02.0"] = "XXVI - The Coming of the Shining One" lpDict["4.03.0"] = "XXVII - A true pilot! A true hero!" lpDict["3.02.0"] = "XXVIII - The Central Column" lpDict["3.01.0"] = "XXIX - Light at the end of the tunnel" lpDict["2.02.0"] = "XXX - Bypass Alpha" lpDict["0.04.0"] = "XXXI - The Lander's Grief" lpDict["1.05.0"] = "XXXII - The Fall of Enemies" lpDict["2.07.0"] = "XXXIII - Omicron Collider" lpDict["0.05.0"] = "XXXIV - Insert Consciousness here" lpDict["3.06.0"] = "XXXV - Eternal Dead" lpDict["7.07.0"] = "The End of the Journey" --Landing Pad ID Dictionary --["RoomX.0RoomY.0"] = id lpIdDict = {} lpIdDict["0.00.0"] =1 lpIdDict["0.01.0"] =2 lpIdDict["1.03.0"] =3 lpIdDict["1.01.0"] =4 lpIdDict["1.00.0"] =5 lpIdDict["2.01.0"] =6 lpIdDict["1.02.0"] =7 lpIdDict["2.03.0"] =8 lpIdDict["2.00.0"] =9 lpIdDict["5.00.0"] =10 lpIdDict["5.01.0"] =11 lpIdDict["5.02.0"] =12 lpIdDict["6.01.0"] =13 lpIdDict["6.00.0"] =14 lpIdDict["6.02.0"] =15 lpIdDict["6.03.0"] =16 lpIdDict["5.03.0"] =17 lpIdDict["7.03.0"] =18 lpIdDict["4.01.0"] =19 lpIdDict["7.00.0"] =20 lpIdDict["4.04.0"] =21 lpIdDict["2.04.0"] =22 lpIdDict["4.05.0"] =23 lpIdDict["5.04.0"] =24 lpIdDict["5.06.0"] =25 lpIdDict["4.02.0"] =26 lpIdDict["4.03.0"] =27 lpIdDict["3.02.0"] =28 lpIdDict["3.01.0"] =29 lpIdDict["2.02.0"] =30 lpIdDict["0.04.0"] =31 lpIdDict["1.05.0"] =32 lpIdDict["2.07.0"] =33 lpIdDict["0.05.0"] =34 lpIdDict["3.06.0"] =35 lpIdDict["a.00.0"] = 99 lpIdDict["a.00.0"] = 99 lpIdDict["a.00.0"] = 98 lpIdDict["a.00.0"] = 99 lpIdDict["7.07.0"] = 36 mDTime =3--how long to display message mTimer = 3--how long has current message been displayed lastM = ""--last message displayed gSavedTime = 0--time loaded from pmem gStartTime = 0--time when gamestate=play musicPlaying=false musicOn=false initDone = false function sign(n) return n>0 and 1 or n<0 and -1 or 0 end function lerp(a,b,t) return (1-t)*a + t*b end function init() t=0 --frame count or time cam={x=sx,y=sy} l="\n" s=" " end init() function TIC() -- if btn(7) then -- if musicPlaying then -- music() -- musicPlaying = false -- else -- music(1,-1,-1,true,false,20,-1) -- musicPlaying = true -- end -- end if btn(7) then if gameState ==STATE_PLAY then if (time()-timeSinceMapPressed)>500then timeSinceMapPressed = time() gameState = STATE_MAP mj=0 end else if (time()-timeSinceMapPressed)>500then timeSinceMapPressed = time() gameState = STATE_PLAY end end end if gameState == STATE_INIT then -- initGame() gameState = STATE_START elseif gameState == STATE_START then doStartScreen() elseif gameState == STATE_INTRO then doIntroScreen() elseif gameState == STATE_CONTINUE then doContinueScreen() elseif gameState == STATE_PLAY then doPlayGame() elseif gameState == STATE_MAP then doMapScreen() end end function doStartScreen() cls() map(0,-17,31,18,0,0) print ("THE MOON POOL", 45,40,13,false,2) print ("press X to continue", 67,100,12) print ("press Z to restart", 68,110,12) if not musicplaying then music(2,-1,-1,true,false,100,-1) musicplaying = true end if btnp(6) then gameState = STATE_INTRO end if btnp(5) then if pmem(2)~=0 then gameState = STATE_CONTINUE else gameState = STATE_INTRO end end end function doIntroScreen() cls() map(0,-17,31,18,0,0) print ("About her hovered something unearthly.", 2,40,13,false,1) print("A sweet echo of the Dweller was Yolara,", 2,50,13,false,1) print("the Dweller's priestess- and as gloriously,", 2,60,13,false,1) print("terrifyingly evil!", 25,70,13,false,1) print ("press X to start", 70,90,12) if btnp(5) then gStartTime = time() playerShip.position.x = sx playerShip.position.y = sy gameState = STATE_PLAY for i =50,150 do pmem(i,0) end end end function doContinueScreen() cls() map(0,-17,31,18,0,0) print("I was sensible", 2,40,13,false,1) print(" of an acceleration of every pulse", 2,50,13,false,1) print("; a wild stimulation of every nerve.", 2,60,13,false,1) print("I felt myself being lifted above the ", 2,70,13,false,1) print("world—close to the threshold of the", 2,80,13,false,1) print(" high gods—soon their essence and ", 2,90,13,false,1) print("their power would stream out into me!", 25,100,13,false,1) print("press X to start", 70,110,12) if btnp(5) then gStartTime = time() gSavedTime = pmem(2) sx=pmem(0) sy=pmem(1) totalLanded = pmem(3) doubleFuel = pmem(4) playerShip.position.x = sx playerShip.position.y = sy gameState = STATE_PLAY end end function doPlayGame() cls() cam.x = math.min(120,lerp (cam.x,120-playerShip.position.x,0.05)) cam.y = math.min(64,lerp (cam.y,64-playerShip.position.y,0.05)) dx,dy = cam.x-120,cam.y-64 local ccx=cam.x/8+(cam.x%8==0 and 1 or 0) local ccy=cam.y/8+(cam.y%8==0 and 1 or 0) checkPlayerButtons() moveParticles() movePlayerShip() map(0,-17,31,18,0,0) drawParticles() map(15-ccx,8-ccy,31,18,(cam.x%8)-8,(cam.y%8)-8,0) drawVectorShape(playerShip) ShipCollision(playerShip) print('Time:'..(time()+gSavedTime-gStartTime)//1000,190,130,12) drawFuel() local croom = getCurrentRoom(playerShip.position.x,playerShip.position.y) local str = lpDict[tostring(croom.x)..tostring(croom.y)] drawMessage(str) posString ="X:"..croom.x.." Y:"..croom.y t=t+1 if gatesRemoved == false then removeDoneGates() gatesRemoved = true end end function doMapScreen() if mj<136 then for i=0,239 do local c=0 local roomX =0 local roomY =0 if terrainTilesOuter:contains(mget(i,mj)) then c=9 elseif mget(i,mj)==16 then c=8 elseif mget(i,mj)==33 then c=2 elseif upgradeTiles:contains(mget(i,mj)) then c=5 elseif trussTiles:contains(mget(i,mj)) then c=15 elseif gateTiles:contains(mget(i,mj)) then c=3 elseif landingPadTiles:contains(mget(i,mj)) then c=10 roomX = i//30 roomY = mj//17 local padId = lpIdDict[tostring(roomX)..".0"..tostring(roomY)..".0"] if pmem(50+padId)==1 then c=06 end--if end--if pix(i,mj,c) end--for mj=mj+1 spr(32,(playerShip.position.x)//8+12,(playerShip.position.y)//8+1,0) end--if end function ShipCollision(object) components = getVectorComponents(object.velocity) local crashed =false local landed = false local top ={x=object.position.x+cam.x,y=object.position.y+cam.y-2} local bottom ={x=object.position.x+cam.x,y=object.position.y+cam.y+5} local right ={x=object.position.x+cam.x+3,y=object.position.y+cam.y} local left ={x=object.position.x+cam.x-3,y=object.position.y+cam.y} if pix(top.x,top.y)==15 then--navy, hit the wall crashed = true end if pix(bottom.x,bottom.y)==15 then--navy, hit the wall crashed = true end if pix(left.x,left.y)==15 then--navy, hit the wall crashed = true end if pix(right.x,right.y)==15 then--navy, hit the wall crashed = true end if pix(bottom.x,bottom.y)==10 then--landed!! if fuel<.99 then fuel = fuel+.001 end landed=true -- if playerShip.velocity.speed <3 then playerShip.velocity.direction =up playerShip.rotation = up playerShip.velocity.speed =grav+0.002 sx=playerShip.position.x sy = playerShip.position.y pmem(0,math.floor(sx)) pmem(1,math.floor(sy)) pmem(2,math.floor(time()+gSavedTime-gStartTime)) local croom = getCurrentRoom(playerShip.position.x,playerShip.position.y) local str = lpDict[tostring(croom.x)..tostring(croom.y)] local lpID = lpIdDict[tostring(croom.x)..tostring(croom.y)] if landedPads[tostring(croom.x)..tostring(croom.y)]==nil then -- table.insert(landedPads,tostring(croom.x)..tostring(croom.y)) landedPads[tostring(croom.x)..tostring(croom.y)]=1 if pmem(50+lpID)==0 then totalLanded=totalLanded+1 sfx(17,50,60,0,15,5) pmem(3,totalLanded) pmem(50+lpID,1) end end removeGates(totalLanded) mTimer = 0 drawMessage(str) -- else -- crashed = true -- end end if crashed == true then playerShip.position.x = sx playerShip.position.y = sy playerShip.velocity.direction =up playerShip.rotation =up playerShip.velocity.speed = grav fuel = 1 end if crashed ==false then playerShip.position = gravObject(playerShip) end if pix(object.position.x+cam.x,object.position.y+cam.y) ==02 then--red, fuel can sfx(18,50,60,0,15,6) mset((object.position.x)//8+15,(object.position.y)//8+8,0) if doubleFuel ==1then fuel =fuel+ .4 if fuel > 1 then fuel = 1 end else fuel = 1 end end if pix(object.position.x+cam.x,object.position.y+cam.y) ==06 then--green double fuel sfx(18,50,60,0,15,6) doubleFuel = 1 pmem(4,1) mset((object.position.x)//8+15,(object.position.y)//8+8,0) fuel = 1 end end function checkPlayerButtons() -- thrust if btn(5) then -- up key playerShipThrust() sfx(16,90,-1,0,5,1) else sfx(16,90,-1,0,0,1) end -- if if btn(2) then -- left playerShip.rotation = playerShip.rotation - playerShip.rotationSpeed end if btn(3) then -- right playerShip.rotation = playerShip.rotation + playerShip.rotationSpeed end playerShip.rotation = keepAngleInRange(playerShip.rotation) end -- checkPlayerButtons function keepAngleInRange(angle) if angle < 0 then while angle < 0 do angle = angle + (2 * math.pi) end end if angle > (2 * math.pi) then while angle > (2 * math.pi) do angle = angle - (2 * math.pi) end end return angle end -- keepAngleInRange function playerShipThrust() if fuel<=0 then return end if doubleFuel==1 then fuel = fuel -.001 else fuel = fuel -.002 end local acceleration = { speed = playerShip.acceleration, direction = playerShip.rotation } playerShip.velocity = addVectors(playerShip.velocity, acceleration) --sfx(3,10,10,3,-8,1) local particleVelocity = {} local direction = 0 local relSpawnPosition = rotatePoint(playerThrustOffset, playerShip.rotation) local spawnPosition = { x = relSpawnPosition.x + playerShip.position.x+cam.x, y = relSpawnPosition.y + playerShip.position.y+cam.y } for particle = 1, 5 do direction = playerShip.rotation + math.pi + (math.random() * math.pi / 6) - (math.pi / 12) direction = keepAngleInRange(direction) particleVelocity = { speed = (math.random()+1)/2, direction = direction } spawnParticle(spawnPosition, particleVelocity,55, smokeColours, 1, 0.04, 1) end -- for end -- playerShipThrust function addVectors(vector1, vector2) v1Comp = getVectorComponents(vector1) v2Comp = getVectorComponents(vector2) resultantX = v1Comp.xComp + v2Comp.xComp resultantY = v1Comp.yComp + v2Comp.yComp local resVector = compToVector(resultantX, resultantY) return resVector end -- addVectors function reverseVector(vector1) v1Comp = getVectorComponents(vector1) resultantX = -v1Comp.xComp resultantY = -v1Comp.yComp local resVector = compToVector(resultantX, resultantY) return resVector end -- addVectors function drawVectorShape(shape) -- spr(p.spr,p.x-cam.x,p.y-cam.y) local firstPoint = true local lastPoint = 0 local rotatedPoint = 0 for index, point in ipairs(shape.points) do rotatedPoint = rotatePoint(point,shape.rotation) if firstPoint then lastPoint = rotatedPoint firstPoint = false else line(lastPoint.x + shape.position.x+cam.x, lastPoint.y + shape.position.y+cam.y, rotatedPoint.x + shape.position.x+cam.x, rotatedPoint.y + shape.position.y+cam.y, point.colour) lastPoint = rotatedPoint end end -- for end -- drawVectorShape function rotatePoint(point, rotation) local rotatedX = (point.x * math.cos(rotation)) - (point.y * math.sin(rotation)) local rotatedY = (point.y * math.cos(rotation)) + (point.x * math.sin(rotation)) return {x=rotatedX, y=rotatedY} end -- rotatePoint function movePlayerShip() playerShip.velocity.speed = playerShip.velocity.speed - playerShip.deceleration if playerShip.velocity.speed < 0 then playerShip.velocity.speed = 0 end playerShip.position = movePointByVelocity(playerShip) end -- movePlayerShip function gravObject(object) local newPosition = { x = object.position.x , y = object.position.y + grav} return newPosition end -- gravPlayerShip function movePointByVelocity(object) components = getVectorComponents(object.velocity) local newPosition = { x = object.position.x + components.xComp, y = object.position.y + components.yComp} return newPosition end -- movePointByVelocity function getVectorComponents(vector) local xComp = vector.speed * math.cos(vector.direction) local yComp = vector.speed * math.sin(vector.direction) local components = { xComp = xComp, yComp = yComp } return components end -- getVectorComponents function compToVector(x, y) local magnitude = math.sqrt( (x * x) + (y * y)) local direction = math.atan2(y, x) direction = keepAngleInRange(direction) local vector = { speed = magnitude, direction = direction} return vector end -- compToVector function spawnParticle(position, velocity, maxLifetime, colours, maxSize, deceleration, type) local particle = { position = { x = position.x, y = position.y }, velocity = { speed = velocity.speed, direction = velocity.direction }, lifeTimer = (maxLifetime / 2) + (math.random() * maxLifetime / 2), colours = colours, size = math.random(1, maxSize), deceleration = deceleration, type = type } table.insert(particles, particle) end -- spawnParticle function moveParticles() for index, particle in ipairs(particles) do particle.lifeTimer = particle.lifeTimer - 1 if particle.lifeTimer < 0 then table.remove(particles, index) else particle.position = movePointByVelocity(particle) end --if particle.velocity.speed = particle.velocity.speed - particle.deceleration if particle.velocity.speed < 0 then particle.velocity.speed = 0 end --gravObject(particle) end -- for end function drawParticles() local particleColour = 0 for index, particle in ipairs(particles) do particleColour = particle.colours[ math.random(1, #particle.colours) ] if particle.type == 2 then circ(particle.position.x, particle.position.y, particle.size, particleColour) elseif particle.type == 1 then pix(particle.position.x, particle.position.y, particleColour) else rect(particle.position.x, particle.position.y, particle.size, particle.size, particleColour) end -- if end -- for end function drawFuel() --center line line(1,120,1,120-(fuel*100),12) line(2,120,2,120-(fuel*100),12) --outline line(0,120,0,120-(100),14) line(3,120,3,120-(100),14) print("E",1,122,12) print("F",1,14,12) rect(0,3,10,9,12) rect(1,4,8,7,15) print(tostring(totalLanded),2,5,06) end function getCurrentRoom(xi,yi) local crx = ((xi+120)//240) local cry = ((yi+68)//136) local result= {x,y} result.x = crx result.y = cry return result end function removeDoneGates() for a = 0,totalLanded do removeGates(a) end end function removeGates(currentGate) local blockCounter = 0 local xVal = true local mx = 0 local my = 0 local xs = "" local ys = "" local wordTest = "" gs=gateBlocks[currentGate] if gs~=nil then for word in string.gmatch(gs, '[^,%s]+') do -- xVal=true if blockCounter == 2 then wordTest = word end --- print(word,5,10,12) -- for num in string.gmatch(word, ',') do if xVal == true then mx= tonumber(word) xVal = false elseif xVal == false then my= tonumber(word) mset(mx,my,0) blockCounter = blockCounter +1 xVal = true end end -- print(tostring(blockCounter),5,5,12) end --print(wordTest,5,5,12) --print(tostring(mx).." "..tostring(my),5,5,12) end function drawMessage(message) --if message ==nil then return end if message~=lastM then lastM=message mTimer=mDTime end if mTimer