389 lines
18 KiB
Plaintext
389 lines
18 KiB
Plaintext
#using scripts\codescripts\struct;
|
|
|
|
#using scripts\shared\callbacks_shared;
|
|
#using scripts\shared\clientfield_shared;
|
|
#using scripts\shared\flag_shared;
|
|
#using scripts\shared\flagsys_shared;
|
|
#using scripts\shared\system_shared;
|
|
#using scripts\shared\util_shared;
|
|
#using scripts\shared\weapons\_weaponobjects;
|
|
|
|
#using scripts\shared\abilities\_ability_player;
|
|
#using scripts\shared\abilities\_ability_power;
|
|
#using scripts\shared\abilities\_ability_util;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#namespace armor;
|
|
|
|
function autoexec __init__sytem__() { system::register("gadget_armor",&__init__,undefined,undefined); }
|
|
|
|
function __init__()
|
|
{
|
|
ability_player::register_gadget_activation_callbacks( 4, &gadget_armor_on, &gadget_armor_off );
|
|
ability_player::register_gadget_possession_callbacks( 4, &gadget_armor_on_give, &gadget_armor_on_take );
|
|
ability_player::register_gadget_flicker_callbacks( 4, &gadget_armor_on_flicker );
|
|
ability_player::register_gadget_is_inuse_callbacks( 4, &gadget_armor_is_inuse );
|
|
ability_player::register_gadget_is_flickering_callbacks( 4, &gadget_armor_is_flickering );
|
|
|
|
clientfield::register( "allplayers", "armor_status" , 1, 5, "int" );
|
|
clientfield::register( "toplayer", "player_damage_type" , 1, 1, "int" );
|
|
|
|
callback::on_connect( &gadget_armor_on_connect );
|
|
}
|
|
|
|
function gadget_armor_is_inuse( slot )
|
|
{
|
|
// returns true when local script gadget state is on
|
|
return self GadgetIsActive( slot );
|
|
}
|
|
|
|
function gadget_armor_is_flickering( slot )
|
|
{
|
|
// returns true when local script gadget state is flickering
|
|
return self GadgetFlickering( slot );
|
|
}
|
|
|
|
function gadget_armor_on_flicker( slot, weapon )
|
|
{
|
|
// excuted when the gadget flickers
|
|
self thread gadget_armor_flicker( slot, weapon );
|
|
}
|
|
|
|
function gadget_armor_on_give( slot, weapon )
|
|
{
|
|
// executed when gadget is added to the players inventory
|
|
|
|
self clientfield::set( "armor_status", 0 );
|
|
|
|
self._gadget_armor_slot = slot;
|
|
self._gadget_armor_weapon = weapon;
|
|
}
|
|
|
|
function gadget_armor_on_take( slot, weapon )
|
|
{
|
|
// executed when gadget is removed from the players inventory
|
|
|
|
self gadget_armor_off( slot, weapon );
|
|
}
|
|
|
|
//self is the player
|
|
function gadget_armor_on_connect()
|
|
{
|
|
// setup up stuff on player connec
|
|
}
|
|
|
|
function gadget_armor_on( slot, weapon )
|
|
{
|
|
if ( IsAlive(self) )
|
|
{
|
|
// excecutes when the gadget is turned on
|
|
self flagsys::set( "gadget_armor_on" );
|
|
|
|
//armor section
|
|
self.shock_onpain = 0;
|
|
|
|
//set the hitpoints
|
|
self.gadgetHitPoints = ( ( IsDefined( weapon.gadget_max_hitpoints ) && weapon.gadget_max_hitpoints > 0 ) ? weapon.gadget_max_hitpoints : undefined );
|
|
|
|
if ( isdefined( self.overridePlayerDamage ) )
|
|
{
|
|
self.originalOverridePlayerDamage = self.overridePlayerDamage;
|
|
}
|
|
|
|
self.overridePlayerDamage = &armor_player_damage;
|
|
self thread gadget_armor_status( slot, weapon );
|
|
}
|
|
}
|
|
|
|
function gadget_armor_off( slot, weapon )
|
|
{
|
|
armorOn = flagsys::get( "gadget_armor_on" );
|
|
|
|
self notify( "gadget_armor_off" );
|
|
|
|
// excecutes when the gadget is turned off
|
|
self flagsys::clear( "gadget_armor_on" );
|
|
|
|
//armor section
|
|
self.shock_onpain = 1;
|
|
self clientfield::set( "armor_status", 0 );
|
|
if ( isdefined( self.originalOverridePlayerDamage ) )
|
|
{
|
|
self.overridePlayerDamage = self.originalOverridePlayerDamage;
|
|
self.originalOverridePlayerDamage = undefined;
|
|
}
|
|
|
|
if ( armorOn && IsAlive( self ) && isdefined( level.playGadgetSuccess ) )
|
|
{
|
|
self [[ level.playGadgetSuccess ]]( weapon );
|
|
}
|
|
}
|
|
|
|
function gadget_armor_flicker( slot, weapon )
|
|
{
|
|
self endon( "disconnect" );
|
|
|
|
if ( !self gadget_armor_is_inuse( slot ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
eventTime = self._gadgets_player[slot].gadget_flickertime;
|
|
|
|
self set_gadget_status( "Flickering", eventTime );
|
|
|
|
while( 1 )
|
|
{
|
|
if ( !self GadgetFlickering( slot ) )
|
|
{
|
|
self set_gadget_status( "Normal" );
|
|
return;
|
|
}
|
|
|
|
wait( 0.5 );
|
|
}
|
|
}
|
|
|
|
function set_gadget_status( status, time )
|
|
{
|
|
timeStr = "";
|
|
|
|
if ( IsDefined( time ) )
|
|
{
|
|
timeStr = "^3" + ", time: " + time;
|
|
}
|
|
|
|
if ( GetDvarInt( "scr_cpower_debug_prints" ) > 0 )
|
|
self IPrintlnBold( "Gadget Armor: " + status + timeStr );
|
|
}
|
|
|
|
function armor_damage_type_multiplier( sMeansOfDeath )
|
|
{
|
|
switch(sMeansOfDeath)
|
|
{
|
|
case "MOD_CRUSH":
|
|
case "MOD_TELEFRAG":
|
|
case "MOD_SUICIDE":
|
|
case "MOD_DROWN":
|
|
case "MOD_HIT_BY_OBJECT":
|
|
case "MOD_FALLING":
|
|
return 0; // no protection - damage will fall through to player
|
|
|
|
|
|
case "MOD_PROJECTILE":
|
|
return GetDvarFloat( "scr_armor_mod_proj_mult", 1 );
|
|
|
|
case "MOD_MELEE":
|
|
case "MOD_MELEE_WEAPON_BUTT":
|
|
return GetDvarFloat( "scr_armor_mod_melee_mult", 2 );
|
|
break;
|
|
|
|
case "MOD_EXPLOSIVE":
|
|
case "MOD_PROJECTILE_SPLASH":
|
|
case "MOD_GRENADE":
|
|
case "MOD_GRENADE_SPLASH":
|
|
return GetDvarFloat( "scr_armor_mod_expl_mult", 1 );
|
|
break;
|
|
|
|
case "MOD_PISTOL_BULLET":
|
|
case "MOD_RIFLE_BULLET":
|
|
return GetDvarFloat( "scr_armor_mod_bullet_mult", .7 );
|
|
break;
|
|
|
|
|
|
case "MOD_BURNED":
|
|
case "MOD_UNKNOWN":
|
|
case "MOD_TRIGGER_HURT":
|
|
default:
|
|
return GetDvarFloat( "scr_armor_mod_misc_mult", 1 );
|
|
}
|
|
}
|
|
|
|
function armor_damage_mod_allowed( weapon, sMeansOfDeath )
|
|
{
|
|
switch( weapon.name )
|
|
{
|
|
case "hero_lightninggun":
|
|
case "hero_lightninggun_arc":
|
|
return false;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
switch(sMeansOfDeath)
|
|
{
|
|
case "MOD_CRUSH":
|
|
case "MOD_TELEFRAG":
|
|
case "MOD_SUICIDE":
|
|
case "MOD_DROWN":
|
|
case "MOD_HIT_BY_OBJECT":
|
|
case "MOD_FALLING":
|
|
case "MOD_MELEE":
|
|
case "MOD_MELEE_WEAPON_BUTT":
|
|
case "MOD_EXPLOSIVE":
|
|
case "MOD_PROJECTILE_SPLASH":
|
|
case "MOD_GRENADE":
|
|
case "MOD_GRENADE_SPLASH":
|
|
case "MOD_BURNED":
|
|
case "MOD_UNKNOWN":
|
|
case "MOD_TRIGGER_HURT":
|
|
return false;
|
|
|
|
case "MOD_PISTOL_BULLET":
|
|
case "MOD_RIFLE_BULLET":
|
|
return true;
|
|
|
|
case "MOD_PROJECTILE":
|
|
// if we are using this as a impact damage only projectile then we allow it
|
|
if (weapon.explosionradius == 0 )
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
default:
|
|
return false;
|
|
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function armor_should_take_damage( eAttacker, weapon, sMeansOfDeath, sHitLoc )
|
|
{
|
|
if ( isdefined( eAttacker ) && !weaponobjects::friendlyFireCheck( self, eAttacker ) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if ( !armor_damage_mod_allowed( weapon, sMeansOfDeath ) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if( isDefined( sHitLoc ) && ( sHitLoc == "head" || sHitLoc == "helmet" ) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function armor_player_damage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime )
|
|
{
|
|
damage = iDamage;
|
|
self.power_armor_took_damage = false;
|
|
if ( ( self armor_should_take_damage( eAttacker, weapon, sMeansOfDeath, sHitLoc ) ) && isdefined( self._gadget_armor_slot ) )
|
|
{
|
|
self clientfield::set_to_player( "player_damage_type", 1 );
|
|
if ( self gadget_armor_is_inuse( self._gadget_armor_slot ) )
|
|
{
|
|
armor_damage = damage * armor_damage_type_multiplier( sMeansOfDeath );
|
|
|
|
damage = 0;
|
|
|
|
if ( armor_damage > 0 )
|
|
{
|
|
if( IsDefined( self.gadgetHitPoints ) )
|
|
{
|
|
hitPointsLeft = self.gadgetHitPoints;
|
|
}
|
|
else
|
|
{
|
|
hitPointsLeft = self GadgetPowerChange( self._gadget_armor_slot, 0.0 );
|
|
}
|
|
|
|
if ( weapon == level.weaponLightningGun || weapon == level.weaponLightningGunArc )
|
|
{
|
|
// lightning gun will take all armor but do no damage
|
|
armor_damage = hitPointsLeft;
|
|
}
|
|
else if ( hitPointsLeft < armor_damage )
|
|
{
|
|
// will apply rest of damage back to player
|
|
damage = armor_damage - hitPointsLeft;
|
|
}
|
|
|
|
if( IsDefined( self.gadgetHitPoints ) )
|
|
{
|
|
self hitpoints_loss_event( armor_damage );
|
|
}
|
|
else
|
|
{
|
|
self ability_power::power_loss_event( self._gadget_armor_slot, eAttacker, armor_damage, "armor damage" );
|
|
}
|
|
self.power_armor_took_damage = true;
|
|
self.power_armor_last_took_damage_time = GetTime();
|
|
self AddToDamageIndicator( int( armor_damage * GetDvarFloat( "scr_armor_mod_view_kick_mult", .001 ) ), vDir);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
self clientfield::set_to_player( "player_damage_type", 0 );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
self clientfield::set_to_player( "player_damage_type", 0 );
|
|
}
|
|
|
|
return damage;
|
|
}
|
|
|
|
function hitpoints_loss_event( val )
|
|
{
|
|
if ( val > 0 )
|
|
{
|
|
self.gadgetHitPoints -= val;
|
|
}
|
|
}
|
|
|
|
function gadget_armor_status( slot, weapon )
|
|
{
|
|
self endon( "disconnect" );
|
|
|
|
maxHitPoints = ( ( IsDefined( weapon.gadget_max_hitpoints ) && weapon.gadget_max_hitpoints > 0 ) ? weapon.gadget_max_hitpoints : 100 );
|
|
|
|
while ( self flagsys::get( "gadget_armor_on" ) )
|
|
{
|
|
if( IsDefined( self.gadgetHitPoints ) && self.gadgetHitPoints <= 0 )
|
|
{
|
|
self playsoundtoplayer( "wpn_power_armor_destroyed_plr", self );
|
|
self playsoundtoallbutplayer( "wpn_power_armor_destroyed_npc", self );
|
|
|
|
self GadgetDeactivate( slot, weapon );
|
|
self GadgetPowerSet( slot, 0.0 );
|
|
break;
|
|
}
|
|
if( IsDefined( self.gadgetHitPoints ) )
|
|
{
|
|
hitPointsRatio = self.gadgetHitPoints / maxHitPoints;
|
|
}
|
|
else
|
|
{
|
|
hitPointsRatio = self GadgetPowerChange( self._gadget_armor_slot, 0.0 ) / maxHitPoints;
|
|
}
|
|
stage = 1 + int( hitPointsRatio * 5 );
|
|
|
|
if ( stage > 5 )
|
|
{
|
|
stage = 5;
|
|
}
|
|
|
|
self clientfield::set( "armor_status", stage );
|
|
|
|
{wait(.05);};
|
|
}
|
|
|
|
self clientfield::set( "armor_status", 0 );
|
|
} |