forked from pyrex/chameleonic
		
	Make all APIs point-oriented
This commit is contained in:
		
							
								
								
									
										138
									
								
								chameleonic.p8
									
									
									
									
									
								
							
							
						
						
									
										138
									
								
								chameleonic.p8
									
									
									
									
									
								
							@@ -102,6 +102,13 @@ function _mnmx(x,y)
 | 
			
		||||
 return x,y
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function _anch_eq(a0,a1) 
 | 
			
		||||
 if (a0==nil) return a1==nil
 | 
			
		||||
 if (a1==nil) return false
 | 
			
		||||
 return a0.ax==a1.ax and a0.ay==a1.ay 
 | 
			
		||||
end
 | 
			
		||||
function _anch_unpack(a0) return a0.ax,a0.ay end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function _rast(
 | 
			
		||||
 xs,ys,x0,y0,x1,y1
 | 
			
		||||
@@ -394,7 +401,7 @@ function level:recollide_reanchor()
 | 
			
		||||
  local old=(self._anch or {})[k]
 | 
			
		||||
  if old then
 | 
			
		||||
   anch_new[k]=new
 | 
			
		||||
   if (old.ax!=new.ax or old.ay!=new.ay) add(moves,{old.ax,old.ay,new.ax,new.ay,old,key=k})
 | 
			
		||||
   if (not _anch_eq(old,new)) add(moves,{old,new,key=k})
 | 
			
		||||
  end
 | 
			
		||||
 end
 | 
			
		||||
 self._anch=anch_new
 | 
			
		||||
@@ -428,9 +435,9 @@ function level:anchor_points()
 | 
			
		||||
 end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function level:anchor_at(ax,ay)
 | 
			
		||||
function level:anchor_at(point)
 | 
			
		||||
 for i in self:anchor_points() do
 | 
			
		||||
  if (i.ax==ax and i.ay==ay) return i
 | 
			
		||||
  if (_anch_eq(point,i)) return i
 | 
			
		||||
 end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@@ -672,8 +679,8 @@ function player:update()
 | 
			
		||||
    while not level:mcoll(x,y) do x+=dx y+=dy end
 | 
			
		||||
 | 
			
		||||
    self.rope=rope:new(
 | 
			
		||||
     x+0.5-dx*0.5,y+0.5-dy*0.5,
 | 
			
		||||
     self.x+0.5,self.y+0.5,
 | 
			
		||||
     {ax=x+0.5-dx*0.5,ay=y+0.5-dy*0.5},
 | 
			
		||||
     {ax=self.x+0.5,ay=self.y+0.5},
 | 
			
		||||
     level:get_latch(dx,dy,x*8,y*8)
 | 
			
		||||
    )
 | 
			
		||||
    
 | 
			
		||||
@@ -815,19 +822,15 @@ rope={}
 | 
			
		||||
rope.__index=rope
 | 
			
		||||
 | 
			
		||||
function rope:new(
 | 
			
		||||
 src_ax,src_ay,dst_ax,dst_ay,latch
 | 
			
		||||
 src,dst,latch
 | 
			
		||||
)
 | 
			
		||||
 local r={
 | 
			
		||||
  id=0,
 | 
			
		||||
  anchors={
 | 
			
		||||
   {ax=src_ax,ay=src_ay},
 | 
			
		||||
   {ax=dst_ax,ay=dst_ay}
 | 
			
		||||
  },
 | 
			
		||||
  state={name="cast",frame=0},
 | 
			
		||||
  latch=latch,
 | 
			
		||||
 }
 | 
			
		||||
 r.src=r.anchors[1]
 | 
			
		||||
 r.dst=r.anchors[2]
 | 
			
		||||
 r.src=src
 | 
			
		||||
 r.dst=dst
 | 
			
		||||
 r.src.next=r.dst
 | 
			
		||||
 r.dst.prev=r.src
 | 
			
		||||
 setmetatable(r,rope)
 | 
			
		||||
@@ -991,7 +994,7 @@ function rope:draw(artificial_px,artificial_py)
 | 
			
		||||
 local sy=0
 | 
			
		||||
 while true do
 | 
			
		||||
  if (n1==nil) break
 | 
			
		||||
  local anch=level:anchor_at(n1.ax,n1.ay)
 | 
			
		||||
  local anch=level:anchor_at(n1)
 | 
			
		||||
  local x=n1.ax*8
 | 
			
		||||
  local y=n1.ay*8
 | 
			
		||||
  if anch then
 | 
			
		||||
@@ -1042,8 +1045,8 @@ end
 | 
			
		||||
 | 
			
		||||
function rope:drag(n1,ax_new,ay_new)
 | 
			
		||||
 self:relax()
 | 
			
		||||
 self:_drag(n1,ax_new,n1.ay)
 | 
			
		||||
 self:_drag(n1,ax_new,ay_new)
 | 
			
		||||
 self:_drag(n1,{ax=ax_new,ay=n1.ay})
 | 
			
		||||
 self:_drag(n1,{ax=ax_new,ay=ay_new})
 | 
			
		||||
 self:relax()
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@@ -1053,7 +1056,7 @@ function rope:relax()
 | 
			
		||||
  local n1=n0.next
 | 
			
		||||
  if (not n1) break
 | 
			
		||||
  local n2=n1.next
 | 
			
		||||
  if n0.ax==n1.ax and n0.ay==n1.ay then 
 | 
			
		||||
  if _anch_eq(n0,n1) then
 | 
			
		||||
   n0.next=n2 
 | 
			
		||||
   if (n2) n2.prev=n0
 | 
			
		||||
  else
 | 
			
		||||
@@ -1068,14 +1071,10 @@ function rope:relax()
 | 
			
		||||
  local n2=n1.next
 | 
			
		||||
  if (not n2) return
 | 
			
		||||
 | 
			
		||||
  local x0,y0=n0.ax,n0.ay
 | 
			
		||||
  local x1,y1=n1.ax,n1.ay
 | 
			
		||||
  local x2,y2=n2.ax,n2.ay
 | 
			
		||||
 | 
			
		||||
  local anch=level:anchor_at(n1.ax,n1.ay)
 | 
			
		||||
  local would,x1_new,y1_new=would_stick(anch,x0,y0,x1,y1,x2,y2)
 | 
			
		||||
  if not would and not (n1.ax==x1_new and n1.ay==y1_new) then
 | 
			
		||||
   self:_drag(n1,x1_new,y1_new,n1.ax,n1.ay)
 | 
			
		||||
  local anch=level:anchor_at(n1)
 | 
			
		||||
  local wouldstick,axy_new=would_stick(anch,n0,n1,n2)
 | 
			
		||||
  if not (wouldstick or _anch_eq(n1,axy_new)) then
 | 
			
		||||
   self:_drag(n1,axy_new,{ax=n1.ax,ay=n1.ay})
 | 
			
		||||
   n0=n1.prev
 | 
			
		||||
   n2=n1.next
 | 
			
		||||
   n0.next=n2
 | 
			
		||||
@@ -1097,7 +1096,9 @@ function rope:_check_sane()
 | 
			
		||||
  local n1=n0.next
 | 
			
		||||
  if (not n1) break 
 | 
			
		||||
 | 
			
		||||
  _rast(qxs,qys,flr(n0.ax*2),flr(n0.ay*2),flr(n1.ax*2),flr(n1.ay*2)) 
 | 
			
		||||
  local n0ax,n0ay=_anch_unpack(n0)
 | 
			
		||||
  local n1ax,n1ay=_anch_unpack(n1)
 | 
			
		||||
  _rast(qxs,qys,flr(n0ax*2),flr(n0ay*2),flr(n1ax*2),flr(n1ay*2)) 
 | 
			
		||||
  n0=n1
 | 
			
		||||
 end
 | 
			
		||||
 | 
			
		||||
@@ -1154,8 +1155,10 @@ function rope:_check_sane()
 | 
			
		||||
 return true
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function would_stick(anchor,x0,y0,x1,y1,x2,y2)
 | 
			
		||||
 x1,y1=x1 or anchor.ax,y1 or anchor.ay
 | 
			
		||||
function would_stick(anchor,xy0,xy1,xy2)
 | 
			
		||||
 local x0,y0=_anch_unpack(xy0)
 | 
			
		||||
 local x1,y1=_anch_unpack(xy1 or anchor)
 | 
			
		||||
 local x2,y2=_anch_unpack(xy2)
 | 
			
		||||
 | 
			
		||||
 local dx,dy=x2-x0,y2-y0
 | 
			
		||||
 | 
			
		||||
@@ -1181,7 +1184,7 @@ function would_stick(anchor,x0,y0,x1,y1,x2,y2)
 | 
			
		||||
 | 
			
		||||
 return 
 | 
			
		||||
  anchor and anchor.adx==adx and anchor.ady==ady,
 | 
			
		||||
  x1_new,y1_new
 | 
			
		||||
  {ax=x1_new,ay=y1_new}
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function rope:experience_anchor_moves(moves)
 | 
			
		||||
@@ -1194,15 +1197,15 @@ function rope:_be_dragged_by(moves)
 | 
			
		||||
 local n=self.src
 | 
			
		||||
 while n do
 | 
			
		||||
  for t in all(moves) do
 | 
			
		||||
   local ax_old,ay_old,ax_new,ay_new=unpack(t)
 | 
			
		||||
   if (ax_old==n.ax and ay_old==n.ay) n.dest={ax_new,ay_new} break
 | 
			
		||||
   local axy_old,axy_new=unpack(t)
 | 
			
		||||
   if (_anch_eq(axy_old,n)) n.dest=axy_new break
 | 
			
		||||
  end
 | 
			
		||||
  n=n.next
 | 
			
		||||
 end
 | 
			
		||||
 | 
			
		||||
 n=self.src
 | 
			
		||||
 while n do
 | 
			
		||||
  if (n.dest) self:_drag(n,unpack(n.dest)) n.dest=nil
 | 
			
		||||
  if (n.dest) self:_drag(n,n.dest) n.dest=nil
 | 
			
		||||
  n=n.next
 | 
			
		||||
 end
 | 
			
		||||
end
 | 
			
		||||
@@ -1213,25 +1216,30 @@ function rope:_be_pushed_by(moves)
 | 
			
		||||
 end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function rope:_be_pushed_by1(ax_old,ay_old,ax_new,ay_new,anch)
 | 
			
		||||
function rope:_be_pushed_by1(anch_old,anch_new)
 | 
			
		||||
 local n0=self.src
 | 
			
		||||
 while true do
 | 
			
		||||
 | 
			
		||||
 local ax_old,ay_old=_anch_unpack(anch_old)
 | 
			
		||||
 local ax_new,ay_new=_anch_unpack(anch_new)
 | 
			
		||||
 | 
			
		||||
 while n0 do
 | 
			
		||||
  n1=n0.next
 | 
			
		||||
  if (not n1) return
 | 
			
		||||
 | 
			
		||||
  local nx0,ny0=n0.ax,n0.ay
 | 
			
		||||
  local nx1,ny1=n1.ax,n1.ay
 | 
			
		||||
  local nx0,ny0=_anch_unpack(n0)
 | 
			
		||||
  local nx1,ny1=_anch_unpack(n1)
 | 
			
		||||
 | 
			
		||||
  local nxmn,nxmx = _mnmx(nx0,nx1)
 | 
			
		||||
  local nymn,nymx = _mnmx(ny0,ny1)
 | 
			
		||||
 | 
			
		||||
  -- nprinth("has: "..tostring{anch==nil,n0==nil,n1==nil})
 | 
			
		||||
  if
 | 
			
		||||
   (ax_new!=ax_old or (nxmn<ax_new and ax_new<nxmx)) and 
 | 
			
		||||
   (ay_new!=ay_old or (nymn<ay_new and ay_new<nymx)) and 
 | 
			
		||||
 | 
			
		||||
   (_which_side(ax_old,ay_old,nx0,ny0,nx1,ny1)!= 
 | 
			
		||||
    _which_side(ax_new,ay_new,nx0,ny0,nx1,ny1) 
 | 
			
		||||
   ) and would_stick(anch,nx0,ny0,nil,nil,nx1,ny1)
 | 
			
		||||
   (_which_side(anch_old,n0,n1)!= 
 | 
			
		||||
    _which_side(anch_new,n0,n1) 
 | 
			
		||||
   ) and would_stick(anch_new,n0,nil,n1)
 | 
			
		||||
  then
 | 
			
		||||
   local nx05,ny05
 | 
			
		||||
   if ax_new==ax_old then
 | 
			
		||||
@@ -1247,21 +1255,20 @@ function rope:_be_pushed_by1(ax_old,ay_old,ax_new,ay_new,anch)
 | 
			
		||||
   n1.prev=n05
 | 
			
		||||
   -- printh("creating: "..tostring{anch,{n0.ax,n0.ay},{n05.ax,n05.ay},{n1.ax,n1.ay}})
 | 
			
		||||
   -- printh("dragging: "..tostring{anch,{n05.ax,n05.ay},{ax_new,ay_new}})
 | 
			
		||||
   self:_drag(n05,ax_new,ay_new)
 | 
			
		||||
   self:_drag(n05,{ax=ax_new,ay=ay_new})
 | 
			
		||||
  else
 | 
			
		||||
   n0=n0.next
 | 
			
		||||
  end
 | 
			
		||||
 end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function rope:_drag(n1,ax1_new,ay1_new,ax_removing,ay_removing)
 | 
			
		||||
 local function _sweep_radar(ax_lhs,ay_lhs,ax_rhs,ay_rhs,ax_pivot,ay_pivot,ax_src,ay_src,ax_dst,ay_dst)
 | 
			
		||||
  if (ax_src==ax_dst and ay_src==ay_dst) return 
 | 
			
		||||
function rope:_drag(n1,new,removing)
 | 
			
		||||
 local function _sweep_radar(lhs,rhs,pivot,src,dst)
 | 
			
		||||
  -- printh(tostring{{lhs.ax,lhs.ay},{rhs.ax,rhs.ay},{pivot.ax,pivot.ay},{src.ax,src.ay},{dst.ax,dst.ay}})
 | 
			
		||||
  if (_anch_eq(src,dst)) return
 | 
			
		||||
 | 
			
		||||
  local function _uncreatable(anchor)
 | 
			
		||||
   return anchor.ax==ax_lhs and anchor.ay==ay_lhs or
 | 
			
		||||
    anchor.ax==ax_rhs and anchor.ay==ay_rhs or
 | 
			
		||||
    anchor.ax==ax_removing and anchor.ay==ay_removing
 | 
			
		||||
   return _anch_eq(anchor,lhs) or _anch_eq(anchor,lhs) or _anch_eq(anchor,removing)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  local function _sweep(extent_old,extent_new,cb_in_bounds,cb_would_stick,cb_side)
 | 
			
		||||
@@ -1278,34 +1285,31 @@ function rope:_drag(n1,ax1_new,ay1_new,ax_removing,ay_removing)
 | 
			
		||||
   end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  if ax_src==ax_dst then
 | 
			
		||||
  if src.ax==dst.ax then
 | 
			
		||||
   local ax_pivot,ax_dst=pivot.ax,dst.ax
 | 
			
		||||
   return _sweep(
 | 
			
		||||
    ay_src,ay_dst,
 | 
			
		||||
    src.ay,dst.ay,
 | 
			
		||||
    function(anchor) return mid(ax_pivot,anchor.ax,ax_dst)==anchor.ax end,
 | 
			
		||||
    function(anchor,ay) return would_stick(anchor,ax_pivot,ay_pivot,nil,nil,ax_dst,ay) end,
 | 
			
		||||
    function(anchor,ay) return _which_side(anchor.ax,anchor.ay,ax_pivot,ay_pivot,ax_dst,ay) end
 | 
			
		||||
    function(anchor,ay) return would_stick(anchor,pivot,nil,{ax=ax_dst,ay=ay}) end,
 | 
			
		||||
    function(anchor,ay) return _which_side(anchor,pivot,{ax=ax_dst,ay=ay}) end
 | 
			
		||||
   )
 | 
			
		||||
  else
 | 
			
		||||
   assert(ay_src==ay_dst)
 | 
			
		||||
   local ay_pivot,ay_dst=pivot.ay,dst.ay
 | 
			
		||||
   return _sweep(
 | 
			
		||||
    ax_src,ax_dst,
 | 
			
		||||
    src.ax,dst.ax,
 | 
			
		||||
    function(anchor) return mid(ay_pivot,anchor.ay,ay_dst)==anchor.ay end,
 | 
			
		||||
    function(anchor,ax) return would_stick(anchor,ax_pivot,ay_pivot,nil,nil,ax,ay_dst) end,
 | 
			
		||||
    function(anchor,ax) return _which_side(anchor.ax,anchor.ay,ax_pivot,ay_pivot,ax,ay_dst) end
 | 
			
		||||
    function(anchor,ax) return would_stick(anchor,pivot,nil,{ax=ax,ay=ay_dst}) end,
 | 
			
		||||
    function(anchor,ax) return _which_side(anchor,pivot,{ax=ax,ay=ay_dst}) end
 | 
			
		||||
   )
 | 
			
		||||
  end
 | 
			
		||||
 end
 | 
			
		||||
 | 
			
		||||
 local ax1_old,ay1_old=n1.ax,n1.ay
 | 
			
		||||
 n1.ax=ax1_new
 | 
			
		||||
 n1.ay=ay1_new
 | 
			
		||||
 local old={ax=n1.ax,ay=n1.ay}
 | 
			
		||||
 n1.ax,n1.ay=new.ax,new.ay
 | 
			
		||||
 | 
			
		||||
 local n0=n1.prev
 | 
			
		||||
 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
 | 
			
		||||
   )
 | 
			
		||||
  local anch=_sweep_radar(n0,n1,n0,old,new)
 | 
			
		||||
  if (not anch) break
 | 
			
		||||
  local n05={ax=anch.ax,ay=anch.ay,prev=n0,next=n1}
 | 
			
		||||
  n0.next=n05
 | 
			
		||||
@@ -1315,10 +1319,7 @@ function rope:_drag(n1,ax1_new,ay1_new,ax_removing,ay_removing)
 | 
			
		||||
 | 
			
		||||
 local n2=n1.next
 | 
			
		||||
 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
 | 
			
		||||
  )
 | 
			
		||||
  local anch=_sweep_radar(n1,n2,n2,old,new)
 | 
			
		||||
  if (not anch) break
 | 
			
		||||
  local n15={ax=anch.ax,ay=anch.ay,prev=n1,next=n2}
 | 
			
		||||
  n1.next=n15
 | 
			
		||||
@@ -1354,7 +1355,12 @@ function _stepfrom(x0,x1)
 | 
			
		||||
 end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function _which_side(x,y,x0,y0,x1,y1)
 | 
			
		||||
function _which_side(xy,x0y0,x1y1)
 | 
			
		||||
 local x,y=_anch_unpack(xy)
 | 
			
		||||
 local x0,y0=_anch_unpack(x0y0)
 | 
			
		||||
 local x1,y1=_anch_unpack(x1y1)
 | 
			
		||||
 -- printh("anchors: "..tostring{x,y,x0,y0,x1,y1})
 | 
			
		||||
 | 
			
		||||
 return sgn0((x1-x0)*(y-y0) - (y1-y0)*(x-x0))
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@@ -1606,7 +1612,7 @@ function rope:_anchors_simplified()
 | 
			
		||||
   x=flr(a.ax*8+0.5),y=flr(a.ay*8+0.5),
 | 
			
		||||
   ax=a.ax,ay=a.ay
 | 
			
		||||
  }
 | 
			
		||||
  local aw=level:anchor_at(a.ax,a.ay)
 | 
			
		||||
  local aw=level:anchor_at(a)
 | 
			
		||||
  local l=self.latch
 | 
			
		||||
  if aw then
 | 
			
		||||
   if (aw.adx==1) point.x-=1
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user