Boss death with walls

Toranks

Active member
Is a stage without holes, surrounded by walls. If I throw the boss against the walls, the stage ends instantly. How can I avoid this death?
 
This is the stage

Code:
music		data/music/dock3.ogg

background	data/bgs/53lvl/back0.gif 0 0
layer		data/bgs/53lvl/back.gif -2500 0 0 0 0 0 0 -1 1 1 0 0 0 0 0 0.7
layer		data/bgs/53lvl/back3.gif -2000 0 0 0 260 0 0 -1 1 1 0 0 0 0 0 0.8
layer		data/bgs/53lvl/seamiddle.gif -1500 0 0 0 60 0 0 -1 1 1 1 0 0 0 0 0.8
layer		data/bgs/53lvl/back2.gif -500 0 0 0 130 0 0 -1 1 1 0 0 0 0 0 0.8
panel		data/bgs/53lvl/panel.gif
layer		data/bgs/27lvl/back2.gif 1000 0 0 0 270 0 0 -1 1 1 1 0 0 0 0 1.2
layer		data/bgs/53lvl/sun.gif 1500 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0


direction       leftright
light  		-90   100
at       	0
settime         0
notime          1
noslow          0
order		a
spawn1  	480 100
spawn2  	485 100
spawn3  	490 100


bgspeed		-5 0


cameraoffset            0 -100
cameratype              1

#------------------------

wall    -100 600  0 0 410 410 280 5000
wall    350 600  0 0 510 510 115 5000
wall    300 600  0 0 -10 170 180 5000

wall    350 370  0 0 510 510 60 5000
wall    300 397  -30 -30 163 0 85 5000
wall    830 600  0 0 600 600 280 5000

wall    650 429  0 0 210 210 70 100
wall    640 430  0 0 20 20 70 140
wall    650 430  0 0 210 210 10 140

wall    170 490  110 110 710 710 125 2
#------------------------
#----------------------------------
spawn   stgSET5
@script void main() {
   performattack(getlocalvar("self"), openborconstant("ANI_FOLLOW3"));
} @end_script
coords  -500 515 350
at      0
#----------------------------------
#-------//-badbreak---//--------
spawn   badbreak
coords  50 420
at      0
#-------//-badbreak---//--------

spawn   bird7
flip    1
coords  -300 190
at      0

spawn   bird7
coords  550 240
at      0

spawn   wale3
coords  120 475
at      0

spawn   wale3
flip    1
coords  -280 515
at      0


spawn   bossboat2
flip    1
coords  -50 360
at      0


spawn   crazyjoe
health  4000
boss    1
flip    1
coords  122 430
at      0
 
Hi Toranks,

If you are using scripted grabs and the throw/slam are finished too close of the walls/platforms, the throwned/slammed characters will be moved to the top of the wall/platform.

I can see some walls with 5000 height, maybe the throwned/slammed characters are in the top of the wall and dying instantly because they are a very off screen in Y axis.

You can test it by reducing wall height to a lower value like 50 or 100 and see if the throwned character is moved to the top.

I suggest to use some "antiwall" script to prevents throwned/slammed chacarters to be stucked or moved to top, like this:
Code:
void antiWall(int distX, int moveX, int distZ)
{//Checks distance from the walls
 //If near of the walls at defined distance, entity (Self/Grabbed) will be moved away with defined movement
	void self 		= getlocalvar("self");
	void target		= getentityproperty(self, "grabbing");
	int direction 	= getentityproperty(self, "direction");
	int x 			= getentityproperty(self, "x");
	int Tx 			= getentityproperty(target, "x");
	int z 			= getentityproperty(self, "z");
	int Tz 			= getentityproperty(target, "z");
	int subWall		= getentityproperty(self, "subject_to_wall");
	float W;
	float Wz;

	if(direction == 0){ //Is entity facing left?                  
		distX = -distX;
		moveX = -moveX;
	}

	W  = checkwall(x+distX, z);
	Wz = checkwall(x+distX, z+distZ);

	if(Wz){
		if(subWall == 1){
			changeentityproperty(self, "position", x, z-distZ);
			changeentityproperty(target, "position", Tx, Tz-distZ);
		}
	}

	if(W){
		if(subWall == 1){
			changeentityproperty(self, "position", x+moveX);
			changeentityproperty(target, "position", Tx+moveX);
		}
	}
}

This is a simple version of the antiwall script that need to be applied to the grabber at the first or second frames of the throw/slam animations . I have another script system that moves only the throwned/slammed characters but it is a bit more complex, first we can try the simple script.
 
I have lowered the height of the walls and now the enemy reappears above. It also happened to me with an enemy grab, and I got stuck in an invisible roof.

About the antiwall command I don't quite understand what exactly it does. What parameters should I put in distX, moveX, and distZ? Would there be a way to apply it to all the default game characters via script instead of adding that command one by one to all characters and enemies that perform scripted grabs?
I have located the script causing this error. It is the "finish" that takes place at the end of all "slamstart"'s. I put both:

Code:
void slamstart()
{ // Slam Starter
// Use finish after using this
   void self = getlocalvar("self");
   void target = getlocalvar("Target" + self);

   if(target==NULL())
   {
     target = getentityproperty(self, "grabbing");
     setlocalvar("Target" + self, target);
   }
   if(target!=NULL())
   {
     damageentity(target, self, 0, 1, openborconstant("ATK_NORMAL7")); // Slam Starter
   }
}

void slamstart2()
{ // Slam Starter for nongrab slams
// Use finish or throw after using this
   void self = getlocalvar("self");
   void target = getlocalvar("Target" + self);


   if(target==NULL())
   {
     target = getentityproperty(self, "opponent");
     setlocalvar("Target" + self, target);
   }
   if(target!=NULL())
   {
     damageentity(target, self, 0, 1, openborconstant("ATK_NORMAL7")); // Slam Starter
   }
}



void slamstart3()
{ // Slam Starter for nongrab slams release if obstacle 
   void self = getlocalvar("self");
   void target = getlocalvar("Target" + self);


   if(target==NULL())
   {
     target = getentityproperty(self, "opponent");
     setlocalvar("Target" + self, target);
   }

   if(target!=NULL())
   {

	if(getentityproperty(target, "type")==openborconstant("TYPE_OBSTACLE"))
	{
    	performattack(self, openborconstant("ANI_PAIN"));
	bindentity(target, NULL());
	}
	else
   	{
     	damageentity(target, self, 0, 1, openborconstant("ATK_NORMAL7")); // Slam Starter
   	}
  }
}


void finish(int Damage, int Type, int x, int y, int z, int Face)
{ // Damage as slam finisher
   void self = getlocalvar("self");
   void target = getlocalvar("Target" + self);
   int SDir = getentityproperty(target,"direction");
   int MDir;

   if(Face==0){ // Same facing?
       MDir = SDir;
   }

   if(Face==1){ // Opposite facing?

     if(SDir==0){ // Facing left?
       MDir = 1;
     } else { MDir = 0;}
   }

   if(target==NULL())
   {
     target = getentityproperty(self, "grabbing");
     setlocalvar("Target" + self, target);
   }
   if(target!=NULL())
   {
     int dir = getentityproperty(target,"direction"); //Get opponent's facing direction
     if(dir==0){ // Facing left?
       x = -x;
     }

     if(Type==1)
     {
       damageentity(target, self, Damage, 1, openborconstant("ATK_NORMAL")); // 1st Finisher
     }

     if(Type==2)
     {
       damageentity(target, self, Damage, 1, openborconstant("ATK_NORMAL9")); // 2nd Finisher
     }

     tossentity(target, y, x, z); // Toss opponent ;)
     changeentityproperty(target, "direction", MDir);

     setlocalvar("Target"+self, NULL()); //Clears variable
   }
}
 

Attachments

  • Captura.JPG
    Captura.JPG
    157.9 KB · Views: 5
Toranks said:
I have lowered the height of the walls and now the enemy reappears above. It also happened to me with an enemy grab, and I got stuck in an invisible roof.
So this confirms my theory - you were releasing the grabbed enemy inside a wall. if the wall is not too tall, the entity will appear over it. But if its tall (I can't remember how much), it gets killed.

On my game, to avoid this, I always release the target at the exactly the same spot that I am, in both X and Z axis (because this can happens with walls in z planes too).

What parameters should I put in distX, moveX, and distZ
DistX and DistZ are the distance, in both planes, that you want to check if there is a wall. MoveX is how much you want to move.
But pay attention that if you want to detect Z, you will need to make it to move in the Z axis too.

Would there be a way to apply it to all the default game characters via script instead of adding that command one by one to all characters and enemies that perform scripted grabs?
If you prepare and think about the throw beforehand, you won't be needing to do this (as I told above, I release my targets on the same spot that I am, so I am 100% sure its a safe spot - 1 tick, in any direction, could be not safe). But you can adapt this code to work on a onfallscript script, so it will trigger on all fall animations - because the scripted slam works with fall animations
 
Toranks said:
I have lowered the height of the walls and now the enemy reappears above. It also happened to me with an enemy grab, and I got stuck in an invisible roof.

About the antiwall command I don't quite understand what exactly it does. What parameters should I put in distX, moveX, and distZ? Would there be a way to apply it to all the default game characters via script instead of adding that command one by one to all characters and enemies that perform scripted grabs?
I have located the script causing this error. It is the "finish" that takes place at the end of all "slamstart"'s. I put both:

Code:
void slamstart()
{ // Slam Starter
// Use finish after using this
   void self = getlocalvar("self");
   void target = getlocalvar("Target" + self);

   if(target==NULL())
   {
     target = getentityproperty(self, "grabbing");
     setlocalvar("Target" + self, target);
   }
   if(target!=NULL())
   {
     damageentity(target, self, 0, 1, openborconstant("ATK_NORMAL7")); // Slam Starter
   }
}

void slamstart2()
{ // Slam Starter for nongrab slams
// Use finish or throw after using this
   void self = getlocalvar("self");
   void target = getlocalvar("Target" + self);


   if(target==NULL())
   {
     target = getentityproperty(self, "opponent");
     setlocalvar("Target" + self, target);
   }
   if(target!=NULL())
   {
     damageentity(target, self, 0, 1, openborconstant("ATK_NORMAL7")); // Slam Starter
   }
}



void slamstart3()
{ // Slam Starter for nongrab slams release if obstacle 
   void self = getlocalvar("self");
   void target = getlocalvar("Target" + self);


   if(target==NULL())
   {
     target = getentityproperty(self, "opponent");
     setlocalvar("Target" + self, target);
   }

   if(target!=NULL())
   {

	if(getentityproperty(target, "type")==openborconstant("TYPE_OBSTACLE"))
	{
    	performattack(self, openborconstant("ANI_PAIN"));
	bindentity(target, NULL());
	}
	else
   	{
     	damageentity(target, self, 0, 1, openborconstant("ATK_NORMAL7")); // Slam Starter
   	}
  }
}


void finish(int Damage, int Type, int x, int y, int z, int Face)
{ // Damage as slam finisher
   void self = getlocalvar("self");
   void target = getlocalvar("Target" + self);
   int SDir = getentityproperty(target,"direction");
   int MDir;

   if(Face==0){ // Same facing?
       MDir = SDir;
   }

   if(Face==1){ // Opposite facing?

     if(SDir==0){ // Facing left?
       MDir = 1;
     } else { MDir = 0;}
   }

   if(target==NULL())
   {
     target = getentityproperty(self, "grabbing");
     setlocalvar("Target" + self, target);
   }
   if(target!=NULL())
   {
     int dir = getentityproperty(target,"direction"); //Get opponent's facing direction
     if(dir==0){ // Facing left?
       x = -x;
     }

     if(Type==1)
     {
       damageentity(target, self, Damage, 1, openborconstant("ATK_NORMAL")); // 1st Finisher
     }

     if(Type==2)
     {
       damageentity(target, self, Damage, 1, openborconstant("ATK_NORMAL9")); // 2nd Finisher
     }

     tossentity(target, y, x, z); // Toss opponent ;)
     changeentityproperty(target, "direction", MDir);

     setlocalvar("Target"+self, NULL()); //Clears variable
   }
}

I agree to everything the O Ilusionista says.

Basically the antiwall detects walls from the characters at the defined distance in X axis (distX)  and will move according to defined "moveX" value. The same happens to "distZ" but its value will work for both distZ/moveZ.

The only thing I add is an alternative way to use it. You can put antiwall inside the "finish" or "throw" scripts and it will automatically work for every character that uses scripted grabs. The script will move the throwned/slammed charater instead to move the grabber, like I did in SOR2X.

Here is a example, you will see the antiwall at the end of the "finish" script:
Code:
void finish(int damage, int type, int x, int y, int z, int face)
{//Damage as slam finisher
	void self 	= getlocalvar("self");
	void target = getentityvar(self,"grabbed");
	int tDir 	= getentityproperty(target,"direction");
	int vDir;
	
	if(face == 0){ //SAME FACING?
		vDir = tDir;
	}

	if(face == 1){ //OPPOSITE FACING?
		if(tDir == 0){ //FACING LEFT?
			vDir = 1;
		}else{
			vDir = 0;
		}
	}

	if(target == NULL()){
		target = getentityproperty(self, "grabbing");
		setentityvar(self, "grabbed", target);
	}
	
	if(target != NULL()){
		void atkType;
		void projectile;
		void eType = getentityproperty(target,"type"); //Get opponent's type
		int dir    = getentityproperty(target,"direction"); //Get opponent's facing direction
		
		if(dir == 0){ //FACING LEFT?
			x = -x;
		}
		
		if(type == 1){
			atkType = openborconstant("ATK_NORMAL8"); //1st Finisher
		}

		if(type == 2){
			atkType = openborconstant("ATK_NORMAL9"); //2nd Finisher
		}
		
		if(eType == openborconstant("TYPE_PLAYER") || eType == openborconstant("TYPE_NPC")){
			changeentityproperty(target, "projectilehit", "type_player", "type_npc", "type_obstacle");
		}else if(eType == openborconstant("TYPE_ENEMY")){
			changeentityproperty(target, "projectilehit", "type_enemy", "type_obstacle");
		}
		
		damageentity(target, self, damage/1.5, 1, atkType); //SPLIT DAMAGE
		lockMp();
		specialCost();
		changeentityproperty(target, "direction", vDir);
		changeentityproperty(target, "aiflag", "projectile", 1);
		changeentityproperty(target, "damage_on_landing", damage/3); //RESET PROJECTILE STATUS TO 0 WHEN FALL ON THE GROUND, SPLIT DAMAGE
		tossentity(target, y, x, z); //TOSS OPPONENT
		antiWall();
		koCount(); //USED FOR DAMAGEENTITY BUG
		setentityvar(self, "grabbed", NULL()); //CLEAR ENTITYVAR
	}
}

And this is the antiwall version used in my "finish" script
Code:
void antiWall()
{//Checks distance from the walls
 //If inside of the walls, entity will be moved away with defined movement
	void self 		= getlocalvar("self");
	void target 	= getentityvar(self, "grabbed");
	int direction 	= getentityproperty(self, "direction");
	int x 			= getentityproperty(self, "x");
	int Tx 			= getentityproperty(target, "x");
	int z 			= getentityproperty(self, "z");
	int Tz 			= getentityproperty(target, "z");
	int subWall		= getentityproperty(self, "subject_to_wall");
	float wall 		= checkwall(Tx, Tz);

	if(target != NULL()){
		if(wall){
			if(subWall == 1){
				changeentityproperty(target, "position", x);
				changeentityproperty(target, "velocity", 0, 0, NULL());
			}
		}
	}
}

PS: I'm using "getentityvar" to load the grabbed entity because I need to use it in other scripts. Instead to use setlocalvar in slamstart, I changed it to "setentityvar" too
 
I've added an antiwall2 script an added to finish script as you say, but still dying when grab releases between walls. I'm missing anything?
I've changed too all my finish script for your finish script, deleting lockMp(); specialCost(); and koCount() and works, but still happens the same problem.
I think I should clarify that it does not always happen at any stage, only have I seen it happen at this particular stage.
I must also clarify that most characters use an antiwall, but not all. I have tried to add the antiwall with the same parameters (@cmd antiwall 40 -5 0) to the grab that gives me problems but does not solve it either.

Code:
void antiWall2()
{//Checks distance from the walls
 //If inside of the walls, entity will be moved away with defined movement
	void self 		= getlocalvar("self");
	void target 	= getentityvar(self, "grabbed");
	int direction 	= getentityproperty(self, "direction");
	int x 			= getentityproperty(self, "x");
	int Tx 			= getentityproperty(target, "x");
	int z 			= getentityproperty(self, "z");
	int Tz 			= getentityproperty(target, "z");
	int subWall		= getentityproperty(self, "subject_to_wall");
	float wall 		= checkwall(Tx, Tz);

	if(target != NULL()){
		if(wall){
			if(subWall == 1){
				changeentityproperty(target, "position", x);
				changeentityproperty(target, "velocity", 0, 0, NULL());
			}
		}
	}
}


void finish(int Damage, int Type, int x, int y, int z, int Face)
{ // Damage as slam or throw finisher
   void self = getlocalvar("self");
   void target = getlocalvar("Target" + self);
   int SDir = getentityproperty(target,"direction");
   int MDir;

   if(Face==0){ // Same facing?
       MDir = SDir;
   }

   if(Face==1){ // Opposite facing?

     if(SDir==0){ // Facing left?
       MDir = 1;
     } else { MDir = 0;}
   }

   if(target==NULL())
   {
     target = getentityproperty(self, "grabbing");
     setlocalvar("Target" + self, target);
   }
   if(target!=NULL())
   {
     int dir = getentityproperty(target,"direction"); //Get opponent's facing direction
     if(dir==0){ // Facing left?
       x = -x;
     }

     if(Type==1)
     {
       damageentity(target, self, Damage, 1, openborconstant("ATK_NORMAL")); // 1st Finisher
     }

     if(Type==2)
     {
       damageentity(target, self, Damage, 1, openborconstant("ATK_NORMAL9")); // 2nd Finisher
     }

     tossentity(target, y, x, z); // Toss opponent ;)
	 antiWall2();
     changeentityproperty(target, "direction", MDir);
   }
}
 
Toranks said:
I've added an antiwall2 script an added to finish script as you say, but still dying when grab releases between walls. I'm missing anything?
I've changed too all my finish script for your finish script, deleting lockMp(); specialCost(); and koCount() and works, but still happens the same problem.
I think I should clarify that it does not always happen at any stage, only have I seen it happen at this particular stage.
I must also clarify that most characters use an antiwall, but not all. I have tried to add the antiwall with the same parameters (@cmd antiwall 40 -5 0) to the grab that gives me problems but does not solve it either.

Code:
void antiWall2()
{//Checks distance from the walls
 //If inside of the walls, entity will be moved away with defined movement
	void self 		= getlocalvar("self");
	void target 	= getentityvar(self, "grabbed");
	int direction 	= getentityproperty(self, "direction");
	int x 			= getentityproperty(self, "x");
	int Tx 			= getentityproperty(target, "x");
	int z 			= getentityproperty(self, "z");
	int Tz 			= getentityproperty(target, "z");
	int subWall		= getentityproperty(self, "subject_to_wall");
	float wall 		= checkwall(Tx, Tz);

	if(target != NULL()){
		if(wall){
			if(subWall == 1){
				changeentityproperty(target, "position", x);
				changeentityproperty(target, "velocity", 0, 0, NULL());
			}
		}
	}
}


void finish(int Damage, int Type, int x, int y, int z, int Face)
{ // Damage as slam or throw finisher
   void self = getlocalvar("self");
   void target = getlocalvar("Target" + self);
   int SDir = getentityproperty(target,"direction");
   int MDir;

   if(Face==0){ // Same facing?
       MDir = SDir;
   }

   if(Face==1){ // Opposite facing?

     if(SDir==0){ // Facing left?
       MDir = 1;
     } else { MDir = 0;}
   }

   if(target==NULL())
   {
     target = getentityproperty(self, "grabbing");
     setlocalvar("Target" + self, target);
   }
   if(target!=NULL())
   {
     int dir = getentityproperty(target,"direction"); //Get opponent's facing direction
     if(dir==0){ // Facing left?
       x = -x;
     }

     if(Type==1)
     {
       damageentity(target, self, Damage, 1, openborconstant("ATK_NORMAL")); // 1st Finisher
     }

     if(Type==2)
     {
       damageentity(target, self, Damage, 1, openborconstant("ATK_NORMAL9")); // 2nd Finisher
     }

     tossentity(target, y, x, z); // Toss opponent ;)
	 antiWall2();
     changeentityproperty(target, "direction", MDir);
   }
}
O Ilusionista
Thanks man! I'm glad you liked the script

Toranks
Maybe the problem is due to the function "getentityvar" is not present in your script slamstart. I will post all my grab scripts because they are better working together.

Code:
void slamstart()
{//Grab Starter for grab moves
 //Use FINISH or THROW after using this
	void self 	= getlocalvar("self");
	void target = getentityvar(self,"grabbed");

	if(target == NULL()){
		target = getentityproperty(self, "grabbing");
		if(target == NULL() || getentityproperty(target, "dead") == 1){
			setidle(self);
		}else{
			setentityvar(self, "grabbed", target);
		}
	}
	
	if(target != NULL()){
		damageentity(target, self, 0, 1, openborconstant("ATK_NORMAL7")); //Grab Starter
	}
}

void slamstart2()
{//Grab Starter for non-grab moves
 //Use FINISH or THROW after using this
	void self 	= getlocalvar("self");
	void target = getentityvar(self,"grabbed");

	if(target == NULL()){
		target = getentityproperty(self, "opponent");
		if(target == NULL() || getentityproperty(target, "dead") == 1){
			setidle(self);
		}else{
			setentityvar(self, "grabbed", target);
		}
	}
	
	if(target != NULL()){
		damageentity(target, self, 0, 1, openborconstant("ATK_NORMAL7")); //Grab Starter
	}
}

void position(int frame, float dx, float dy, float dz, int face)
{//Modify grabbed entity's position relative to grabber
 //Use grabstart 1st before using this
	void self 	= getlocalvar("self");
	void target = getentityvar(self,"grabbed");
	int dead	= getentityproperty(target,"dead");

	if(target == NULL()){
		target = getentityproperty(self, "grabbing");
		setentityvar(self, "grabbed", target);
	}
	
	if(target != NULL()){
		if(dead == 1){ //USED WHEN PLAYER DIES BY TIME OVER AND THE GRABBER IS THE ENEMY
			bindentity(target, NULL());
			damageentity(target, self, 0, 1, openborconstant("ATK_NORMAL"));
			damageentity(self, self, 0, 1, openborconstant("ATK_NORMAL"));
			setentityvar(self, "grabbed", NULL());
		}else{
			updateframe(target, frame);
			bindentity(target, self, dx, dz, dy, face, 0);
		}
	}
}

void depost()
{//Release grabbed entity
	void self 	= getlocalvar("self");
	void target = getentityvar(self,"grabbed");

	if(target == NULL()){
		target = getentityproperty(self, "grabbing");
		setentityvar(self, "grabbed", target);
	}
	
	if(target != NULL()){
		bindentity(target, NULL());
	}
}

void finish(int damage, int type, int x, int y, int z, int face)
{//Damage as slam finisher
	void self 	= getlocalvar("self");
	void target = getentityvar(self,"grabbed");
	int tDir 	= getentityproperty(target,"direction");
	int vDir;
	
	if(face == 0){ //SAME FACING?
		vDir = tDir;
	}

	if(face == 1){ //OPPOSITE FACING?
		if(tDir == 0){ //FACING LEFT?
			vDir = 1;
		}else{
			vDir = 0;
		}
	}

	if(target == NULL()){
		target = getentityproperty(self, "grabbing");
		setentityvar(self, "grabbed", target);
	}
	
	if(target != NULL()){
		void atkType;
		void projectile;
		void eType = getentityproperty(target,"type"); //Get opponent's type
		int dir    = getentityproperty(target,"direction"); //Get opponent's facing direction
		
		if(dir == 0){ //FACING LEFT?
			x = -x;
		}
		
		if(type == 1){
			atkType = openborconstant("ATK_NORMAL8"); //1st Finisher
		}

		if(type == 2){
			atkType = openborconstant("ATK_NORMAL9"); //2nd Finisher
		}
		
		if(eType == openborconstant("TYPE_PLAYER") || eType == openborconstant("TYPE_NPC")){
			changeentityproperty(target, "projectilehit", "type_player", "type_npc", "type_obstacle");
		}else if(eType == openborconstant("TYPE_ENEMY")){
			changeentityproperty(target, "projectilehit", "type_enemy", "type_obstacle");
		}
		
		damageentity(target, self, damage/1.5, 1, atkType); //SPLIT DAMAGE
		changeentityproperty(target, "direction", vDir);
		changeentityproperty(target, "aiflag", "projectile", 1);
		changeentityproperty(target, "damage_on_landing", damage/3); //RESET PROJECTILE STATUS TO 0 WHEN FALL ON THE GROUND, SPLIT DAMAGE
		tossentity(target, y, x, z); //TOSS OPPONENT
		antiWall();
		setentityvar(self, "grabbed", NULL()); //CLEAR ENTITYVAR
	}
}

void throw(int damage, int type, int Vx, int Vy, int Vz, int face)
{//Damage as throw finisher
	void self 	= getlocalvar("self");
	void target = getentityvar(self,"grabbed");
	int z 		= getentityproperty(self,"z");
	int tDir 	= getentityproperty(target,"direction");
	int vDir;
	
	if(face == 0){ //SAME FACING?
		vDir = tDir;
	}

	if(face == 1){ //OPPOSITE FACING?
		if(tDir == 0){ //FACING LEFT?
			vDir = 1;
		}else{
			vDir = 0;
		}
	}

	if(target == NULL()){
		target = getentityproperty(self, "grabbing");
		setentityvar(self, "grabbed", target);
	}
	
	if(target != NULL()){
		void atkType;
		void projectile;
		void eType = getentityproperty(target,"type"); //Get opponent's type
		int dir    = getentityproperty(target,"direction"); //Get opponent's facing direction

		if(dir == 0){ //FACING LEFT?
			Vx = -Vx;
		}
		
		if(type == 1){
			atkType = openborconstant("ATK_NORMAL8"); //1st Finisher
		}

		if(type == 2){
			atkType = openborconstant("ATK_NORMAL9"); //2nd Finisher
		}
		
		if(z > (openborconstant("PLAYER_MIN_Z")+openborconstant("PLAYER_MAX_Z"))/2){
			Vz = -Vz ;
		}
		
		if(eType == openborconstant("TYPE_PLAYER") || eType == openborconstant("TYPE_NPC")){
			changeentityproperty(target, "projectilehit", "type_player", "type_npc", "type_obstacle");
		}else if(eType == openborconstant("TYPE_ENEMY")){
			changeentityproperty(target, "projectilehit", "type_enemy", "type_obstacle");
		}
		
		damageentity(target, self, 0, 1, atkType);
		changeentityproperty(target, "direction", vDir);
		changeentityproperty(target, "aiflag", "projectile", 1);
		changeentityproperty(target, "damage_on_landing", damage); //RESET PROJECTILE STATUS TO 0 WHEN FALL ON THE GROUND, TOTAL DAMAGE
		tossentity(target, Vy, Vx, Vz); //TOSS OPPONENT
		antiWall();
		setentityvar(self, "grabbed", NULL()); //CLEAR ENTITYVAR
	}
}

void antiWall()
{//Checks distance from the walls
 //If inside of the walls, entity will be moved away with defined movement
	void self 		= getlocalvar("self");
	void target 	= getentityvar(self, "grabbed");
	int direction 	= getentityproperty(self, "direction");
	int x 			= getentityproperty(self, "x");
	int Tx 			= getentityproperty(target, "x");
	int z 			= getentityproperty(self, "z");
	int Tz 			= getentityproperty(target, "z");
	float wall 		= checkwall(Tx, Tz);

	if(target != NULL()){
		if(wall){
			changeentityproperty(target, "position", x);
			changeentityproperty(target, "velocity", 0, 0, NULL());
		}
	}
}

I removed all unecessary scripts like "lockMp" and "specialCost". Removed the "subject_to_wall" detection to reduce the restrictions too.
I suggest to try all scripts together to see if it works.

One question, are you using platforms as a walls? If yes, need to change the "checkwall" by "checkplatform" functions, otherwise the script will not work. For platforms, I'm using "onblockpscript" event instead of grab scripts because they need different rules, and some of them are breakable.
 
I have tried to change all the scripts that Kratus offered me and it works the same, including the bug. Perhaps the problem is in the grab as Bloodbane says, so I put here one of the grabs that give problems. The @cmd antiwall was added by me, before it didn't exist.

Death always occurs when the character releases the enemy, never before. Must be related to "finish" script...

Code:
anim	follow5
@script
	void self = getlocalvar("self");
	void plyr = getentityproperty(self, "playerindex");
	float Vx = getlocalvar("x"+self);
	float Vz = getlocalvar("z"+self);

	if(frame >= 4 && frame <= 25 )
	{
	  if( playerkeys(plyr, 0, "moveup"))
	  {
	  changeentityproperty(self, "velocity", Vx, -0.5);
	  }
	  if( playerkeys(plyr, 0, "movedown"))
	  {
	  changeentityproperty(self, "velocity", Vx, 0.5);
	  }
	  if( playerkeys(plyr, 0, "moveleft"))
	  {
	  changeentityproperty(self, "velocity", -1.5, Vz);
	  }
	  if( playerkeys(plyr, 0, "moveright"))
	  {
	  changeentityproperty(self, "velocity", 1.5, Vz);
	  }
	  if( playerkeys(plyr, 0, "attack"))
	  {
	  updateframe(self, 26);
	  }
	}
	@end_script
	loop	0
	delay	20
	offset	100 191
	bbox	0 0 0 0
	fastattack	1
	@cmd	slamstart2
	@cmd	position 5 85 50 1 -1
	frame	data/chars/3remuinho/2grab01.gif
	delay	12
	@cmd	position 0 100 60 1 -1
	frame	data/chars/3remuinho/2grab02.gif
	@cmd	position 1 85 70 1 -1
	frame	data/chars/3remuinho/2grab03.gif
	@cmd	position 2 85 55 1 -1
	frame	data/chars/3remuinho/2grab04.gif
	delay	8
	@cmd	position 12 70 40 1 1
	frame	data/chars/3remuinho/2grab05.gif
	attack	60 130 90 110 20 1 1 0 9 70
	dropv	3 0 1
	@cmd	position 15 15 40 1 1
	frame	data/chars/3remuinho/2grab06.gif
	@cmd	spawnGun4 "torn2" 60 0 10 -1 1
	@cmd	spawnGun4 "torn2" -40 0 10 0 2
	attack	0 0 0 0
	@cmd	position 12 -50 40 1 -1
	frame	data/chars/3remuinho/2grab07.gif
	attack	-30 85 140 60 20 1 1 0 9 15
	dropv	3 4 0
	sound	data/sounds/punch2.wav
	@cmd	position 1 -85 110 1 1
	frame	data/chars/3remuinho/2grab08.gif
	attack	0 0 0 0
	@cmd	hurt 1
	@cmd	position 0 -45 135 -1 1
	frame	data/chars/3remuinho/2grab09.gif
	attack	60 40 90 120 20 1 1 0 9 70
	dropv	3 0 -1
	@cmd	position 11 0 130 -1 1
	frame	data/chars/3remuinho/2grab10.gif
	attack	0 0 0 0
	@cmd	position 0 65 135 -1 -1
	frame	data/chars/3remuinho/2grab11.gif
	@cmd	hurt 1
	sound	data/sounds/punch2.wav
	attack	100 90 140 55 20 1 1 0 9 15
	dropv	3 4 0
	@cmd	position 1 100 110 1 -1
	frame	data/chars/3remuinho/2grab12.gif
	delay	5
	@cmd	position 12 70 40 1 1
	frame	data/chars/3remuinho/2grab05.gif
	attack	60 130 90 110 20 1 1 0 9 70
	dropv	3 0 1
	@cmd	position 15 15 40 1 1
	frame	data/chars/3remuinho/2grab06.gif
	attack	0 0 0 0
	@cmd	position 12 -50 40 1 -1
	frame	data/chars/3remuinho/2grab07.gif
	@cmd	hurt 1
	attack	-30 85 140 60 20 1 1 0 9 15
	dropv	3 4 0
	sound	data/sounds/punch2.wav
	@cmd	position 1 -85 110 1 1
	frame	data/chars/3remuinho/2grab08.gif
	attack	0 0 0 0
	@cmd	position 0 -45 135 -1 1
	frame	data/chars/3remuinho/2grab09.gif
	attack	60 40 90 120 20 1 1 0 9 70
	dropv	3 0 -1
	@cmd	position 11 0 130 -1 1
	frame	data/chars/3remuinho/2grab10.gif
	attack	0 0 0 0
	@cmd	position 0 65 135 -1 -1
	frame	data/chars/3remuinho/2grab11.gif
	sound	data/sounds/punch2.wav
	@cmd	hurt 1
	attack	100 90 140 55 20 1 1 0 9 15
	dropv	3 4 0
	@cmd	position 1 100 110 1 -1
	frame	data/chars/3remuinho/2grab12.gif
	@cmd	looper 12 30
	@cmd	position 12 70 40 1 1
	frame	data/chars/3remuinho/2grab05.gif
	attack	60 130 90 110 20 1 1 0 9 70
	dropv	3 0 1
	@cmd	position 15 15 40 1 1
	frame	data/chars/3remuinho/2grab06.gif
	attack	0 0 0 0
	@cmd	position 12 -50 40 1 -1
	frame	data/chars/3remuinho/2grab07.gif
	attack	-30 85 140 60 20 1 1 0 9 15
	dropv	3 4 0
	sound	data/sounds/punch2.wav
	@cmd	position 1 -85 110 1 1
	frame	data/chars/3remuinho/2grab08.gif
	attack	0 0 0 0
	@cmd	position 0 -45 120 -1 1
	frame	data/chars/3remuinho/2grab09.gif
	attack	60 40 90 120 20 1 1 0 9 70
	dropv	3 0 -1
	@cmd	position 11 0 100 -1 1
	frame	data/chars/3remuinho/2grab10.gif
	attack	0 0 0 0
	@cmd	position 0 0 80 1 -1
	@cmd	antiwall
	frame	data/chars/3remuinho/2grab11.gif
	sound	data/sounds/punch2.wav
	@cmd	spawn02 "flashsc2" -10 200 190
	@cmd	depost 0
	@cmd	antiwall
	@cmd	finish 80 2 -5 1 0 0
	delay	5
	move	6
	@cmd	stop
	frame	data/chars/3remuinho/2grab13.gif
	@cmd	killgun 1 0
	@cmd	killgun 2 0
	frame	data/chars/3remuinho/2grab13.gif
	@cmd	clearL
	frame	data/chars/3remuinho/2grab14.gif
	attack	95 115 100 55 35 1 1 0 7 10
	dropv	3 4 0
	frame	data/chars/3remuinho/2grab14.gif
	frame	data/chars/3remuinho/2grab15.gif
	frame	data/chars/3remuinho/2grab15.gif
	frame	data/chars/3remuinho/2grab16.gif
	attack	0 0 0 0
	frame	data/chars/3remuinho/2grab16.gif
	move	0
	frame	data/chars/3remuinho/2grab17.gif
	delay	30
	frame	data/chars/3remuinho/2grab17.gif
	delay	12
	frame	data/chars/3remuinho/rise4.gif
 
Toranks said:
...
Death always occurs when the character releases the enemy, never before. Must be related to "finish" script...

Just to give my two cents, the "finish" function is doing what is supposed to. It just releases the grabed opponent. What you should be aware of, is that the distance on which the opponent will be released is defined by the last @cmd position set before the "finish".
So if the last x distance is set to 20 for example, then the opponent will be released at 20 pixels in front of you. So if you are just 10 pixels away from a wall in front of you, that means your opponent will be released inside the wall in this case. This is why you need to set an antiwall script for this.
Another note is that the antiwall script needs to be set in a frame where no velocity x moving is happening in order for it to work.
 
magggas said:
Toranks said:
...
Death always occurs when the character releases the enemy, never before. Must be related to "finish" script...

Just to give my two cents, the "finish" function is doing what is supposed to. It just releases the grabed opponent. What you should be aware of, is that the distance on which the opponent will be released is defined by the last @cmd position set before the "finish".
So if the last x distance is set to 20 for example, then the opponent will be released at 20 pixels in front of you. So if you are just 10 pixels away from a wall in front of you, that means your opponent will be released inside the wall in this case. This is why you need to set an antiwall script for this.
Another note is that the antiwall script needs to be set in a frame where no velocity x moving is happening in order for it to work.
Strangely it is not working... Maybe other script is affecting the character?

Basically the "antiwall" script I sent will work during the "finish" script. The grabber will check if the grabbed entity position is the same as any wall position in X and Z axis. If yes, the grabbed entity will be moved to the same X/Z position of the grabber because he is certainly in a safe place (outside of any wall). Both X/Z velocity are set to 0 to prevent any problem, as maggas mentioned.

If this task is not occurring, maybe the scripts I sent are not added in the right place.

However, you can use the first antiwall script I sent at the first frame of the grab animation (after @cmd slamstart, for example). It will check X/Z wall distance of the grabber and will move instantly as soon the grab animation starts. The only problem is you will need to add @cmd antiwall to any animation that uses @cmd slamstart.

I saw you added the "move 6" function after "@cmd finish" in the follow5 animation. Have you tried to erase it? Maybe the bug occrus if it works in the same frame as finish script

I'm very curious about this bug. If want, send us a demo of your game to take a look
 
Kratus The antiwall scripts can't work on this animation as it is right now, because it's a moving animation using velocity until after the finish function. So the problem here is that the scripted velocity on this anim is not allowing any antiwall to work properly. This is why i also pointed out velocity in my previous comment.

And yes, the "move 6" he added on the same frame where the finish is happening, definitely defeats the purpose of the antiwall because it is taking away 6 pixels entity-push-back from it. He can still let it there if he really needs it, but he must increase his antiwall push-back to +6 pixels from what it's set.
 
magggas said:
Kratus The antiwall scripts can't work on this animation as it is right now, because it's a moving animation using velocity until after the finish function. So the problem here is that the scripted velocity on this anim is not allowing any antiwall to work properly. This is why i also pointed out velocity in my previous comment.

And yes, the "move 6" he added on the same frame where the finish is happening, definitely defeats the purpose of the antiwall because it is taking away 6 pixels entity-push-back from it.
Strange, I tested antiwall on Max slide at the first frame together with X velocity and it worked. But I understand your point because both @cmd antiwall and X velocity will try to move the character at the same time and it can have some conflicts.

However, the alternative antiwall inside the finish script will not be affected by grabber velocity because he will have your own velocity defined to 0. For example, in SOR2X Max have an aerial throw and antiwall works (for the grabbed entity) even if his X velocity is not 0 during jump animation.
 
Kratus Oh yeah you are right. As long as your antiwall has this "changeentityproperty(target, "velocity", 0, 0, NULL());", then yeah there will be no conflicts with velocity. I just forgot about that. But he still have to take care or at least into consideration the "move 6" because this command will still do its thing no matter what.
 
Back
Top Bottom