8. Scripting an Archer
To make your baddy use a bow, we're going to go back to the if (created)
script (from the basic baddy), and change it slightly.
//New Beginning Part
if (created){
showcharacter;
this.speed=.5;
setcharprop #7,wbow1.gif; //removed
this.pow, and this sets the gif for the bow to be used by the baddy.
hearts=3;
hurtdx=0;
hurtdy=0;
timeout=.05;
}
//End of Script
Now we have our bow in place.
We just need to mess with the timeout loop again to allow use of the
bow. Also, I'm changing the hearts>0 part in the with timeout (like
I did with the sword) for ease of use.
if (timeout&&hearts>0&&this.shoot!=1){ //this
shows all the stuff to be done in the timeout while the npc has hearts,
and is not using his bow.
sprite=(sprite%8)+1;
this.distx=abs(playerx-x);
this.disty=abs(playery-y);
if (this.distx<=this.disty){
if (playery<y)dir=0;
if (playery>y)dir=2;
}else{
if (playerx<x)dir=1;
if (playerx>x)dir=3;
}
if (this.distx==0){
this.addy=this.speed;
}else if (this.disty==0){
this.addx=this.speed;
}else if (this.distx>this.disty){
this.ratio=this.disty/this.distx;
this.addx=this.speed;
this.addy=this.speed*this.ratio;
}else if (this.disty>this.distx){
this.ratio=this.distx/this.disty;
this.addy=this.speed;
this.addx=this.speed*this.ratio;
}
if (y<playery&&!onwall(x+1.5,y+3+this.addy)) y+=this.addy;
if (y>playery&&!onwall(x+1.5,y-this.addy)) y-=this.addy;
if (x<playerx&&!onwall(x+3+this.addx,y+1.5)) x+=this.addx;
if (x>playerx&&!onwall(x-this.addx,y+1.5)) x-=this.addx;
if((x-players[this.player].x<1&&players[this.player].x-x<1)||(y-players[this.player].y<1&&players[this.player].y-y<1)){
//this
checks to see if the player shares the x cordinate, or y cordinate with
the baddy (that means the NPC has a straight shot at the player).
this.shoot=1; //tells
the baddy to be ready to shoot.
sprite=33; //the shooting
sprite
sleep
1; //players dont tend to shoot instantly,
this is a way to make the baddy pause.
}
timeout=.05;
}
if (timeout&&hearts>0&&this.shoot==1){ //what
to do when the baddy is supposed to shoot
shootarrow dir; //this will shoot
an arrow the direction the baddy is facing. Of course you can change
this to shoot any other projectile.
sleep .1; //so the baddy doesnt
withdraw his bow instantly
this.shoot=0; // to reset the loops
sprite=1; //first walking sprite
timeout=.05; //to continue the other
timeout loop
}
//End of Script
The thing with this script is the "sleep" command. It works good
and all, but I personally don't like it because you can't hurt the baddy
while he's preparing to shoot because he's sleeping. If you want
to know why, read sections 2Bvi,
2Bvii.
This of course can be fixed, but that's for a script in a future update.
An occuring problem is that a player can reflect the baddy's arrows,
thus hurting him. So we need to fix that, as well as the same problem
that occurs in the sword script (that happens when the archer is hurt while
shooting).
//New Hurting Script
if ((washit||shotbyplayer||exploded||waspelt)&&hearts>0){
//Changed wasshot to shotbyplayer
if (washit){
hurtdx=x;
hurtdy=y;
hearts-=playerswordpower;
}
if (shotbyplayer){
//Changed wasshot to shotbyplayer
hearts--;
}
if (exploded){
hearts--;
}
if (waspelt){
if (peltwithbush) hearts-=.5;
if (peltwithsign || peltwithvase
|| peltwithstone) hearts-=1;
if (peltwithblackstone) hearts
-=1.5;
}
sprite=39;
this.hit=1;
while(this.hit==1){
i+=.5;
if (x>playerx&&!onwall(x+2.5,y+1.5)) x+=.5;
if (x<playerx&&!onwall(x-.5,y+1.5)) x-=.5;
if (y>playery&&!onwall(x+1.5,y+2.5)) y+=.5;
if (y<playery&&!onwall(x-1.5,y-.5)) y-=.5;
if (i>=3.5){
this.hit=0;
i=0;
}
sleep .05;
}
this.shoot=0; //Necessary to fix
some glitches when hit while shooting.
timeout=.05;
}
//End of Script
Well now those problems are fixed.
Lets make the script for a basic archer:
//Basic Archer Script
if (created){
showcharacter;
setcharprop #7,wbow1.gif;
setcharprop #n,Basic Archer;
hearts=3;
hurtdx=0;
hurtdy=0;
}
if (playerenters||wasthrown){
this.speed=.5;
timeout=.05;
}
if (timeout&&this.shoot!=1&&isleader){
if (hearts>0){
sprite=(sprite%8)+1;
this.distx=abs(playerx-x);
this.disty=abs(playery-y);
if (this.distx<=this.disty){
if (playery<y)dir=0;
if (playery>y)dir=2;
}else{
if (playerx<x)dir=1;
if (playerx>x)dir=3;
}
if (this.distx==0){
this.addy=this.speed;
}else if (this.disty==0){
this.addx=this.speed;
}else if (this.distx>this.disty){
this.ratio=this.disty/this.distx;
this.addx=this.speed;
this.addy=this.speed*this.ratio;
}else if (this.disty>this.distx){
this.ratio=this.distx/this.disty;
this.addy=this.speed;
this.addx=this.speed*this.ratio;
}
if (y<playery&&!onwall(x+1.5,y+3+this.addy))
y+=this.addy;
if (y>playery&&!onwall(x+1.5,y-this.addy))
y-=this.addy;
if (x<playerx&&!onwall(x+3+this.addx,y+1.5))
x+=this.addx;
if (x>playerx&&!onwall(x-this.addx,y+1.5))
x-=this.addx;
if((x-players[this.player].x<1&&players[this.player].x-x<1)||(y-players[this.player].y<1&&players[this.player].y-y<1)){
this.shoot=1;
sprite=33;
sleep 1;
}
timeout=.05;
}
}
if (timeout&&isleader&&hearts>0&&this.shoot==1){
shootarrow dir;
sleep .1;
this.shoot=0;
sprite=1;
timeout=.05;
}
if ((washit||shotbyplayer||exploded||waspelt)&&hearts>0){
if (washit){
hurtdx=x;
hurtdy=y;
hearts-=playerswordpower;
}
if (shotbyplayer){
hearts--;
}
if (exploded){
hearts--;
}
if (waspelt){
if (peltwithbush) hearts-=.5;
if (peltwithsign || peltwithvase || peltwithstone)
hearts-=1;
if (peltwithblackstone) hearts -=1.5;
}
sprite=39;
this.shoot=0;
this.hit=1;
while(this.hit==1){
i+=.5;
if (x>playerx&&!onwall(x+2.5,y+1.5)) x+=.5;
if (x<playerx&&!onwall(x-.5,y+1.5)) x-=.5;
if (y>playery&&!onwall(x+1.5,y+2.5)) y+=.5;
if (y<playery&&!onwall(x-1.5,y-.5)) y-=.5;
if (i>=3.5){
this.hit=0;
i=0;
}
sleep .05;
}
timeout=.05;
}
if (hurtdx!=0||hurtdy!=0){
sprite=39;
hurtdx=0;
hurtdy=0;
}
if (timeout&&hearts<=0&&isleader){
while(d<=8){
dir=(dir+3)%4;
d++;
sleep .1;
}
i = random(0,100);
if (i<10) lay greenrupee;
else if (i<15) lay bluerupee;
else if (i<30) lay heart;
sprite=40;
}
//End of Script
This is the script of the NPC in level basicarchers.graal with the
name of Basic Archer.