0,]']>S}WÚp8du)6o;]AsVl3????????????????????155 555.5/686H7I7Y898L8M9M9L9J:J;I;I;9<:<:=:>*>*?????$   0@@0  @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ` ` ` ` ` ````` ` ` `` ` ` ` @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @  @ $ D $ D $ D $ D     dd         f*B <33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333**2#2#2#2#2#2#2#2#U2#2#U2#2#U&b&b&b&b&b&b&b&b&b&b&b&b&b&b&b&b&b&b&b&bbffffffffffffffffffffffffffffffffffffff&bffffffffffffffffffffffffffffffffffffef&fVffffVfffVfffVfffVfffVfffVfffVfffVfffffffffffffffffffffffffffffffffffffffffffffbfffVfffVfffVfffVfffVfffVfffVfffVfffffV&bffefffffffffffffffffffffffffffffffffff&fffffffffffffffffffffffffffffffffffffffffffffUUffUUfffffffffffffffffffffffffffffbfffVUUeVUUefffffffffffffffffffffffffff&bfVfVUUeVUUeffVfffVfffVfffffVfffVfffe&ffffVUUeVUUeffffffffffffhfffffffffffffffffUUffUUfffffffffffffffffffffffffbefff""ff""ffffffffffffffffffffffef&bffff""ff""fVfffVfffVfffVfffVffffff&fffff""ff""ffffffffffffffffffffffffffffffUUffUUfffffffffffffffffffffffffffff**bfffVUUeVUUefffffffffffffffff&bff&bffff&2#2#bfVfVUUeUR%UffVfffVfffVfffVff""ff2%fffe&2#2#ffffVUUeUURUffffffffffffffff&""b&3bffff2#2#fffffUUf%UURffffffffffffffff&""b&3=bffff2#2#befff""fU%UUfffffffffffffffff""ff2#ffef&2#2#bffff""f%U%UVfffVfffVfffVffff&bff&bffff&2#2#fffff""fVUUeffffffffffffffffffffffffffff****fffffUUffffffffffffffffffffffDDfffffffff2#2#2#2#bfffVUUeffffffffffffffffffffFffdf&bffff&2#2#2#2#bfVfUR%UffVfffVfffVfffVfffVfdffFf""fffe&2#2#2#2#ffffUURUffffffffffffffffffffDDDD&"bffff2#2#2#2#ffff%UURffffffffffffffffffff$B$B&2/bffff2#2#2#2#beffU%UUffffffffffffffffffff$B$Bf""ffef&2#2#2#2#bfff%U%UVfffVfffVfffVfffVfff$""Bf&bffff&ffffVUUeffffffffffffffffffffDDDDffffffffffffffffffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffff&bfVfffVfffVfffffVfffVfffVfffVfffVfffe&ffffffffffffhffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbefffffffffffffffffffffffffffffffef&bfffVfffVfffVfffVfffVfffVfffVffffff&ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffff&beffffffffffffffffffffffffffffffffffffe&ffffffVfffVfffVfffVfffVfffVfffVfffVfffffffffffffffffffffffffffffffffffffffffffffbffeVfffVfffVfffVfffVfffVfffVfffVffffef&bffffffffffffffffffffffffffffffffffffff&&b&b&b&b&b&b&b&b&b&b&b&b&b&b&b&b&b&b&b&b****2#2#2#2#2#2#2#2#2#2#2#2#U2#2#U2#2#U2#2#U2#2#U2#2#U2#2#'e-- title: Melocraft -- author: ElStep -- desc: short description -- site: website link -- license: MIT License (change this to your license of choice) -- version: 0.1 -- script: lua COLS=30 ROWS=17 SCRW=240 SCRH=136 GAME_STATE="MENU" PLAYER_SPRITE=257 PLAYER_SPEED=1 TID={ WATER=1, TREE=3, BBUSH=4, CHEST1=5, GRASS=34, GROUND=21, GSEED=36, WGROUND=52, RAFT=37, TRAP=38, FLASH=23, WKBCH=71, FROD=260, WOOD=261, ACORN=262, SEEDS=263, BSEEDS=264, APPLE=273, BERRY=274, ORANGE=275, RFISH=289, CFISH=290, SHOVEL=276, IPICK=277, DPICK=278, ISWORD=279, DSWORD=280, ROPE=291, BOTTLE=292 } F={ WALL=1, SHOVEL=0, PICK=1, SWORD=2, SEEDS=3, FOOD=4, BOTTLE=5, WORK=6 } SEEDS={ [TID.ACORN]=TID.TREE, [TID.BSEEDS]=TID.BBUSH } GRASS_SPRITE = 34 FLASH_SPRITE = 23 S={ PLR={ STAND=257, WALK1=258, WALK2=259, }, SCRIM=97 } INV_SIZE = 16 MAX_STACK = 99 NAMES = { [TID.FROD]="Fishing rod", [TID.ROPE]="Rope", [TID.WOOD]="Wood", [TID.ACORN]="Acorn", [TID.APPLE]="Apple", [TID.BERRY]="Berry", [TID.BSEEDS]="Berry seeds", [TID.ORANGE]="Orange", [TID.RFISH]="Raw fish", [TID.CFISH]="Cooked fish", [TID.SHOVEL]="Shovel", [TID.IPICK]="Iron pick", [TID.DPICK]="Gem pick", [TID.ISWORD]="Iron sword", [TID.DSWORD]="Gem sword", [TID.WKBCH]="Workbench", [TID.RAFT]="Raft", [TID.TRAP]="Fish trap" } DIRS = {[0]={0,-6}, [1]={0,8}, [2]={-8,0}, [3]={8,0}} DROPS = { [TID.TREE] = { {id=TID.WOOD,p=100,min=3,max=5}, {id=TID.ACORN,p=90,min=1,max=2}, {id=TID.APPLE,p=50,min=1,max=1} }, [TID.BBUSH] = { {id=TID.BERRY,p=100,min=3,max=5} }, [TID.CHEST1] = { {id=TID.ROPE,p=100,min=2,max=3} } } TRAP_DROPS={ [TID.RFISH]=50, [TID.ROPE]=35, [TID.BOTTLE]=15 } BE = {HURT={},TRAP={},TICK={},REPL={}} PB = { START=65, END=70 } RCP={ [TID.WKBCH]={w=nil,num=1,req={{TID.WOOD,2}}}, [TID.BSEEDS]={w=nil,num=3,req={{TID.BERRY,1}}}, [TID.RAFT]={w=1,req={{TID.WOOD,3},{TID.ROPE,2}}}, [TID.TRAP]={w=1,req={{TID.WOOD,3},{TID.ROPE,2},{TID.BERRY,4}}} } GMPD={ A=81, B=82, X=83, Y=84 } EBT = { [TID.TREE]={ beh={BE.HURT,BE.TICK}, data={max_hp=4} }, [TID.TRAP]={ beh={BE.TICK,BE.TRAP}, data={ max_hp=5, c_time=7200 } }, [TID.WGROUND]={ beh={BE.TICK,BE.REPL}, data={ repl=TID.TREE } }, } L={ ["Context"]={ w=102,h=38, text={},c={}, name="Item", init=function(l) l.num=1 l.text={"Add to toolbar","Discard"} l.c={12,12} end, upd=function(l) l.name=NAMES[inv_id[inv_sel]] if btnp(2) then l.num=l.num-1 end if btnp(3) then l.num=l.num+1 end if l.num>inv_count[inv_sel] then l.num=1 end if l.num<1 then l.num=inv_count[inv_sel] end if btnp(4) then if l.sel==1 then PushToTB(inv_id[inv_sel],l.num,inv_sel) elseif l.sel==2 then removeItem(inv_id[inv_sel],l.num,inv_sel) end end if inv_id[inv_sel]<1 then SpawnList(L["Context"],l.x,l.y) end end, rend=function(l) local text="<" .. l.num .. ">" local w=print(text,0,-10) local x=l.x+(l.w/2-(w/2)) print(text,x,l.y+l.h-10,12) end }, ["Craft"]={ w=80,h=98, text={},c={}, name="Craft", init=function(l) local tx,ty=getBestTarget() l.ids={} for k,v in pairs(RCP) do if not v.w or v.w==WORK[mget(tx,ty)] then Ins(l.ids,k) end end SortMenu(l) l.sel=1 end, upd=function(l) if btnp(4) and #l.ids>0 then local cid=l.ids[l.sel] Craft(cid) SortMenu(l) --l.c[l.sel]=12+(not TryCraft(l.ids[l.sel]) and 1 or 0) end end, rend=function(l) local sy=l.y+10 for i=1,#l.ids do local cy=sy+((i-1)*8) spr(l.ids[i],l.x+l.w-10,cy-2,0) end end } } LIST_X=36 LIST_Y=20 TRAP_DROPS={ [TID.RFISH]=50, [TID.ROPE]=35, [TID.BOTTLE]=15 } SFX={ [TID.TREE]=1, [TID.BBUSH]=2, [TID.CHEST1]=2 } REPL_TIME=7200 BE.HURT.init=function(e) local d=EBT[e.id].data e.hp=d.max_hp end BE.TICK.init=function(e) e.t=0 e.c=false end BE.TRAP.init=function(e) local d=EBT[e.id].data e.use=false e.c_time=d.c_time end BE.REPL.init=function(e) local d=EBT[e.id].data local s=GetSeedAt(e.x,e.y) e.repl=SEEDS[s.id] or d.repl end BE.HURT.update = function(e) e.sprite = PB.START+e.hp-1 e.t=e.t+1 end BE.TICK.update = function(e) if not e.c then e.t=e.t+1 end end BE.TRAP.update = function(e) if e.t == e.c_time then e.c = true end if e.c then local tid = 55 + (t // 30) % 2 e.sprite = tid end if e.use and not e.c then e.use = false end end BE.REPL.update=function(e) if fget(e.repl,F.WALL) then if AABB(e.x,e.y) then e.c=true else e.c=false end end if e.t%REPL_TIME==0 then mset(e.x/8,e.y/8,e.repl) e.dead=true end end PFX={ POP={ rad=2, count=7, speed=4, fall=true, ttl=15 }, FW={ rad=3, count=40, speed=1, fall=false, ttl=10 } } PCLR={ [TID.TREE]=2, [TID.RAFT]=2, [TID.CHEST1]=2, [TID.GROUND]=2, [TID.TRAP]=3, [TID.BBUSH]=5, [TID.GRASS]=5, [TID.GSEED]=10 } WORK={ [TID.WKBCH]=1 } FP={ [TID.APPLE]=4, [TID.BERRY]=1, [TID.ORANGE]=4, [TID.RFISH]=2, [TID.CFISH]=5 } MAX_FP=12 t=0 Plr={ hp=12, fp=12, x=14*8,y=8*8, dir=1, ddir=1, cr = { left = 1, right = 1, top = 5, bottom = 0 }, tb={}, slot=1, anim=false } inv_id = {} inv_count = {} drops = {} Parts = {} Ents = {} Lists = {} Seeds = {} con_sel=1 con_num=1 shake = 0 shPower = 1 shTime=2 show_tile=false show_inv=false show_inv_timer=0 show_context=false inv_sel=1 work=0 flash_time = -100 flash_tx = 0 flash_ty = 0 function Max(x,y) return math.max(x,y) end function Min(x,y) return math.min(x,y) end function Abs(x,y) return math.abs(x,y) end function Rnd(lo,hi) return math.random(lo,hi) end function Rnd01() return math.random() end function RndSeed(s) return math.randomseed(s) end function Ins(tbl,e) return table.insert(tbl,e) end function Rem(tbl,e) return table.remove(tbl,e) end function Sin(a) return math.sin(a) end function Cos(a) return math.cos(a) end function Iif(cond,t,f) if cond then return t else return f end end function Iif2(cond,t,cond2,t2,f2) if cond then return t end return Iif(cond2,t2,f2) end function SortMenu(l) table.sort(l.ids,function(a, b) local can_a=TryCraft(a) local can_b=TryCraft(b) if can_a ~= can_b then return can_a end return (NAMES[a] or "") < (NAMES[b] or "") end) l.text={} l.c={} for i=1, #l.ids do local id=l.ids[i] Ins(l.text,NAMES[id]) Ins(l.c, 12+(not TryCraft(id) and 1 or 0)) end end function EntInit(e) for _,b in pairs(EBT[e.id].beh) do if b.init then b.init(e) end end end function EntUpdate(e) for _,b in pairs(EBT[e.id].beh) do if b.update then b.update(e) end end end function ListUpdate(l) if btnp(0) then l.sel=l.sel-1 end if btnp(1) then l.sel=l.sel+1 end if l.sel>#l.text then l.sel=1 end if l.sel<1 then l.sel=#l.text end if l.update then l.update(l) end end function RendList(l) rect(l.x,l.y,l.w,l.h,8) rectb(l.x,l.y,l.w,l.h,12) print(l.name,l.x+2,l.y+2,12) local sy=l.y+10 if l.rend then l.rend(l) end if #l.text<1 then return end for i=1,#l.text do local cy=sy+((i-1)*8) print(l.text[i],l.x+6,cy,l.c[i]) if l.sel==i then print(">",l.x+2,cy,12) end end end function tryMergeDrop(idx) local d1 = drops[idx] local merge_radius_sq = 16 for i = 1, #drops do if i ~= idx then local d2 = drops[i] if d2.id == d1.id and not d2.moving and not d2.dead then local dx = d2.x - d1.x local dy = d2.y - d1.y local dist_sq = dx*dx + dy*dy if dist_sq <= merge_radius_sq then d2.count = d2.count + d1.count d1.dead = true return true end end end end return false end function SpawnParts(fx,cx,cy,clr) for i=1,fx.count do local r=Rnd01()*fx.rad local phi=Rnd01()*math.pi*2 local part={ x=cx+r*Cos(phi), y=cy+r*Sin(phi), vx=fx.speed*Cos(phi), vy=fx.speed*Sin(phi), fall=fx.fall, ttl=fx.ttl, age=0, clr=clr } Ins(Parts,part) end end function SpawnEnt(id,x,y,sprite) local ent = { id=id,t=0, sprite=sprite or id, x=x,y=y, dead=false } EntInit(ent) Ins(Ents,ent) end function SpawnList(lt,x,y) local k,l=GetListAt(x,y) if l then Rem(Lists,k) return end local list = { x=x,y=y, w=lt.w,h=lt.h, sel=1,name=lt.name, text=lt.text,c=lt.c, update=lt.upd,rend=lt.rend } lt.init(list) Ins(Lists,list) end function NewSeed(id,x,y) Ins(Seeds,{id=id,x=x,y=y}) end function spawnDrop(id,x,y,count) count = count or 1 table.insert(drops, { id = id, x = x, y = y, count = count, vx = math.random(-7, 7) / 7, vy = math.random(-8, -7) / 7, gravity = 0.15, bounce = 2, ground_y = y + math.random(2, 6), moving = true }) end function addItem(id, count) count = count or 1 for i = 1, INV_SIZE do if inv_id[i] == id and inv_count[i] < MAX_STACK then local available = MAX_STACK - inv_count[i] if count <= available then inv_count[i] = inv_count[i] + count return true else inv_count[i] = MAX_STACK count = count - available end end end for i = 1, INV_SIZE do if inv_id[i] == 0 then if count <= MAX_STACK then inv_id[i] = id inv_count[i] = count return true else inv_id[i] = id inv_count[i] = MAX_STACK count = count - MAX_STACK end end if count <= 0 then return true end end return count <= 0 end function removeItem(id, count, slot) count = count or 1 if slot then if inv_id[slot] == id then if inv_count[slot] > count then inv_count[slot] = inv_count[slot] - count return true else count = count - inv_count[slot] inv_id[slot] = 0 inv_count[slot] = 0 return count == 0 end end return false end for i = INV_SIZE, 1, -1 do if inv_id[i] == id then if inv_count[i] > count then inv_count[i] = inv_count[i] - count return true else count = count - inv_count[i] inv_id[i] = 0 inv_count[i] = 0 if count == 0 then return true end end end end return count == 0 end function CountItem(id) local c=0 for i=1,INV_SIZE do if inv_id[i]==id then c=c+inv_count[i] end end return c end function TryCraft(id) local r=RCP[id] and RCP[id].req if not r then return false end for i=1,#r do if CountItem(r[i][1]) < r[i][2] then return false end end return true end function Craft(id) local r = RCP[id] and RCP[id].req if not r or not TryCraft(id) then return end for i = 1, #r do removeItem(r[i][1], r[i][2]) end addItem(id,RCP[id].num) end function AABB(x, y) if x < Plr.x + 8 and x + 8 > Plr.x and y < Plr.y + 8 and y + 8 > Plr.y then return true end return false end function is_solid(px, py) local tile_x = math.floor(px / 8) local tile_y = math.floor(py / 8) local tile_id = mget(tile_x, tile_y) return fget(tile_id, 0) or fget(tile_id, 1) end function CanMove(x, y, cr) local x1 = x + cr.left local x2 = x + 7 - cr.right local y1 = y + cr.top local y2 = y + 7 - cr.bottom if is_solid(x1, y1) then return false end if is_solid(x2, y1) then return false end if is_solid(x1, y2) then return false end if is_solid(x2, y2) then return false end return true end function TryMoveBy(dx, dy) if dx ~= 0 then if CanMove(Plr.x + dx, Plr.y, Plr.cr) then Plr.x = Plr.x + dx end end if dy ~= 0 then if CanMove(Plr.x, Plr.y + dy, Plr.cr) then Plr.y = Plr.y + dy end end end function GetHand() local item = Plr.tb[Plr.slot] if item then return item.id end return 0 end function getBestTarget() local px=math.floor((Plr.x+4)/8) local py=math.floor((Plr.y+4)/8) local hand=GetHand() local best_tx,best_ty = nil,nil local min_dist=9999 local radius=1 for ty=py-radius, py+radius do for tx=px-radius, px+radius do local tid = mget(tx, ty) local valid = false if fget(hand,F.PICK) then valid=fget(tid, 1) elseif fget(hand,F.SHOVEL) then valid=(tid==TID.GRASS) elseif fget(hand,F.SEEDS) then valid=(tid==TID.GROUND) elseif fget(hand,F.BOTTLE) then valid=(tid==TID.GSEED) elseif fget(hand,F.WORK) then valid=(tid==TID.GRASS) elseif hand==TID.RAFT or hand==TID.TRAP then valid=(tid==TID.WATER) else valid=(tid==TID.BBUSH) or (tid==CHEST1) end valid = valid or fget(tid,F.WORK) or tid==TID.TRAP if valid then local dx=(Plr.x+4)-(tx*8+4) local dy=(Plr.y+4)-(ty*8+4) local dist=dx*dx+dy*dy if dist0 and count>0 then return true end return false end function GetEntAt(x,y) for i=1,#Ents do local e=Ents[i] if e.x==x and e.y==y then return e end end return nil end function GetListAt(x,y) for k,v in pairs(Lists) do if v.x==x and v.y==y then return k,v end end return nil end function GetSeedAt(x,y) for i=1,#Seeds do local s=Seeds[i] if s.x==x and s.y==y then return s end end return nil end function getTile() local cx = Plr.x + 4 local cy = Plr.y + 4 local offset = DIRS[Plr.dir] local front_x = cx + offset[1] local front_y = cy + offset[2] local map_x = math.floor(front_x / 8) local map_y = math.floor(front_y / 8) return map_x, map_y end function Eat(is_tb,slot) if Plr.fp>=12 then return end local fp=1 if is_tb then fp=FP[Plr.tb.id] Plr.tb.slot.count=Plr.tb.slot.count-1 else fp=FP[inv_id[slot]] removeItem(inv_id[slot],1,slot) end Plr.fp=Min(Plr.fp+fp,MAX_FP) end function Interact() local tx,ty=getBestTarget() if not (tx and ty) then return end local tid=mget(tx,ty) local ntid=TID.GRASS local hand=GetHand() local isEnt = false local drop=true if fget(hand,F.PICK) then if fget(tid,F.WALL) then for k,_ in pairs(EBT) do if k==tid then isEnt=true break end end if isEnt then local e=GetEntAt(tx*8,ty*8) drop=false if e then e.hp=e.hp-1 if e.hp<1 then e.dead=true mset(tx,ty,TID.GRASS) drop=true end else SpawnEnt(tid,tx*8,ty*8) end else mset(tx,ty,TID.GRASS) end SpawnParts(PFX.POP,tx*8+4,ty*8+4,PCLR[tid]) if SFX[tid] then sfx(SFX[tid]) end --shake=shTime flash_time=t flash_tx=tx flash_ty=ty end elseif fget(hand,F.SHOVEL) then if tid==TID.GRASS then mset(tx,ty,TID.GROUND) SpawnParts(PFX.POP,tx*8+4,ty*8+4,5) end elseif fget(hand,F.SEEDS) then if tid==TID.GROUND then mset(tx,ty,TID.GSEED) local s=GetSeedAt(tx*8,ty*8) if s then s.id=hand else NewSeed(hand,tx*8,ty*8) end RemoveFromTB(1) end elseif fget(hand,F.BOTTLE) then if tid==TID.GSEED then mset(tx,ty,TID.WGROUND) SpawnEnt(TID.WGROUND,tx*8,ty*8) SpawnParts(PFX.FW,tx*8+4,ty*8+4,10) end elseif fget(hand,F.FOOD) then Eat(true,Plr.slot) elseif fget(hand,F.WORK) then mset(tx,ty,hand) elseif hand==TID.RAFT or hand==TID.TRAP then if tid==TID.WATER then if hand==TID.TRAP then SpawnEnt(hand,tx*8,ty*8) end mset(tx,ty,hand) RemoveFromTB(1) end end local loot = DROPS[tid] if loot and drop then for i = 1, #loot do local item = loot[i] if math.random(1, 100) <= item.p then spawnDrop(item.id, tx*8, ty*8, math.random(item.min, item.max)) end end end end function PushToTB(id,count,slot) for i=1,#Plr.tb do if Plr.tb[i].id==0 then Plr.tb[i].id=id Plr.tb[i].count=count removeItem(id,count,slot) return end if Plr.tb[i].id==id then Plr.tb[i].count=Plr.tb[i].count+count removeItem(id,count,slot) return end end end function RemoveFromTB(count) local c=Plr.tb[Plr.slot].count Plr.tb[Plr.slot].count=math.max(0,c-count) end function UseEnt() local tx,ty = getBestTarget() if not (tx and ty) then return end local e = GetEntAt(tx * 8, ty * 8) if e and e.id == TID.TRAP then if e.c then e.use = true e.c = false e.sprite = 0 e.t = 0 local r = math.random(100) local rolled_item for item_id, chance in pairs(TRAP_DROPS) do r = r - chance if r <= 0 then rolled_item = item_id break end end local rx = tx * 8 + math.random(-2, 2) local ry = ty * 8 + math.random(-2, 2) spawnDrop(rolled_item, rx, ry, 1) SpawnParts(PFX.POP,tx*8+4,ty*8+4,10) end end end function Use() local tx,ty = getBestTarget() if not (tx and ty) then return end local e = GetEntAt(tx * 8, ty * 8) if e then UseEnt() return end local tid=mget(tx,ty) if not tid then return end if fget(tid,F.WORK) then SpawnList(L["Craft"],LIST_X,LIST_Y) show_inv=true show_inv_timer = t end end function UpdateShake() if shake>0 then poke(0x3FF9, math.random(-shPower, shPower)) poke(0x3FF9 + 1, math.random(-shPower, shPower)) shake = shake-1 end if shake == 0 then memset(0x3FF9, 0, 2) end end function UpdateEnts() for i = #Ents, 1, -1 do local e = Ents[i] EntUpdate(e) if e.dead then Rem(Ents, i) end end end function UpdateParts() for i=#Parts,1,-1 do local p=Parts[i] p.age=p.age+1 if p.age>=p.ttl then Rem(Parts,i) else p.x=p.x+p.vx p.y=p.y+p.vy+(p.fall and p.age//2 or 0) end end end function UpdateLists() for i = 1, #Lists do ListUpdate(Lists[i]) end end function UpdateDRP() local magnet_dist_sq = 256 local magnet_speed = 1.5 for i = #drops, 1, -1 do local d = drops[i] if d.dead then table.remove(drops, i) else if d.moving then d.vy = d.vy + d.gravity d.x = d.x + d.vx d.y = d.y + d.vy if d.y >= d.ground_y then d.y = d.ground_y d.vy = -d.vy * 0.4 d.vx = d.vx * 0.6 d.bounce = d.bounce - 1 if d.bounce <= 0 then d.moving = false d.vx = 0 d.vy = 0 tryMergeDrop(i) end end else local dx = (Plr.x + 4) - (d.x + 4) local dy = (Plr.y + 4) - (d.y + 4) local dist_sq = dx*dx + dy*dy if dist_sq <= magnet_dist_sq then local dist = math.sqrt(dist_sq) if dist > 0 then d.x = d.x + (dx / dist) * magnet_speed d.y = d.y + (dy / dist) * magnet_speed end end end if not d.dead and Plr.x + 7 >= d.x and Plr.x <= d.x + 7 and Plr.y + 7 >= d.y and Plr.y <= d.y + 7 then local amt = d.count or 1 if addItem(d.id, amt) then table.remove(drops, i) sfx(3) end end end end end function updatePlr() local dx,dy = 0,0 if btn(0) then dy=-PLAYER_SPEED; Plr.dir=0 end if btn(1) then dy=PLAYER_SPEED; Plr.dir=1 end if btn(2) then dx=-PLAYER_SPEED Plr.dir=2 Plr.ddir=1 end if btn(3) then dx=PLAYER_SPEED Plr.dir=3 Plr.ddir=0 end Plr.anim = (dx ~= 0 or dy ~= 0) if t % 2 == 0 then TryMoveBy(dx,dy) end local tx,ty = getBestTarget() local tid = mget(tx,ty) if fget(GetHand(),SHOVEL_FLAG) then show_tile = mget(tx,ty) == TID.GRASS elseif fget(GetHand(),F.SEEDS) then show_tile = mget(tx,ty) == TID.GROUND elseif fget(GetHand(),F.BOTTLE) then show_tile = mget(tx,ty) == TID.GSEED elseif fget(tid,F.PICK) then show_tile = fget(tid,F.PICK) elseif GetHand()==TID.RAFT or GetHand==TID.TRAP then show_tile=mget(tx,ty) == TID.WATER end for i=1,#Plr.tb do if Plr.tb[i].count==0 then Plr.tb[i].id=0 end end if btnp(4) then Interact() end if btnp(6) then Plr.slot=Plr.slot-1 if Plr.slot<1 then Plr.slot=4 end Use() end if btnp(7) then Plr.slot=Plr.slot+1 if Plr.slot>4 then Plr.slot=1 end end end function UpdateINV() if not show_inv then return end if show_inv_timer and show_inv_timer == t then UpdateLists() return end local size = #inv_id local _,l=GetListAt(LIST_X,LIST_Y) if btnp(6) then SpawnList(L["Context"],LIST_X,LIST_Y) end if btnp(7) then SpawnList(L["Craft"],LIST_X,LIST_Y) end if not l then if btnp(2) then inv_sel = inv_sel - 1 if inv_sel < 1 then inv_sel = size end end if btnp(3) then inv_sel = inv_sel + 1 if inv_sel > size then inv_sel = 1 end end if btnp(0) then inv_sel = inv_sel - 2 if inv_sel < 1 then inv_sel = inv_sel + size end end if btnp(1) then inv_sel = inv_sel + 2 if inv_sel > size then inv_sel = inv_sel - size end end if btnp(4) then if fget(inv_id[inv_sel],F.FOOD) and Plr.fpCOLS then return end for r=0,ROWS-1 do for c=0,COLS-1 do local d=Max(Abs(fc-c), Abs(fr-r)) local sa=d-rad -- scrim amount local spid=Iif2(sa<=0,-1,sa<=3, S.SCRIM+sa-1,0) if spid>=0 then spr(spid,c*8,r*8,12) end end end end function RendEnts() for i = 1, #Ents do local e = Ents[i] local sx = e.x if sx > -8 and sx < SCRW then spr(e.sprite, sx, e.y, 0, 1, e.flipped and 1 or 0) end end end function RendLists() for i = 1, #Lists do RendList(Lists[i]) end end function RendParts() for i,p in pairs(Parts) do pix(p.x,p.y,p.clr) end end function DrawDRP() for i = 1, #drops do local d = drops[i] spr(d.id, d.x, d.y, 0) if d.count and d.count > 1 then print(d.count, d.x + 1, d.y + 6, 12, true) end end end function RendPlr() if show_tile then local tx, ty = getBestTarget() if tx and ty then local tid = 39 + (t // 30) % 2 spr(tid, tx * 8, ty * 8, 0) end end local spid = Plr.anim and (S.PLR.WALK1 + ((time() // 150) % 2)) or S.PLR.STAND spr(spid, Plr.x, Plr.y, 6, 1, Plr.ddir) if t < flash_time + 8 then local sx = (Plr.ddir == 0) and (Plr.x+4) or (Plr.x-4) spr(FLASH_SPRITE, flash_tx * 8, flash_ty * 8, 0) spr(100,sx,Plr.y,0,1,Plr.ddir) end end function RendHUD() rect(0,0,26,17,8) rectb(0,0,26,17,12) rect(0,SCRH-10,240,10,8) line(0,SCRH-11,SCRW,SCRH-11,12) spr(54,2,1,0) spr(72,2,8,0) print(Plr.hp,12,2,12) print(Plr.fp,12,9,12) local startX = (SCRW - 48) / 2 local y = SCRH - 10 for i = 1, 4 do local x = startX + (i - 1) * 12 local item = Plr.tb[i] if i == Plr.slot then rectb(x, y, 10, 10, 12) end if item and item.id > 0 then spr(item.id, x + 1, y + 1, 0) if item.count > 1 then print(item.count, x + 1, y + 5, 12, true) end end end end function RendINV() if not show_inv then return end local sx=4 local sy=20 local cx=sx+32 local cols = 2 Plr.anim = false rect(sx,sy,26,98,8) rectb(sx,sy,26,98,12) for i=1, 16 do local col = (i-1) % cols local row = (i-1) // cols local x = sx + 2 + col * 12 local y = sy + 2 + row * 12 if inv_id[i] > 0 then spr(inv_id[i], x+1, y+1, 0) if inv_count[i]>1 then print(inv_count[i], x, y+4, 12) end end if inv_sel == i then rectb(x,y,10,10,12) end end spr(GMPD.A,sx+24+3,sy+98-32,0) print("/Z - Use",sx+24+12,sy+98-31,12) spr(GMPD.B,sx+24+3,sy+98-24,0) print("/X - Close",sx+24+12,sy+98-23,12) spr(GMPD.X,sx+24+3,sy+98-16,0) print("/A - Menu",sx+24+12,sy+98-15,12) spr(GMPD.Y,sx+24+3,sy+98-8,0) print("/S - Craft",sx+24+12,sy+98-7,12) RendLists() end function wRemap(tile) if tile == 1 or tile == 2 then if (t // 60) % 2 == 0 then return 1 else return 2 end end return tile end function MenuDraw() local text="Press Z to start" local name="Melocraft" local tx=120-(#text*3) local nx=120-(#name*6) if t%60<30 then print("Press Z to start",tx,SCRH-6,12) end rect(0,0,SCRW,16,3) print(name,nx,3,12,false,2) end function GameInit() music() for i=1,INV_SIZE do inv_id[i]=0 inv_count[i]=0 end for i=1,4 do Plr.tb[i]={id=0,count=0} end Plr.tb[1] = {id = 277, count = 1} Plr.tb[2] = {id = 276, count = 1} --Plr.tb[3] = {id = 262, count = 1} Plr.tb[4] = {id = 292, count = 1} end function GameUpd() if keyp(28) then Plr.slot = 1 end if keyp(29) then Plr.slot = 2 end if keyp(30) then Plr.slot = 3 end if keyp(31) then Plr.slot = 4 end if not show_inv then updatePlr() UpdateEnts() UpdateDRP() UpdateParts() UpdateShake() end if btnp(5) then show_inv = not show_inv inv_sel = 1 if GetListAt(LIST_X,LIST_Y) then SpawnList(L["Craft"],LIST_X,LIST_Y) end end UpdateINV() cls(0) Render() RendParts() DrawDRP() RendEnts() RendPlr() RendHUD() RendINV() end function BOOT() music(0) if GAME_STATE=="GAME" then GameInit() end end function TIC() if GAME_STATE=="MENU" then map(210,120,COLS,ROWS) MenuDraw() RendSpotFx(COLS//2,ROWS//2,t) if btnp(4) then GAME_STATE="GAME" GameInit() end elseif GAME_STATE=="GAME" then GameUpd() end t=t+1 end