215 lines
6.5 KiB
Plaintext
215 lines
6.5 KiB
Plaintext
#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;
|
|
#include maps\mp\bots\_bots_util;
|
|
#include maps\mp\bots\_bots_strategy;
|
|
|
|
//===========================================
|
|
// constants
|
|
//===========================================
|
|
CONST_MAX_ACTIVE_KILLSTREAK_AGENTS_PER_GAME = 5;
|
|
CONST_MAX_ACTIVE_KILLSTREAK_AGENTS_PER_PLAYER = 2;
|
|
|
|
|
|
//===========================================
|
|
// init
|
|
//===========================================
|
|
init()
|
|
{
|
|
level.killStreakFuncs["agent"] = ::tryUseSquadmate;
|
|
level.killStreakFuncs["recon_agent"] = ::tryUseReconSquadmate;
|
|
}
|
|
|
|
|
|
//===========================================
|
|
// setup_callbacks
|
|
//===========================================
|
|
setup_callbacks()
|
|
{
|
|
level.agent_funcs["squadmate"] = level.agent_funcs["player"];
|
|
|
|
level.agent_funcs["squadmate"]["think"] = ::squadmate_agent_think;
|
|
level.agent_funcs["squadmate"]["on_killed"] = ::on_agent_squadmate_killed;
|
|
level.agent_funcs["squadmate"]["on_damaged"] = maps\mp\agents\_agents::on_agent_player_damaged;
|
|
level.agent_funcs["squadmate"]["gametype_update"]= ::no_gametype_update;
|
|
}
|
|
|
|
no_gametype_update()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//===========================================
|
|
// tryUseSquadmate
|
|
//===========================================
|
|
tryUseSquadmate( lifeId, streakName )
|
|
{
|
|
return useSquadmate( "agent" );
|
|
}
|
|
|
|
|
|
//===========================================
|
|
// tryUseReconSquadmate
|
|
//===========================================
|
|
tryUseReconSquadmate( lifeId, streakName )
|
|
{
|
|
return useSquadmate( "reconAgent" );
|
|
}
|
|
|
|
|
|
//===========================================
|
|
// useSquadmate
|
|
//===========================================
|
|
useSquadmate( killStreakType )
|
|
{
|
|
// limit the number of active "squadmate" agents allowed per game
|
|
if( getNumActiveAgents( "squadmate" ) >= CONST_MAX_ACTIVE_KILLSTREAK_AGENTS_PER_GAME )
|
|
{
|
|
self iPrintLnBold( &"KILLSTREAKS_AGENT_MAX" );
|
|
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;
|
|
}
|
|
|
|
// try to spawn the agent on a path node near the player
|
|
nearestPathNode = self getValidSpawnPathNodeNearPlayer( false, true );
|
|
|
|
if( !IsDefined(nearestPathNode) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// make sure the player is still alive before the agent trys to spawn on the player
|
|
if( !isReallyAlive(self) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
spawnOrigin = nearestPathNode.origin;
|
|
spawnAngles = VectorToAngles( self.origin - nearestPathNode.origin );
|
|
|
|
agent = maps\mp\agents\_agents::add_humanoid_agent( "squadmate", self.team, undefined, spawnOrigin, spawnAngles, self, false, false, "veteran" );
|
|
if( !IsDefined( agent ) )
|
|
{
|
|
self iPrintLnBold( &"KILLSTREAKS_AGENT_MAX" );
|
|
return false;
|
|
}
|
|
|
|
agent.killStreakType = killStreakType;
|
|
|
|
if ( agent.killStreakType == "reconAgent" )
|
|
{
|
|
// 2013-06-26 wallace
|
|
// At the time of this comment, giveLoadout runs and finishes execution immediately
|
|
// We run sendAgentWeaponNotify and finishReconAgentLoadout since they block until giveLoadout sends its notify
|
|
agent thread sendAgentWeaponNotify( "iw6_riotshield_mp" );
|
|
agent thread finishReconAgentLoadout();
|
|
agent thread maps\mp\gametypes\_class::giveLoadout( self.pers["team"], "reconAgent", false );
|
|
agent maps\mp\agents\_agent_common::set_agent_health( 250 );
|
|
agent maps\mp\perks\_perkfunctions::setLightArmor();
|
|
}
|
|
else
|
|
{
|
|
agent maps\mp\perks\_perkfunctions::setLightArmor();
|
|
}
|
|
|
|
agent _setNameplateMaterial( "player_name_bg_green_agent", "player_name_bg_red_agent" );
|
|
|
|
self maps\mp\_matchdata::logKillstreakEvent( agent.killStreakType, self.origin );
|
|
|
|
return true;
|
|
}
|
|
|
|
finishReconAgentLoadout()
|
|
{
|
|
self endon( "death" );
|
|
self endon( "disconnect" );
|
|
level endon( "game_ended" );
|
|
|
|
self waittill( "giveLoadout" );
|
|
|
|
self maps\mp\perks\_perkfunctions::setLightArmor();
|
|
self givePerk( "specialty_quickswap", false );
|
|
self givePerk( "specialty_regenfaster", false );
|
|
|
|
// 2014-04-24 JC: Reduced accuracy on Squad Mate Support Streak
|
|
self BotSetDifficultySetting( "minInaccuracy", 1.5 * self BotGetDifficultySetting( "minInaccuracy" ) );
|
|
self BotSetDifficultySetting( "maxInaccuracy", 1.5 * self BotGetDifficultySetting( "maxInaccuracy" ) );
|
|
// 2014-04-24 JC: Reduced fire rate on Squad Mate Support Streak
|
|
// min: from 200 to 300
|
|
// max: from 400 to 500
|
|
self BotSetDifficultySetting( "minFireTime", 1.5 * self BotGetDifficultySetting( "minFireTime" ) );
|
|
self BotSetDifficultySetting( "maxFireTime", 1.25 * self BotGetDifficultySetting( "maxFireTime" ) );
|
|
}
|
|
|
|
|
|
//===========================================
|
|
// sendAgentWeaponNotify
|
|
//===========================================
|
|
sendAgentWeaponNotify( weaponName )
|
|
{
|
|
self endon( "death" );
|
|
self endon( "disconnect" );
|
|
level endon( "game_ended" );
|
|
|
|
self waittill( "giveLoadout" );
|
|
|
|
if( !IsDefined(weaponName) )
|
|
weaponName = "iw6_riotshield_mp";
|
|
|
|
self notify( "weapon_change", weaponName );
|
|
}
|
|
|
|
|
|
//=======================================================
|
|
// squadmate_agent_think
|
|
//=======================================================
|
|
squadmate_agent_think()
|
|
{
|
|
self endon( "death" );
|
|
self endon( "disconnect" );
|
|
self endon( "owner_disconnect" );
|
|
|
|
level endon( "game_ended" );
|
|
|
|
while(1)
|
|
{
|
|
// Squad mate agent prefers to have shield out when not in combat and guarding player
|
|
self BotSetFlag( "prefer_shield_out", true );
|
|
|
|
handled_by_gametype = self [[ self agentFunc("gametype_update") ]]();
|
|
if ( !handled_by_gametype )
|
|
{
|
|
if ( !self bot_is_guarding_player( self.owner ) )
|
|
self bot_guard_player( self.owner, 350 );
|
|
}
|
|
|
|
wait(0.05);
|
|
}
|
|
}
|
|
|
|
|
|
//=======================================================
|
|
// on_agent_squadmate_killed
|
|
//=======================================================
|
|
on_agent_squadmate_killed(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration)
|
|
{
|
|
self maps\mp\agents\_agents::on_humanoid_agent_killed_common(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration, false);
|
|
|
|
// award XP for killing agents
|
|
if( IsPlayer( eAttacker ) && IsDefined(self.owner) && eAttacker != self.owner )
|
|
{
|
|
self.owner leaderDialogOnPlayer( "squad_killed" );
|
|
self maps\mp\gametypes\_damage::onKillstreakKilled( eAttacker, sWeapon, sMeansOfDeath, iDamage, "destroyed_squad_mate" );
|
|
}
|
|
|
|
self maps\mp\agents\_agent_utility::deactivateAgent();
|
|
}
|