Preventing death

O Ilusionista

Captain 100K
I want to make a script where instead of dying, the player will survive the last attack, with 1 of HP, randomly and this should not trigger in holes or time over.

What is the best way to this? On takedamagescript, nullifying the hit confirm flag and checking the attack type?
 
You can't nullify the hit-confirm flag in takedamage script. The damage has already been calculated and applied at that point. You need to use doattack for to nullify hits. I have an example script used for a parry function, but the principal is the same.

Here is the do attack event. It first verifies the activating event is from receiving an attack (vs giving one). Then it verifies the attack IDs are not the same. Long story how this works internally - just check and set the values as I do here and you'll be good. Once that is done, the parry function is run. If a parry does happen (the parry function returns true), then lasthitc is set false. That's what tells the engine to ignore its own hitcode.
Code:
void main()
{
	void self;      // Entity running event
	void other;     // Entity attacking or receiving vs. self.
	int which;      // Attacker or defender event?
	int id_hit_by;  // Entity ID of entity attack hit.
	int id_attack;  // Entity ID of entity that performed attack.

	self        = getlocalvar("self");
	other       = getlocalvar("other");
	which       = getlocalvar("which");
	
	// Is this a defending event?
	if(!which))
	{
	    // IDs are not the same? This is how we prevent repeat
	    // hits from the same attack.
	    hit_by_id   = getentityproperty(self, "hitbyid");
        attack_id   = getlocalvar("attackid");
	
	    if(hit_by_id != attack_id)
        {
            // Execute parry function. It will check for key timing, 
            // and apply any parry effects. If the parry function
            // returns true, then an attack was successfully parried.
            // In that case, we set last hit confirm variable to
            // false so the engine will skip its internal hit routines.
            if (dc_parry(self, other))
            {		
                changeopenborvariant("lasthitc", 0);
            }
        }				
	}
    
    // Set hit id on self to attack ID for the next cycle.
	changeentityproperty(self, "hitbyid", hit_by_id);
}

The parry function. It's quite old and needs updating, but you can get the idea. You'd do something similar here - checking for your "no death" conditions, and applying the appropriate effects. Remember you have to spawn the flash and sounds yourself (my flash effects actually do the sound work) if you cancel the engine's hit code but still want it to look like a hit.
Code:
#include "data/scripts/vars/anims.h"
#include "data/scripts/vars/entity.h"
#include "data/scripts/com/ani0009.h"
#include "data/scripts/com/summ0001.h"

#define DC_PARRY_MP_GAIN_FACTOR     0.3
#define DC_PARRY_TARGET_FREEZE      30
#define DC_PARRY_OPPONENT_FREEZE    75
#define DC_PARRY_KEY_WINDOW         25                 

// dc_parry
// Caskey, Damon V.
// 2010-xx-xx
// Check opponent_pos_r block key timing and
// parry the attack accordingly.
int dc_parry(void target, void opponent){
           
    float	last_hit_X;         // Last hit, X axis. 
    float   last_hit_Y;         // Last hit, Y axis.
    float   last_hit_Z;         // Last hit, Z axis.																		    
    int		MP_current;         // MP, current value.
	float	MP_max = 0.0;       // MP, maximum.
	int		animation_current;  // Animation in use.
    float   opponent_pos_X;     // Opponent position, X axis.
    int		elapsed_time;       // Current elapsed time.
    int		key_time;           // Time of last key press.
    int		target_next_time;   // Elapsed time for next action (animations, toss, etc.), target.
	int		opponent_next_time; // Elapsed time for next action (animations, toss, etc.), opponent.
	int		pause_add;          // Pause add value of attack to parry.
	int		target_pos_B;       // Target position, base.
	int		target_pos_D;	    // Target position, direction.
	float	target_pos_X;       // Target position, X axis.
	float   target_pos_Y;       // Target position, Y axis.
	int		animation_parry;    // Animation to use for parry.
	
	
	if(!target)
    {	
        target = getlocalvar("self");	
    }
	
	key_time	= getentityvar(target, KEY1SP);														//Get time of last special press.	
	elapsed_time	= openborvariant("elapsed_time");													//Get elapsed time.
	animation_current	= getentityproperty(target, "animationid");											//Get current animation.

	// Player must press Special (block) inside of the parry window timing, 
	// and can't be attacking, in pain, or block stun.
    if ((elapsed_time-key_time) <= DC_PARRY_KEY_WINDOW 																	
		&& (animation_current == openborconstant("ANI_BLOCK")												
		||	animation_current == AIRBLOCK
		||	animation_current == PARRY
		||	animation_current == APARRY))
    {
        // Reset last Special press time.
		setentityvar(target, KEY1SP, 0);															        

		// Get target position.
		target_pos_B	=	getentityproperty(target, "base");
		target_pos_Y	=	getentityproperty(target, "y");

		// If target is on the ground, use ground parry
		// animation (if available). If in the air, then
		// use air parry (if available).
		if(target_pos_Y == target_pos_B)
		{
			animation_parry = ani0009(target, PARRY, 0);													
		}
		else
		{
			animation_parry = ani0009(target, APARRY, 0);													
		}

		// Was a parry animation set? If so we will need to perform several
		// actions to complete the parry effect.
		// 
		// - Turn target toward the attack.
		// - Apply parry animation to the target.
		// - Add a short, static length freeze to the target.
		// - Add a freeze effect to opponent, with a slightly
		// longer static time than target's, plus the pause_add 
		// value of the attack that was parried.
		//
		// - Give target a small MP reward.
		// - Spawn an appropriate flash effect.
		// - Return a true value.
		if(animation_parry)																				
		{   
		    // Get the screen position of the hit. We'll need this 
		    // to spawn the flash correctly.
			last_hit_X		=	openborvariant("lasthitx") - openborvariant("xpos");
			last_hit_Y		=	openborvariant("lasthita");
			last_hit_Z		=	openborvariant("lasthitz");
			
			// Get target and opponent positions.
			target_pos_X    =	getentityproperty(target, "x");
			opponent_pos_X  =	getentityproperty(opponent, "x");
			MP_current		=	getentityproperty(target, "mp");
			MP_max	        +=	getentityproperty(target, "maxmp");
			target_pos_D	=	getentityproperty(target, "direction");
			
			// Get a direction facing attack.
			if(target_pos_X > opponent_pos_X)
			{
				target_pos_D = openborconstant("DIRECTION_LEFT");
			}
			else if(target_pos_X < opponent_pos_X)
			{				
				target_pos_D = openborconstant("DIRECTION_RIGHT");
			}
			
			// Face target toward attack.
			changeentityproperty(target, "direction", target_pos_D);
			
			// MP reward. Calculate a percentage of target's
			// maximum MP and add it to current MP value.
			MP_current = getentityproperty(target, "mp");			
			MP_current += (MP_max * DC_PARRY_MP_GAIN_FACTOR);			
			changeentityproperty(target, "mp", MP_current + (MP_max * DC_PARRY_MP_GAIN_FACTOR));
						
			// Spawn the parry flash.
			summ0001("pflash", "pflash", 0, 1, last_hit_X, last_hit_Y, last_hit_Z, target_pos_D, 0, 0, 1);
				
            // Get the current nextanim times and attack pause add.
			target_next_time	= getentityproperty(target, "nextanim"); + DC_PARRY_TARGET_FREEZE;            	                
	        opponent_next_time	= getentityproperty(opponent, "nextanim"); + DC_PARRY_OPPONENT_FREEZE;
	        pause_add  = getlocalvar("pauseadd");
			
			// Add our additional freeze times to get a new nextanim
			// to use. The opponent's should be slightly longer. This 
			// will "pause" both subjects, but the target is able to act 
			// first, just like the parry function in Street Fighter 3. 
			// For the opponent, we also add in pause_add value of the 
			// parried attack. This means that harder, heavier attacks 
			// have a longer recovery from getting parried than lighter 
			// attacks.
			target_next_time    += DC_PARRY_TARGET_FREEZE;
			opponent_next_time  += DC_PARRY_OPPONENT_FREEZE;
			opponent_next_time  += pause_add;
			
			// Apply opponent's next times to its AI control flags.
	        changeentityproperty(opponent, "nextanim", opponent_next_time);
	        changeentityproperty(opponent, "nextthink", opponent_next_time); 
			changeentityproperty(opponent, "tosstime", opponent_next_time); 

            // Apply target's next times to its AI control flags.
			changeentityproperty(target, "nextanim", target_next_time);
	        changeentityproperty(target, "nextthink", target_next_time);
			changeentityproperty(target, "tosstime", target_next_time);
                            
            return 1;
        }        
    }

    return 0;
}
 
Back
Top Bottom