Skip to content

Instantly share code, notes, and snippets.

@kaansoral
Created March 18, 2019 08:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kaansoral/45f53e3f36b7d1266fb022153989134f to your computer and use it in GitHub Desktop.
Save kaansoral/45f53e3f36b7d1266fb022153989134f to your computer and use it in GitHub Desktop.
function can_move(monster,based)
{
// An XY-tree would be ideal, but the current improvements should be enough [16/07/18]
var GEO=G.geometry[monster.map]||{},c=0;
var x0=monster.x,y0=monster.y,x1=monster.going_x,y1=monster.going_y,next,minx=min(x0,x1),miny=min(y0,y1),maxx=max(x0,x1),maxy=max(y0,y1);
if(!based && monster.base) // If entity is a rectangle, check all 4 corner movements
{
var can=true;
[[-monster.base.h,monster.base.vn],[monster.base.h,monster.base.vn],[-monster.base.h,-monster.base.v],[monster.base.h,-monster.base.v]].forEach(function(mxy){
var mx=mxy[0],my=mxy[1];
if(!can || !can_move({map:monster.map,x:x0+mx,y:y0+my,going_x:x1+mx,going_y:y1+my},1)) can=false;
});
if(1) // fence logic, orphan lines - at the destination, checks whether we can move from one rectangle point to the other, if we can't move, it means a line penetrated the rectangle
{ // [20/07/18]
var px0=monster.base.h,px1=-monster.base.h; m_line_x=max;// going left
if(x1>x0) px0=-monster.base.h,px1=monster.base.h,mcy=m_line_x=min; // going right
var py0=monster.base.vn,py1=-monster.base.v; m_line_y=max; // going up
if(y1>y0) py0=-monster.base.v,py1=monster.base.vn,m_line_y=min; // going down
m_dx=-px1; m_dy=-py1; // Find the line hit, then convert to actual coordinates
if(!can || !can_move({map:monster.map,x:x1+px1,y:y1+py0,going_x:x1+px1,going_y:y1+py1},1)) can=false;
if(!can || !can_move({map:monster.map,x:x1+px0,y:y1+py1,going_x:x1+px1,going_y:y1+py1},1)) can=false;
m_line_x=m_line_y=false;
}
return can;
}
function line_hit_logic(ax,ay,bx,by)
{
line_hit_x=m_line_x(ax,bx),line_hit_x=m_line_x(line_hit_x+6*EPS,line_hit_x-6*EPS)+m_dx;
line_hit_y=m_line_y(ay,by),line_hit_y=m_line_y(line_hit_y+6*EPS,line_hit_y-6*EPS)+m_dy;
}
for(var i=bsearch_start(GEO.x_lines||[],minx);i<(GEO.x_lines||[]).length;i++)
{
var line=GEO.x_lines[i]; // c++;
if(line[0]==x1 && (line[1]<=y1 && line[2]>=y1 || line[0]==x0 && y0<=line[1] && y1>line[1])) // can't move directly onto lines - or move over lines, parallel to them
{
if(m_line_y) line_hit_logic(line[0],line[1],line[0],line[2]);
return false;
}
if(minx>line[0]) continue; // can be commented out with: while(start<arr.length && arr[start][0]<value) start++;
if(maxx<line[0]) break; // performance improvement, we moved past our range [16/07/18]
next=y0+(y1-y0)*(line[0]-x0)/(x1-x0+REPS);
if(!(line[1]-EPS<=next && next<=line[2]+EPS)) continue; // Fixed EPS [16/07/18]
//add_log("line clash")
if(m_line_y) line_hit_logic(line[0],line[1],line[0],line[2]);
return false;
}
for(var i=bsearch_start(GEO.y_lines||[],miny);i<(GEO.y_lines||[]).length;i++)
{
var line=GEO.y_lines[i]; // c++;
if(line[0]==y1 && (line[1]<=x1 && line[2]>=x1 || line[0]==y0 && x0<=line[1] && x1>line[1]))
{
if(m_line_x) line_hit_logic(line[1],line[0],line[2],line[0]);
return false;
}
if(miny>line[0]) continue;
if(maxy<line[0]) break;
next=x0+(x1-x0)*(line[0]-y0)/(y1-y0+REPS);
if(!(line[1]-EPS<=next && next<=line[2]+EPS)) continue;
if(m_line_x) line_hit_logic(line[1],line[0],line[2],line[0]);
return false;
}
// console.log(c);
return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment