1112 lines
26 KiB
Plaintext
1112 lines
26 KiB
Plaintext
#using scripts\codescripts\struct;
|
|
|
|
#using scripts\shared\array_shared;
|
|
#using scripts\shared\system_shared;
|
|
#using scripts\shared\tweakables_shared;
|
|
#using scripts\shared\scoreevents_shared;
|
|
#using scripts\shared\util_shared;
|
|
#using scripts\shared\weapons\_weapons;
|
|
#using scripts\shared\weapons\_weapon_utils;
|
|
|
|
|
|
|
|
#using scripts\mp\gametypes\_battlechatter;
|
|
#using scripts\mp\gametypes\_dev;
|
|
#using scripts\mp\gametypes\_spawning;
|
|
#using scripts\mp\gametypes\_spawnlogic;
|
|
|
|
#using scripts\mp\_util;
|
|
#using scripts\mp\killstreaks\_killstreakrules;
|
|
#using scripts\mp\killstreaks\_killstreaks;
|
|
#using scripts\mp\killstreaks\_supplydrop;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#precache( "string", "KILLSTREAK_EARNED_DOGS" );
|
|
#precache( "string", "KILLSTREAK_DOGS_NOT_AVAILABLE" );
|
|
#precache( "string", "KILLSTREAK_DOGS_INBOUND" );
|
|
#precache( "string", "KILLSTREAK_DOGS_HACKED" );
|
|
#precache( "eventstring", "mpl_killstreak_dogs" );
|
|
|
|
#namespace dogs;
|
|
|
|
//REGISTER_SYSTEM( "dogs", &__init__, undefined )
|
|
|
|
//Please note, the killstreak init is a separate call below
|
|
function init()
|
|
{
|
|
level.dog_targets = [];
|
|
level.dog_targets[ level.dog_targets.size ] = "trigger_radius";
|
|
level.dog_targets[ level.dog_targets.size ] = "trigger_multiple";
|
|
level.dog_targets[ level.dog_targets.size ] = "trigger_use_touch";
|
|
|
|
level.dog_spawns = [];
|
|
//init_spawns();
|
|
|
|
/#
|
|
level thread devgui_dog_think();
|
|
#/
|
|
|
|
level.dogsOnFlashDogs = &flash_dogs;
|
|
}
|
|
|
|
function init_spawns()
|
|
{
|
|
spawns = GetNodeArray( "spawn", "script_noteworthy" );
|
|
|
|
if ( !IsDefined( spawns ) || !spawns.size )
|
|
{
|
|
/# println( "No dog spawn nodes found in map" ); #/
|
|
return;
|
|
}
|
|
|
|
dog_spawner = GetEnt( "dog_spawner", "targetname" );
|
|
|
|
if ( !IsDefined( dog_spawner ) )
|
|
{
|
|
/# println( "No dog_spawner entity found in map" ); #/
|
|
return;
|
|
}
|
|
|
|
valid = spawnlogic::get_spawnpoint_array( "mp_tdm_spawn" );
|
|
dog = dog_spawner SpawnFromSpawner();
|
|
|
|
foreach( spawn in spawns )
|
|
{
|
|
valid = ArraySort( valid, spawn.origin, false );
|
|
|
|
for( i = 0; i < 5; i++ )
|
|
{
|
|
if ( dog FindPath( spawn.origin, valid[i].origin, true, false ) )
|
|
{
|
|
level.dog_spawns[ level.dog_spawns.size ] = spawn;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/#
|
|
if ( !level.dog_spawns.size )
|
|
{
|
|
println( "No dog spawns connect to MP spawn nodes" );
|
|
}
|
|
#/
|
|
|
|
dog delete();
|
|
}
|
|
|
|
function initKillstreak()
|
|
{
|
|
// register the dog hardpoint
|
|
if ( tweakables::getTweakableValue( "killstreak", "allowdogs" ) )
|
|
{
|
|
//killstreaks::register( "dogs", "dogs", "killstreak_dogs","dogs_used",&useKillstreakDogs, true );
|
|
//killstreaks::register_strings( "dogs", &"KILLSTREAK_EARNED_DOGS", &"KILLSTREAK_DOGS_NOT_AVAILABLE", &"KILLSTREAK_DOGS_INBOUND", undefined, &"KILLSTREAK_DOGS_HACKED" );
|
|
//killstreaks::register_dialog( "dogs", "mpl_killstreak_dogs", "kls_dogs_used", "","kls_dogs_enemy", "", "kls_dogs_ready" );
|
|
//killstreaks::set_team_kill_penalty_scale( "dogs", 0.0 );
|
|
|
|
//killstreaks::register_alt_weapon( "dogs", "dog_bite" );
|
|
}
|
|
}
|
|
|
|
function useKillstreakDogs(hardpointType)
|
|
{
|
|
if ( !dog_killstreak_init() )
|
|
return false;
|
|
|
|
if ( !self killstreakrules::isKillstreakAllowed( hardpointType, self.team ) )
|
|
return false;
|
|
|
|
killstreak_id = self killstreakrules::killstreakStart( "dogs", self.team );
|
|
|
|
self thread ownerHadActiveDogs();
|
|
|
|
if ( killstreak_id == -1 )
|
|
return false;
|
|
|
|
if ( level.teambased )
|
|
{
|
|
foreach( team in level.teams )
|
|
{
|
|
if ( team == self.team )
|
|
continue;
|
|
}
|
|
}
|
|
|
|
self killstreaks::play_killstreak_start_dialog( "dogs", self.team, true );
|
|
//self AddPlayerStat( "DOGS_USED", 1 );
|
|
self AddWeaponStat( GetWeapon( "dogs" ), "used", 1 );
|
|
|
|
ownerDeathCount = self.deathCount;
|
|
|
|
level thread dog_manager_spawn_dogs( self, ownerDeathCount, killstreak_id );
|
|
level notify( "called_in_the_dogs" );
|
|
return true;
|
|
}
|
|
|
|
function ownerHadActiveDogs()
|
|
{
|
|
self endon( "disconnect" );
|
|
self.dogsActive = true;
|
|
self.dogsActiveKillstreak = 0;
|
|
self util::waittill_any( "death", "game_over", "dogs_complete" );
|
|
|
|
self.dogsActiveKillstreak = 0;
|
|
self.dogsActive = undefined;
|
|
}
|
|
|
|
function dog_killstreak_init()
|
|
{
|
|
dog_spawner = GetEnt( "dog_spawner", "targetname" );
|
|
|
|
if( !isdefined( dog_spawner ) )
|
|
{
|
|
/# println( "No dog spawners found in map" ); #/
|
|
return false;
|
|
}
|
|
|
|
spawns = GetNodeArray( "spawn", "script_noteworthy" );
|
|
|
|
if ( level.dog_spawns.size <= 0 )
|
|
{
|
|
/# println( "No dog spawn nodes found in map" ); #/
|
|
return false;
|
|
}
|
|
|
|
exits = GetNodeArray( "exit", "script_noteworthy" );
|
|
|
|
if ( exits.size <= 0 )
|
|
{
|
|
/# println( "No dog exit nodes found in map" ); #/
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function dog_set_model()
|
|
{
|
|
self SetModel( "german_shepherd_vest" );
|
|
self SetEnemyModel( "german_shepherd_vest_black" );
|
|
}
|
|
|
|
function init_dog()
|
|
{
|
|
assert( IsAi( self ) );
|
|
|
|
self.targetname = "attack_dog";
|
|
|
|
self.animTree = "dog.atr";
|
|
self.type = "dog";
|
|
self.accuracy = 0.2;
|
|
self.health = 100;
|
|
self.maxhealth = 100; // this currently does not hook to code maxhealth
|
|
self.secondaryweapon = "";
|
|
self.sidearm = "";
|
|
self.grenadeAmmo = 0;
|
|
self.goalradius = 128;
|
|
self.noDodgeMove = true;
|
|
self.ignoreSuppression = true;
|
|
self.suppressionThreshold = 1;
|
|
self.disableArrivals = false;
|
|
self.pathEnemyFightDist = 512;
|
|
self.soundMod = "dog";
|
|
|
|
self thread dog_health_regen();
|
|
self thread selfDefenseChallenge();
|
|
}
|
|
|
|
function get_spawn_node( owner, team )
|
|
{
|
|
assert( level.dog_spawns.size > 0 );
|
|
return array::random( level.dog_spawns );
|
|
}
|
|
|
|
function get_score_for_spawn( origin, team )
|
|
{
|
|
players = GetPlayers();
|
|
score = 0;
|
|
|
|
foreach( player in players )
|
|
{
|
|
if ( !isdefined( player ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ( !IsAlive( player ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ( player.sessionstate != "playing" )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ( DistanceSquared( player.origin, origin ) > 2048 * 2048 )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ( player.team == team )
|
|
{
|
|
score++;
|
|
}
|
|
else
|
|
{
|
|
score--;
|
|
}
|
|
}
|
|
|
|
return score;
|
|
}
|
|
|
|
function dog_set_owner( owner, team, requiredDeathCount )
|
|
{
|
|
self SetEntityOwner( owner );
|
|
self.team = team;
|
|
|
|
self.requiredDeathCount = requiredDeathCount;
|
|
}
|
|
|
|
function dog_create_spawn_influencer( team )
|
|
{
|
|
self spawning::create_entity_enemy_influencer( "dog", team );
|
|
}
|
|
|
|
function dog_manager_spawn_dog( owner, team, spawn_node, requiredDeathCount )
|
|
{
|
|
dog_spawner = GetEnt( "dog_spawner", "targetname" );
|
|
|
|
dog = dog_spawner SpawnFromSpawner();
|
|
dog ForceTeleport( spawn_node.origin, spawn_node.angles );
|
|
|
|
dog init_dog();
|
|
dog dog_set_owner( owner, team, requiredDeathCount );
|
|
dog dog_set_model();
|
|
dog dog_create_spawn_influencer( team );
|
|
|
|
dog thread dog_owner_kills();
|
|
dog thread dog_notify_level_on_death();
|
|
dog thread dog_patrol();
|
|
dog thread monitor_dog_special_grenades();
|
|
|
|
return dog;
|
|
}
|
|
|
|
|
|
function monitor_dog_special_grenades() // self == dog
|
|
{
|
|
// watch and see if the dog gets damage from a flash or concussion
|
|
// smoke and tabun handle themselves
|
|
self endon("death");
|
|
|
|
while(1)
|
|
{
|
|
self waittill( "damage", damage, attacker, direction_vec, point, type, modelName, tagName, partName, weapon, iDFlags );
|
|
|
|
if( weapon_utils::isFlashOrStunWeapon( weapon ) )
|
|
{
|
|
damage_area = spawn( "trigger_radius", self.origin, 0, 128, 128 );
|
|
attacker thread dogs::flash_dogs( damage_area );
|
|
{wait(.05);};
|
|
damage_area delete();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
function dog_manager_spawn_dogs( owner, deathCount, killstreak_id )
|
|
{
|
|
requiredDeathCount = deathCount;
|
|
team = owner.team;
|
|
|
|
level.dog_abort = false;
|
|
owner thread dog_manager_abort();
|
|
level thread dog_manager_game_ended();
|
|
|
|
for ( count = 0; count < 10; )
|
|
{
|
|
if ( level.dog_abort )
|
|
{
|
|
break;
|
|
}
|
|
|
|
dogs = dog_manager_get_dogs();
|
|
|
|
while ( dogs.size < 5 && count < 10 && !level.dog_abort )
|
|
{
|
|
node = get_spawn_node( owner, team );
|
|
level dog_manager_spawn_dog( owner, team, node, requiredDeathCount );
|
|
count++;
|
|
|
|
wait ( randomfloatrange( 2, 5 ) );
|
|
dogs = dog_manager_get_dogs();
|
|
}
|
|
|
|
level waittill( "dog_died" );
|
|
}
|
|
|
|
for ( ;; )
|
|
{
|
|
dogs = dog_manager_get_dogs();
|
|
|
|
if ( dogs.size <= 0 )
|
|
{
|
|
killstreakrules::killstreakStop( "dogs", team, killstreak_id );
|
|
if ( isdefined( owner ) )
|
|
{
|
|
owner notify( "dogs_complete" );
|
|
}
|
|
return;
|
|
}
|
|
|
|
level waittill( "dog_died" );
|
|
}
|
|
}
|
|
|
|
function dog_abort()
|
|
{
|
|
level.dog_abort = true;
|
|
|
|
dogs = dog_manager_get_dogs();
|
|
|
|
foreach( dog in dogs )
|
|
{
|
|
dog notify( "abort" );
|
|
}
|
|
|
|
level notify( "dog_abort" );
|
|
}
|
|
|
|
function dog_manager_abort()
|
|
{
|
|
level endon( "dog_abort" );
|
|
self util::wait_endon( 45, "disconnect", "joined_team", "joined_spectators" );
|
|
dog_abort();
|
|
}
|
|
|
|
function dog_manager_game_ended()
|
|
{
|
|
level endon( "dog_abort" );
|
|
|
|
level waittill( "game_ended" );
|
|
dog_abort();
|
|
}
|
|
|
|
function dog_notify_level_on_death()
|
|
{
|
|
self waittill( "death" );
|
|
level notify( "dog_died" );
|
|
}
|
|
|
|
function dog_leave()
|
|
{
|
|
// have them run to an exit node
|
|
self clearentitytarget();
|
|
self.ignoreall = true;
|
|
self.goalradius = 30;
|
|
self SetGoal( self dog_get_exit_node() );
|
|
|
|
self util::wait_endon( 20, "goal", "bad_path" );
|
|
self delete();
|
|
}
|
|
|
|
function dog_patrol()
|
|
{
|
|
self endon( "death" );
|
|
/#
|
|
self endon( "debug_patrol" );
|
|
#/
|
|
|
|
for ( ;; )
|
|
{
|
|
if ( level.dog_abort )
|
|
{
|
|
self dog_leave();
|
|
return;
|
|
}
|
|
|
|
if ( isdefined( self.enemy ) )
|
|
{
|
|
wait( RandomIntRange( 3, 5 ) );
|
|
continue;
|
|
}
|
|
|
|
nodes = [];
|
|
|
|
objectives = dog_patrol_near_objective();
|
|
|
|
for ( i = 0; i < objectives.size; i++ )
|
|
{
|
|
objective = array::random( objectives );
|
|
|
|
nodes = GetNodesInRadius( objective.origin, 256, 64, 512, "Path", 16 );
|
|
|
|
if ( nodes.size )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( !nodes.size )
|
|
{
|
|
player = self dog_patrol_near_enemy();
|
|
|
|
if ( isdefined( player ) )
|
|
{
|
|
nodes = GetNodesInRadius( player.origin, 1024, 0, 128, "Path", 8 );
|
|
}
|
|
}
|
|
|
|
if ( !nodes.size && isdefined( self.script_owner ) )
|
|
{
|
|
if ( IsAlive( self.script_owner ) && self.script_owner.sessionstate == "playing" )
|
|
{
|
|
nodes = GetNodesInRadius( self.script_owner.origin, 512, 256, 512, "Path", 16 );
|
|
}
|
|
}
|
|
|
|
if ( !nodes.size )
|
|
{
|
|
nodes = GetNodesInRadius( self.origin, 1024, 512, 512, "Path" );
|
|
}
|
|
|
|
if ( nodes.size )
|
|
{
|
|
nodes = array::randomize( nodes );
|
|
|
|
foreach( node in nodes )
|
|
{
|
|
if ( isdefined( node.script_noteworthy ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ( isdefined( node.dog_claimed ) && IsAlive( node.dog_claimed ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
self SetGoal( node );
|
|
node.dog_claimed = self;
|
|
|
|
nodes = [];
|
|
event = self util::waittill_any_return( "goal", "bad_path", "enemy", "abort" );
|
|
|
|
if ( event == "goal" )
|
|
{
|
|
util::wait_endon( RandomIntRange( 3, 5 ), "damage", "enemy", "abort" );
|
|
}
|
|
|
|
node.dog_claimed = undefined;
|
|
break;
|
|
}
|
|
}
|
|
|
|
wait( 0.5 );
|
|
}
|
|
}
|
|
|
|
function dog_patrol_near_objective()
|
|
{
|
|
if ( !isdefined( level.dog_objectives ) )
|
|
{
|
|
level.dog_objectives = [];
|
|
level.dog_objective_next_update = 0;
|
|
}
|
|
|
|
if ( level.gameType == "tdm" || level.gameType == "dm" )
|
|
{
|
|
return level.dog_objectives;
|
|
}
|
|
|
|
if ( GetTime() >= level.dog_objective_next_update )
|
|
{
|
|
level.dog_objectives = [];
|
|
|
|
foreach( target in level.dog_targets )
|
|
{
|
|
ents = GetEntArray( target, "classname" );
|
|
|
|
foreach( ent in ents )
|
|
{
|
|
if ( level.gameType == "koth" )
|
|
{
|
|
if ( isdefined( ent.targetname ) && ent.targetname == "radiotrigger" )
|
|
{
|
|
level.dog_objectives[ level.dog_objectives.size ] = ent;
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
if ( level.gameType == "sd" )
|
|
{
|
|
if ( isdefined( ent.targetname ) && ent.targetname == "bombzone" )
|
|
{
|
|
level.dog_objectives[ level.dog_objectives.size ] = ent;
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
if ( !isdefined( ent.script_gameobjectname ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ( !IsSubStr( ent.script_gameobjectname, level.gameType ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
level.dog_objectives[ level.dog_objectives.size ] = ent;
|
|
}
|
|
}
|
|
|
|
level.dog_objective_next_update = GetTime() + RandomIntRange( 5000, 10000 );
|
|
}
|
|
|
|
return level.dog_objectives;
|
|
}
|
|
|
|
function dog_patrol_near_enemy()
|
|
{
|
|
players = GetPlayers();
|
|
|
|
closest = undefined;
|
|
distSq = 99999999;
|
|
|
|
foreach( player in players )
|
|
{
|
|
if ( !isdefined( player ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ( !IsAlive( player ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ( player.sessionstate != "playing" )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ( isdefined( self.script_owner ) && player == self.script_owner )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ( level.teambased )
|
|
{
|
|
if ( player.team == self.team )
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if ( GetTime() - player.lastFireTime > 3000 )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ( !isdefined( closest ) )
|
|
{
|
|
closest = player;
|
|
distSq = DistanceSquared( self.origin, player.origin );
|
|
continue;
|
|
}
|
|
|
|
d = DistanceSquared( self.origin, player.origin );
|
|
|
|
if ( d < distSq )
|
|
{
|
|
closest = player;
|
|
distSq = d;
|
|
}
|
|
}
|
|
|
|
return closest;
|
|
}
|
|
|
|
function dog_manager_get_dogs()
|
|
{
|
|
dogs = GetEntArray( "attack_dog", "targetname" );
|
|
return dogs;
|
|
}
|
|
|
|
function dog_owner_kills()
|
|
{
|
|
if ( !isdefined( self.script_owner ) )
|
|
return;
|
|
|
|
self endon("clear_owner");
|
|
self endon("death");
|
|
self.script_owner endon("disconnect");
|
|
|
|
while(1)
|
|
{
|
|
self waittill("killed", player);
|
|
self.script_owner notify( "dog_handler" );
|
|
}
|
|
}
|
|
|
|
function dog_health_regen()
|
|
{
|
|
self endon( "death" );
|
|
|
|
interval = 0.5;
|
|
regen_interval = Int( ( self.health / 5 ) * interval );
|
|
regen_start = 2;
|
|
|
|
for ( ;; )
|
|
{
|
|
self waittill( "damage", damage, attacker, direction, point, type, tagName, modelName, partname, weapon, iDFlags );
|
|
self trackAttackerDamage( attacker );
|
|
|
|
self thread dog_health_regen_think( regen_start, interval, regen_interval );
|
|
}
|
|
}
|
|
|
|
function trackAttackerDamage( attacker )
|
|
{
|
|
if ( !isdefined( attacker ) || !isPlayer( attacker ) || !isdefined( self.script_owner ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( ( level.teambased && attacker.team == self.script_owner.team ) || attacker == self )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( !isdefined( self.attackerData ) || !isdefined( self.attackers ) )
|
|
{
|
|
self.attackerData = [];
|
|
self.attackers = [];
|
|
}
|
|
if ( !isdefined( self.attackerData[attacker.clientid] ) )
|
|
{
|
|
self.attackerClientID[attacker.clientid] = spawnstruct();
|
|
self.attackers[ self.attackers.size ] = attacker;
|
|
}
|
|
}
|
|
|
|
function resetAttackerDamage()
|
|
{
|
|
self.attackerData = [];
|
|
self.attackers = [];
|
|
}
|
|
|
|
function dog_health_regen_think( delay, interval, regen_interval )
|
|
{
|
|
self endon( "death" );
|
|
self endon( "damage" );
|
|
|
|
wait( delay );
|
|
|
|
for ( step = 0; step <= 5; step += interval )
|
|
{
|
|
if ( self.health >= 100 )
|
|
{
|
|
break;
|
|
}
|
|
|
|
self.health += regen_interval;
|
|
wait( interval );
|
|
}
|
|
|
|
self resetAttackerDamage();
|
|
self.health = 100;
|
|
}
|
|
|
|
function selfDefenseChallenge()
|
|
{
|
|
self waittill ("death", attacker);
|
|
|
|
if ( isdefined( attacker ) && isPlayer( attacker ) )
|
|
{
|
|
if (isdefined ( self.script_owner ) && self.script_owner == attacker)
|
|
return;
|
|
if ( level.teambased && isdefined ( self.script_owner ) && self.script_owner.team == attacker.team )
|
|
return;
|
|
|
|
if ( isdefined( self.attackers ) )
|
|
{
|
|
foreach ( player in self.attackers )
|
|
{
|
|
if ( player != attacker )
|
|
{
|
|
scoreevents::processScoreEvent( "killed_dog_assist", player );
|
|
}
|
|
}
|
|
}
|
|
attacker notify ("selfdefense_dog");
|
|
}
|
|
|
|
}
|
|
|
|
function dog_get_exit_node()
|
|
{
|
|
exits = GetNodeArray( "exit", "script_noteworthy" );
|
|
return ArrayGetClosest( self.origin, exits );
|
|
}
|
|
|
|
function flash_dogs( area )
|
|
{
|
|
self endon("disconnect");
|
|
|
|
dogs = dog_manager_get_dogs();
|
|
|
|
foreach( dog in dogs )
|
|
{
|
|
if ( !isalive(dog) )
|
|
continue;
|
|
|
|
if ( dog istouching(area) )
|
|
{
|
|
do_flash = true;
|
|
if ( isPlayer( self ) )
|
|
{
|
|
if ( level.teamBased && (dog.team == self.team) )
|
|
{
|
|
do_flash = false;
|
|
}
|
|
else if ( !level.teambased && isdefined(dog.script_owner) && self == dog.script_owner )
|
|
{
|
|
do_flash = false;
|
|
}
|
|
}
|
|
|
|
if ( isdefined( dog.lastFlashed ) && dog.lastFlashed + 1500 > gettime() )
|
|
{
|
|
do_flash = false;
|
|
}
|
|
|
|
if ( do_flash )
|
|
{
|
|
dog setFlashBanged( true, 500 );
|
|
dog.lastFlashed = gettime();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/#
|
|
|
|
function devgui_dog_think()
|
|
{
|
|
SetDvar( "devgui_dog", "" );
|
|
|
|
debug_patrol = false;
|
|
|
|
for( ;; )
|
|
{
|
|
cmd = GetDvarString( "devgui_dog" );
|
|
|
|
switch( cmd )
|
|
{
|
|
case "spawn_friendly":
|
|
player = util::getHostPlayer();
|
|
devgui_dog_spawn( player.team );
|
|
break;
|
|
|
|
case "spawn_enemy":
|
|
player = util::getHostPlayer();
|
|
foreach( team in level.teams )
|
|
{
|
|
if ( team == player.team )
|
|
continue;
|
|
|
|
devgui_dog_spawn( team );
|
|
}
|
|
break;
|
|
|
|
case "delete_dogs":
|
|
level dog_abort();
|
|
break;
|
|
|
|
case "dog_camera":
|
|
devgui_dog_camera();
|
|
break;
|
|
|
|
case "spawn_crate":
|
|
devgui_crate_spawn();
|
|
break;
|
|
|
|
case "delete_crates":
|
|
devgui_crate_delete();
|
|
break;
|
|
|
|
case "show_spawns":
|
|
devgui_spawn_show();
|
|
break;
|
|
|
|
case "show_exits":
|
|
devgui_exit_show();
|
|
break;
|
|
|
|
case "debug_route":
|
|
devgui_debug_route();
|
|
break;
|
|
}
|
|
|
|
if ( cmd != "" )
|
|
{
|
|
SetDvar( "devgui_dog", "" );
|
|
}
|
|
|
|
wait( 0.5 );
|
|
}
|
|
}
|
|
|
|
function devgui_dog_spawn( team )
|
|
{
|
|
player = util::getHostPlayer();
|
|
|
|
dog_spawner = GetEnt( "dog_spawner", "targetname" );
|
|
level.dog_abort = false;
|
|
|
|
if( !isdefined( dog_spawner ) )
|
|
{
|
|
iprintln( "No dog spawners found in map" );
|
|
return;
|
|
}
|
|
|
|
// Trace to where the player is looking
|
|
direction = player GetPlayerAngles();
|
|
direction_vec = AnglesToForward( direction );
|
|
eye = player GetEye();
|
|
|
|
scale = 8000;
|
|
direction_vec = ( direction_vec[0] * scale, direction_vec[1] * scale, direction_vec[2] * scale );
|
|
trace = bullettrace( eye, eye + direction_vec, 0, undefined );
|
|
|
|
nodes = GetNodesInRadius( trace["position"], 256, 0, 128, "Path", 8 );
|
|
|
|
if ( !nodes.size )
|
|
{
|
|
iprintln( "No nodes found near crosshair position" );
|
|
return;
|
|
}
|
|
|
|
iprintln( "Spawning dog at your crosshair position" );
|
|
node = ArrayGetClosest( trace["position"], nodes );
|
|
|
|
dog = dog_manager_spawn_dog( player, player.team, node, 5 );
|
|
|
|
if ( team != player.team )
|
|
{
|
|
dog.team = team;
|
|
dog ClearEntityOwner();
|
|
dog notify ( "clear_owner" );
|
|
}
|
|
}
|
|
|
|
function devgui_dog_camera()
|
|
{
|
|
player = util::getHostPlayer();
|
|
|
|
if ( !isdefined( level.devgui_dog_camera ) )
|
|
{
|
|
level.devgui_dog_camera = 0;
|
|
}
|
|
|
|
dog = undefined;
|
|
dogs = dog_manager_get_dogs();
|
|
|
|
if ( dogs.size <= 0 )
|
|
{
|
|
level.devgui_dog_camera = undefined;
|
|
player CameraActivate( false );
|
|
return;
|
|
}
|
|
|
|
for ( i = 0; i < dogs.size; i++ )
|
|
{
|
|
dog = dogs[i];
|
|
|
|
if ( !isdefined( dog ) || !IsAlive( dog ) )
|
|
{
|
|
dog = undefined;
|
|
continue;
|
|
}
|
|
|
|
if ( !isdefined( dog.cam ) )
|
|
{
|
|
forward = AnglesToForward( dog.angles );
|
|
dog.cam = spawn( "script_model", dog.origin + ( 0, 0, 50 ) + forward * -100 );
|
|
dog.cam SetModel( "tag_origin" );
|
|
dog.cam LinkTo( dog );
|
|
}
|
|
|
|
if ( dog GetEntityNumber() <= level.devgui_dog_camera )
|
|
{
|
|
dog = undefined;
|
|
continue;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
if ( isdefined( dog ) )
|
|
{
|
|
level.devgui_dog_camera = dog GetEntityNumber();
|
|
|
|
player CameraSetPosition( dog.cam );
|
|
player CameraSetLookAt( dog );
|
|
player CameraActivate( true );
|
|
}
|
|
else
|
|
{
|
|
level.devgui_dog_camera = undefined;
|
|
player CameraActivate( false );
|
|
}
|
|
}
|
|
|
|
function devgui_crate_spawn()
|
|
{
|
|
player = util::getHostPlayer();
|
|
|
|
// Trace to where the player is looking
|
|
direction = player GetPlayerAngles();
|
|
direction_vec = AnglesToForward( direction );
|
|
eye = player GetEye();
|
|
|
|
scale = 8000;
|
|
direction_vec = ( direction_vec[0] * scale, direction_vec[1] * scale, direction_vec[2] * scale );
|
|
trace = bullettrace( eye, eye + direction_vec, 0, undefined );
|
|
|
|
killCamEnt = spawn( "script_model", player.origin );
|
|
level thread supplydrop::dropCrate( trace[ "position" ] + ( 0, 0, 25 ), direction, "supplydrop", player, player.team, killcamEnt );
|
|
}
|
|
|
|
function devgui_crate_delete()
|
|
{
|
|
if ( !isdefined( level.devgui_crates ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
for ( i = 0; i < level.devgui_crates.size; i++ )
|
|
{
|
|
level.devgui_crates[i] delete();
|
|
}
|
|
|
|
level.devgui_crates = [];
|
|
}
|
|
|
|
function devgui_spawn_show()
|
|
{
|
|
if ( !isdefined( level.dog_spawn_show ) )
|
|
{
|
|
level.dog_spawn_show = true;
|
|
}
|
|
else
|
|
{
|
|
level.dog_spawn_show = !level.dog_spawn_show;
|
|
}
|
|
|
|
if ( !level.dog_spawn_show )
|
|
{
|
|
level notify( "hide_dog_spawns" );
|
|
return;
|
|
}
|
|
|
|
spawns = level.dog_spawns;
|
|
color = ( 0, 1, 0 );
|
|
|
|
for ( i = 0; i < spawns.size; i++ )
|
|
{
|
|
dev::showOneSpawnPoint( spawns[i], color, "hide_dog_spawns", 32, "dog_spawn" );
|
|
}
|
|
}
|
|
|
|
function devgui_exit_show()
|
|
{
|
|
if ( !isdefined( level.dog_exit_show ) )
|
|
{
|
|
level.dog_exit_show = true;
|
|
}
|
|
else
|
|
{
|
|
level.dog_exit_show = !level.dog_exit_show;
|
|
}
|
|
|
|
if ( !level.dog_exit_show )
|
|
{
|
|
level notify( "hide_dog_exits" );
|
|
return;
|
|
}
|
|
|
|
exits = GetNodeArray( "exit", "script_noteworthy" );
|
|
color = ( 1, 0, 0 );
|
|
|
|
for ( i = 0; i < exits.size; i++ )
|
|
{
|
|
dev::showOneSpawnPoint( exits[i], color, "hide_dog_exits", 32, "dog_exit" );
|
|
}
|
|
}
|
|
|
|
function dog_debug_patrol( node1, node2 )
|
|
{
|
|
self endon( "death" );
|
|
self endon( "debug_patrol" );
|
|
|
|
for( ;; )
|
|
{
|
|
self SetGoal( node1 );
|
|
self util::waittill_any( "goal", "bad_path" );
|
|
wait( 1 );
|
|
|
|
self SetGoal( node2 );
|
|
self util::waittill_any( "goal", "bad_path" );
|
|
wait( 1 );
|
|
}
|
|
}
|
|
|
|
function devgui_debug_route()
|
|
{
|
|
iprintln( "Choose nodes with 'A' or press 'B' to cancel" );
|
|
nodes = dev::dev_get_node_pair();
|
|
|
|
if ( !isdefined( nodes ) )
|
|
{
|
|
iprintln( "Route Debug Cancelled" );
|
|
return;
|
|
}
|
|
|
|
iprintln( "Sending dog to chosen nodes" );
|
|
dogs = dog_manager_get_dogs();
|
|
|
|
if ( isdefined( dogs[0] ) )
|
|
{
|
|
dogs[0] notify( "debug_patrol" );
|
|
dogs[0] thread dog_debug_patrol( nodes[0], nodes[1] );
|
|
}
|
|
}
|
|
|
|
#/
|