hole damage

My method is to record's player's fall to hole status then on respawn, return missing life but deduct some health instead. This method is useful if you want player to return to respawn point after falling to hole.

Ilu's method is to check falling to hole status then force player to play certain animation (get out of hole animation I believe).

Another method which I haven't tried is to give immunity against hole damage then force player to play certain animation.
 
msmalik681 said:
when you fall in a hole you lose a life how to set damage taken rather then losing a life ?
Hi msmalik681
I'm using a script similar to Ilu's method, but Bloodbane's method is also good.

Basically you need to detect the character's "y" position until it reaches something like -100 and from this point you can perform any action you want. I will show my script as an example, I know that it's big but I have a lot of other tasks running together.
Code:
void main()
{//Jump back to the ground when fall in any hole if current health is higher than 1/4 of max health, same as original SOR3
	void self	 = getlocalvar("self");
	void target	 = getentityvar(self,"grabbed");
	void branch  = openborvariant("current_branch");
	void type 	 = getentityproperty(self,"type");
	void sType 	 = getentityproperty(self,"subtype");
	int mHealth	 = getentityproperty(self, "maxhealth");
	int health	 = getentityproperty(self, "health");
	int x		 = getentityproperty(self, "x");
	int y		 = getentityproperty(self, "y");
	int z		 = getentityproperty(self, "z");
	int jumping	 = getentityproperty(self, "aiflag", "jumping");
	int falling	 = getentityproperty(self, "aiflag", "falling");
	int damage	 = mHealth/4; //DAMAGE IS ALWAYS 1/4 OF MAX THE HEALTH
	int xDir 	 = getentityproperty(self, "xdir");
	int vDir 	 = getentityproperty(self, "direction");
	int dir;
	float hole	 = checkhole(x, z, y);
	float yLimit = -100; //HEIGHT LIMIT WHEN FALLING IN ANY HOLE
	float xPos;
	float zPos;
	float xVel;
	float yVel;
	float zVel;
	
	if(type == openborconstant("TYPE_PLAYER") || type == openborconstant("TYPE_NPC")){ //WORKS FOR PLAYERS AND NPCS ONLY
		
		//USED TO RESET THE VARIABLE IF THE PLAYER IS ON THE GROUND
		if(y >= 0 && getlocalvar("inhole"+self) != NULL()){setlocalvar("inhole"+self, NULL());}
		
		//USED TO MAKE THE PLAYER JUMP BACK TO THE GROUND, GET OFF OF THE HOLE
		if(y < yLimit && getlocalvar("inhole"+self) != 1){ //PLAYER IS FALLING ABOVE THE GROUND TOO MUCH?? CERTAINLY IS A HOLE :D
			if(health > damage){ //HAS ENOUGH HEALTH TO REMAIN ALIVE??
			
				//SOR2 STAGE 1A, MANHOLE 1, MANHOLE 2
				//SOR3 STAGE 3A, HOLE 1, HOLE 2
				xPos = x;
				zPos = z;
				xVel = 0;
				yVel = 5;
				zVel = -3;
				dir	 = vDir;
				
				//SOR3 STAGE 3A, HOLE 3, LAST LARGE HOLE AT THE END OF THE LEVEL
				if(branch == "sor3_st3a" && x > 1700){ 
					xPos = 1763;
					zPos = 270;
					xVel = -2;
					zVel = 0;
					dir	 = 0;
				}
				
				//SOR3 STAGE 3C, THE ONLY HOLE AT THE LEFT SIDE OF THE LEVEL
				if(branch == "sor3_st3c"){
					xPos = 200;
					zPos = 270;
					xVel = -2;
					zVel = 0;
					dir	 = 0;
				}
				
				//RUN ALL TASKS
				changeentityproperty(self, "health", health-damage); //SUBTRACT HEALTH
				changeentityproperty(self, "position", xPos, zPos, NULL()); //CHANGE POSITION
				changeentityproperty(self, "direction", dir); //CHANGE DIRECTION
				changeentityproperty(self, "animation", openborconstant("ANI_LAND")); //CHANGE ANIMATION
				tossentity(self, yVel, xVel, zVel); //TOSS THE PLAYER OFF OF THE HOLE
				setlocalvar("inhole"+self, 1); //CHANGE VARIABLE FLAG TO RUN ONCE
			}
		}
	
		//USED TO SLOW CHARACTER MOVEMENT WHEN A HOLE IS DETECTED, USED TO AVOID ENGINE ISSUE THAT FALL IN THE HOLE TOO LATE IF SPEED IS HIGH
		if(hole && y <= 0){ //A HOLE IS DETECTED ON THE GROUND??
			if(branch == "sor2_st1a" || branch == "sor3_st3a" || branch == "sor3_st3c"){ //IN THESE LEVELS??
			
				//CHANGE VELOCITY TO ZERO IF THE CHARACTER IS FALLING IN THE HOLE AT Z AXIS, OTHERWISE, DEFINE X VELOCITY
				if(xDir > 0){	xVel = 0.7;}else
				if(xDir < 0){	xVel = -0.7;}else
				if(xDir == 0){	xVel = 0;}
				
				//RUN ALL TASKS
				if(target != NULL()){ //USED TO UNBIND ANY GRABBED OPPONENT IF FALLING IN ANY HOLE, LIKE THE "GRABEND" SCRIPT
					changeentityproperty(target,"damage_on_landing",0);
					changeentityproperty(target,"aiflag","falling",0);
					changeentityproperty(target,"aiflag","drop",0);
					changeentityproperty(target,"aiflag","projectile",0);
					changeentityproperty(target,"aiflag","frozen", 0); //USED TO AVOID GRAB INTERRUPTION WHEN THE NODROPEN IS OFF AND ANY PLAYER IS RESPAWNED
					changeentityproperty(target,"takeaction", "common_animation_normal");
					changeentityproperty(target, "velocity", xVel);
					bindentity(target, NULL());
					setidle(target);
					setentityvar(self, "grabbed", NULL());
				}
				
				//IF IS NOT FALLING OR JUMPING, RESET TO IDLE STATUS
				if(falling != 1){if(jumping != 1){setidle(self);}}
				
				//CHANGE X VELOCITY
				changeentityproperty(self, "velocity", xVel);
			}
		}
	}
}

I tried to use my script in the "inhole" event or using "checkhole" function in other events but I discovered that if the character touch any hole border, both are instantly disabled. I've read a lot of posts about it and maybe it is the main cause of some hole problems. This is why I'm using this in the "onmovea" script event together with the "inhole"+self variable as a trigger.

Also I made some adjustments for specific levels, I let as an example but you can change it freely.

I have a secondary script to reduce character's "X" speed to avoid some issues when the entity is falling in small holes at high speeds. In addition, I'm using this secondary script to unbind grabbed entities and reset to idle status. You can remove all them if is not useful for you

I hope it helps
 
msmalik681 this is the code I was talking about:

Code:
void actual_main()
{ // Performs FOLLOW50 if character falls to hole and reduces 10 HP
// Won't perform if HP is below 10
// THANKS BLOODBANE AND KRATUS

    void self = getlocalvar("self"); // GET CALLER

    int y = getentityproperty(self,"y"); // GET Y POSITION
    int HP = getentityproperty(self,"health"); // GET CALLER HEALTH
    int Vy = getentityproperty(self,"tossv"); // GET Y VELOCITY

    if(Vy < 0 && y < -120 && HP > 10){ // 
      changeentityproperty(self, "health", HP-10); // DAMAGE CALLER
      changeentityproperty(self, "subject_to_gravity", 0); // DISABLE GRAVITY (and I should not be doing it)
      performattack(self, openborconstant("ANI_FOLLOW50")); // CHANGE TO "ANTIHOLE" ANIMATION
	  			  
    }
}

This will force the player to go to FOLLOW50 as a "hole escape" animation. Watch out that I've disabled the gravity and if you don't enable it again, you will have some problems.
I really should be using tosstime for that, but whatever.

On my game, I've customized it even further, so I unbind any target or effect which is bind on my character
Code:
void actual_main()
{ // Performs FOLLOW50 if character falls to hole and reduces 10 HP
// Won't perform if HP is below 10
// THANKS BLOODBANE AND KRATUS

    void self = getlocalvar("self"); // GET CALLER
	void target = getentityvar(self,"grabbed"); // GET AVAILABLED TARGET (ENTITYVAR)
	void bindfx = getentityvar(self, "bindfx"); // GET AVAILABLED BIND EFFECT 

    int y = getentityproperty(self,"y"); // GET Y POSITION
    int HP = getentityproperty(self,"health"); // GET CALLER HEALTH
    int Vy = getentityproperty(self,"tossv"); // GET Y VELOCITY

    if(Vy < 0 && y < -120 && HP > 10){ // 
      changeentityproperty(self, "health", HP-10); // DAMAGE CALLER
      changeentityproperty(self, "subject_to_gravity", 0); // DISABLE GRAVITY (and I should not be doing it)
      performattack(self, openborconstant("ANI_FOLLOW50")); // CHANGE TO "ANTIHOLE" ANIMATION
	  
		if(bindfx!=NULL()) // UNBIND ANY BINDED FX
		{
		killentity(bindfx); // KILL BIND FX
		setentityvar(self, "bindfx", NULL()); // CLEAN BINDFX ENTITY VAR
		}
		
		if(target != NULL()){ //USED WHEN PLAYER IS FALLING BY TIME OVER AND THE GRABBER IS THE PLAYER, NEED TO UNBIND THE ENEMY
		bindentity(target, NULL());
		damageentity(target, self, 0, 1, openborconstant("ATK_NORMAL"));
		changeentityproperty(target,"subject_to_gravity",1);
		bindentity(self, NULL());
		setentityvar(self, "grabbed", NULL());
		}
	  
    }
}

And I use it as "onmoveascript" and not as "inhole".
onmoveascript data/scripts/antihole.c
 
Back
Top Bottom