#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 ); }