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

#/
