Code:
const int M_NORMAL = 0;
const int M_MOVINGTOPOS = 1;
const int M_SOLIDATPOS = 2;
ffc script FollowLink{
void run(){
int orig = this->Data;
int lastDir;
int MovementState;
int CurrentScreen;
int idle;
while(true){
int x = Link->X; int y = Link->Y;
if(Link->Dir == DIR_UP||Link->Dir == DIR_DOWN) y -= Link->Dir*32-16;
else x -= (Link->Dir-2)*32-16;
if(CurrentScreen != Game->GetCurScreen()) MovementState = NormalPlacement(this,x,y);
if(MovementState == M_NORMAL){
if(lastDir != Link->Dir) MovementState = MoveToPosition(this,x,y);
else MovementState = NormalPlacement(this,x,y);
}else if(MovementState == M_MOVINGTOPOS) MovementState = WhileMoving(this,x,y,idle);
else if(MovementState == M_SOLIDATPOS) MovementState = CheckPos(this,x,y);
SetGraphics(this,orig);
CurrentScreen = Game->GetCurScreen();
idle = (idle+1)%6;
lastDir = Link->Dir;
Waitframe();
}
}
int NormalPlacement(ffc this,int x,int y){
if(Solid(this,x,y)) return M_SOLIDATPOS;
this->X = x; this->Y = y;
return M_NORMAL;
}
int MoveToPosition(ffc this,int x,int y){
if(Solid(this,x,y)) return M_SOLIDATPOS;
int speed = Distance(x,y,this->X,this->Y)/8;
if(speed < 0.5) return M_NORMAL;
else if(speed < 1.2) speed *= 2;
FFCToPoint(this,x,y,speed);
return M_MOVINGTOPOS;
}
int WhileMoving(ffc this,int x,int y,int idle){
if(Abs(this->X-x) < 3 && Abs(this->Y-y) < 3){
this->Vx = 0; this->Vy = 0;
return M_NORMAL;
}
if(idle == 0) return MoveToPosition(this,x,y);
return M_MOVINGTOPOS;
}
int CheckPos(ffc this,int x,int y){
if(Solid(this,x,y)) return M_SOLIDATPOS;
return MoveToPosition(this,x,y);
}
bool Solid(ffc this,int x,int y){
if(Screen->isSolid(x+8,y+8)){
this->Vx = 0; this->Vy = 0;
return true;
}
}
void SetGraphics(ffc this,int orig){
int moving;
if(Link->InputUp || Link->InputDown || Link->InputLeft || Link->InputRight
|| this->Vx != 0 || this->Vy != 0) moving = 4;
this->Data = orig+moving+Link->Dir;
}
int FFCToPoint(ffc f,int x,int y,int speed){
if(speed == 0) return -1;
int dx = x-f->X; int dy = y-f->Y;
int dis = Abs(dx) + Abs(dy);
int d = dis/speed;
f->Vx = dx/d; f->Vy = dy/d;
return d;
}
}