PDA

View Full Version : NPC Follower



Joe123
04-16-2009, 08:51 AM
Example Quest (http://zc.celestialrealm.net/scripts/10_NPCFollowerex.qst)

This script will have an ffc follow right behind Link whilst walking around.
It's based on me watching the behaviour from Terranigma, but it should work the same as when you have Marin in tow in Link's Awakening, for example.

You should arrange the NPC's combos like this:


Still Up | Still Down | Still Left | Still Right
Walking Up | Walking Down | Walking Left | Walking Right
And set the ffc's combo to the first one.
If you want it to work for more than one screen, the 'Carryover' flag is advised.
You could probably set it up to work ok-ish with the 'No FFC Carryover' screen flag, but if you wanted anything more complicated you'd need some sort of script to toggle when this one functions, but obviously that's very much dependant on your quest so I can't write it to work for everyone.

Thanks to LinkTheMaster for the 'FFCToPoint' function


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;
}
}

Din
04-16-2009, 10:19 AM
It's not working in the example version. What build does this use?

Joe123
04-16-2009, 11:07 AM
Oh wouldja look at that, I accidently cleared the buffer before I posted the test quest.
Now that was a bit silly of me wasn't it.

Try again now.

Din
04-16-2009, 04:36 PM
Heh, you uploaded the key to the heavens scripts into the buffer. ;)

If it's included in there, it still isn't working, it might be me, but I dunno.

Still, this script sounds great.

Beta Link
04-16-2009, 06:22 PM
but it should work the same as when you have Marin in tow in Link's Awakening, for example.
Mwahahahaha!!! :naughty:

*Yoinks*


You are made of epic win, Joe.

Joe123
04-17-2009, 04:24 AM
Oh, oops =P

Well it's working for me now...


Glad you like it Beta Link =)