0,β]>SuYW<,$p8d H8)6o;]AVl3DD"" ""  """ "  ""    " 3330000= """"   "" "" B $BB $$BBBB$B$$BBB<33000 334C0" "  ""  "" "" ""     "" "" """" """" "   " " "" "" " ">DD   """"   ""333CD4C4C4CD4333S36fc733CDDC4CC4CC4CC4MC4CC4Cc000 3f3sg000nn73f7300ew3Sfw3sgfweef73fv733033C400330333@CD003 @0 =3@3 00       VfUfwvggsg3s33333334343333434333VfUfwvggsg3s33333334343333434333VwUfwvggsg3s33333334343333434333Vfuwwvggsg3s33333334343333434333VfUfwvggsg3s33333334343333434333 "" " ""=CDDA3C00@DDA3C    " "   " " ̻ """"" "" """DUfPffPff`ff`fffw   " " "" " "  $$$$$  K#$KK$ K#K$$##" $# "#$$$#$$$$$K$$"$ $ "$$$$$$ "$$$$$$$$$$# $$$$$"$$$"$$$# +,S 9:;<  "#KKKK#""" >?""̻̻UfUf""""ʻʻZffZff""""ʻʻZffZff*""*""jffjff*""*""jffjff"D"Dfwfw""̻̻UfUf""""ʻʻZffZff""""ʻʻZffZff*""*""jffjff*""*""jffjff"D"Dfwfw""̻UfUf""""ʻZffZff""""ʻZffZff*""*""jffjff*""*""jffjff"D"Dfwfw""̻UfUf""""ʻZffZff""""ʻZffZff*""*""jffjff*""*""jffjff"D"Dfwfw""̻UfUf""""ʻZffZff""""ʻZffZff*""*""jffjff*""*""jffjff"D"Dfwfw̪ʬ̪̪ʬʬʬʬ̪̪ʬ̬̪̬̪̬̬̬̪̬̬̪̪̪̬ʪ̪̪ʬ̪̬̪ʬ̪̬ʬʬ̪ʬʬ̪ʬʬʬ̬ʬ̪ʬ̪̬̪ʬ̪̬ʬʬ̪ʬʬ̪̬̬ʬ̬̪̬̪̬̪̬̪̪̬̬̪̬̬̪̪ʬ̬̪̪ݪݪ33Ue 6 then spr(48,x,y,0, 1, 0, 0, 2, 2) elseif o.cut.re > 2 then spr(48,x,y+8,0, 1, 0, 0, 2, 1) elseif o.cut.re > 0 then spr(33,x,y+8,0, 1) end end }, chest={ name="chest", cost={0,0,0,0}, desc="there is a card inside", sx=1, sy=1, sprites={194,194,194,195,195}, isblock=false, collect = { verb = "open", re = 1, gain = {0,0,0,0,1}, time = 30, effect = function(o) destroyobject(o) end }, draw = function(o) x = o.x*8-sx y = o.y*8 if o.collect.re > 0 then spr(194,x,y,0) else spr(195,x,y,0) end end }, tree={ name="tree", cost={0,0,0,180}, desc="you can collect apples from it, or cut it for wood.", sx=2, sy=2, sprites={75,39,11,41,45}, isblock=false, spoutline=75, spoutlinered=107, cut = { verb = "cut", re = 0, gain = {0,5,0,0}, time = 250 }, collect = { verb = "pick", re = 0, gain = {0,0,2,0}, time = 10 }, create = function(o) o.ttg = 300 o.tta = 400 * appletimemulti o.state = 2 end, update = function(o) if o.ttg > 0 then o.ttg = o.ttg - 1 elseif o.state == 2 then o.state = 3 o.cut.re = 1 stopwait() end if o.state == 3 then if o.tta > 0 then o.tta = o.tta - 1 end if o.tta <= 0 then o.tta = 200 * appletimemulti if o.collect.re < 4 then stopwait() end o.collect.re = math.min(4,o.collect.re+1) end end -- die when it is cut down if o.state == 3 and o.cut.re == 0 then o.state = 4 end -- die when it touches water and is not already cut down if o.state < 4 then for xx = o.x, o.x+o.type.sx-1 do for yy = o.y, o.y+o.type.sy-1 do if iswater(xx,yy) then o.state = 5 o.collect.re = 0 o.cut.re = 0 end end end end end, canwait = function(o) return o.state < 4 and o.collect.re < 4 end, draw = function(o) x = o.x*8-sx y = o.y*8 sp = o.type.sprites[o.state] if o.ttg > 0 then sp = 39 end if o.state == 3 then n = 0 for xi = 0,1 do for yi = 0,1 do off = 0 n = n + 1 if (o.collect.re >= n) then off = 32 end spr(sp + xi + 16 * yi + off,x + xi*8,y+yi*8,0, 1) end end else spr(sp,x,y,0, 1, 0, 0, 2, 2) end end }, well={ name="well", cost={5,0,0,300}, desc="your plants get their fruit quicker", sx=1, sy=2, sprites={151,150,149,149,149}, isblock=false, spoutline=151, spoutlinered=152, create = function(o) appletimemulti = appletimemulti * 0.7 end, }, sheep={ name="sheep", cost={0,5,10,30}, desc="If gives you wool or meat.", sx=1, sy=1, sprites={192,176,177,177,180}, isblock=false, spoutline=192, spoutlinered=193, cut = { verb = "butcher", re = 0, gain = {0,0,25,0}, time = 200, effect = function(o) destroyobject(o) o.state = 5 o.butchered = true end }, collect = { verb = "shear", re = 0, gain = {0,0,5,0}, time = 150 }, create = function(o) o.ttg = 500 o.tta = 600 * wooltimemulti o.state = 2 end, update = function(o) if o.ttg > 0 then o.ttg = o.ttg - 1 elseif o.state == 2 then o.state = 3 o.cut.re = 1 stopwait() end if o.state == 3 then if o.tta > 0 then o.tta = o.tta - 1 end if o.tta <= 0 then o.tta = 600 * wooltimemulti if o.collect.re < 2 then stopwait() end o.collect.re = math.min(2,o.collect.re+1) end end if o.state < 4 then for xx = o.x, o.x+o.type.sx-1 do for yy = o.y, o.y+o.type.sy-1 do if iswater(xx,yy) then o.state = 5 o.collect.re = 0 o.cut.re = 0 end end end end end, canwait = function(o) return o.state < 4 and o.collect.re < 4 end, draw = function(o) x = o.x*8-sx y = o.y*8 sp = o.type.sprites[o.state] if o.state == 5 then if o.butchered then sp = 0 end end if o.state == 3 then if o.collect.re == 0 then sp = 177 elseif o.collect.re == 1 then sp = 178 elseif o.collect.re == 2 then sp = 179 end end spr(sp,x,y,0) end }, mine={ name="mine", cost={2,5,0,300}, desc="mine an unlimited supply of stones", sx=2, sy=2, sprites={155,155,155,155,155}, isblock=false, spoutline=181, spoutlinered=183, collect = { verb = "mine", re = 999, gain = {1,0,0,0}, time = 150 }, }, house={ name="house", cost={2,5,5,300}, desc="study at home to gain knowledge, aka cards", sx=2, sy=2, sprites={153,153,153,153,153}, isblock=false, spoutline=153, spoutlinered=153, collect = { verb = "study", re = 10, gain = {0,0,0,0,1}, time = 240 }, } } objects = {} cards = {} permanents = {} function canwait() for _,o in pairs(objects) do if o.type.canwait and o.type.canwait(o) then return true end end return false end function createobject(type,tx,ty) object = { type = type, x = tx, y = ty, state = 1, cut = { re = 0 }, collect = { re = 0 } } if type.cut then object.cut.re = type.cut.re end if type.collect then object.collect.re = type.collect.re end if type.create then type.create(object) end table.insert(objects, object) for xx = tx, tx+type.sx-1 do for yy = ty, ty+type.sy-1 do lmset(xx,yy, 4) end end return object end function destroyobject(o) o.state = 4 for xx = o.x, o.x+o.type.sx-1 do for yy = o.y, o.y+o.type.sy-1 do lmset(xx,yy, 0) end end end function drawobject(o) ty = o.type if ty.draw then ty.draw(o) else sp = ty.sprites[o.state] spr(sp,o.x*8-sx,o.y*8,0, 1, 0, 0, ty.sx, ty.sy) end end function dump(o) if type(o) == 'table' then local s = '{ ' for k,v in pairs(o) do if type(k) ~= 'number' then k = '"'..k..'"' end s = s .. '['..k..'] = ' .. dump(v) .. ',' end return s .. '} ' else return tostring(o) end end function loadlevel(i) definecards() levelwidth = levels[i].w levelheight = 17 levelx = levels[i].x levely = levels[i].y tm = levels[i].m re = table.shallow_copy(levels[i].re) t=0 --global time px=12 -- player x (y is not saved, but computed) tx=12 -- target x (to walk to) bx=0 -- build target x by=0 -- build target y tb=nil -- to build (nil or object) to=1 -- tool (1=walk, 2=build, 3=collect, 4=cut, 5=wait, 6=card) wo = false -- working, time passing, accept no input during this tl = 0 pf=0 -- player flip (walking direction) sx=0 cuttimemulti = 1 walktimemulti = 1 appletimemulti = 1 wooltimemulti = 1 objects = {} permanents = {} for x=0,levelwidth do for y=0,levelheight do type = nil if lmget(x,y) == 224 then type = objecttypes['rock'] end if lmget(x,y) == 75 then type = objecttypes['tree'] end if lmget(x,y) == 192 then type = objecttypes['sheep'] end if lmget(x,y) == 181 then type = objecttypes['mine'] end if lmget(x,y) == 153 then type = objecttypes['house'] end if lmget(x,y) == 194 then type = objecttypes['chest'] end if type then o = createobject(type,x,y) end end end end function OVR() x,y,l = mouse() if globalstate == "title" then map(120,34,30,levelheight,0,0,0) prints("Click to start the game", 12*8, 8*8, 12) print("A game by @LenaSchimmel", 2*8, 14*8, 12, false, 1, false) print("Made in 72 hours for Ludum Dare 50", 2*8, 15*8, 12, false, 1, true) if l then globalstate = "levelstart" end return end if globalstate == "gamewon" then map(120,34,30,levelheight,0,0,0) prints("Thank you for playing!", 12*8, 8*8, 12) print("You won all levels of Dyker", 2*8, 14*8, 12, false, 1, false) print("Come back later to see if there is a post-jam version.", 2*8, 15*8, 12, false, 1, true) return end if globalstate == "levelstart" or globalstate == "play" or globalstate == "levelend" or globalstate == "restart" then map(levelx,levely,levelwidth,levelheight,-sx,0,0) if not l then clicklock = false end my = y // 8 -- show resources te = string.format("%2d# %2d/ %4d$",re[1],re[2],re[3]) prints(te, 6, 8, 12) end ct = "" --center text -- draw cursor, handle potential actions local sp = 119 if globalstate == "play" then -- show actions prints("Action:", 16*6, 8, 12) for i=1,6 do spr(95 + i, 132 + 12*i, 8, 0) if to==i then spr(104, 132 + 12*i, 8, 0) end end prints(""..#handcards, 212, 8, 14) if x >= 228 and y < 8 then myspr(228, 29, 0) ct = "Restart level" if l then globalstate = "restart" end else myspr(227, 29, 0) end if to==6 then sp = 119 local ci, bu = paintcards(x/8, y/8) if bu then card = handcards[ci] mis = canpay(card.cost) if mis > 0 then sp = 164 ct = "Not enough " .. re_symbols[mis] .. " to play '" .. card.title .. "'" paintcards(0,0,true,2) else sp = 148 ct = "Play the card '" .. card.title .. "'" paintcards(0,0,true,5) if l and not clicklock then if not card.buildingtype then pay(card.cost) -- buildings are paid later end selectedcard = 0 trace("Remove card " .. ci) table.remove(handcards, ci) card.y = 14 if card.effect then card.effect() elseif card.gain then earn(card.gain) end if card.ispermanent then table.insert(permanents, card) end if card.buildingtype then buildingcard = card buildingtype = card.buildingtype clicklock = true to = 2 end end end elseif ci > 0 and selectedcard ~= ci then ct = "Look at card '" .. handcards[ci].title .. "'" elseif ci == 0 and selectedcard > 0 then ct = "Move card out of the way" end if l then selectedcard = ci clicklock = true end end if my > 2 then -- lower screen part if wo then sp = 102 else if to ~= 6 then sp = 159 + to -- disabled end if to == 1 then -- walk ly = yabovefloor(mx) if iswalkable(mx,my) then if isreachable(mx,ly) then if ly ~= my then spr(122,mx*8-sx,ly*8,0) end sp = sp - 16 -- enable ct = "Walk here: " .. timestring(walktimetox(mx)) if l and not clicklock then tx = mx wo = true end else spr(138,mx*8-sx,ly*8,0) ct = "Not reachable" end else ct = "Not walkable" end end if to == 2 then -- build ty = buildingtype or objecttypes['dyke'] wantscancel = false if ty == objecttypes['dyke'] then validpos = isvaliddykepos(mx,my) else printc("Place " .. ty.name, 110, 8*3) printc("Click here to cancel", 110, 8*4) if my >= 3 and my <= 4 then wantscancel = true end validpos = true for xx = 1, ty.sx do for yy = 1, ty.sy do if not isbuildable(xx+mx-1, yy+my-1) then validpos = false end end if not isblock(xx+mx-1, my+ty.sy) then validpos = false end end end mis = canpay(ty.cost) if wantscancel then ct = "That card will go back to your hand" if l then buildingtype = nil table.insert(handcards, buildingcard) buildingcard = nil to = 0 end elseif mis > 0 then ct = "Not enough " .. re_symbols[mis] .. " to build " .. ty.name elseif not validpos then ct = "Cant build " .. ty.name .. " here" sp = ty.spoutlinered -- no real cursor, we draw the building outline else sp = ty.spoutline -- no real cursor, we draw the building outline left = mx right = mx + ty.sx - 1 ptx = workpoint(left, right) if isreachable(ptx, my) then ct = "Build " .. ty.name .. " here: " .. coststring(ty.cost, walktimetox(ptx)) if l and not clicklock then buildingtype = nil buildingcard = nil tx = ptx bx = mx by = my pay(ty.cost) wo = true tb = createobject(ty,mx,my) if left > px then -- must reach to the right pf = 1 elseif right < px then -- must reach to the left pf = 0 end end else ct = "Can't reach this place." end end spr(sp,mx*8-sx,my*8,0,1,0,0,ty.sx, ty.sy) end if to == 3 or to == 4 then -- collect / cut for _,o in pairs(objects) do ty = o.type left = o.x right = o.x + ty.sx -1 ptx = workpoint(left, right) if mx >= left and mx <= right and my >= o.y and my <= o.y + ty.sy -1 then action = nil releft = 0 if to == 3 and ty.collect then action = ty.collect releft = o.collect.re elseif to == 4 and ty.cut then action = ty.cut releft = o.cut.re end if action then if releft > 0 then if isreachable(ptx, my) then sp = sp - 16 -- enable actiontime = action.time if action.verb == "cut" then actiontime = actiontime * cuttimemulti end ct = action.verb .. " " .. ty.name .. " to get " .. coststring(action.gain) .. ": " .. timestring(walktimetox(ptx) + actiontime) .. " ("..releft.."x left)" if l then tb = o wo = true tx = ptx tl = 0 end else ct = "Can't reach this place." end else ct = "nothing to " .. action.verb .. " there" end end end end end end spr(sp,mx*8-sx,my*8,0) else -- upper screen part mxc = x // 6 if wo then sp = 102 else if my == 1 then for i = 1,3 do if mxc > i*4 - 4 and (mxc < i*4 or (i==3 and mxc < i*4+2)) then ct = re[i] .. " " .. re_names[i] if i == 3 then ct = ct .. " (earn " .. tm .. "$ to win)" end end end for i=1,6 do if mxc == 22 + 2*i then sp = 120 ct = to_names[i] if i == 5 then -- wait if not canwait() then ct = "Nothing to wait for" sp = 136 end end if i == 6 then -- card if #handcards == 0 then ct = "No cards" sp = 136 end end if l then -- return the card if the player currently builds a card building if to == 2 and i ~= 2 and buildingcard then buildingtype = nil table.insert(handcards, buildingcard) buildingcard = nil end if (i ~= 5 or canwait()) and (i ~= 6 or #handcards > 0) then to = i end if to == 5 and canwait() then wo = true end end end end end end spr(sp,mxc*6,my*8,0) -- cursor end end if globalstate == "levelstart" or globalstate == "levelend" or globalstate == "restart" then paintframe(3,2,24,13,777) color = 12 if x >= 8*4 and x <= 8*26 and y >= 100 and y <= 110 then color = 5 end if globalstate == "levelstart" then printc(levels[levelindex].name, 120,29, 15) textrect(levels[levelindex].introtext, 42, 55, 200 - 42) printc("Click here to start the level", 120,100, color) if color == 5 and l and clicklock == false then globalstate = "play" clicklock = true end end if globalstate == "levelend" then printc("You won the level!", 120,29, 15) textrect(levels[levelindex].outrotext, 42, 55, 200 - 42) printc("Click here for the next level", 120,100, color) if color == 5 and l and clicklock == false then clicklock = true levelindex = levelindex + 1 if #levels < levelindex then globalstate = "gamewon" else loadlevel(levelindex) globalstate = "levelstart" end end end if globalstate == "restart" then printc("Restart this level?", 120,29, 15) textrect("If you think you can't win anymore - or it would be really tedious to win after you had a bad start - you may restart this level.", 42, 55, 200 - 42) color2 = 12 if x >= 8*4 and x <= 8*26 and y >= 88 and y <= 98 then color2 = 5 end printc("Click here to restart", 120,88, color2) printc("Click here to contiune playing", 120,100, color) if l and clicklock == false then clicklock = true if color == 5 then -- continue globalstate = "play" end if color2 == 5 then -- restart sync(4) loadlevel(levelindex) globalstate = "levelstart" end end end end printc(ct, 120, 0, 12) end function stopwait() if to == 5 then to = 0 wo = false end end function workpoint(left, right) if px < left then ptx = left - 1 elseif px > right then ptx = right + 1 else ptx = px end return ptx end function walktimetox(x) return math.abs(px - x) * pt * walktimemulti end function canpay(cost) for i = 1,3 do if re[i] < cost[i] then return i end end return 0 end function pay(cost) for i = 1,3 do re[i] = re[i] - cost[i] end end function earn(gain) for i = 1,3 do re[i] = re[i] + gain[i] end if gain[5] then for i = 1,gain[5] do drawrandomcard() end end if re[3] >= tm then trace("Level won") globalstate = "levelend" end end function timestring(time, compact) if compact then return string.format("%d%s", math.floor(time / wt), re_symbols[4]) else return string.format("%1.1f%s", time / wt, re_symbols[4]) end end function coststring(cost, extratime, compact) extratime = extratime or 0 str = "" for i = 1,5 do co = cost[i] or 0 if i ~= 4 and co > 0 then if string.len(str) > 0 then if compact then str = str .. " " else str = str .. ", " end end str = string.format("%s%d%s", str, co, re_symbols[i]) end end time = (cost[4] or 0) + extratime if time > 0 then if string.len(str) > 0 then if compact then str = str .. " " else str = str .. ", " end end str = str .. timestring(time, compact) end return str end function TIC() if globalstate == "title" or globalstate == "gamewon" then cls(10) else cls(11) end -- mouse calc x,y,l,_,_,sxv = mouse() -- mouse position in grid coords mx = math.floor((x+sx) / 8) mxa = math.floor(x / 8) my = math.floor(y / 8) -- update scroll if x < sb then sv = sb - x sx = sx - sv * sv / 400 end if x > (240 - sb) then sv = x - (240 - sb) sx = sx + sv * sv / 400 end sx = sx + sxv * 2 sx = math.max(sx, 0) sx = math.min(sx, (levelwidth * 8) - 240) movecards() -- update if wo then t=t+1 --update objects for _,o in pairs(objects) do if o.type.update then o.type.update(o) end end if px ~= tx then -- still walking ttw = ttw - 1 if ttw <= 0 then ttw = pt * walktimemulti if px < tx then px = px + 1 pf = 1 else px = px - 1 pf = 0 end end else -- doing something else if to == 1 then -- walk wo = false end if to == 2 and tb ~= nil then if tb.state == 1 then -- planned -> building tb.state = 2 tl = tb.type.cost[4] elseif tb.state == 2 then -- building -> finished tl = tl - 1 if tl <= 0 then if tb.type.name ~= "tree" and tb.type.name ~= "sheep" then tb.state = 3 end if tb.type.isblock then lmset(tb.x,tb.y,3) end tb = nil wo = false end end end action = nil if tb then ty = tb.type if to == 3 then action = ty.collect end if to == 4 then action = ty.cut end if action then -- collect or cut if tl <= 0 then -- start doing it tl = action.time if to == 4 then tl = tl * cuttimemulti end end tl = tl - 1 if tl <= 0 then -- finished doing it if to == 3 then tb.collect.re = tb.collect.re - 1 end if to == 4 then tb.cut.re = tb.cut.re - 1 if tb.cut.re == 0 then -- todo should this be an effect? destroyobject(tb) end end earn(action.gain) if action.effect then action.effect(tb) end tb = nil wo = false end end end end if t % wt == 0 then addwater() t = 0 end end -- draw map if globalstate ~= "title" then map(levelx,levely+17,levelwidth,levelheight,-sx,0,0) end if globalstate == "gamewon" then return end -- draw objects for _,o in pairs(objects) do drawobject(o) end -- draw player py = yabovefloor(px) body = 7 legs = 23 pfb = pf -- body flip if not wo then if my < py - 4 then body = 52 elseif mx < px - 4 then pfb = 0 elseif mx > px + 4 then pfb = 1 else body = 53 end end if wo and px ~= tx then legs = 68 if t % 10 >= 5 then legs = 69 end end if wo and to > 1 and to < 5 then dx = px - 1 + 2 * pf spr(50,dx*8-sx,(py-1)*8,0, 1, pf) -- arm if (to == 2 or to == 4) and t % 30 < 15 and px == tx then spr(to+79,dx*8-sx,(py-1)*8,0, 1, pf, 1) -- tool else spr(to+79,dx*8-sx,(py-0)*8,0, 1, pf) -- tool end body = 51 -- no double arm legs = 67 end spr(body,px*8-sx,(py-1)*8,0, 1, pfb) -- body spr(legs,px*8-sx,(py-0)*8,0, 1, pf) -- legs if globalstate == "title" then map(120,34,30,levelheight,0,0,0) prints("Click to start the game", 12*8, 8*8, 12) print("A game by @LenaSchimmel", 2*8, 14*8, 12, false, 1, false) print("Made in 72 hours for Ludum Dare 50", 2*8, 15*8, 12, false, 1, true) if l then globalstate = "levelstart" end return end end function yabovefloor(x) for y = 0,18,1 do if isblock(x,y) then return y - 1 end end return -1 end function rightmostwater() for x = levelwidth, 0, -1 do for y = 0, levelheight, 1 do if iswater(x,y) then return x,y end end end return 0,15 end function addwater() x,y = rightmostwater() if x == levelwidth - 1 then trace ("GAME OVER") exit() return end if isfloodable(x+1, y) then while isfloodable(x+1,y+1) do y = y + 1 end setwater(x+1, y) return end while x > 0 and isfloodable(x-1,y) do x = x - 1 end if isfloodable(x,y) then while isfloodable(x+1,y+1) do y = y + 1 end setwater(x+1, y) else y = y - 1 while x > 0 and isfloodable(x-1,y) do x = x - 1 end setwater(x,y) end end function setwater(x,y) if isblock(x+1,y) then lmset(x, y+levelheight, 17) else lmset(x, y+levelheight, 18) end if iswater(x-1,y) then lmset(x-1, y+levelheight, 17) end if iswater(x,y+1) then lmset(x, y+1+levelheight, 2) end if x >= px then px = x + 1 py = yabovefloor(px) end if x >= tx then tx = x + 1 end end -- tile flags: -- 0 = water -- 1 = blocks water, can stand upon -- 2 = blocks building function iswater(x,y) return fget(lmget(x,y+levelheight),0) end function isblock(x,y) return fget(lmget(x,y),1) end function setblock(x,y) return lmset(x,y+levelheight,3) end -- does not test reachability, only if it was allowed to actually *be* there function iswalkable(x,y) return not fget(lmget(x,y),1) and not iswater(x,y) end function isreachable(x,y) minx = math.min(x,px) maxx = math.max(x,px) lasth = yabovefloor(minx) for i = minx, maxx do h = yabovefloor(i) if h < 0 or iswater(i, h) then return false end d = math.abs(h - lasth) lasth = h if d > 1 then return false end end return true end -- can this grid pos hold water, but does currently not? function isfloodable(x,y) return not fget(lmget(x,y),1) and not iswater(x,y) end function isbuildable(x,y) return not fget(lmget(x,y),2) and not iswater(x,y) end function isvaliddykepos(x,y) return isbuildable(x,y) and isblock(x-1,y+1) and isblock(x,y+1) and isblock(x+1,y+1) end --Prints text where x is the center of text. function printc(s,x,y,c,fixed,scale,small) local w=print(s,0,-8,c or 15,true) prints(s,x-(w/2//6*6),y,c or 15,fixed,scale,small) end --Prints text, replaces some symbols with sprites function prints(s,x,y,c,fixed,scale,small) scale = scale or 1 print(s:gsub("%$"," "):gsub("/"," "):gsub("#"," "):gsub("%*"," "):gsub("@"," "),x,y+1,c or 15, true,scale,small) for i = 1, s:len() do ch = s:sub(i,i) sp = 0 if(ch == "#") then -- stone sp = 128 end if(ch == "/") then -- wood sp = 129 end if(ch == "$") then -- score sp = 130 end if(ch == "*") then -- time sp = 131 end if(ch == "@") then -- card sp = 132 end spr(sp,x+(i-1)*6,y,0) end end function myspr(sp, x, y) spr(sp, x*8, y*8, 0) end function myrspr(spa, spb, x, y, pa, r) sp = eitheror(spa, spb, pa, r * 13 + x * 19 + y * -5) spr(sp, x*8, y*8, 0) end function eitheror(a,b,pa,r) r = (r * 17 + a * 23 + b * -7) * 111 + (r * 11 + a * -3 + b * 29) * 97 if math.abs(r) % 100 > pa * 100 then return b else return a end end function mysplit (inputstr, sep) if sep == nil then sep = "%s" end local t={} for str in string.gmatch(inputstr, "([^"..sep.."]+)") do table.insert(t, str) end return t end function paintframe(x,y,w,h,r) myspr(204, x,y) myspr(207, x+w-1,y) myspr(252, x,y+h-1) myspr(255, x+w-1,y+h-1) stains = {222, 237, 238} for xx = x+1, x+w-2 do for yy = y+1, y+h-2 do stain = stains[math.abs(r*2+x*19+y*17)%3+1] myrspr(stain, 221, xx,yy, 0.03, r) end myrspr(205, 206, xx,y, 0.1, r) myrspr(253, 254, xx,y + h - 1, 0.25, r) end for yy = y+1, y+h-2 do myrspr(220, 236, x,yy, 0.1, r) myrspr(223, 239, x + w - 1,yy, 0.25, r) end myspr(216, x+1,y+3) for xx = x+2, x+w-3 do myspr(217, xx,y+3) end myspr(218, x+w-2,y+3) end function paintcard(x,y,w,h,title,text,cost,r,onlybutton, buttoncolor) if not onlybutton then paintframe(x,y,w,h,r) print(title, x*8+6, y*8 + 6, 15) prints(coststring(cost, 0, true), x*8+6, (y+2)*8) end paintcardbutton(x*8+w*4, (y+h-1)*8 - 6, buttoncolor or 9) if y > 13 or onlybutton then return end textrect(text, x*8+6, (y+4)*8+6, w*8 - 12) end function textrect(text,x,tey,w) words = mysplit(text) tex = x for _,word in pairs(words) do tw = print(word, 0, -10, 15, false, 1, true) if tex + tw > x + w then tex = x tey = tey + 6 end prints(word, tex, tey, 15, false, 1, true) tex = tex + tw + 6 end end function paintcardbutton(x,y,c) printc("PLAY CARD", x, y, c) end function table.shallow_copy(t) local t2 = {} for k,v in pairs(t) do t2[k] = v end return t2 end function definecards() cards = { { title="Book", text="Read a book. Draw 3 cards.", cost = {0,0,25,0}, r=234, effect = function() for i=1,3 do drawrandomcard() end end, }, { title="Boots", text="With these boots, you can walk 20% faster.", cost = {0,3,3,0}, ispermanent = true, effect = function() walktimemulti = walktimemulti * 0.8 end, r=235, }, { title="Axe", text="With this improved axe, you can cut trees and rocks 20% faster.", cost = {1,3,5,0}, ispermanent = true, effect = function() cuttimemulti = cuttimemulti * 0.8 end, r=235, }, { title="Well", text="The well waters all your plants, so their fruit will grow 30% faster.", r=236, buildingtype=objecttypes["well"] }, { title="Appleseed", text="You may plant an apple tree.", r=237, buildingtype=objecttypes["tree"] }, { title="Appleseed", text="You may plant an apple tree.", r=237, buildingtype=objecttypes["tree"] }, { title="Mine", text="It gives you access to an unlimited supply of stones, but they take longer to mine.", r=237, buildingtype=objecttypes["mine"] }, { title="Sheep", text="Your sheep gives you wool ($ ) until you butcher it (more $ ).", r=237, buildingtype=objecttypes["sheep"] }, { title="Sheep", text="Your sheep gives you wool ($ ) until you butcher it (more $ ).", r=237, buildingtype=objecttypes["sheep"] }, { title="Woodsale", text="Someone pays you enormous 35$ if you sell them 10/.", r=239, cost={0,10,0,0}, gain={0,0,30,0} }, { title="Quickstones", text="If you need stones quickly, get 5# for 20$.", r=240, cost={0,0,20,0}, gain={5,0,0,0} }, { title="Gift", text="Here, have 10$ :)", r=241, cost={0,0,0,0}, gain={0,0,10,0} }, { title="Wood reserve", text="You find a lot of wood! It's 10/!", r=242, cost={0,0,0,0}, gain={0,10,0,0} } } for i, card in pairs(cards) do card.y = 14 if card.buildingtype then card.cost = card.buildingtype.cost end end handcards = {} for i = 1,5 do drawrandomcard() end end function drawrandomcard() ind = math.random(1, #cards) trace("Add card " .. ind .. " to hand") table.insert(handcards, table.shallow_copy(cards[ind])) cards[ind].y = 14 end function movecards() for i, card in pairs(handcards) do if i == selectedcard then if card.y > 2 then card.y = card.y - 1 end else if card.y < 14 then card.y = card.y + 1 end end end end function paintcards(mx,my,onlybutton, buttoncolor) ci, button = 0, false if #handcards > 0 then -- effective width: 30 - 9 - 2 = 19 if #handcards > 1 then wpc = 19 // (#handcards - 1) else wpc = 0 end for i, card in pairs(handcards) do cx = 1 + (i-1) * wpc paintcard(cx,card.y,9,13,card.title, card.text, card.cost, card.r, onlybutton, buttoncolor) if mx >= cx and mx <= cx + 9 and my >= card.y and my <= card.y + 13 then ci = i if mx >= cx + 1 and mx < cx + 9 - 1 and my >= card.y + 13 - 2 and my < card.y + 13 - 1 then button = true end end end end return ci, button end start()