forked from pyrex/chameleonic
main #21
123
chameleonic.p8
123
chameleonic.p8
@ -117,7 +117,7 @@ function _rast(
|
||||
if (x0<x1) sx=1
|
||||
if (y0<y1) sy=1
|
||||
|
||||
local done=false,err
|
||||
local done,err
|
||||
if dx>dy then
|
||||
err=dx/2.0
|
||||
while x0!=x1 do
|
||||
@ -252,8 +252,7 @@ end
|
||||
normpal = {[1]=0,[8]=0,[14]=0}
|
||||
pitpal = {[8]=0,[13]=3,[4]=3,[7]=3}
|
||||
function level:draw()
|
||||
fillp(0b1111111110111111)
|
||||
rectfill(0,0,127,127,0x55)
|
||||
cls(5)
|
||||
fillp()
|
||||
pal(normpal)
|
||||
map(
|
||||
@ -289,7 +288,7 @@ function level:busy()
|
||||
for _,crate in pairs(self._crates) do
|
||||
if (#crate.todo>0) return true
|
||||
end
|
||||
return false
|
||||
return
|
||||
end
|
||||
|
||||
function level:update()
|
||||
@ -352,7 +351,7 @@ function level:recollide()
|
||||
local mxy=_mix(mx,my)
|
||||
self._coll[mxy]=
|
||||
fget(self:_mget(mx,my),7) or
|
||||
self._crates[mxy]!=nil
|
||||
self._crates[mxy]
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -390,8 +389,7 @@ function level:reanchor()
|
||||
end
|
||||
end
|
||||
|
||||
local anch_old=self._anch
|
||||
if (anch_old==nil) anch_old={}
|
||||
local anch_old=self._anch or {}
|
||||
for _,old in pairs(anch_old) do
|
||||
old.dropped=true
|
||||
end
|
||||
@ -429,19 +427,18 @@ function level:anchor_points()
|
||||
keys=all(self._anch_keys)
|
||||
return function()
|
||||
local k=keys()
|
||||
if (k==nil) return nil
|
||||
return self._anch[k.key]
|
||||
if (k) return self._anch[k.key]
|
||||
end
|
||||
end
|
||||
|
||||
function level:get_open_pit(mx,my)
|
||||
local pit=self._pits[_mix(mx,my)]
|
||||
if (pit and pit.contents==nil) return pit
|
||||
if (pit and not pit.contents) return pit
|
||||
end
|
||||
|
||||
function level:spawn_exit()
|
||||
self._wins={}
|
||||
local spawned=false
|
||||
local spawned
|
||||
local spawn_at=function(x,y)
|
||||
if (self:_mget(x,y)!=1) return
|
||||
assert(not spawned,x..","..y)
|
||||
@ -470,7 +467,7 @@ function level:spawn_exit()
|
||||
end
|
||||
|
||||
function level:mcoll(mx,my)
|
||||
return self._coll[_mix(mx,my)]!=false
|
||||
return self._coll[_mix(mx,my)]
|
||||
end
|
||||
|
||||
function level:pcoll(px,py)
|
||||
@ -557,12 +554,12 @@ function level:can_move(
|
||||
if (is_player and self:win_at(mx1,my1)) return true
|
||||
if (is_player and self:get_open_pit(mx1,my1)) return wrongbleep:adequately_warned()
|
||||
|
||||
if (self:mcoll(mx1,my1) or player.x==mx1 and player.y==my1) return false
|
||||
if (self:mcoll(mx1,my1) or player.x==mx1 and player.y==my1) return
|
||||
|
||||
if player.rope then
|
||||
local w,h=1.2,0.2
|
||||
if (dmx==0) w,h=0.2,1.2
|
||||
if (player.rope:collide_mrect(mx0+ropecheck[dmx+2],my0+ropecheck[dmy+2],w,h,exclude_src,exclude_dst)) return false
|
||||
if (player.rope:collide_mrect(mx0+ropecheck[dmx+2],my0+ropecheck[dmy+2],w,h,exclude_src,exclude_dst)) return
|
||||
end
|
||||
|
||||
return true
|
||||
@ -604,7 +601,7 @@ function player:reinit(x,y)
|
||||
self.px,self.py=0,0
|
||||
self.todo={}
|
||||
self.cooldown=4
|
||||
self.rope=nil
|
||||
self.rope=nil -- don't elide, needs to be cleared if present
|
||||
|
||||
self.fall_frame=0
|
||||
|
||||
@ -856,9 +853,9 @@ function rope:update()
|
||||
if (self.state.frame>=3) self.state={name="latched"}
|
||||
|
||||
elseif self.state.name=="latched" then
|
||||
if (self.latch==nil) wrongbleep:bleep(5) self:destroy() return
|
||||
if (not self.latch) wrongbleep:bleep(5) self:destroy() return
|
||||
|
||||
if self.latch and self.latch.rec then
|
||||
if self.latch.rec then
|
||||
self:drag_src(
|
||||
self.latch.rec.mx+0.5+self.latch.ax_offset,
|
||||
self.latch.rec.my+0.5+self.latch.ay_offset
|
||||
@ -920,7 +917,7 @@ end
|
||||
|
||||
function rope:draw(artificial_px,artificial_py)
|
||||
local points,highlight=self:_tug(true)
|
||||
local n,perc_to_show,from_end = self.state.name,1.0,false
|
||||
local n,perc_to_show,from_end = self.state.name,1.0
|
||||
if (n=="done") return
|
||||
if (n=="cast") perc_to_show=self.state.frame/2
|
||||
if (n=="destroy") perc_to_show=(1.0-self.state.frame/4)^2
|
||||
@ -1058,8 +1055,7 @@ end
|
||||
|
||||
function rope:relax()
|
||||
local n0=self.src
|
||||
while true do
|
||||
if (n0==nil) break
|
||||
while n0 do
|
||||
if n0.associated_with and n0.associated_with.dropped then
|
||||
for i in level:anchor_points() do
|
||||
if i.ax==n0.ax and i.ay==n0.ay then
|
||||
@ -1075,26 +1071,25 @@ function rope:relax()
|
||||
local n0=self.src
|
||||
while true do
|
||||
local n1=n0.next
|
||||
if (n1==nil) break
|
||||
if (not n1) break
|
||||
local n2=n1.next
|
||||
|
||||
if n0.ax==n1.ax and n0.ay==n1.ay then
|
||||
n0.next=n2
|
||||
if (n2!=nil) n2.prev=n0
|
||||
if (n2) n2.prev=n0
|
||||
else
|
||||
n0=n0.next
|
||||
end
|
||||
end
|
||||
|
||||
local n0=self.src
|
||||
while true do
|
||||
if (n0==nil) return
|
||||
while n0 do
|
||||
local n1=n0.next
|
||||
if (n1==nil) return
|
||||
if (not n1) return
|
||||
local n2=n1.next
|
||||
if (n2==nil) return
|
||||
if (not n2) return
|
||||
|
||||
if n1.associated_with!=nil then
|
||||
if n1.associated_with then
|
||||
|
||||
local x0,y0=n0.ax,n0.ay
|
||||
local x1,y1=n1.ax,n1.ay
|
||||
@ -1130,7 +1125,7 @@ function rope:_check_sane()
|
||||
local qxs,qys={},{}
|
||||
while true do
|
||||
local n1=n0.next
|
||||
if (n1==nil) break
|
||||
if (not n1) break
|
||||
|
||||
_rast(qxs,qys,flr(n0.ax*2),flr(n0.ay*2),flr(n1.ax*2),flr(n1.ay*2))
|
||||
n0=n1
|
||||
@ -1152,21 +1147,21 @@ function rope:_check_sane()
|
||||
end
|
||||
local function _blocked(qx,qy)
|
||||
for i in all(_possible_tiles(qx,qy)) do
|
||||
if (not level:mcoll(i.mx,i.my)) return false
|
||||
if (not level:mcoll(i.mx,i.my)) return
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
-- find cases where i move through an impassable zone
|
||||
for i=1,#qxs do
|
||||
if (_blocked(qxs[i],qys[i])) return false
|
||||
if (_blocked(qxs[i],qys[i])) return
|
||||
end
|
||||
|
||||
-- find cases where i am cut off diagonally
|
||||
for i=3,#qxs do
|
||||
local qx1,qy1=qxs[i-1],qys[i-1]
|
||||
if qx1%2==0 and qy1%2==0 then
|
||||
local ok=false
|
||||
local ok
|
||||
for m0 in all(_possible_tiles(qxs[i-2],qys[i-2])) do
|
||||
for m2 in all(_possible_tiles(qxs[i],qys[i])) do
|
||||
local mx0,my0=m0.mx,m0.my
|
||||
@ -1183,7 +1178,7 @@ function rope:_check_sane()
|
||||
end
|
||||
end
|
||||
|
||||
if (not ok) return false
|
||||
if (not ok) return
|
||||
end
|
||||
end
|
||||
return true
|
||||
@ -1195,8 +1190,8 @@ function would_stick(x0,y0,anchor,x2,y2)
|
||||
local dx=x2-x0
|
||||
local dy=y2-y0
|
||||
|
||||
if (x1==x0 and y1==y0) return false
|
||||
if (x1==x2 and y1==y2) return false
|
||||
if (x1==x0 and y1==y0) return
|
||||
if (x1==x2 and y1==y2) return
|
||||
|
||||
local adx,ady
|
||||
local x1_new,y1_new
|
||||
@ -1255,8 +1250,6 @@ function rope:be_pushed_by(anchor,ax_old,ay_old)
|
||||
ny05=anchor.ay
|
||||
nx05=nx0+(ny05-ny0)/(ny1-ny0) * (nx1-nx0)
|
||||
-- printh("found (y): "..tostring({nx05,ny05}))
|
||||
else
|
||||
assert(false,"wtf?")
|
||||
end
|
||||
|
||||
local n05={ax=nx05,ay=ny05,associated_with=anchor,prev=n0,next=n1}
|
||||
@ -1280,7 +1273,7 @@ function rope:_drag(n1,ax1_new,ay1_new,ax_removing,ay_removing)
|
||||
(anchor.ax==ax_removing and anchor.ay==ay_removing)
|
||||
end
|
||||
|
||||
if (ax_far0==ax_far1 and ay_far0==ay_far1) return nil
|
||||
if (ax_far0==ax_far1 and ay_far0==ay_far1) return
|
||||
|
||||
if ax_far0==ax_far1 then
|
||||
local ax_far=ax_far0
|
||||
@ -1332,13 +1325,12 @@ function rope:_drag(n1,ax1_new,ay1_new,ax_removing,ay_removing)
|
||||
n1.ay=ay1_new
|
||||
|
||||
local n0=n1.prev
|
||||
while true do
|
||||
if (n0==nil) break
|
||||
while n0 do
|
||||
local anch=_sweep_radar(
|
||||
n0.ax,n0.ay,n1.ax,n1.ay,
|
||||
n0.ax,n0.ay,ax1_old,ay1_old,ax1_new,ay1_new
|
||||
)
|
||||
if (anch==nil) break
|
||||
if (not anch) break
|
||||
local n05={ax=anch.ax,ay=anch.ay,associated_with=anch,prev=n0,next=n1}
|
||||
-- printh("creating pre: "..tostring(n0.associated_with).."->"..tostring(n05.associated_with).."->"..tostring(n1.associated_with))
|
||||
n0.next=n05
|
||||
@ -1347,13 +1339,12 @@ function rope:_drag(n1,ax1_new,ay1_new,ax_removing,ay_removing)
|
||||
end
|
||||
|
||||
local n2=n1.next
|
||||
while true do
|
||||
if (n2==nil) break
|
||||
while n2 do
|
||||
local anch=_sweep_radar(
|
||||
n1.ax,n1.ay,n2.ax,n2.ay,
|
||||
n2.ax,n2.ay,ax1_old,ay1_old,ax1_new,ay1_new
|
||||
)
|
||||
if (anch==nil) break
|
||||
if (not anch) break
|
||||
local n15={ax=anch.ax,ay=anch.ay,associated_with=anch,prev=n1,next=n2}
|
||||
-- printh("creating post: "..tostring(n1.associated_with).."->"..tostring(n15.associated_with).."->"..tostring(n2.associated_with))
|
||||
n1.next=n15
|
||||
@ -1363,7 +1354,7 @@ function rope:_drag(n1,ax1_new,ay1_new,ax_removing,ay_removing)
|
||||
end
|
||||
|
||||
function _stepfrom(x0,x1)
|
||||
local done=false
|
||||
local done
|
||||
if x0==x1 then
|
||||
return function()
|
||||
if (done) return
|
||||
@ -1378,12 +1369,12 @@ function _stepfrom(x0,x1)
|
||||
local i=flr(x0)
|
||||
local top=flr(x1)
|
||||
return function()
|
||||
if (done) return nil
|
||||
if (done) return
|
||||
i+=1
|
||||
if i>top then
|
||||
done = true
|
||||
if (x1!=flr(x1)) return mul*x1
|
||||
return nil
|
||||
return
|
||||
end
|
||||
return mul*i
|
||||
end
|
||||
@ -1409,25 +1400,25 @@ function rope:collide_mrect(mx0,my0,mw,mh,exclude_src,exclude_dst)
|
||||
|
||||
while true do
|
||||
local n1=n0.next
|
||||
if (n1==nil) return false
|
||||
if (not n1) return
|
||||
|
||||
local nd=n0
|
||||
for i=1,exclude_dst do
|
||||
nd=nd.next
|
||||
if (nd==nil) return false
|
||||
if (not nd) return
|
||||
end
|
||||
|
||||
local x1,y1,x2,y2=n0.ax,n0.ay,n1.ax,n1.ay
|
||||
local function _line_line(x3,y3,x4,y4)
|
||||
local denom=((y4-y3)*(x2-x1)-(x4-x3)*(y2-y1))
|
||||
local denom=(y4-y3)*(x2-x1)-(x4-x3)*(y2-y1)
|
||||
|
||||
local ua=
|
||||
((x4-x3)*(y1-y3)-(y4-y3)*(x1-x3))/denom
|
||||
if (ua<0 or ua>1) return false
|
||||
if (ua<0 or ua>1) return
|
||||
|
||||
local ub=
|
||||
((x2-x1)*(y1-y3)-(y2-y1)*(x1-x3))/denom
|
||||
if (ub<0 or ub>1) return false
|
||||
if (ub<0 or ub>1) return
|
||||
|
||||
return true
|
||||
end
|
||||
@ -1448,12 +1439,12 @@ function rope:tug_orientxy()
|
||||
local a1=self.dst
|
||||
local a0=self.dst.prev
|
||||
local dx=a0.ax-a1.ax
|
||||
local tdx=nil
|
||||
local tdx
|
||||
if (dx>3/8) tdx=1
|
||||
if (dx<-3/8) tdx=-1
|
||||
|
||||
local dy=a0.ay-a1.ay
|
||||
local tdy=nil
|
||||
local tdy
|
||||
if abs(dy)>abs(dx)/2 then
|
||||
if (dy>3/8) tdy=1
|
||||
if (dy<-3/8) tdy=-1
|
||||
@ -1494,11 +1485,11 @@ function rope:_tug(hypothetically)
|
||||
end
|
||||
|
||||
local latch=self.latch
|
||||
if latch!=nil and latch.el=="eyehook" then
|
||||
if latch and latch.el=="eyehook" then
|
||||
if (hypothetically) return ancs,0
|
||||
player.todo={{
|
||||
update=function(s)
|
||||
if s.rope==nil or s.rope:done() then
|
||||
if not s.rope or s.rope:done() then
|
||||
return true
|
||||
end
|
||||
end
|
||||
@ -1506,7 +1497,7 @@ function rope:_tug(hypothetically)
|
||||
self:destroy(true)
|
||||
return true
|
||||
end
|
||||
if latch!=nil and latch.el=="crate" then
|
||||
if latch and latch.el=="crate" then
|
||||
local dmx,dmy=
|
||||
sgn0(latch.dx),
|
||||
sgn0(latch.dy)
|
||||
@ -1522,7 +1513,7 @@ function rope:_tug(hypothetically)
|
||||
local mxa=(pull_anc.x+dmx)\8
|
||||
local mya=(pull_anc.y+dmy)\8
|
||||
|
||||
local invalid_move=false
|
||||
local invalid_move
|
||||
if
|
||||
(dmx!=0 and sgn0(pull_dx)!=dmx) or
|
||||
(dmy!=0 and sgn0(pull_dy)!=dmy) or
|
||||
@ -1546,15 +1537,15 @@ function rope:_tug(hypothetically)
|
||||
end
|
||||
end
|
||||
|
||||
if (hypothetically) return ancs,nil
|
||||
return false
|
||||
if (hypothetically) return ancs
|
||||
return
|
||||
end
|
||||
|
||||
function rope:_calc_push(
|
||||
an,a0,a1,af
|
||||
)
|
||||
local ops={}
|
||||
if (an==nil) return ops
|
||||
if (not an) return ops
|
||||
|
||||
if a0.x==a1.x then
|
||||
-- no far side applying pressure?
|
||||
@ -1616,12 +1607,12 @@ function rope:_calc_push(
|
||||
-- great!
|
||||
else
|
||||
local crate=level:get_crate(o.mx,o.my)
|
||||
if crate==nil then
|
||||
break
|
||||
else
|
||||
if crate then
|
||||
if not level:can_move(false,o.mx,o.my,o.dmx,o.dmy,0,0) then
|
||||
break
|
||||
end
|
||||
else
|
||||
break
|
||||
end
|
||||
add(ops2,o)
|
||||
end
|
||||
@ -1636,7 +1627,7 @@ function rope:_anchors_simplified()
|
||||
return atan2(p1.y-p0.y,p1.x-p0.x)
|
||||
end
|
||||
a=self.src
|
||||
while a!=nil do
|
||||
while a do
|
||||
local point={
|
||||
x=flr(a.ax*8+0.5),y=flr(a.ay*8+0.5),
|
||||
ax=a.ax,ay=a.ay
|
||||
@ -1646,13 +1637,13 @@ function rope:_anchors_simplified()
|
||||
if aw then
|
||||
if (aw.adx==1) point.x-=1
|
||||
if (aw.ady==1) point.y-=1
|
||||
elseif a.prev==nil and l then
|
||||
elseif not a.prev and l then
|
||||
if (l.ax_offset<0) point.x-=1
|
||||
if (l.ay_offset<0) point.y-=1
|
||||
end
|
||||
|
||||
local p0,p1=points[#points-1],points[#points]
|
||||
if p0==nil then
|
||||
if not p0 then
|
||||
add(points,point)
|
||||
elseif _slope(p0,p1)==_slope(p1,point) then -- epsilon?
|
||||
points[#points]=point
|
||||
|
Loading…
Reference in New Issue
Block a user