Script to make entity walk towards point and perform attack from there

ABK

Well-known member
Hey guys im working on script that lets me add some pattern behaviour to characters, this one lets you set your coords and entity will walk towards them ,
When he will reach the coords then he will perform defined attack/ animation, it kinda works but not as good with Z axis.
Sometimes Z axis is screwed up and he walks towards lower location onscreen , i have direction both in stage so screen moves and i suspect this have something to do with it not working the same way all the time, can you give me a hint what to do to make it work nicely so he will reach the point ? Do i need additional detection of screen position?
Also in this script i only detect X and perform attack, because with x and z it doesnt work , Z axis isnt always the same but X is basically working right.
I would like him to reach 1000 450 and then stop,turn around  towards player and perform attack2.

Code:
void targetxz(float Velx, float Velz, float Tx, float Tz , int Ani)
{// Targetting opponent before leaping or dashing
    void self = getlocalvar("self");
    int dir = getentityproperty(self, "direction"); // Get enemy's facing direction
    float x = getentityproperty(self, "x"); // Get enemy's x coordinate
    float z = getentityproperty(self, "z"); // Get enemy's z coordinate

    setlocalvar("T"+self, findtarget(self)); // Find target and put it in local variable
    float Vx = getentityproperty(self, "x"); // Attain x velocity
    float Vz = getentityproperty(self, "z"); // Attain z velocity
    if((dir==1) && ( Vx > Tx )){ // Are both velocity available?
    changeentityproperty(self, "direction", 0); // Face left
changeentityproperty(self, "velocity", 0,0,0 );
  performattack(self, openborconstant(Ani));
    }
    if((dir==0) && ( Vx < Tx )){ // Are both velocity available?
    changeentityproperty(self, "direction", 0); // Face left
changeentityproperty(self, "velocity", 0,0,0 );
  performattack(self, openborconstant(Ani));
    }

    if( getlocalvar("T"+self) != NULL()){ // Is there a target?
      void target = getlocalvar("T"+self);

      float Disx = Tx - x; // Get x distance
      float Disz = Tz - z; // Get z distance
      if(Disx < 0){ // Negative Disx?
        Disx = -Disx; // Turn it to positive
        changeentityproperty(self, "direction", 0); // Face left
      } else {
        changeentityproperty(self, "direction", 1); // Face right
      }

      if(Disz < 0){ // Negative Disz?
        Disz = -Disz; // Turn it to positive
      }


      if(Disz < Disx) // Disx bigger than Disz?
      {
        if(Tx < x){ // Player is behind enemy?
          setlocalvar("x"+self, -Velx); // Turn Vx to negative
        } else { setlocalvar("x"+self, Velx); } // Use defined Vx

        setlocalvar("z"+self, Velx*(Tz-z)/Disx); // Calculate Vz then store value in local variable
      } else { // Disz bigger than Disx!
        if(Tz < z){ // Player is behind enemy?
          setlocalvar("z"+self, -Velz); // Turn Vz to negative
        } else { setlocalvar("z"+self, Velz); } // Use defined Vz

        setlocalvar("x"+self, Velz*(Tx-x)/Disz); // Calculate Vx then store value in local variable
      }

    } else { // No target at all!
      setlocalvar("z"+self, 0); // 0 velocity
      if(dir==0){ // Facing left?
        setlocalvar("x"+self, -Velx); // Negative velocity
      } else { setlocalvar("x"+self, Velx); } // Positive velocity

    }
} 


void dash()
{// Dash with previously attained speed!
    void self = getlocalvar("self");
    float Vx = getlocalvar("x"+self); // Attain x velocity
    float Vz = getlocalvar("z"+self); // Attain z velocity
    if( Vx!=NULL() && Vz!=NULL() ){ // Are both velocity available?
      changeentityproperty(self, "velocity", Vx, Vz); //Move towards target!
    }
}

Code:
anim	attack4
	loop	1 
	offset	90 177
	bbox	59 30 65 148
	delay	5
          range	100 600
 	@cmd	targetxz 3 3 950 480 "ANI_ATTACK2"
	@cmd	dash
	frame	data/chars/rocks/walk1.gif
	frame	data/chars/rocks/walk2.gif
	frame	data/chars/rocks/walk3.gif
 	frame	data/chars/rocks/walk4.gif
	frame	data/chars/rocks/walk5.gif
	frame	data/chars/rocks/walk6.gif
	frame	data/chars/rocks/walk7.gif
 	@cmd	targetxz 3 3 950 480 "ANI_ATTACK2"
	frame	data/chars/rocks/walk8.gif
	frame	data/chars/rocks/walk9.gif
	frame	data/chars/rocks/walk10.gif
	frame	data/chars/rocks/walk11.gif
 	frame	data/chars/rocks/walk12.gif
 	frame	data/chars/rocks/walk13.gif
	frame	data/chars/rocks/walk14.gif
	frame	data/chars/rocks/walk15.gif
	frame	data/chars/rocks/walk16.gif

Did you guys tried something like this and got it working ?
 
Haven't made anything like that before but it shouldn't be too hard :)

Code:
    float x = getentityproperty(self, "x"); // Get enemy's x coordinate
    float z = getentityproperty(self, "z"); // Get enemy's z coordinate

    setlocalvar("T"+self, findtarget(self)); // Find target and put it in local variable
    float Vx = getentityproperty(self, "x"); // Attain x velocity
    float Vz = getentityproperty(self, "z"); // Attain z velocity

Ummm.... why are you acquiring x and z coords twice?
 
I also made other scripts to use both and didnt want to change all of them , i want to acquire coords before you walk there and after youre there and wasnt sure if one will overwrite the other, animation runs in a loop.
Ive seen some of your scripts for jumping to set coordinates but i want to make walking , it feels more natural, also i want it only for enemies so it would be nice if they would face player instead of dumb change direction to opposite.
Could You lend a hand on that script Bloodbane ?
Currently it doesnt work properly if Coords are below 400 depending where enemy is facing, id like it to work in most situations.What i mean by that, it changes to Animation without walking to the location sometimes.
And i would prefere to keep this as one script and one animation without breaking it to 2, even merging it with dash script would be nice.
O Ilu waypoints are undocumented so i have no clue where and now to use them.
------
I changed it and removed Vx, this was modified target script from targeting enemy, i tried your script Bloodbane with targetting coords but it was set to use X and Y not Z so was more for calculating leaps + dash wasa bit different for it and couldnt get i to work and move enemies.
Code:
void targetxz(float Velx, float Velz, float Tx, float Tz , int Ani)
{// Targetting opponent before leaping or dashing
    void self = getlocalvar("self");
    int dir = getentityproperty(self, "direction"); // Get enemy's facing direction
    float x = getentityproperty(self, "x"); // Get enemy's x coordinate
    float z = getentityproperty(self, "z"); // Get enemy's z coordinate

    setlocalvar("T"+self, findtarget(self)); // Find target and put it in local variable
    if((dir==1) && ( x > Tx )){ // Are both velocity available?
    changeentityproperty(self, "direction", 0); // Face left
changeentityproperty(self, "velocity", 0,0,0 );
  performattack(self, openborconstant(Ani));
    }
    if((dir==0) && ( x < Tx )){ // Are both velocity available?
    changeentityproperty(self, "direction", 0); // Face left
changeentityproperty(self, "velocity", 0,0,0 );
  performattack(self, openborconstant(Ani));
    }

    if( getlocalvar("T"+self) != NULL()){ // Is there a target?
      void target = getlocalvar("T"+self);

      float Disx = Tx - x; // Get x distance
      float Disz = Tz - z; // Get z distance
      if(Disx < 0){ // Negative Disx?
        Disx = -Disx; // Turn it to positive
        changeentityproperty(self, "direction", 0); // Face left
      } else {
        changeentityproperty(self, "direction", 1); // Face right
      }

      if(Disz < 0){ // Negative Disz?
        Disz = -Disz; // Turn it to positive
      }


      if(Disz < Disx) // Disx bigger than Disz?
      {
        if(Tx < x){ // Player is behind enemy?
          setlocalvar("x"+self, -Velx); // Turn Vx to negative
        } else { setlocalvar("x"+self, Velx); } // Use defined Vx

        setlocalvar("z"+self, Velx*(Tz-z)/Disx); // Calculate Vz then store value in local variable
      } else { // Disz bigger than Disx!
        if(Tz < z){ // Player is behind enemy?
          setlocalvar("z"+self, -Velz); // Turn Vz to negative
        } else { setlocalvar("z"+self, Velz); } // Use defined Vz

        setlocalvar("x"+self, Velz*(Tx-x)/Disz); // Calculate Vx then store value in local variable
      }

    } else { // No target at all!
      setlocalvar("z"+self, 0); // 0 velocity
      if(dir==0){ // Facing left?
        setlocalvar("x"+self, -Velx); // Negative velocity
      } else { setlocalvar("x"+self, Velx); } // Positive velocity

    }
}

Heres another one
Code:
void target(float Velx, float Velz, float Cx, float Cz)
{// Targetting opponent before leaping or dashing
    void self = getlocalvar("self");
    int dir = getentityproperty(self, "direction"); // Get enemy's facing direction
    float x = getentityproperty(self, "x"); // Get enemy's x coordinate
    float z = getentityproperty(self, "z"); // Get enemy's z coordinate

    setlocalvar("T"+self, findtarget(self)); // Find target and put it in local variable

    if( getlocalvar("T"+self) != NULL()){ // Is there a target?
      void target = getlocalvar("T"+self);
      float Tx = Cx; // Get target's x coordinate
      float Tz = Cz; // Get target's z coordinate
      float Disx = Tx - x; // Get x distance
      float Disz = Tz - z; // Get z distance

      if(Disx < 0){ // Negative Disx?
        Disx = -Disx; // Turn it to positive
        changeentityproperty(self, "direction", 0); // Face left
      } else {
        changeentityproperty(self, "direction", 1); // Face right
      }

 

      if(Disz < Disx) // Disx bigger than Disz?
      {
        if(Tx < x){ // Player is behind enemy?
          setlocalvar("x"+self, -Velx); // Turn Vx to negative
        } else { setlocalvar("x"+self, Velx); } // Use defined Vx

        setlocalvar("z"+self, Velx*(Tz-z)/Disx); // Calculate Vz then store value in local variable
      } else { // Disz bigger than Disx!
        if(Tz < z){ // Player is behind enemy?
          setlocalvar("z"+self, -Velz); // Turn Vz to negative
        } else { setlocalvar("z"+self, Velz); } // Use defined Vz

        setlocalvar("x"+self, Velz*(Tx-x)/Disz); // Calculate Vx then store value in local variable
      }

    } else { // No target at all!
      setlocalvar("z"+self, 0); // 0 velocity
      if(dir==0){ // Facing left?
        setlocalvar("x"+self, -Velx); // Negative velocity
      } else { setlocalvar("x"+self, Velx); } // Positive velocity
    }
}

I think sometimes these scripts interfere one with another because of variables, for example im storing variable X Z for one thing and after its doner this variable is still there and will interfere with next function that acquire this variable unless this variable is reset at the beginning of script.This isnt good.
--
Ok for now this works for me with small issues:
Code:
void targetXZ(float Velx, float Velz, float Cx, float Cz )
{// Targetting opponent before leaping or dashing
    void self = getlocalvar("self");
setlocalvar("x"+self,NULL());
setlocalvar("z"+self,NULL());
    int dir = getentityproperty(self, "direction"); // Get enemy's facing direction
    float x = getentityproperty(self, "x"); // Get enemy's x coordinate
    float z = getentityproperty(self, "z"); // Get enemy's z coordinate

    setlocalvar("T"+self, findtarget(self)); // Find target and put it in local variable

    if( getlocalvar("T"+self) != NULL()){ // Is there a target?
      void target = getlocalvar("T"+self);
      float Tx = Cx; // Get target's x coordinate
      float Tz = Cz; // Get target's z coordinate
      float Disx = Tx - x; // Get x distance
      float Disz = Tz - z; // Get z distance

      if(Disx < 0){ // Negative Disx?
        Disx = -Disx; // Turn it to positive
        changeentityproperty(self, "direction", 0); // Face left
      } else {
        changeentityproperty(self, "direction", 1); // Face right
      }

 

      if(Disz < Disx) // Disx bigger than Disz?
      {
        if(Tx < x){ // Player is behind enemy?
          setlocalvar("x"+self, -Velx); // Turn Vx to negative
        } else { setlocalvar("x"+self, Velx); } // Use defined Vx

        setlocalvar("z"+self, Velx*(Tz-z)/Disx); // Calculate Vz then store value in local variable
      } else { // Disz bigger than Disx!
        if(Tz < z){ // Player is behind enemy?
          setlocalvar("z"+self, -Velz); // Turn Vz to negative
        } else { setlocalvar("z"+self, Velz); } // Use defined Vz

        setlocalvar("x"+self, Velz*(Tx-x)/Disz); // Calculate Vx then store value in local variable
      }

    } else { // No target at all!
      setlocalvar("z"+self, 0); // 0 velocity
      if(dir==0){ // Facing left?
        setlocalvar("x"+self, -Velx); // Negative velocity
      } else { setlocalvar("x"+self, Velx); } // Positive velocity
    }
} 






void stopXZ(  float Tx,  float Tz,int Ani )
{// stops at certain square coordinates
    void self = getlocalvar("self");
int dir = getentityproperty(self, "direction"); // Get enemy's facing direction
    float Vx = getentityproperty(self, "x"); // Attain x velocity
    float Vz = getentityproperty(self, "z"); // Attain z velocity
      float Disx = Tx - Vx; // Get x distance
      float Disz = Tz - Vz; // Get z distance
      void	target = findtarget(self);
      int TarX = getentityproperty(target, "x"); // Get enemy's pos
  if ((TarX > Vx)&&(Disx < 2)){
    changeentityproperty(self, "direction", 1); // Face r
changeentityproperty(self, "velocity", 0,0,0 );
setlocalvar("x"+self,NULL());
setlocalvar("z"+self,NULL());
  performattack(self, openborconstant(Ani));
    }
  if ((TarX < Vx)&&(Disx < 2)){
    changeentityproperty(self, "direction", 0); // Face l
changeentityproperty(self, "velocity", 0,0,0 );
setlocalvar("x"+self,NULL());
setlocalvar("z"+self,NULL());
  performattack(self, openborconstant(Ani));
    }
}

Issue is - when enemy is on top and player on bottom and enemy performs dash then his dash is not moving forward because their X coords match so theres no X velocity added and Z is not added as well , not sure why Z is not applied even if X is similar.
 
A simple question I need to ask you is: why do you need to care about player before going defined coords?

It's best for the function to just calculate the required velocities to go there. Then the function to decide to walk or not should be another function
 
Im using this one now , frame based walk is much more precise
http://www.chronocrash.com/forum/index.php?topic=1638.msg54018;topicseen#new
 
Back
Top Bottom