init
This commit is contained in:
345
maps/mp/killstreaks/_dog_killstreak.gsc
Normal file
345
maps/mp/killstreaks/_dog_killstreak.gsc
Normal file
@ -0,0 +1,345 @@
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\agents\_agent_utility;
|
||||
#include maps\mp\gametypes\_damage;
|
||||
|
||||
//===========================================
|
||||
// constants
|
||||
//===========================================
|
||||
CONST_MAX_ACTIVE_KILLSTREAK_DOGS_PER_GAME = 5;
|
||||
CONST_MAX_ACTIVE_KILLSTREAK_DOGS_PER_PLAYER = 1;
|
||||
CONST_MAX_ACTIVE_KILLSTREAK_AGENTS_PER_PLAYER = 2;
|
||||
|
||||
//===========================================
|
||||
// init
|
||||
//===========================================
|
||||
init()
|
||||
{
|
||||
level.killStreakFuncs["guard_dog"] = ::tryUseDog;
|
||||
|
||||
/#
|
||||
SetDevDvarIfUninitialized( "scr_devWolf", 0 ); // 0 == dog, 1 == wolf
|
||||
SetDevDvarIfUninitialized( "scr_devWolfType", 0 ); // 0 == wolfA, 1 == wolfB
|
||||
#/
|
||||
}
|
||||
|
||||
|
||||
//===========================================
|
||||
// setup_callbacks
|
||||
//===========================================
|
||||
setup_callbacks()
|
||||
{
|
||||
level.agent_funcs["dog"] = level.agent_funcs["player"];
|
||||
|
||||
level.agent_funcs["dog"]["spawn"] = ::spawn_dog;
|
||||
level.agent_funcs["dog"]["on_killed"] = ::on_agent_dog_killed;
|
||||
level.agent_funcs["dog"]["on_damaged"] = maps\mp\agents\_agents::on_agent_generic_damaged;
|
||||
level.agent_funcs["dog"]["on_damaged_finished"] = ::on_damaged_finished;
|
||||
level.agent_funcs["dog"]["think"] = maps\mp\agents\dog\_dog_think::main;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//===========================================
|
||||
// tryUseDog
|
||||
//===========================================
|
||||
tryUseDog( lifeId, streakName )
|
||||
{
|
||||
return useDog();
|
||||
}
|
||||
|
||||
|
||||
//===========================================
|
||||
// useDog
|
||||
//===========================================
|
||||
useDog()
|
||||
{
|
||||
// limit the number of active "dog" agents allowed per player
|
||||
if( isDefined(self.hasDog) && self.hasDog )
|
||||
{
|
||||
dog_type = self GetCommonPlayerDataReservedInt( "mp_dog_type" );
|
||||
if( dog_type == 1 )
|
||||
self iPrintLnBold( &"KILLSTREAKS_ALREADY_HAVE_WOLF" );
|
||||
else
|
||||
self iPrintLnBold( &"KILLSTREAKS_ALREADY_HAVE_DOG" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// limit the number of active "dog" agents allowed per game
|
||||
if( getNumActiveAgents( "dog" ) >= CONST_MAX_ACTIVE_KILLSTREAK_DOGS_PER_GAME )
|
||||
{
|
||||
self iPrintLnBold( &"KILLSTREAKS_TOO_MANY_DOGS" );
|
||||
return false;
|
||||
}
|
||||
// limit the number of active agents allowed per player
|
||||
if( getNumOwnedActiveAgents( self ) >= CONST_MAX_ACTIVE_KILLSTREAK_AGENTS_PER_PLAYER )
|
||||
{
|
||||
self iPrintLnBold( &"KILLSTREAKS_AGENT_MAX" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: we should probably do a queue system for these, so the player can call it but it'll go into a queue for when an agent dies to open up a spot
|
||||
// limit the number of active agents allowed per player
|
||||
maxagents = GetMaxAgents();
|
||||
if( getNumActiveAgents() >= maxagents )
|
||||
{
|
||||
self iPrintLnBold( &"KILLSTREAKS_UNAVAILABLE" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// make sure the player is still alive before the agent trys to spawn on the player
|
||||
if( !isReallyAlive( self ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// try to spawn the agent on a path node near the player
|
||||
nearestPathNode = self getValidSpawnPathNodeNearPlayer( true );
|
||||
if( !IsDefined(nearestPathNode) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// find an available agent
|
||||
agent = maps\mp\agents\_agent_common::connectNewAgent( "dog" , self.team );
|
||||
if( !IsDefined( agent ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
self.hasDog = true;
|
||||
|
||||
// set the agent to the player's team
|
||||
agent set_agent_team( self.team, self );
|
||||
|
||||
spawnOrigin = nearestPathNode.origin;
|
||||
spawnAngles = VectorToAngles( self.origin - nearestPathNode.origin );
|
||||
|
||||
agent thread [[ agent agentFunc("spawn") ]]( spawnOrigin, spawnAngles, self );
|
||||
|
||||
agent _setNameplateMaterial( "player_name_bg_green_dog", "player_name_bg_red_dog" );
|
||||
|
||||
if ( IsDefined( self.ballDrone ) && self.ballDrone.ballDroneType == "ball_drone_backup" )
|
||||
{
|
||||
self maps\mp\gametypes\_missions::processChallenge( "ch_twiceasdeadly" );
|
||||
}
|
||||
|
||||
self maps\mp\_matchdata::logKillstreakEvent( "guard_dog", self.origin );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================
|
||||
// on_agent_dog_killed
|
||||
//=======================================================
|
||||
on_agent_dog_killed( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration )
|
||||
{
|
||||
self.isActive = false;
|
||||
self.hasDied = false;
|
||||
|
||||
//agent dogs in safeguard do not have an owner.
|
||||
if( IsDefined( self.owner ) )
|
||||
self.owner.hasDog = false;
|
||||
|
||||
eAttacker.lastKillDogTime = GetTime();
|
||||
|
||||
if ( IsDefined( self.animCBs.OnExit[ self.aiState ] ) )
|
||||
self [[ self.animCBs.OnExit[ self.aiState ] ]] ();
|
||||
|
||||
// award XP for killing agents
|
||||
if( isPlayer( eAttacker ) && IsDefined(self.owner) && (eAttacker != self.owner) )
|
||||
{
|
||||
self.owner leaderDialogOnPlayer( "dog_killed" );
|
||||
self maps\mp\gametypes\_damage::onKillstreakKilled( eAttacker, sWeapon, sMeansOfDeath, iDamage, "destroyed_guard_dog" );
|
||||
|
||||
if ( IsPlayer( eAttacker ) )
|
||||
{
|
||||
eAttacker maps\mp\gametypes\_missions::processChallenge( "ch_notsobestfriend" );
|
||||
|
||||
// assume jumping?
|
||||
if ( !self IsOnGround() )
|
||||
{
|
||||
eAttacker maps\mp\gametypes\_missions::processChallenge( "ch_hoopla" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self SetAnimState( "death" );
|
||||
animEntry = self GetAnimEntry();
|
||||
animLength = GetAnimLength( animEntry );
|
||||
|
||||
deathAnimDuration = int( animLength * 1000 ); // duration in milliseconds
|
||||
|
||||
self.body = self CloneAgent( deathAnimDuration );
|
||||
|
||||
self PlaySound( ter_op( self.bIsWolf, "anml_wolf_shot_death", "anml_dog_shot_death" ) );
|
||||
|
||||
self maps\mp\agents\_agent_utility::deactivateAgent();
|
||||
|
||||
self notify( "killanimscript" );
|
||||
}
|
||||
|
||||
|
||||
on_damaged_finished( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset )
|
||||
{
|
||||
if( !IsDefined( self.playing_pain_sound ) )
|
||||
self thread play_pain_sound( 2.5 );
|
||||
|
||||
// damage needs to be modified depending on the weapon and hit location because the head is really easy to hit when the dog is running at you
|
||||
// assuming 1.4 modifier for head shots
|
||||
damageModified = iDamage;
|
||||
if( IsDefined( sHitLoc ) && sHitLoc == "head" && level.gametype != "horde" )
|
||||
{
|
||||
damageModified = int( damageModified * 0.6 );
|
||||
if ( iDamage > 0 && damageModified <= 0 )
|
||||
damageModified = 1;
|
||||
}
|
||||
|
||||
if ( self.health - damageModified > 0 )
|
||||
{
|
||||
self maps\mp\agents\dog\_dog_think::OnDamage( eInflictor, eAttacker, damageModified, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset );
|
||||
}
|
||||
|
||||
// attack the player that has damaged them
|
||||
if( IsPlayer( eAttacker ) )
|
||||
{
|
||||
// is the dog already attacking?
|
||||
if ( IsDefined( self.attackState ) && self.attackState != "attacking" )
|
||||
{
|
||||
// is the attacker within the dog damaged range?
|
||||
if( DistanceSquared( self.origin, eAttacker.origin ) <= self.dogDamagedRadiusSq )
|
||||
{
|
||||
self.favoriteEnemy = eAttacker;
|
||||
self.forceAttack = true;
|
||||
self thread maps\mp\agents\dog\_dog_think::watchFavoriteEnemyDeath();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
maps\mp\agents\_agents::agent_damage_finished( eInflictor, eAttacker, damageModified, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset );
|
||||
}
|
||||
|
||||
play_pain_sound( delay ) // self == dog
|
||||
{
|
||||
self endon( "death" );
|
||||
|
||||
self PlaySound( ter_op( self.bIsWolf, "anml_wolf_shot_pain", "anml_dog_shot_pain" ) );
|
||||
self.playing_pain_sound = true;
|
||||
wait( delay );
|
||||
self.playing_pain_sound = undefined;
|
||||
}
|
||||
|
||||
spawn_dog( optional_spawnOrigin, optional_spawnAngles, optional_owner ) // self == agent
|
||||
{
|
||||
dog_type = 0; // 0 == dog, 1 == wolf
|
||||
wolf_type = 0; // 0 == wolfB, 1 == wolfC
|
||||
if( IsDefined( optional_owner ) )
|
||||
{
|
||||
if( IsDefined( optional_owner.squad_bot_dog_type ) )
|
||||
{
|
||||
dog_type = optional_owner.squad_bot_dog_type;
|
||||
}
|
||||
else
|
||||
{
|
||||
dog_type = optional_owner GetCommonPlayerDataReservedInt( "mp_dog_type" );
|
||||
}
|
||||
}
|
||||
|
||||
/#
|
||||
if( GetDvarInt( "scr_devWolf" ) != 0 )
|
||||
{
|
||||
dog_type = GetDvarInt( "scr_devWolf" );
|
||||
wolf_type = GetDvarInt( "scr_devWolfType" );
|
||||
}
|
||||
#/
|
||||
dog_model = "mp_fullbody_dog_a";
|
||||
if( dog_type == 1 )
|
||||
{
|
||||
if ( wolf_type == 0 )
|
||||
dog_model = "mp_fullbody_wolf_b";
|
||||
else
|
||||
dog_model = "mp_fullbody_wolf_c";
|
||||
}
|
||||
|
||||
if( IsHairRunning() )
|
||||
dog_model = dog_model + "_fur";
|
||||
|
||||
self SetModel( dog_model );
|
||||
|
||||
self.species = "dog";
|
||||
|
||||
self.OnEnterAnimState = maps\mp\agents\dog\_dog_think::OnEnterAnimState;
|
||||
|
||||
// allow killstreaks to pass in specific spawn locations
|
||||
if( IsDefined(optional_spawnOrigin) && IsDefined(optional_spawnAngles) )
|
||||
{
|
||||
spawnOrigin = optional_spawnOrigin;
|
||||
spawnAngles = optional_spawnAngles;
|
||||
}
|
||||
else
|
||||
{
|
||||
spawnPoint = self [[level.getSpawnPoint]]();
|
||||
spawnOrigin = spawnpoint.origin;
|
||||
spawnAngles = spawnpoint.angles;
|
||||
}
|
||||
self activateAgent();
|
||||
self.spawnTime = GetTime();
|
||||
self.lastSpawnTime = GetTime();
|
||||
|
||||
self.bIsWolf = (dog_type == 1);
|
||||
|
||||
self maps\mp\agents\dog\_dog_think::init();
|
||||
|
||||
if ( dog_type == 1 )
|
||||
animclass = "wolf_animclass";
|
||||
else
|
||||
animclass = "dog_animclass";
|
||||
|
||||
// called from code when an agent is done initializing after AddAgent is called
|
||||
// this should set up any state specific to this agent and game
|
||||
self SpawnAgent( spawnOrigin, spawnAngles, animclass, 15, 40, optional_owner );
|
||||
level notify( "spawned_agent", self );
|
||||
|
||||
self maps\mp\agents\_agent_common::set_agent_health( 250 );
|
||||
|
||||
// must set the team after SpawnAgent to fix a bug with weapon crosshairs and nametags
|
||||
if( IsDefined(optional_owner) )
|
||||
{
|
||||
self set_agent_team( optional_owner.team, optional_owner );
|
||||
}
|
||||
|
||||
self SetThreatBiasGroup( "Dogs" );
|
||||
|
||||
self TakeAllWeapons();
|
||||
|
||||
// hide the dog, let the whistle happen, then show the dog
|
||||
if( IsDefined(self.owner) )
|
||||
{
|
||||
self Hide();
|
||||
wait( 1.0 ); // not sure what to endon for this
|
||||
|
||||
// The dog could have died during the 1 second wait (for example if he spawned in a kill trigger), so if that happened,
|
||||
// don't start thinking since it will cause SREs due to him missing a self.agent_type
|
||||
if ( !IsAlive(self) )
|
||||
return;
|
||||
|
||||
self Show();
|
||||
}
|
||||
|
||||
self thread [[ self agentFunc("think") ]]();
|
||||
|
||||
wait( 0.1 );
|
||||
|
||||
if ( IsHairRunning() )
|
||||
{
|
||||
if ( dog_type == 1 )
|
||||
furFX = level.wolfFurFX[ wolf_type ];
|
||||
else
|
||||
furFX = level.furFX;
|
||||
|
||||
assert( IsDefined( furFX ) );
|
||||
PlayFXOnTag( furFX, self, "tag_origin" );
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user