mirror of
https://github.com/JezuzLizard/Recompilable-gscs-for-BO2-zombies-and-multiplayer.git
synced 2025-06-09 10:27:51 -05:00
492 lines
12 KiB
Plaintext
492 lines
12 KiB
Plaintext
#include maps/mp/_scoreevents;
|
|
#include maps/mp/killstreaks/_killstreak_weapons;
|
|
#include maps/mp/killstreaks/_killstreaks;
|
|
#include common_scripts/utility;
|
|
#include maps/mp/_utility;
|
|
|
|
#using_animtree( "mp_riotshield" );
|
|
|
|
init()
|
|
{
|
|
if ( !isDefined( level.riotshield_name ) )
|
|
{
|
|
level.riotshield_name = "riotshield_mp";
|
|
if ( isDefined( level.is_zombie_level ) && level.is_zombie_level )
|
|
{
|
|
level.riotshield_name = "riotshield_zm";
|
|
}
|
|
}
|
|
level.deployedshieldmodel = "t6_wpn_shield_carry_world";
|
|
level.stowedshieldmodel = "t6_wpn_shield_stow_world";
|
|
level.carriedshieldmodel = "t6_wpn_shield_carry_world";
|
|
level.detectshieldmodel = "t6_wpn_shield_carry_world_detect";
|
|
if ( isDefined( level.is_zombie_level ) && level.is_zombie_level )
|
|
{
|
|
level.deployedshieldmodel = "t6_wpn_zmb_shield_world";
|
|
level.stowedshieldmodel = "t6_wpn_zmb_shield_stow";
|
|
level.carriedshieldmodel = "t6_wpn_zmb_shield_world";
|
|
}
|
|
precachemodel( level.stowedshieldmodel );
|
|
precachemodel( level.carriedshieldmodel );
|
|
precachemodel( level.detectshieldmodel );
|
|
level.riotshielddestroyanim = %o_riot_stand_destroyed;
|
|
level.riotshielddeployanim = %o_riot_stand_deploy;
|
|
level.riotshieldshotanimfront = %o_riot_stand_shot;
|
|
level.riotshieldshotanimback = %o_riot_stand_shot_back;
|
|
level.riotshieldmeleeanimfront = %o_riot_stand_melee_front;
|
|
level.riotshieldmeleeanimback = %o_riot_stand_melee_back;
|
|
loadfx( "weapon/riotshield/fx_riotshield_depoly_lights" );
|
|
loadfx( "weapon/riotshield/fx_riotshield_depoly_dust" );
|
|
level.riotshield_placement_zoffset = 26;
|
|
}
|
|
|
|
register()
|
|
{
|
|
registerclientfield( "scriptmover", "riotshield_state", 1, 2, "int" );
|
|
}
|
|
|
|
watchpregameclasschange()
|
|
{
|
|
self endon( "death" );
|
|
self endon( "disconnect" );
|
|
self endon( "track_riot_shield" );
|
|
self waittill( "changed_class" );
|
|
if ( level.ingraceperiod && !self.hasdonecombat )
|
|
{
|
|
self clearstowedweapon();
|
|
self refreshshieldattachment();
|
|
self thread trackriotshield();
|
|
}
|
|
}
|
|
|
|
watchriotshieldpickup()
|
|
{
|
|
self endon( "death" );
|
|
self endon( "disconnect" );
|
|
self endon( "track_riot_shield" );
|
|
self notify( "watch_riotshield_pickup" );
|
|
self endon( "watch_riotshield_pickup" );
|
|
self waittill( "pickup_riotshield" );
|
|
self endon( "weapon_change" );
|
|
/#
|
|
println( "Picked up riotshield, expecting weapon_change notify..." );
|
|
#/
|
|
wait 0,5;
|
|
/#
|
|
println( "picked up shield but didn't change weapons, attach it!" );
|
|
#/
|
|
self.hasriotshield = self hasweapon( level.riotshield_name );
|
|
self.hasriotshieldequipped = self getcurrentweapon() == level.riotshield_name;
|
|
self refreshshieldattachment();
|
|
}
|
|
|
|
trackriotshield()
|
|
{
|
|
self endon( "death" );
|
|
self endon( "disconnect" );
|
|
self notify( "track_riot_shield" );
|
|
self endon( "track_riot_shield" );
|
|
self thread watchpregameclasschange();
|
|
self waittill( "weapon_change", newweapon );
|
|
self refreshshieldattachment();
|
|
self.hasriotshield = self hasweapon( level.riotshield_name );
|
|
self.hasriotshieldequipped = self getcurrentweapon() == level.riotshield_name;
|
|
self.lastnonshieldweapon = "none";
|
|
while ( 1 )
|
|
{
|
|
self thread watchriotshieldpickup();
|
|
currentweapon = self getcurrentweapon();
|
|
self.hasriotshield = self hasweapon( level.riotshield_name );
|
|
self.hasriotshieldequipped = self getcurrentweapon() == level.riotshield_name;
|
|
refresh_attach = 0;
|
|
self waittill( "weapon_change", newweapon );
|
|
if ( newweapon == level.riotshield_name )
|
|
{
|
|
refresh_attach = 1;
|
|
if ( isDefined( self.riotshieldentity ) )
|
|
{
|
|
self notify( "destroy_riotshield" );
|
|
}
|
|
if ( self.hasriotshield )
|
|
{
|
|
if ( isDefined( self.riotshieldtakeweapon ) )
|
|
{
|
|
self takeweapon( self.riotshieldtakeweapon );
|
|
self.riotshieldtakeweapon = undefined;
|
|
}
|
|
}
|
|
if ( isvalidnonshieldweapon( currentweapon ) )
|
|
{
|
|
self.lastnonshieldweapon = currentweapon;
|
|
}
|
|
}
|
|
if ( self.hasriotshield || refresh_attach == 1 )
|
|
{
|
|
self refreshshieldattachment();
|
|
}
|
|
}
|
|
}
|
|
|
|
isvalidnonshieldweapon( weapon )
|
|
{
|
|
if ( maps/mp/killstreaks/_killstreaks::iskillstreakweapon( weapon ) )
|
|
{
|
|
return 0;
|
|
}
|
|
if ( maps/mp/killstreaks/_killstreak_weapons::isheldkillstreakweapon( weapon ) )
|
|
{
|
|
return 0;
|
|
}
|
|
if ( maps/mp/killstreaks/_killstreak_weapons::isgameplayweapon( weapon ) )
|
|
{
|
|
return 0;
|
|
}
|
|
if ( weapon == "none" )
|
|
{
|
|
return 0;
|
|
}
|
|
if ( isweaponequipment( weapon ) )
|
|
{
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
startriotshielddeploy()
|
|
{
|
|
self notify( "start_riotshield_deploy" );
|
|
self thread watchriotshielddeploy();
|
|
}
|
|
|
|
resetreconmodelvisibility( owner )
|
|
{
|
|
if ( !isDefined( self ) )
|
|
{
|
|
return;
|
|
}
|
|
self setinvisibletoall();
|
|
self setforcenocull();
|
|
if ( !isDefined( owner ) )
|
|
{
|
|
return;
|
|
}
|
|
i = 0;
|
|
while ( i < level.players.size )
|
|
{
|
|
if ( level.players[ i ] hasperk( "specialty_showenemyequipment" ) )
|
|
{
|
|
if ( level.players[ i ].team == "spectator" )
|
|
{
|
|
i++;
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
isenemy = 1;
|
|
if ( level.teambased )
|
|
{
|
|
if ( level.players[ i ].team == owner.team )
|
|
{
|
|
isenemy = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( level.players[ i ] == owner )
|
|
{
|
|
isenemy = 0;
|
|
}
|
|
}
|
|
if ( isenemy )
|
|
{
|
|
self setvisibletoplayer( level.players[ i ] );
|
|
}
|
|
}
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
|
|
resetreconmodelonevent( eventname, owner )
|
|
{
|
|
self endon( "death" );
|
|
for ( ;; )
|
|
{
|
|
level waittill( eventname, newowner );
|
|
if ( isDefined( newowner ) )
|
|
{
|
|
owner = newowner;
|
|
}
|
|
self resetreconmodelvisibility( owner );
|
|
}
|
|
}
|
|
|
|
attachreconmodel( modelname, owner )
|
|
{
|
|
if ( !isDefined( self ) )
|
|
{
|
|
return;
|
|
}
|
|
reconmodel = spawn( "script_model", self.origin );
|
|
reconmodel.angles = self.angles;
|
|
reconmodel setmodel( modelname );
|
|
reconmodel.model_name = modelname;
|
|
reconmodel linkto( self );
|
|
reconmodel setcontents( 0 );
|
|
reconmodel resetreconmodelvisibility( owner );
|
|
reconmodel thread resetreconmodelonevent( "joined_team", owner );
|
|
reconmodel thread resetreconmodelonevent( "player_spawned", owner );
|
|
self.reconmodel = reconmodel;
|
|
}
|
|
|
|
spawnriotshieldcover( origin, angles )
|
|
{
|
|
shield_ent = spawn( "script_model", origin, 1 );
|
|
shield_ent.targetname = "riotshield_mp";
|
|
shield_ent.angles = angles;
|
|
shield_ent setmodel( level.deployedshieldmodel );
|
|
shield_ent setowner( self );
|
|
shield_ent.owner = self;
|
|
shield_ent.team = self.team;
|
|
shield_ent setteam( self.team );
|
|
shield_ent attachreconmodel( level.detectshieldmodel, self );
|
|
shield_ent useanimtree( -1 );
|
|
shield_ent setscriptmoverflag( 0 );
|
|
shield_ent disconnectpaths();
|
|
return shield_ent;
|
|
}
|
|
|
|
watchriotshielddeploy()
|
|
{
|
|
self endon( "death" );
|
|
self endon( "disconnect" );
|
|
self endon( "start_riotshield_deploy" );
|
|
self waittill( "deploy_riotshield", deploy_attempt );
|
|
self setheldweaponmodel( 0 );
|
|
self setplacementhint( 1 );
|
|
placement_hint = 0;
|
|
if ( deploy_attempt )
|
|
{
|
|
placement = self canplaceriotshield( "deploy_riotshield" );
|
|
if ( placement[ "result" ] )
|
|
{
|
|
self.hasdonecombat = 1;
|
|
zoffset = level.riotshield_placement_zoffset;
|
|
shield_ent = self spawnriotshieldcover( placement[ "origin" ] + ( 0, 0, zoffset ), placement[ "angles" ] );
|
|
item_ent = deployriotshield( self, shield_ent );
|
|
primaries = self getweaponslistprimaries();
|
|
/#
|
|
assert( isDefined( item_ent ) );
|
|
assert( !isDefined( self.riotshieldretrievetrigger ) );
|
|
assert( !isDefined( self.riotshieldentity ) );
|
|
if ( level.gametype != "shrp" )
|
|
{
|
|
assert( primaries.size > 0 );
|
|
#/
|
|
}
|
|
shield_ent setclientfield( "riotshield_state", 1 );
|
|
shield_ent.reconmodel setclientfield( "riotshield_state", 1 );
|
|
if ( level.gametype != "shrp" )
|
|
{
|
|
if ( self.lastnonshieldweapon != "none" && self hasweapon( self.lastnonshieldweapon ) )
|
|
{
|
|
self switchtoweapon( self.lastnonshieldweapon );
|
|
}
|
|
else
|
|
{
|
|
self switchtoweapon( primaries[ 0 ] );
|
|
}
|
|
}
|
|
if ( !self hasweapon( "knife_held_mp" ) )
|
|
{
|
|
self giveweapon( "knife_held_mp" );
|
|
self.riotshieldtakeweapon = "knife_held_mp";
|
|
}
|
|
self.riotshieldretrievetrigger = item_ent;
|
|
self.riotshieldentity = shield_ent;
|
|
self thread watchdeployedriotshieldents();
|
|
self thread deleteshieldontriggerdeath( self.riotshieldretrievetrigger );
|
|
self thread deleteshieldonplayerdeathordisconnect( shield_ent );
|
|
self.riotshieldentity thread watchdeployedriotshielddamage();
|
|
level notify( "riotshield_planted" );
|
|
}
|
|
else
|
|
{
|
|
placement_hint = 1;
|
|
clip_max_ammo = weaponclipsize( level.riotshield_name );
|
|
self setweaponammoclip( level.riotshield_name, clip_max_ammo );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
placement_hint = 1;
|
|
}
|
|
if ( placement_hint )
|
|
{
|
|
self setriotshieldfailhint();
|
|
}
|
|
}
|
|
|
|
riotshielddistancetest( origin )
|
|
{
|
|
/#
|
|
assert( isDefined( origin ) );
|
|
#/
|
|
min_dist_squared = getDvarFloat( "riotshield_deploy_limit_radius" );
|
|
min_dist_squared *= min_dist_squared;
|
|
i = 0;
|
|
while ( i < level.players.size )
|
|
{
|
|
if ( isDefined( level.players[ i ].riotshieldentity ) )
|
|
{
|
|
dist_squared = distancesquared( level.players[ i ].riotshieldentity.origin, origin );
|
|
if ( min_dist_squared > dist_squared )
|
|
{
|
|
/#
|
|
println( "Shield placement denied! Failed distance check to other riotshields." );
|
|
#/
|
|
return 0;
|
|
}
|
|
}
|
|
i++;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
watchdeployedriotshieldents()
|
|
{
|
|
/#
|
|
assert( isDefined( self.riotshieldretrievetrigger ) );
|
|
assert( isDefined( self.riotshieldentity ) );
|
|
#/
|
|
self waittill( "destroy_riotshield" );
|
|
if ( isDefined( self.riotshieldretrievetrigger ) )
|
|
{
|
|
self.riotshieldretrievetrigger delete();
|
|
}
|
|
if ( isDefined( self.riotshieldentity ) )
|
|
{
|
|
if ( isDefined( self.riotshieldentity.reconmodel ) )
|
|
{
|
|
self.riotshieldentity.reconmodel delete();
|
|
}
|
|
self.riotshieldentity connectpaths();
|
|
self.riotshieldentity delete();
|
|
}
|
|
}
|
|
|
|
watchdeployedriotshielddamage()
|
|
{
|
|
self endon( "death" );
|
|
damagemax = getDvarInt( "riotshield_deployed_health" );
|
|
self.damagetaken = 0;
|
|
while ( 1 )
|
|
{
|
|
self.maxhealth = 100000;
|
|
self.health = self.maxhealth;
|
|
self waittill( "damage", damage, attacker, direction, point, type, tagname, modelname, partname, weaponname, idflags );
|
|
while ( !isDefined( attacker ) )
|
|
{
|
|
continue;
|
|
}
|
|
/#
|
|
if ( isDefined( self.owner ) )
|
|
{
|
|
assert( isDefined( self.owner.team ) );
|
|
}
|
|
#/
|
|
while ( isplayer( attacker ) )
|
|
{
|
|
while ( level.teambased && attacker.team == self.owner.team && attacker != self.owner )
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
if ( type == "MOD_MELEE" )
|
|
{
|
|
damage *= getDvarFloat( "riotshield_melee_damage_scale" );
|
|
}
|
|
else if ( type == "MOD_PISTOL_BULLET" || type == "MOD_RIFLE_BULLET" )
|
|
{
|
|
damage *= getDvarFloat( "riotshield_bullet_damage_scale" );
|
|
}
|
|
else
|
|
{
|
|
if ( type != "MOD_GRENADE" && type != "MOD_GRENADE_SPLASH" && type != "MOD_EXPLOSIVE" && type != "MOD_EXPLOSIVE_SPLASH" || type == "MOD_PROJECTILE" && type == "MOD_PROJECTILE_SPLASH" )
|
|
{
|
|
damage *= getDvarFloat( "riotshield_explosive_damage_scale" );
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if ( type == "MOD_IMPACT" )
|
|
{
|
|
damage *= getDvarFloat( "riotshield_projectile_damage_scale" );
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if ( type == "MOD_CRUSH" )
|
|
{
|
|
damage = damagemax;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
self.damagetaken += damage;
|
|
if ( self.damagetaken >= damagemax )
|
|
{
|
|
self thread damagethendestroyriotshield( attacker, weaponname );
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
}
|
|
}
|
|
}
|
|
|
|
damagethendestroyriotshield( attacker, weaponname )
|
|
{
|
|
self notify( "damageThenDestroyRiotshield" );
|
|
self endon( "death" );
|
|
if ( isDefined( self.owner.riotshieldretrievetrigger ) )
|
|
{
|
|
self.owner.riotshieldretrievetrigger delete();
|
|
}
|
|
if ( isDefined( self.reconmodel ) )
|
|
{
|
|
self.reconmodel delete();
|
|
}
|
|
self connectpaths();
|
|
self.owner.riotshieldentity = undefined;
|
|
self notsolid();
|
|
self setclientfield( "riotshield_state", 2 );
|
|
if ( isDefined( attacker ) && isDefined( weaponname ) && attacker != self.owner && isplayer( attacker ) )
|
|
{
|
|
maps/mp/_scoreevents::processscoreevent( "destroyed_shield", attacker, self.owner, weaponname );
|
|
}
|
|
wait getDvarFloat( "riotshield_destroyed_cleanup_time" );
|
|
self delete();
|
|
}
|
|
|
|
deleteshieldontriggerdeath( shield_trigger )
|
|
{
|
|
shield_trigger waittill_any( "trigger", "death" );
|
|
self notify( "destroy_riotshield" );
|
|
}
|
|
|
|
deleteshieldonplayerdeathordisconnect( shield_ent )
|
|
{
|
|
shield_ent endon( "death" );
|
|
shield_ent endon( "damageThenDestroyRiotshield" );
|
|
self waittill_any( "death", "disconnect", "remove_planted_weapons" );
|
|
shield_ent thread damagethendestroyriotshield();
|
|
}
|
|
|
|
watchriotshieldstuckentitydeath( grenade, owner )
|
|
{
|
|
grenade endon( "death" );
|
|
self waittill_any( "damageThenDestroyRiotshield", "death", "disconnect", "weapon_change", "deploy_riotshield" );
|
|
grenade detonate( owner );
|
|
}
|