And for those who want just the code:
PHP Code:
//NPC made by Dusty
if (created) {
this.speed=.4; // Customize the NPCs speed
// MODE 0 : idle
// MODE 1 : aimless walking
// MODE 2 : chasing via player-npc
// MODE 3 : chasing via tracking players movements
this.mode=0;
setstring this.animations,idle,walkslow,walk,walk;
showcharacter;
timeout=0.05;
}
if (timeout) {
if (this.mode in {0,1}) {
this.delta={(playerx+2)-(x+1.5),(playery+2)-(y+2),((this.delta[0]^2)+(this.delta[1]^2))^.5};
if (this.mode==0) {
if (random(0,100)<3) {
dir=int(random(0,4));
this.mode=1;
}
}
if (this.mode=1) {
if (onwall(x+1.5+vecx(dir)*2,y+2+vecy(dir)*2)) dir=(dir+2)%4;
else {
x+=vecx(dir)*(this.speed/2);
y+=vecy(dir)*(this.speed/2);
}
if (random(0,100)<6) dir=int(random(0,4));
if (random(0,100)<2) this.mode=0;
}
this.checkdir=getdir(this.delta[0],this.delta[1]);
if (this.checkdir==dir && this.delta[2]<15) checkbetween();
} else {
calculatetracking();
dir=getdir(this.delta[0],this.delta[1]);
}
if (this.mode==2) {
this.delta={(playerx+2)-(x+1.5),(playery+2)-(y+2),((this.delta[0]^2)+(this.delta[1]^2))^.5};
if (this.delta[2]>3) {
checkbetween();
this.addx=(this.delta[0]/this.delta[2])*this.speed;
this.addy=(this.delta[1]/this.delta[2])*this.speed;
x+=this.addx;
y+=this.addy;
}
}
if (this.mode==3) {
this.delta={(this.trail_x[this.step]+2)-(x+1.5),(this.trail_y[this.step]+2)-(y+2),((this.delta[0]^2)+(this.delta[1]^2))^.5};
this.addx=(this.delta[0]/this.delta[2])*this.speed;
this.addy=(this.delta[1]/this.delta[2])*this.speed;
x+=this.addx;
y+=this.addy;
if (this.delta[2]=<.5) {
this.step++;
checkbetween();
}
}
setcharani #I(this.animations,this.mode),;
timeout=0.05;
}
function calculatetracking() {
this.timer=(this.timer+.5)%2;
if (this.timer==1) {
if (playerx!=this.trail_x[arraylen(this.trail_x)-1]||playery!=this.trail_y[arraylen(this.trail_y)-1]) {
setarray this.trail_x,arraylen(this.trail_x)+1;
setarray this.trail_y,arraylen(this.trail_y)+1;
this.trail_x[arraylen(this.trail_x)-1]=playerx;
this.trail_y[arraylen(this.trail_y)-1]=playery;
}
}
}
function trackplayer() {
this.trackdistance=100;
for (i=0;i<arraylen(this.trail_x);i++) {
this.delta={(this.trail_x[i]+2)-(x+1.5),(this.trail_y[i]+2)-(y+2),((this.delta[0]^2)+(this.delta[1]^2))^.5};
if (this.delta[2]<this.trackdistance) {
for (w=0;w<int(this.delta[2]);w++) {
this.check={x+1.5+(this.delta[0]/this.delta[2])*w,y+2+(this.delta[1]/this.delta[2])*w};
if (!onwall(this.check[0],this.check[1])) {
this.trackdistance=this.delta[2];
this.step=i+1;
}
}
}
}
this.mode=3;
}
function checkbetween() {
this.checkdelta={(playerx+2)-(x+1.5),(playery+2)-(y+2),((this.checkdelta[0]^2)+(this.checkdelta[1]^2))^.5};
this.checkingwall=0;
for (i=0;i<int(this.checkdelta[2]);i++) {
this.check={x+1.5+(this.checkdelta[0]/this.checkdelta[2])*i,y+2+(this.checkdelta[1]/this.checkdelta[2])*i};
if (testplayer(this.check[0],this.check[1])<0) this.checkingwall+=onwall(this.check[0],this.check[1]);
}
if (this.checkingwall>0) {
if (this.mode==2) trackplayer();
} else {
if (this.mode==3) {
this.mode=2;
setarray this.trail_x,0;
setarray this.trail_y,0;
}
if (this.mode<2) this.mode=2;
}
}
Again, sorry it's not GS2/serverside compatible.