2025-05-21 16:23:17 +02:00

945 lines
26 KiB
Plaintext

#include maps\mp\_utility;
#include common_scripts\utility;
ORBITAL_BULLETTRACE_MAX_PER_FRAME = 5;
ORBITAL_TRACE_DIST = 24000;
ORBITAL_TRACE_CP_RADIUS = 26;
ORBITAL_TRACE_G_RADIUS = 41;
ORBITAL_TRACE_GROUND_OFFSET = ( 0, 0, 6 );
ORBITAL_DIST_FROM_PLAYER = 500;
ORBITAL_FIND_NODE_MAX_LINKS = 6;
initStart()
{
level.orbital_util_remote_traces_frame = 0;
level.orbital_util_remote_traces = ORBITAL_BULLETTRACE_MAX_PER_FRAME;
level.orbital_util_capsule_traces_frame = 0;
level.orbital_util_capsule_traces = ORBITAL_BULLETTRACE_MAX_PER_FRAME;
level.orbital_util_last_trace = 0;
level thread deleteMapRemoteMissileClip();
level.orbital_util_covered_volumes = GetEntArray( "orbital_node_covered", "targetname" );
/#
nodes = GetAllNodes();
if ( !NodeHasRemoteMissileSet( nodes[0] ) )
PrintLn( "WARNING: remoteMissileSpawn entities are either missing or do not have script_noteworthy set to 0, 1, 2, 3, or 4." );
#/
}
deleteMapRemoteMissileClip()
{
clipbrushes = GetEntArray( "carepackage_clip", "targetname" );
foreach ( brush in clipbrushes )
brush Delete();
}
playerGetOutsideNode( type ) // self == player
{
if ( !IsDefined( type ) )
type = "goliath";
node = self playerGetNodeLookingAt( type );
if ( !IsDefined( node ) )
return;
self.lastNodeLookingAtTrace = undefined;
return node;
}
playerGetOrbitalStartPos( node, type ) // self == player
{
if ( !IsDefined( type ) )
type = "goliath";
remoteMissileSpawns = maps\mp\killstreaks\_aerial_utility::getEntOrStructArray( "remoteMissileSpawn" , "targetname" );
org = nodeGetRemoteMissileOrigin( node, remoteMissileSpawns, type );
if ( IsDefined( org ) )
return org;
else
return nodeGetRemoteMissileOrgFromAbove( node );
}
getStartPositionAbove( node )
{
return ( node.origin + ( 0, 0, ORBITAL_TRACE_DIST ) );
}
addDropMarker( markerEnt, type )
{
if ( !IsDefined( type ) )
type = "goliath";
markerEnt.orbitalType = type;
level.orbitalDropMarkers[level.orbitalDropMarkers.size] = markerEnt;
thread _addDropMarkerInternal( markerEnt );
}
playerPlayInvalidPositionEffect( effectRef ) // self == player
{
trace = self.lastNodeLookingAtTrace;
nearestNode = self.lastNearestNode;
if ( !IsDefined( trace ) )
{
playerDir = AnglesToForward( self GetPlayerAngles() );
start = self GetEye();
end = start + ( playerDir * ORBITAL_DIST_FROM_PLAYER );
trace = BulletTrace( start, end, false, self, true, false, false, false, false );
}
self.lastNodeLookingAtTrace = undefined;
self.lastNearestNode = undefined;
effectOrg = trace["position"];
// might be looking at a wall so determine whether to use the trace position or this node
if ( IsDefined( nearestNode ) )
{
normal = trace[ "normal" ];
isGroundFlat = normal[2] > 0.8;
if ( !isGroundFlat )
effectOrg = nearestNode.origin;
}
marker = Spawn( "script_model", effectOrg + ( 0, 0, 5 ) );
marker.angles = ( -90, 0, 0 );
marker SetModel( "tag_origin" );
marker Hide();
marker ShowToPlayer( self );
PlayFXOnTag( effectRef, marker, "tag_origin" );
wait 5;
marker Delete();
}
//------------------------------------------------------------------------------------------------
// Internal
playerGetNodeLookingAt( type ) // self == player
{
// Test if player is looking at something
playerDir = AnglesToForward( self GetPlayerAngles() );
start = self GetEye();
end = start + ( playerDir * ORBITAL_DIST_FROM_PLAYER );
trace = BulletTrace( start, end, false, self, true, false, false, false, false );
self.lastNodeLookingAtTrace = trace;
lookingAway = ( trace[ "fraction" ] == 1 );
/# debugPlacementLine( start, start + ( playerDir * ORBITAL_DIST_FROM_PLAYER * trace[ "fraction" ] ), ( 0, 1, 0 ), ( 1, 0, 0 ), lookingAway ); #/
if ( lookingAway )
return playerGetNearestNode( undefined, type );
// Test if position at has nodes nearby (is in playspace)
position = trace[ "position" ];
nodes = GetNodesInRadius( position, 128, 0, 60 );
outOfPlaySpace = ( nodes.size == 0 );
if ( outOfPlaySpace ) // any nodes within the players use radius
return playerGetNearestNode( undefined, type );
// Test if position is on the ground
normal = trace[ "normal" ];
isGroundFlat = normal[2] > 0.8;
/# debugPlacementLine( position, position + ( normal * 20 ), ( 0, 1, 0 ), ( 1, 0, 0 ), !isGroundFlat ); #/
if ( !isGroundFlat )
return playerGetNearestNode( position, type );
// Test if the position is in a 'covered' area
if ( IsDefined( level.orbital_util_covered_volumes ) && level.orbital_util_covered_volumes.size > 0 )
{
pointInVolume = false;
foreach ( volume in level.orbital_util_covered_volumes )
{
pointInVolume = IsPointInVolume( position, volume );
if ( pointInVolume )
break;
}
/# debugPlacementSphere( position, 5.0, ( 0, 1, 0 ), ( 1, 0, 0 ), pointInVolume ); #/
if ( pointInVolume )
return playerGetNearestNode( position, type );
}
// Adding an additional test for Goliath drop pods. We want to restrict landing zones with trigger volumes with targetname, goliath_bad_landing_volume.
if ( type == "goliath" )
{
if ( goliathBadLandingCheck( position ) )
{
return playerGetNearestNode( position, type );
}
}
// Test if the carepackage will fit here
tracePassed = carepackageTrace( position, self, type );
/#
radius = ORBITAL_TRACE_G_RADIUS;
if ( type == "carepackage" )
radius = ORBITAL_TRACE_CP_RADIUS;
debugPlacementSphere( position, radius, ( 0, 1, 0 ), ( 1, 0, 0 ), !tracePassed );
#/
if ( !tracePassed )
return playerGetNearestNode( position, type );
// Test if one of 4 corners of the carepackage/pod is hanging off of the edge of a roof. Reject this case because the projectile could miss the edge of a roof.
if ( groundPositionOffEdge( position, type ) )
return playerGetNearestNode( position, type );
// Test if the carepackage can reach this position from a remoteMissileSpawn
node = SpawnStruct();
node.origin = position;
remoteMissileSpawns = maps\mp\killstreaks\_aerial_utility::getEntOrStructArray( "remoteMissileSpawn" , "targetname" );
org = nodeGetRemoteMissileOrigin( node, remoteMissileSpawns, type );
if ( !IsDefined( org ) )
return playerGetNearestNode( position, type );
return node;
}
groundPositionOffEdge( position, type )
{
if ( type == "goliath" )
radius = ORBITAL_TRACE_G_RADIUS;
else
radius = ORBITAL_TRACE_CP_RADIUS;
xPos = ( radius, 0, 0 );
xNeg = -1*xPos;
yPos = ( 0, radius, 0 );
yNeg = -1*yPos;
endOffset = ( 0, 0, -10 );
testDirections = [xPos, xNeg, yPos, yNeg];
foreach(dir in testDirections)
{
start = position + dir;
end = position + dir + endOffset;
tracePassed = BulletTracePassed( start, end, false, undefined );
if( tracePassed )
return true;
}
return false;
}
_nodeFindNewRemoteMissileOrg( node, remoteMissileSpawns, type )
{
ent = nodeFindRemoteMissleEnt( node, remoteMissileSpawns, type );
if ( IsDefined( ent ) )
{
/# debugNodeFindNewRemoteMissileEnt( node, ent.script_noteworthy ); #/
return nodeGetRemoteMissleEntOrg( node, remoteMissileSpawns );
}
org = nodeTestFireFromAbove( node, type );
if ( IsDefined( org ) )
{
/# debugNodeFindNewRemoteMissileEnt( node, "up" ); #/
return nodeGetRemoteMissileOrgFromAbove( node );
}
else
{
/# debugNodeFindNewRemoteMissileEnt( node, "none" ); #/
}
}
nodeGetRemoteMissileOrigin( node, remoteMissileSpawns, type )
{
/#
if ( GetDvarInt( "scr_remoteMissile_redo_node", 0 ) != 0 )
{
if ( nodeHasRemoteMissileDataSet( node ) )
return _nodeFindNewRemoteMissileOrg( node, remoteMissileSpawns, type );
return;
}
#/
if ( nodeHasRemoteMissileDataSet( node ) )
{
if ( !nodeIsRemoteMissileFromAbove( node ) )
return nodeGetRemoteMissleEntOrg( node, remoteMissileSpawns );
else
return nodeGetRemoteMissileOrgFromAbove( node );
}
else
{
return _nodeFindNewRemoteMissileOrg( node, remoteMissileSpawns, type );
}
}
nodeIsPathnode( node )
{
return ( IsDefined( node.type ) );
}
nodeIsRemoteMissileFromAbove( node )
{
return ( ( nodeIsPathnode( node ) && NodeHasRemoteMissileSet( node ) && NodeGetRemoteMissileName( node ) == "up" ) || IsDefined( node.bestMissileSpawnAbove ) );
}
nodeHasRemoteMissileDataSet( node )
{
return ( ( nodeIsPathnode( node ) && NodeHasRemoteMissileSet( node ) ) || ( IsDefined( node.bestMissileSpawnAbove ) || IsDefined( node.bestMissileSpawn ) ) );
}
nodeGetRemoteMissileOrgFromAbove( node )
{
return getStartPositionAbove( node );
}
nodeTestFireFromAbove( node, type )
{
org = getStartPositionAbove( node );
passed = remoteMissileEntTraceToOriginPassedWrapper( org, node.origin, type );
/# debugPlacementLine( org, node.origin, ( 0, 1, 0 ), ( 1, 0, 0 ), !passed ); #/
if ( passed )
{
node.bestMissileSpawnAbove = org;
return org;
}
}
nodeGetRemoteMissleEntOrg( node, remoteMissileSpawns )
{
remoteMissileEnt = undefined;
if ( nodeIsPathnode( node ) && NodeHasRemoteMissileSet( node ) )
{
name = NodeGetRemoteMissileName( node );
foreach ( ent in remoteMissileSpawns )
{
if ( IsDefined( ent.script_noteworthy ) && ent.script_noteworthy == name )
remoteMissileEnt = ent;
}
}
else if ( IsDefined( node.bestMissileSpawn ) )
{
remoteMissileEnt = node.bestMissileSpawn;
}
Assert( IsDefined( remoteMissileEnt ) );
dir = VectorNormalize( remoteMissileEnt.origin - node.origin );
return ( node.origin + ( dir * ORBITAL_TRACE_DIST ) );
}
nodeFindRemoteMissleEnt( node, remoteMissileSpawns, type )
{
remoteMissileSpawns = SortByDistance( remoteMissileSpawns, node.origin );
foreach ( ent in remoteMissileSpawns )
{
passed = remoteMissileEntTraceToOriginPassedWrapper( ent.origin, node.origin, type );
/# debugPlacementLine( ent.origin, node.origin, ( 0, 1, 0 ), ( 1, 0, 0 ), !passed ); #/
if ( passed )
{
node.bestMissileSpawn = ent;
return ent;
}
waitframe();
}
}
remoteMissileEntTraceToOriginPassedWrapper( remoteMissileSpawnOrigin, groundOrigin, type )
{
if ( level.orbital_util_remote_traces_frame != GetTime() )
{
level.orbital_util_remote_traces_frame = GetTime();
level.orbital_util_remote_traces = ORBITAL_BULLETTRACE_MAX_PER_FRAME;
}
if ( level.orbital_util_remote_traces <= 0 )
{
if ( level.orbital_util_last_trace != GetTime() )
{
waitframe();
level.orbital_util_last_trace = GetTime();
}
level.orbital_util_remote_traces = ORBITAL_BULLETTRACE_MAX_PER_FRAME;
}
level.orbital_util_remote_traces--;
radius = ORBITAL_TRACE_CP_RADIUS;
if ( type == "goliath" )
radius = ORBITAL_TRACE_G_RADIUS;
// expensive
return RemoteMissileEntTraceToOriginPassed( remoteMissileSpawnOrigin, groundOrigin, radius, true );
}
nodeCanHitGround( node, type )
{
if ( IsDefined( type ) && type == "goliath" )
{
if ( goliathBadLandingCheck( node.origin ) )
{
return false;
}
}
if ( NodeHasRemoteMissileSet( node ) )
return ( NodeGetRemoteMissileName( node ) != "none" );
else
return NodeExposedToSky( node, true );
}
carepackageTrace( position, player, type )
{
HEIGHT = 100;
if ( type == "goliath" )
radius = ORBITAL_TRACE_G_RADIUS;
else
radius = ORBITAL_TRACE_CP_RADIUS;
foreach ( marker in level.orbitalDropMarkers )
{
dist = radius;
if ( marker.orbitalType == "goliath" )
dist += ORBITAL_TRACE_G_RADIUS;
else
dist += ORBITAL_TRACE_CP_RADIUS;
distSqMin = dist * dist;
distSq = Distance2DSquared( marker.origin, position );
if ( distSq < distSqMin )
return false;
}
if ( level.orbital_util_capsule_traces_frame != GetTime() )
{
level.orbital_util_capsule_traces_frame = GetTime();
level.orbital_util_capsule_traces = ORBITAL_BULLETTRACE_MAX_PER_FRAME;
}
if ( level.orbital_util_capsule_traces <= 0 )
{
if ( level.orbital_util_last_trace != GetTime() )
{
waitframe();
level.orbital_util_last_trace = GetTime();
}
level.orbital_util_capsule_traces = ORBITAL_BULLETTRACE_MAX_PER_FRAME;
}
level.orbital_util_capsule_traces--;
return CapsuleTracePassed( position + ORBITAL_TRACE_GROUND_OFFSET, radius, radius * 2, player, false );
}
playerGetNearestNode( point, type )
{
if ( !IsDefined( point ) )
{
DIST = 300;
start = self GetEye();
dir = AnglesToForward( self.angles );
end = start + ( dir * DIST );
trace = BulletTrace( start, end, false, self );
point = end;
if ( trace[ "fraction" ] < 1 )
point = start + ( dir * DIST * trace[ "fraction" ] );
}
nearestNode = GetClosestNodeInSight( point, true );
nearestNodeValid = IsDefined( nearestNode );
if ( nearestNodeValid )
{
nearestNodeValid = nodeCanHitGround( nearestNode, type ) && carepackageTrace( nearestNode.origin, self, type );
/#debugPlacementBox( nearestNode.origin + ( 0, 0, 20 ), ( 0, 1, 0 ), ( 1, 0, 0 ), !nearestNodeValid );#/
}
if ( nearestNodeValid )
return nearestNode;
// try some traces to find a node the player can see
result = SpawnStruct();
result.maxTracesPerFrame = 5;
result.maxNodes = 20;
result.numTraces = 5;
self playerFindNodeInFront( point, type, result );
bestNode = result.nearestNode;
if ( IsDefined( bestNode ) )
return bestNode;
if ( !IsDefined( nearestNode ) )
{
nearestNode = self playerGetClosestNode( 500, 100, self.origin, false, true, type );
if ( !IsDefined( nearestNode ) )
nearestNode = self playerGetClosestNode( 500, 0, self.origin, false, false, type );
if ( !IsDefined( nearestNode ) )
nearestNode = self GetNearestNode();
}
self.lastNearestNode = nearestNode;
// player can't see a close node, so find a nearby aerial node, possibly out of fov
if ( IsDefined( nearestNode ) )
return playerFindAltNode( nearestNode, type );
}
goliathBadLandingCheck( pos ) // returns true if pos is in a bad landing volume for Goliaths.
{
if ( IsDefined( level.goliath_bad_landing_volumes ) )
{
foreach ( trig_volume in level.goliath_bad_landing_volumes )
{
if ( IsPointInVolume( pos, trig_volume ) )
{
return true;
}
}
}
return false;
}
playerFindNodeInFront( point, type, result )
{
maxDistSearch = ORBITAL_DIST_FROM_PLAYER;
minDistSearch = 100;
nodeFound = playerFindNodeInFrontInternal( point, minDistSearch, maxDistSearch, type, result );
if ( !IsDefined( nodeFound ) && result.maxNodes > 0 )
{
minDistSearch = 0;
nodeFound = playerFindNodeInFrontInternal( point, minDistSearch, maxDistSearch, type, result );
}
result.nearestNode = nodeFound;
}
playerFindNodeInFrontInternal( point, minDistSearch, maxDistSearch, type, result )
{
while ( minDistSearch < maxDistSearch && result.maxNodes > 0 )
{
nextNode = self playerGetClosestNode( maxDistSearch, minDistSearch, point, true, true, type );
if ( result.numTraces <= 0 && !traceDoneRecently() )
{
waitframe();
result.numTraces = result.maxTracesPerFrame;
}
if ( IsDefined( nextNode ) )
{
result.numTraces--;
result.maxNodes--;
start = self GetEye();
end = nextNode.origin + ORBITAL_TRACE_GROUND_OFFSET;
trace = BulletTrace( start, end, false, self );
nextNodeValid = ( trace[ "fraction" ] == 1 ) && carepackageTrace( nextNode.origin, self, type );
/#debugPlacementBox( nextNode.origin + ( 0, 0, 20 ), ( 0, 1, 0 ), ( 1, 0, 0 ), !nextNodeValid );#/
if ( nextNodeValid )
return nextNode;
minDistSearch = Distance( point, nextNode.origin ) + 1;
}
else
{
minDistSearch = maxDistSearch + 1;
}
}
}
playerFindAltNode( nearestNode, type )
{
// prof_begin( "playerFindAltNodeOrigin" );
bestNode = checkNodeStart( nearestNode, self, type );
// prof_end( "playerFindAltNodeOrigin" );
if ( IsDefined( bestNode ) )
{
if ( type == "goliath" )
{
if ( goliathBadLandingCheck( bestNode.origin ) )
{
return undefined;
}
}
return bestNode;
}
}
traceDoneRecently()
{
return ( level.orbital_util_last_trace == GetTime() );
}
checkNodeStart( startNode, player, type )
{
MAX_DIST_SQ = ORBITAL_DIST_FROM_PLAYER * ORBITAL_DIST_FROM_PLAYER;
NODES_PER_FRAME = 20;
startNode.linkDistance = 0;
startNode.nodeChecked = true;
nodeContainer = SpawnStruct();
nodeContainer.nodesToCheck = [];
nodeContainer.nodesChecked = [];
nodeContainer.nodesChecked["" + startNode GetNodeNumber()] = startNode;
nodeContainer.nextNodes = GetLinkedNodes( startNode, true);
addNodesToBeChecked( nodeContainer, 1, startNode, MAX_DIST_SQ, player, type );
numNodes = 0;
while ( true )
{
nextNode = getNextNode( nodeContainer );
if ( IsDefined( nextNode ) )
{
numNodes++;
if ( !carepackageTrace( nextNode.origin, player, type ) )
{
nextNode.nodeChecked = true;
nodeContainer.nodesToCheck["" + nextNode GetNodeNumber()] = undefined;
nodeContainer.nodesChecked["" + nextNode GetNodeNumber()] = nextNode;
/# drawBadPathDebug( nextNode ); #/
nextLinkDistance = nextNode.linkDistance + 1;
if ( nextLinkDistance <= ORBITAL_FIND_NODE_MAX_LINKS )
{
nodeContainer.nextNodes = GetLinkedNodes( nextNode, true );
addNodesToBeChecked( nodeContainer, nextLinkDistance, nextNode, MAX_DIST_SQ, player, type );
}
}
else
{
cleanupNodeFields( nodeContainer );
/# drawParentPathDebug( nextNode ); #/
/# removeNodeParents( nodeContainer ); #/
return nextNode;
}
}
else
{
cleanupNodeFields( nodeContainer );
//PrintLn( "NUMNODES: " + numNodes );
/# removeNodeParents( nodeContainer ); #/
return;
}
if ( numNodes >= NODES_PER_FRAME )
{
if ( !traceDoneRecently() )
waitframe();
numNodes = 0;
}
}
}
cleanupNodeFields( nodeContainer )
{
foreach ( node in nodeContainer.nodesToCheck )
{
node.linkDistance = undefined;
node.nodeChecked = undefined;
}
foreach ( node in nodeContainer.nodesChecked )
{
node.linkDistance = undefined;
node.nodeChecked = undefined;
}
}
getNextNode( nodeContainer )
{
if ( nodeContainer.nodesToCheck.size == 0 )
return;
bestNode = undefined;
bestLinkDistance = undefined;
keys = GetArrayKeys( nodeContainer.nodesToCheck );
for ( i = 0; i < keys.size; i++ )
{
node = nodeContainer.nodesToCheck[keys[i]];
if ( !IsDefined( bestNode ) || node.linkDistance < bestLinkDistance )
{
bestNode = node;
bestLinkDistance = node.linkDistance;
}
}
return bestNode;
}
addNodesToBeChecked( nodeContainer, linkDistance, parentNode, maxDistSq, player, type )
{
for ( i = 0; i < nodeContainer.nextNodes.size; i++ )
{
node = nodeContainer.nextNodes[i];
if ( !IsDefined( node.nodeChecked ) )
{
validNode = nodeCanHitGround( node, type );
if ( validNode )
{
distSq = DistanceSquared( node.origin, player.origin );
validNode = distSq < maxDistSq;
}
if ( !validNode )
{
node.nodeChecked = true;
nodeContainer.nodesChecked["" + node GetNodeNumber()] = node;
}
else
{
if ( !IsDefined( node.linkDistance ) )
{
node.linkDistance = linkDistance;
nodeContainer.nodesToCheck["" + node GetNodeNumber()] = node;
/# addNodeParent( node, parentNode ); #/
}
else
{
if ( node.linkDistance > linkDistance )
{
node.linkDistance = linkDistance;
/# addNodeParent( node, parentNode ); #/
}
}
}
}
}
}
playerGetClosestNode( maxRadius, minRadius, point, checkExposed, checkPlayerFov, type )
{
if ( !IsDefined( maxRadius ) )
maxRadius = 1500;
if ( !IsDefined( minRadius ) )
minRadius = 0;
if ( !IsDefined( point ) )
point = self.origin;
radiusIncrement = 100;
// want to be sure to get the closest node because if you make the radius too large and get too many nodes then
// native code may skip the close ones so limit to a radius of 100 at a time
nextMinRadius = minRadius;
nextMaxRadius = minRadius + radiusIncrement;
if ( nextMaxRadius > maxRadius )
nextMaxRadius = maxRadius;
while ( nextMaxRadius <= maxRadius && nextMinRadius < maxRadius )
{
node = self playerGetClosestNodeInternal( nextMaxRadius, nextMinRadius, point, checkExposed, checkPlayerFov, type );
if ( IsDefined( node ) )
return node;
nextMinRadius += radiusIncrement;
nextMaxRadius += radiusIncrement;
if ( nextMaxRadius > maxRadius )
nextMaxRadius = maxRadius;
}
}
playerGetClosestNodeInternal( maxRadius, minRadius, point, checkExposed, checkPlayerFov, type )
{
valid = true;
nodes = GetNodesInRadiusSorted( point, maxRadius, minRadius, 120, "path" );
for ( i = 0; i < nodes.size; i++ )
{
if ( checkExposed )
valid = valid & nodeCanHitGround( nodes[ i ], type );
if ( checkPlayerFov )
valid = valid & self playerWithinFOV2D( nodes[ i ].origin );
///#
// if ( !valid )
// debugPlacementBox( nodes[i].origin, ( 1, 0.6, 0 ), ( 1, 1, 0 ), !withinFov );
//#/
if ( valid )
return nodes[ i ];
}
}
playerWithinFov2D( origin )
{
fov = cos( 60 );
normal = VectorNormalize( ( origin[ 0 ], origin[ 1 ], 0 ) - ( self.origin[ 0 ], self.origin[ 1 ], 0 ) );
forward = AnglesToForward( ( 0, self.angles[ 1 ], 0 ) );
return VectorDot( forward, normal ) >= fov;
}
_addDropMarkerInternal( markerEnt )
{
markerEnt waittill( "death" );
level.orbitalDropMarkers = array_remove( level.orbitalDropMarkers, markerEnt );
}
/*
=============
///ScriptDocBegin
"Name: nodeSetRemoteMissileNameWrapper( <origin> , <name> )"
"Summary: Changes the remote missile entity of this node to use in a patch situation. Turn on the following dvars: \ai_shownodes 16, \set scr_remoteMissile_redo_node 1. Give yourself a goliath. Point at a suspect node and call it down. If the number changes then check the output for the script change."
"CallOn: level"
"MandatoryArg: <origin>: the origin of the pathnode"
"MandatoryArg: <name>: Remote missile ent name. Valid names are "0", "1", "2", "3", "4", "up", "none""
"Example: maps\mp\killstreaks\_orbital_util::nodeSetRemoteMissileNameWrapper( (-1249.3, 828.9, 2202.63), "1" );"
///ScriptDocEnd
=============
*/
nodeSetRemoteMissileNameWrapper( origin, name )
{
AssertEx( name == "0" || name == "1" || name == "2" || name == "3" || name == "4" || name == "up" || name == "none" );
nodes = GetNodesInRadiusSorted( origin , 24, 0 );
if ( nodes.size > 0 )
{
node = nodes[0];
NodeSetRemoteMissileName( node, name );
}
else
{
/# PrintLn( "Error: nodeSetRemoteMissileNameWrapper() could not find a node at origin: " + origin ); #/
}
}
// ----------------------------------------------------------------------
// DEBUG
/#
addNodeParent( node, parent )
{
if ( GetDvar( "scr_orbital_path_debug", "0" ) != "0" )
{
node.parent = parent;
}
}
removeNodeParents( nodeContainer )
{
if ( GetDvar( "scr_orbital_path_debug", "0" ) != "0" )
{
foreach ( node in nodeContainer.nodesToCheck )
node.parent = undefined;
foreach ( node in nodeContainer.nodesChecked )
node.parent = undefined;
}
}
drawBadPathDebug( node )
{
if ( GetDvar( "scr_orbital_path_debug", "0" ) != "0" )
{
OFFSET = ( 0, 0, 2 );
if ( IsDefined( node.parent ) )
Line( node.origin + OFFSET, node.parent.origin + OFFSET, ( 1, 0, 0 ), 1, 0, GetDvarInt( "scr_orbital_path_debug_frames", 1000 ) );
Sphere( node.origin + OFFSET, 4.0, ( 0, 0, 1 ), 0, GetDvarInt( "scr_orbital_path_debug_frames", 1000 ) );
}
}
drawParentPathDebug( node )
{
if ( GetDvar( "scr_orbital_path_debug", "0" ) != "0" )
{
OFFSET = ( 0, 0, 10 );
numLinks = 0;
previousNode = node;
nextNode = node.parent;
Sphere( previousNode.origin + OFFSET, 5.0, ( 0, 1, 1 ), 0, GetDvarInt( "scr_orbital_path_debug_frames", 1000 ) );
Print( "PATH DEBUG: Nodes = " + previousNode GetNodeNumber() );
while ( IsDefined( nextNode ) && numLinks <= ORBITAL_FIND_NODE_MAX_LINKS )
{
numLinks++;
Line( previousNode.origin + OFFSET, nextNode.origin + OFFSET, ( 0, 1, 0 ), 1, 0, GetDvarInt( "scr_orbital_path_debug_frames", 1000 ) );
Sphere( nextNode.origin + OFFSET, 5.0, ( 0, 1, 1 ), 0, GetDvarInt( "scr_orbital_path_debug_frames", 1000 ) );
Print( " <- " + nextNode GetNodeNumber() );
previousNode = nextNode;
nextNode = nextNode.parent;
}
PrintLn( "" );
PrintLn( "PATH DEBUG: num links: " + numLinks );
}
}
debugBestNode( node )
{
if ( !IsDefined( node ) )
return;
if ( GetDvar( "scr_goliath_debug_placement", "0" ) != "0" )
{
debugPlacementBox( node.origin + ( 0, 0, 20 ), ( 0, 1, 0 ) );
nextNode = node.parentNode;
prevNode = node;
while ( IsDefined( nextNode ) )
{
debugPlacementBox( nextNode.origin + ( 0, 0, 20 ), ( 0, 0, 1 ) );
if ( IsDefined( prevNode ) )
debugPlacementLine( nextNode.origin + ( 0, 0, 20 ), prevNode.origin + ( 0, 0, 20 ), ( 0, 1, 1 ) );
prevNode = nextNode;
nextNode = nextNode.parentNode;
}
}
}
debugPlacementLine( pos1, pos2, color1, color2, colorCondition )
{
if ( !IsDefined( colorCondition ) )
colorCondition = false;
if ( GetDvar( "scr_goliath_debug_placement", "0" ) != "0" )
{
color = color1;
if ( colorCondition )
color = color2;
Line( pos1, pos2, color, 1, 0, GetDvarInt( "scr_goliath_debug_placement_frames", 1000 ) );
}
}
debugPlacementSphere( pos, radius, color1, color2, colorCondition )
{
if ( !IsDefined( colorCondition ) )
colorCondition = false;
if ( GetDvar( "scr_goliath_debug_placement", "0" ) != "0" )
{
color = color1;
if ( colorCondition )
color = color2;
Sphere( pos, radius, color, 0, GetDvarInt( "scr_goliath_debug_placement_frames", 1000 ) );
}
}
debugPlacementBox( pos, color1, color2, colorCondition )
{
if ( !IsDefined( colorCondition ) )
colorCondition = false;
if ( GetDvar( "scr_goliath_debug_placement", "0" ) != "0" )
{
color = color1;
if ( colorCondition )
color = color2;
Box( pos, 0, color, 0, GetDvarInt( "scr_goliath_debug_placement_frames", 1000 ) );
}
}
debugNodeFindNewRemoteMissileEnt( node, remoteMissileEntName )
{
if ( GetDvarInt( "scr_remoteMissile_redo_node", 0 ) != 0 )
{
PrintLn( "*********************************************************************" );
PrintLn( "To change this nodes remote missile ent add this to your level gsc: " );
Println( "maps\\mp\\killstreaks\\_orbital_util::nodeSetRemoteMissileNameWrapper( " + node.origin + ", \"" + remoteMissileEntName + "\" );" );
PrintLn( "*********************************************************************" );
NodeSetRemoteMissileName( node, remoteMissileEntName );
}
}
#/