ModmeDTZxPorter: Goodbye

New Modme platform coming soon!
Detect damage on a model ( NO TRIGGERS )
Viewed 826 time(s)
Topic created on 1515167290
Original post
Modme User
137 wins
function your_function_name()
{
	e_model = getEnt( "YOUR_KVP_VALUE", "script_noteworthy" );
	e_model setCanDamage( 1 );
    
	while ( 1 )
	{
		e_model waittill( "damage", damage, attacker, dir, point, mod, model, tag, part, weapon, flags, inflictor, chargeLevel );
        
		if ( weapon.name == "weapon_name" ) // Optional if you want a certain weapon only to count
			break;
        
	}
	
	// Your code to run when this model is damaged
	playFx( "fx_path\fx_name", e_model.origin ); // If you want a fx to play on the model when it is damaged
	e_model delete(); // If you want the model to delete when shot
}

HarryBo21's BO3 Perks v2.2.1
LINK TO MODME POST
FX Library v1.0.2
LINK TO MODME POST
Black Ops 3 Gun Pack v2.4.1
LINK TO MODME POST
Black Ops 3 Napalm Zombie v3.0.1
LINK TO MODME POST
Black Ops 3 Shrieker Zombie v3.0.1
LINK TO MODME POST
Reply #1 on 1515167373
Modme User
42 wins

Don't forget to precache


Don't PM me about stuff that should be on the forum.
My creations:
Debug (on/off)
Jukebox
Gum Anti-cheat
Kino box locator
Elemental Bows

Test search engine for this site via Google
Reply #2 on 1515169689
Modme User
137 wins

mathfag

Don't forget to precache

 ...

 

everything in level._effect is precached already

 

precaching again wastes one of the available 800 fx


HarryBo21's BO3 Perks v2.2.1
LINK TO MODME POST
FX Library v1.0.2
LINK TO MODME POST
Black Ops 3 Gun Pack v2.4.1
LINK TO MODME POST
Black Ops 3 Napalm Zombie v3.0.1
LINK TO MODME POST
Black Ops 3 Shrieker Zombie v3.0.1
LINK TO MODME POST
Reply #3 on 1515171652
Modme User
42 wins

You wrote "fx_path\fx_name" not level._effect["fx_path\fx_name"] therefore precache. :)


Don't PM me about stuff that should be on the forum.
My creations:
Debug (on/off)
Jukebox
Gum Anti-cheat
Kino box locator
Elemental Bows

Test search engine for this site via Google
Reply #4 on 1515186210
Modme User
64 wins

mathfag

You wrote "fx_path\fx_name" not level._effect["fx_path\fx_name"] therefore precache. :)

 oh c'mon you're just being nitpicky on purpose. people should know how FX works, and if not they should know this script is not the place to learn it, as FX isn't even related to the topic at hand.


Reply #5 on 1515231562
Modme User
137 wins

Detect damage on a model ( NO TRIGGERS )

 

Detect damage on a model

 

not 

 

how to play a fx when a model is shot

 

i merely advised where to play a fx and how to delete the model - as OPTIONAL extra snippits of info, and the way to do it, not a full tutorial on playing fx

 

at least my code WORKS so do one


HarryBo21's BO3 Perks v2.2.1
LINK TO MODME POST
FX Library v1.0.2
LINK TO MODME POST
Black Ops 3 Gun Pack v2.4.1
LINK TO MODME POST
Black Ops 3 Napalm Zombie v3.0.1
LINK TO MODME POST
Black Ops 3 Shrieker Zombie v3.0.1
LINK TO MODME POST
Reply #6 on 1547211817
Modme User
0 wins

Nice script, by the way, how i can change the "e_model" is a "zombie" and only count the "melee weapons"?

How i can detect the player is knifing a zombie?

function your_function_name()
{
	zombies = level.zombie_team;
    
	while ( 1 )
	{
		zombies waittill( "damage", damage, attacker, dir, point, mod, model, tag, part, weapon, flags, inflictor, chargeLevel );
        
		if ( weapon.name == "MOD_MELEE" ) // Optional if you want a certain weapon only to count
			break;
		}        
	}

	//my code	
	
}
Reply #7 on 1547212561
Modme User
5 wins

eDeK

Nice script, by the way, how i can change the "e_model" is a "zombie" and only count the "melee weapons"? How i can detect the player is knifing a zombie? function your_function_name() { zombies = level.zombie_team; while ( 1 ) { zombies waittill( "damage", damage, attacker, dir, point, mod, model, tag, part, weapon, flags, inflictor, chargeLevel ); if ( weapon.name == "MOD_MELEE" ) // Optional if you want a certain weapon only to count break; } } //my code }

 

if ( mod == "MOD_MELEE" )

Also you should check that the damager is actually a player

if ( mod == "MOD_MELEE" && IsPlayer(attacker) )
Reply #8 on 1547215973
Modme User
0 wins

Im doing a Powerup, this function is "when the player knife the zombie", but not work, i dont know how detect "the player is knifing a zombie".

function knife_me()
{
	self endon( "disconnect" );
    self endon( "death" );
    self endon( "pyrotechnic_done" );

    zombies = level.zombie_team;
               
    zombies waittill( "damage", damage, attacker, dir, point, mod, model, tag, part, weapon, flags, inflictor, chargeLevel );      
    {
	    if ( mod == "MOD_MELEE" && IsPlayer(attacker) )	 
	    {
	        self fire_works_summon( self );	
	    }
	}    

	WAIT_SERVER_FRAME;	
    
}

Thanks for reply/help.

Reply #9 on 1547230085
Modme User
1 wins

eDeK

Im doing a Powerup, this function is "when the player knife the zombie", but not work, i dont know how detect "the player is knifing a zombie". function knife_me() { self endon( "disconnect" ); self endon( "death" ); self endon( "pyrotechnic_done" ); zombies = level.zombie_team; zombies waittill( "damage", damage, attacker, dir, point, mod, model, tag, part, weapon, flags, inflictor, chargeLevel ); { if ( mod == "MOD_MELEE" && IsPlayer(attacker) ) { self fire_works_summon( self ); } } WAIT_SERVER_FRAME; } Thanks for reply/help.

 You cannot waittill on a variable containing the string "axis". You will have to iterate through each zombie, and thread a waittill on each zombie.

 

I'd try something like:

 

function knife_me()
{
    zombies = GetAiTeamArray( level.zombie_team );
    foreach(zombie in zombies)
    {
        zombie thread wait_for_knife();
    }
}
function wait_for_knife()
{
    self endon( "disconnect" );
    self endon( "death" );
    self endon( "pyrotechnic_done" );
    while(1)
    {
        self waittill( "damage", damage, attacker, dir, point, mod, model, tag, part, weapon, flags, inflictor, chargeLevel );
        if ( mod == "MOD_MELEE" && IsPlayer(attacker) )	 
        {
            self fire_works_summon( self );	
        }
        WAIT_SERVER_FRAME;
    }
}

 

Note: I have not tested this code, hope it's error free.

Reply #10 on 1547238545
Modme User
0 wins

Thanks for reply Tom but dont work it.

I need like ihmiskeho say "the damager is actually a player".

Is something like that:

if(isdefined(attacker) && attacker.team != self.team && !isdefined(attacker.playername))  
{
	if ( mod == "MOD_MELEE" && IsPlayer(attacker) )	 
    {
        self fire_works_summon( self );	
    }
}

But this no work too. :(

Reply #11 on 1547241069
Modme User
42 wins
zm_spawner::register_zombie_damage_callback( &knife_dmg ); //in function main

//when a AI is damaged, this will run
//self = AI
function knife_dmg(str_mod, str_hit_location, v_hit_origin, e_player, n_amount, w_weapon, direction_vec, tagName, modelName, partName, dFlags, inflictor, chargeLevel) 
{

if(str_mod == "MOD_MELEE")
	self thread fire_works_summon();

}

function fire_works_summon()
{
//use this new function or you may run into problems


}

Don't PM me about stuff that should be on the forum.
My creations:
Debug (on/off)
Jukebox
Gum Anti-cheat
Kino box locator
Elemental Bows

Test search engine for this site via Google
Reply #12 on 1547253314
Modme User
0 wins

Works fine Mathfag, thanks for reply dude, the problem is when i grab the powerup the "Knifing effect (fireworks)" dont stop, still active after the powerup is over.

function __init__()
{
	
	zm_powerups::register_powerup( "pyrotechnic", &grab_pyrotechnic );
	if( ToLower( GetDvarString( "g_gametype" ) ) != "pyrotechnic" )
	{
		zm_powerups::add_zombie_powerup( "pyrotechnic", "pyrotechnic_powerup_model", "", &zm_powerups::func_should_always_drop, POWERUP_ONLY_AFFECTS_GRABBER, !POWERUP_ANY_TEAM, !POWERUP_ZOMBIE_GRABBABLE );						
	} 
}

function grab_pyrotechnic( player )
{
	player PlayLocalSound("vox_pyrotechnic");
	skip = player add_powerup_hud( "pyrotechnic_material_hud", N_POWERUP_DEFAULT_TIME );
    zm_spawner::register_zombie_damage_callback( &knife_dmg );    

	if( skip )
		return; 
	
	if( isdefined(player.pyrotechnic_active) )
		return;		
	
	player thread do_pyrotechnic();
}

function do_pyrotechnic()
{
	self.pyrotechnic_active = true;

    self notify( "pyrotechnic_done" );
    self endon( "disconnect" );
    self endon( "death" );
    self endon( "pyrotechnic_done" );

    self thread knife_dmg();	
}

function knife_dmg(str_mod, str_hit_location, v_hit_origin, e_player, n_amount, w_weapon, direction_vec, tagName, modelName, partName, dFlags, inflictor, chargeLevel) 
{		
    self endon( "disconnect" );
    self endon( "death" );
    self endon( "pyrotechnic_done" );

	if(str_mod == "MOD_MELEE")
	{
		self thread fire_works_summon( e_player, w_weapon );
	}

	WAIT_SERVER_FRAME;
}
Reply #13 on 1547286864
Modme User
42 wins

Put this in __init__. It should only be activated once.

zm_spawner::register_zombie_damage_callback( &knife_dmg );

 

Remove

self thread knife_dmg();

 

Replace

self.pyrotechnic_active = true;

with

level.pyrotechnic_active = true;

 

Replace function knife_dmg() with

function knife_dmg(str_mod, str_hit_location, v_hit_origin, e_player, n_amount, w_weapon, direction_vec, tagName, modelName, partName, dFlags, inflictor, chargeLevel) 
{		

if(level.pyrotechnic_active == 0)
return 0;

	if(str_mod == "MOD_MELEE")
	{
		self thread fire_works_summon( e_player, w_weapon );
	}

	WAIT_SERVER_FRAME;
}

 

Make sure

level.pyrotechnic_active

is set to false when the powerup is over

 


Don't PM me about stuff that should be on the forum.
My creations:
Debug (on/off)
Jukebox
Gum Anti-cheat
Kino box locator
Elemental Bows

Test search engine for this site via Google
Reply #14 on 1547313271
Modme User
0 wins

I do all you say. 

When i spawn in the game (I shoot the zombies, i cant do points and the "Knife effect is active").

After this, i grab the powerup (I shoot the zombies, i can do points but the "Knife effect is no active" even after powerup is over.").

Very weird all, i gonna still testing but at the moment i have this.

//POWERUP
function __init__()
{	
	zm_powerups::register_powerup( "pyrotechnic", &grab_pyrotechnic );
	if( ToLower( GetDvarString( "g_gametype" ) ) != "pyrotechnic" )
	{
		zm_powerups::add_zombie_powerup( "pyrotechnic", "pyrotechnic_powerup_model", "", &zm_powerups::func_should_always_drop, POWERUP_ONLY_AFFECTS_GRABBER, !POWERUP_ANY_TEAM, !POWERUP_ZOMBIE_GRABBABLE );
		zm_spawner::register_zombie_damage_callback( &knife_dmg );					
	} 
}

function grab_pyrotechnic( player )
{
	player PlayLocalSound("vox_pyrotechnic");
	skip = player add_powerup_hud( "pyrotechnic_material_hud", N_POWERUP_DEFAULT_TIME );    	

	if( skip )
		return; 
	
	if( isdefined(player.pyrotechnic_active) )
		return;		
	
	player thread do_pyrotechnic();
}

function do_pyrotechnic()
{
	level.pyrotechnic_active = true;

    self notify( "pyrotechnic_done" );
    self endon( "disconnect" );
    self endon( "death" );
    self endon( "pyrotechnic_done" );    
}

function knife_dmg(str_mod, str_hit_location, v_hit_origin, e_player, n_amount, w_weapon, direction_vec, tagName, modelName, partName, dFlags, inflictor, chargeLevel) 
{		

	if(level.pyrotechnic_active == 0)
	return 0;

	if(str_mod == "MOD_MELEE")
	{
		self thread fire_works_summon( e_player, w_weapon );
	}

	WAIT_SERVER_FRAME;
}

//HUD
function wait_til_timeout( player, hud )//player = self;
{
	while( hud.time > 0 )
	{
		wait(1);
		hud.time--; 		
	}
	
	player notify( "pyrotechnic_done" );
	player remove_powerup_hud( "pyrotechnic_material_hud" );
	player.pyrotechnic_active = undefined;
	
	
}

function add_powerup_hud( powerup, timer )
{
	if ( !isDefined( self.powerup_hud ) )
		self.powerup_hud = [];
	
	if( isDefined( self.powerup_hud[powerup] ) )
	{
		self.powerup_hud[powerup].time = timer; 
		return true; // tells to skip because powerup is already active
				
	}
	
	self endon( "disconnect" );
	hud = NewClientHudElem( self );
	hud.powerup = powerup;
	hud.foreground = true;
	hud.hidewheninmenu = true;
	hud.alignX = "center";
	hud.alignY = "bottom";
	hud.horzAlign = "center";
	hud.vertAlign = "bottom";
	hud.x = hud.x;
	hud.y = hud.y - 50;
	hud.alpha = 1;
	hud SetShader( powerup , 64, 64 );
	hud scaleOverTime( .5, 32, 32 );
	hud.time = timer;
	hud thread harrybo21_blink_powerup_hud();
	thread wait_til_timeout( self, hud ); 
	
	self.powerup_hud[ powerup ] = hud;
	
	a_keys = GetArrayKeys( self.powerup_hud );
	for ( i = 0; i < a_keys.size; i++ )
	 	self.powerup_hud[ a_keys[i] ] thread move_hud( .5, 0 - ( 24 * ( self.powerup_hud.size ) ) + ( i * 37.5 ) + 25, self.powerup_hud[ a_keys[i] ].y );
	
	//return false;  // powerup is not already active
	level.pyrotechnic_active = false;
		

}

function move_hud( time, x, y )
{
	self moveOverTime( time );
	self.x = x;
	self.y = y;
}

function harrybo21_blink_powerup_hud()
{
	self endon( "delete" );
	self endon( "stop_fade" );
	while( isDefined( self ) )
	{
		if ( self.time >= 20 )
		{
			self.alpha = 1; 
			wait .1;
			continue;
		}
		fade_time = 1;
		if ( self.time < 10 )
			fade_time = .5;
		if ( self.time < 5 )
			fade_time = .25;
			
		self fadeOverTime( fade_time );
		self.alpha = !self.alpha;
		
		wait( fade_time );
	}
}

function remove_powerup_hud( powerup )
{
	self.powerup_hud[ powerup ] destroy();
	self.powerup_hud[ powerup ] notify( "stop_fade" );
	self.powerup_hud[ powerup ] fadeOverTime( .2 );
	self.alpha = 0;
	wait .2;
	self.powerup_hud[ powerup ] delete();
	self.powerup_hud[ powerup ] = undefined;
	self.powerup_hud = array::remove_index( self.powerup_hud, self.powerup_hud[ powerup ], true );
	
	a_keys = GetArrayKeys( self.powerup_hud );
	for ( i = 0; i < a_keys.size; i++ )
	 	self.powerup_hud[ a_keys[i] ] thread move_hud( .5, 0 - ( 24 * ( self.powerup_hud.size ) ) + ( i * 37.5 ) + 25, self.powerup_hud[ a_keys[i] ].y );
}


//FIREWORKS
// Checks to see if fire works is running
// self == zombie
function fire_works_zombie_validation()
{
	if( IS_TRUE( self.barricade_enter ) )
	{
		return false;
	}
	
	if ( IS_TRUE( self.is_traversing ) )
	{
		return false;
	}

	if( !IS_TRUE( self.completed_emerging_into_playable_area ) && !IsDefined( self.first_node ) )
	{
		return false;
	}

	if ( IS_TRUE( self.is_leaping ) )
	{
		return false;
	}
	
	return true;
}

// Summons the player's current gun to pop up and fire in a circle for a period of time
// immune_result_direct == target is immune to death gib
// immune_result_indirect == target is immune to death gib on hit from the magic bullet
// self == target zombie
function fire_works_summon( e_player, w_weapon )
{
	w_summoned_weapon = e_player GetCurrentWeapon();
	v_target_zombie_origin = self.origin;
	
	// Checks if self is immune_result_direct == true. If so, do not kill self
	if ( !IS_TRUE( level.aat[ ZM_AAT_FIRE_WORKS_NAME ].immune_result_direct[ self.archetype ] ) )
	{
		self thread zombie_death_gib( e_player, w_weapon, e_player );
	}

	// Spawns base model
	v_firing_pos = v_target_zombie_origin + ZM_AAT_FIRE_WORKS_ZOMBIE_GUN_HEIGHT;
	v_start_yaw = VectorToAngles( v_firing_pos - v_target_zombie_origin );
	v_start_yaw = (0, v_start_yaw[1], 0);
	mdl_weapon = zm_utility::spawn_weapon_model( w_summoned_weapon, undefined, v_target_zombie_origin, v_start_yaw );

	// Stat tracking definitions
	mdl_weapon.owner = e_player;
	mdl_weapon.b_aat_fire_works_weapon = true;
	mdl_weapon.allow_zombie_to_target_ai = true; // lets the zombie damage callbacks pass through damage from this
	
	// Fires FX
	mdl_weapon thread clientfield::set( ZM_AAT_FIRE_WORKS_NAME, 1 );
	
	// Moves weapon upwards to firing position
	mdl_weapon MoveTo( v_firing_pos, ZM_AAT_FIRE_WORKS_SUMMON_TIME );
	mdl_weapon waittill( "movedone" );

	// Starts firing
	for ( i = 0; i < ZM_AAT_FIRE_WORKS_FIRING_NUM_FRAMES; i++ )
	{
		zombie = mdl_weapon zm_aat_fire_works_get_target();
		if ( !IsDefined( zombie ) )
		{
			//if no target available, just pick a random yaw
			v_curr_yaw = (0, RandomIntRange( 0, 360 ), 0);
			v_target_pos = mdl_weapon.origin + VectorScale( AnglesToForward( v_curr_yaw ), 40 );
		}
		else
		{
			v_target_pos = zombie GetCentroid();
		}

		mdl_weapon.angles = VectorToAngles( v_target_pos - mdl_weapon.origin );
		v_flash_pos = mdl_weapon GetTagOrigin( "tag_flash" );
		mdl_weapon DontInterpolate();

		// MagicBullet shots are credited to the model rather than player, as MagicBullet causes recoil on player
		MagicBullet( w_summoned_weapon, v_flash_pos, v_target_pos, mdl_weapon );

		util::wait_network_frame();
	}

	mdl_weapon MoveTo( v_target_zombie_origin, ZM_AAT_FIRE_WORKS_SUMMON_TIME );
	mdl_weapon waittill( "movedone" );
	
	mdl_weapon clientfield::set( ZM_AAT_FIRE_WORKS_NAME, 0 );
	
	util::wait_network_frame(); // Waits for FX to complete
	util::wait_network_frame(); // extra waits for theater playback
	util::wait_network_frame(); // extra waits for theater playback
	
	mdl_weapon Delete();
	wait .25; // Delay for final projectile-based gun shots to finish firing
}

// Death callback for zombies killed by summoned Fire Works weapon
function zm_aat_fire_works_get_target()
{
	a_ai_zombies = array::randomize( GetAiTeamArray( "axis" ) );

	los_checks = 0;
	for ( i = 0; i < a_ai_zombies.size; i++ )
	{
		zombie = a_ai_zombies[i];
		test_origin = zombie getcentroid();
		if ( DistanceSquared( self.origin, test_origin ) > ZM_AAT_FIRE_WORKS_RANGE_SQ )
		{
			continue;
		}

		if ( los_checks < ZM_AAT_FIRE_WORKS_MAX_LOS_CHECKS && !zombie DamageConeTrace( self.origin ) )
		{
			los_checks++;
			continue;
		}

		return zombie;
	}

	if ( a_ai_zombies.size )
	{
		// just return the first one, so that we at least change direction
		return a_ai_zombies[0];
	}

	return undefined;
}

// self is a zombie
function zm_aat_fire_works_zombie_damage_response( str_mod, str_hit_location, v_hit_origin, e_attacker, n_amount, w_weapon, direction_vec, tagName, modelName, partName, dFlags, inflictor, chargeLevel )
{
	if ( IS_TRUE( level.aat[ ZM_AAT_FIRE_WORKS_NAME ].immune_result_indirect[ self.archetype ] ) )
	{
		return false;
	}

	if ( IS_TRUE( e_attacker.b_aat_fire_works_weapon ) )
	{
		self thread zombie_death_gib( e_attacker, w_weapon, e_attacker.owner );
		return true;
	}

	return false;
}

// Death callback for zombies killed by summoned Fire Works weapon
function zm_aat_fire_works_death_callback( attacker )
{
	if ( isdefined( attacker ) )
	{
		if ( IS_TRUE( attacker.b_aat_fire_works_weapon ) )
		{
			// Checks if player has disconnected
			if ( isdefined( attacker.owner ) )
			{
				e_attacking_player = attacker.owner;
				// TODO set up stat tracking
			}
		}
	}
}

// Gibs and Kills zombie
// self == affected zombie
// e_attacker == the script_model of the gun (needs to do the damage, so the player doesn't receive kickback)
// w_weapon == the weapon to apply damage using
// e_owner == the owner of the gun (for awarding challenge stat progress)
function zombie_death_gib( e_attacker, w_weapon, e_owner )
{
	gibserverutils::gibhead( self );
	
	if ( math::cointoss() )
	{
		gibserverutils::gibleftarm( self );
	}
	else
	{
		gibserverutils::gibrightarm( self );
	}
	
	gibserverutils::giblegs( self );
	
	self DoDamage( self.health, self.origin, e_attacker, w_weapon, "torso_upper" );

	if ( IsDefined( e_owner ) && IsPlayer( e_owner ) )
	{
		e_owner zm_stats::increment_challenge_stat( "ZOMBIE_HUNTER_FIRE_WORKS" );
	}
}

Thanks for your time Mathfag.