cod5-sdk/raw/maps/_civilian_move.gsc

354 lines
11 KiB
Plaintext

#include maps\_utility;
#include common_scripts\utility;
#include maps\_anim;
#include maps\_civilian;
#include maps\_civilian_idle;
waittillSpeedSet()
{
self endon ( "civilian_death" );
while( !isdefined( self.speed ) )
wait 0.05;
}
#using_animtree( "civilian" );
civilian_loop_moveAnims( anime )
{
self civilian_prepare_for_animation();
assert( isdefined( level.scr_anim[self.animname][anime] ) );
assert( level.scr_anim[self.animname][anime].size > 0 );
if ( isdefined( self.current_move_anim ) )
self clearanim( self.current_move_anim, 0 );
self endon ( "stop_civilian_move_anim" );
self endon ( "civilian_death" );
blendTime = 1.0;
for (;;)
{
loopanime = undefined;
if (0 == 1)
loopanime = anime + "_react";
else
loopanime = anime;
assert( isdefined( loopanime ) );
rand = randomint( level.scr_anim[self.animname][loopanime].size );
self.current_move_anim = level.scr_anim[self.animname][loopanime][rand]["anim"];
assert( isdefined( level.scr_anim[self.animname][loopanime][rand]["speed"] ) );
self.speed = level.scr_anim[self.animname][loopanime][rand]["speed"];
animTime = self getAnimTime( self.current_move_anim );
if ( animTime < blendTime )
blendTime = (animTime / 2);
self SetFlaggedAnimKnobAllRestart( "loop_anim_done", self.current_move_anim, %root, 1.0, blendTime, 1.0 );
self waittillmatch ( "loop_anim_done", "end" );
self clearanim( self.current_move_anim, 0 );
}
}
MoveChain( destinationPoint, vecArray )
{
usingNodes = true;
if ( !isdefined( destinationPoint ) )
usingNodes = false;
self notify ( "moving_civilian" );
self endon ( "moving_civilian" );
self endon ( "civilian_death" );
//stop the character from doing his idle
self notify ( "civilian_stop_idle" );
self stopAnimScripted();
//ToDo: Make it support a script_struct targeting multiple script_structs so it can randomly use one
//Create the lookahead point that the character will face and move towards
//------------------------------------------------------------------------
lookaheadPoint = setInitialLookaheadPoint();
if ( usingNodes )
{
//Get array of chained nodes - starting with the characters current location
//--------------------------------------------------------------------------
nodes = getPathArray( destinationPoint, undefined, self.origin );
}
else
{
assert( isdefined( vecArray ) );
assert( isdefined( vecArray[0] ) );
//Get array of nodes from the vectors - starting with the characters current location
//-----------------------------------------------------------------------------------
nodes = getPathArray( undefined, vecArray, self.origin );
}
assert( isdefined( nodes ) );
assert( isdefined( nodes[0] ) );
prof_begin( "civilian_math" );
loopTime = 0.5;
currentNode_LookAhead = 0;
for (;;)
{
if ( !isdefined( nodes[currentNode_LookAhead] ) )
break;
//Calculate how far and what direction the lookahead path point should move
//-------------------------------------------------------------------------
//find point on real path where character is
vec1 = nodes[currentNode_LookAhead]["vec"];
vec2 = ( self.origin - nodes[currentNode_LookAhead]["origin"] );
distanceFromPoint1 = vectorDot( vectorNormalize( vec1 ), vec2 );
//check if this is the last node (wont have a distance value)
if ( !isdefined( nodes[currentNode_LookAhead]["dist"] ) )
break;
lookaheadDistanceFromNode = ( distanceFromPoint1 + level.civilian_lookAhead_value );
assert( isdefined( lookaheadDistanceFromNode ) );
assert( isdefined( currentNode_LookAhead ) );
assert( isdefined( nodes[currentNode_LookAhead] ) );
assert( isdefined( nodes[currentNode_LookAhead]["dist"] ) );
while ( lookaheadDistanceFromNode > nodes[currentNode_LookAhead]["dist"] )
{
//moving the lookahead would pass the node, so move it the remaining distance on the vector of the next node
lookaheadDistanceFromNode = lookaheadDistanceFromNode - nodes[currentNode_LookAhead]["dist"];
currentNode_LookAhead++;
if( !isdefined( nodes[currentNode_LookAhead]["dist"] ) )
{
//last node on the chain
self rotateTo( vectorToAngles( nodes[nodes.size -1]["vec"] ), loopTime );
d = distance( self.origin, nodes[nodes.size -1]["origin"] );
timeOfMove = (d / self.speed);
moveToDest = physicstrace( nodes[nodes.size -1]["origin"] + ( 0, 0, level.traceHeight ), nodes[nodes.size -1]["origin"] - ( 0, 0, level.traceHeight ) );
self moveTo( moveToDest, timeOfMove );
wait timeOfMove;
self notify ( "goal" );
self notify ( "civilian_idle" );
prof_end( "civilian_math" );
return;
}
if ( !isdefined( nodes[currentNode_LookAhead] ) )
{
prof_end( "civilian_math" );
self notify ( "goal" );
self notify ( "civilian_idle" );
return;
}
assert( isdefined( nodes[currentNode_LookAhead] ) );
}
//-------------------------------------------------------------------------
//Move the lookahead point down along it's path
//---------------------------------------------
assert( isdefined( nodes[currentNode_LookAhead]["vec"] ) );
assert( isdefined( nodes[currentNode_LookAhead]["vec"][0] ) );
assert( isdefined( nodes[currentNode_LookAhead]["vec"][1] ) );
assert( isdefined( nodes[currentNode_LookAhead]["vec"][2] ) );
desiredPosition = vectorScale ( nodes[currentNode_LookAhead]["vec"], lookaheadDistanceFromNode);
desiredPosition = desiredPosition + nodes[currentNode_LookAhead]["origin"];
lookaheadPoint = desiredPosition;
//trace the lookahead point to the ground
lookaheadPoint = physicstrace( lookaheadPoint + ( 0, 0, level.traceHeight ), lookaheadPoint - ( 0, 0, level.traceHeight ) );
if ( getdvar( "debug_civilians" ) == "1" )
{
thread debug_line( undefined, lookaheadPoint, 10, (1,0,0) );
iprintln ( lookaheadDistanceFromNode + "/" + nodes[currentNode_LookAhead]["dist"] + " units forward from node[" + currentNode_LookAhead + "]" );
}
//---------------------------------------------
//Rotate character to face the lookahead point
//--------------------------------------------
assert( isdefined ( lookaheadPoint ) );
characterFaceDirection = VectorToAngles( lookaheadPoint - self.origin );
assert( isdefined( characterFaceDirection ) );
assert( isdefined( characterFaceDirection[0] ) );
assert( isdefined( characterFaceDirection[1] ) );
assert( isdefined( characterFaceDirection[2] ) );
self rotateTo( ( 0, characterFaceDirection[1], 0 ), loopTime );
//--------------------------------------------
//Move the character in the direction of the lookahead point
//----------------------------------------------------------
characterDistanceToMove = (self.speed * loopTime);
moveVec = vectorNormalize( lookaheadPoint - self.origin );
desiredPosition = vectorScale ( moveVec, characterDistanceToMove );
desiredPosition = desiredPosition + self.origin;
if ( getdvar( "debug_civilians" ) == "1" )
thread debug_line( undefined, desiredPosition, 10, (0,0,1) );
self moveTo( desiredPosition, loopTime );
//----------------------------------------------------------
wait loopTime;
}
prof_end( "civilian_math" );
self notify ( "goal" );
self notify ( "civilian_idle" );
}
getPathArray( firstTargetName, vecArray, initialPoint )
{
//#########################################################################################################
//make an array of all the points along the spline
//starting with the characters current position, then starting with the point with the passed in targetname
//
// information stored in array:
//
// origin - origin of the node
// dist - distance to the next node (will be undefined if there is not a next node)
// vec - vector to the next node (if there is not a next node, the vector will be the same as the previous node)
//
//#########################################################################################################
usingNodes = true;
if ( !isdefined( firstTargetName ) )
{
usingNodes = false;
assert( isdefined( vecArray ) );
assert( isdefined( vecArray[0] ) );
}
prof_begin("civilian_math");
assert(isdefined(initialPoint));
nodes = [];
nodes[0]["origin"] = initialPoint;
nodes[0]["dist"] = 0;
nextNodeName = undefined;
vecArrayIndex = undefined;
if ( usingNodes )
nextNodeName = firstTargetName;
else
vecArrayIndex = 0;
for (;;)
{
index = nodes.size;
//get the next node in the chain
node = undefined;
if ( usingNodes )
{
node = getstruct( nextNodeName, "targetname" );
//no script_struct was found
if (!isdefined(node))
{
if (index == 0)
assertMsg( "Civilian was told to walk to a node with a targetname that doesnt match a script_struct targetname" );
break;
}
}
//add this node information to the chain data array
if ( usingNodes )
nodes[index]["origin"] = node.origin;
else
{
if (!isdefined(vecArray[vecArrayIndex]))
{
if ( vecArrayIndex == 0 )
assertMsg( "Civilian was told to walk to an undefined vecArray" );
break;
}
nodes[index]["origin"] = vecArray[vecArrayIndex];
}
//find the distance from the previous node to this node, and the vector of of the previous node to this node
//then add the info to the previous nodes data
nodes[index - 1]["dist"] = distance( nodes[index]["origin"], nodes[index - 1]["origin"] );
nodes[index - 1]["vec"] = vectorNormalize( nodes[index]["origin"] - nodes[index - 1]["origin"] );
if ( usingNodes )
{
//if the node doesn't target another node then it's the last of the chain
if (!isdefined(node.target))
break;
//it targets something
nextNodeName = node.target;
}
else
{
//last vector in array, we're all done adding the points
if ( vecArrayIndex >= vecArray.size - 1 )
break;
vecArrayIndex++;
}
}
nodes[index]["vec"] = nodes[index - 1]["vec"];
node = undefined;
prof_end("civilian_math");
return nodes;
}
setInitialLookaheadPoint()
{
prof_begin("civilian_math");
//set the initial lookaheadPoint value
//initial value is 'level.civilian_lookAhead_value' units straight ahead of the character
forward = anglestoforward( self.angles );
lookaheadPoint = vectorScale ( forward, level.civilian_lookAhead_value );
lookaheadPoint = lookaheadPoint + self.origin;
if ( getdvar( "debug_civilians" ) == "1" )
thread debug_line( undefined, lookaheadPoint, 10 );
prof_end("civilian_math");
return lookaheadPoint;
}
Vec3Mad( character_origin, speed, lookDir )
{
prof_begin("civilian_math");
result = [];
result[0] = character_origin[0] + speed * lookDir[0];
result[1] = character_origin[1] + speed * lookDir[1];
result[2] = character_origin[2] + speed * lookDir[2];
prof_end("civilian_math");
return result;
}
debug_line( pointA, pointB, duration, color )
{
if (!isdefined(color))
color = (0,0,0);
usePlayerOrigin = false;
if (!isdefined(pointA))
usePlayerOrigin = true;
for ( i = 0; i < (duration * 20) ; i++ )
{
if (usePlayerOrigin)
pointA = level.player.origin;
line ( pointA, pointB, color );
if ( getdvar( "debug_civilians" ) == "2" )
iprintln ( distance ( level.player.origin, pointB ) );
wait 0.05;
}
}