247 lines
6.5 KiB
Plaintext
247 lines
6.5 KiB
Plaintext
//
|
|
// Scripted agent common functions.
|
|
//
|
|
|
|
// called from code when animation state changes.
|
|
OnEnterState( prevState, nextState )
|
|
{
|
|
if ( IsDefined( self.OnEnterAnimState ) )
|
|
self [[ self.OnEnterAnimState ]]( prevState, nextState );
|
|
}
|
|
|
|
// called from code when the agent is freed.
|
|
OnDeactivate()
|
|
{
|
|
self notify( "killanimscript" );
|
|
}
|
|
|
|
|
|
// util function
|
|
PlayAnimUntilNotetrack( animState, animLabel, notetrack, customFunction )
|
|
{
|
|
PlayAnimNUntilNotetrack( animState, 0, animLabel, notetrack, customFunction );
|
|
}
|
|
|
|
PlayAnimNUntilNotetrack( animState, animIndex, animLabel, notetrack, customFunction )
|
|
{
|
|
self SetAnimState( animState, animIndex );
|
|
|
|
if ( !IsDefined( notetrack ) )
|
|
notetrack = "end";
|
|
|
|
WaitUntilNotetrack( animLabel, notetrack, animState, animIndex, customFunction );
|
|
}
|
|
|
|
PlayAnimNAtRateUntilNotetrack( animState, animIndex, animRate, animLabel, notetrack, customFunction )
|
|
{
|
|
self SetAnimState( animState, animIndex, animRate );
|
|
|
|
if ( !IsDefined( notetrack ) )
|
|
notetrack = "end";
|
|
|
|
WaitUntilNotetrack( animLabel, notetrack, animState, animIndex, customFunction );
|
|
}
|
|
|
|
WaitUntilNotetrack( animLabel, notetrack, animState, animIndex, customFunction )
|
|
{
|
|
startTime = getTime();
|
|
animTime = undefined;
|
|
animLength = undefined;
|
|
|
|
if ( isDefined ( animState ) && isDefined ( animIndex ) )
|
|
animLength = getAnimLength( self GetAnimEntry( animState, animIndex ));
|
|
|
|
while ( true )
|
|
{
|
|
self waittill( animLabel, note );
|
|
|
|
if ( isDefined ( animLength ) )
|
|
animTime = ( getTime() - startTime ) * 0.001 / animLength;
|
|
|
|
if ( !isDefined( animLength ) || animTime > 0 )
|
|
{
|
|
if ( note == notetrack || note == "end" || note == "anim_will_finish" || note == "finish" )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( IsDefined( customFunction ) )
|
|
[[ customFunction ]]( note, animState, animIndex, animTime );
|
|
}
|
|
}
|
|
|
|
PlayAnimForTime( animState, time )
|
|
{
|
|
PlayAnimNForTime( animState, 0, time );
|
|
}
|
|
|
|
PlayAnimNForTime( animState, animIndex, time )
|
|
{
|
|
self SetAnimState( animState, animIndex );
|
|
wait( time );
|
|
}
|
|
|
|
PlayAnimNAtRateForTime( animState, animIndex, animRate, time )
|
|
{
|
|
self SetAnimState( animState, animIndex, animRate );
|
|
wait( time );
|
|
}
|
|
|
|
GetAnimScaleFactors( delta, animDelta, bAnimInWorldSpace )
|
|
{
|
|
distXY = Length2D( delta );
|
|
distZ = delta[2];
|
|
animXY = Length2D( animDelta );
|
|
animZ = animDelta[2];
|
|
|
|
scaleXY = 1;
|
|
scaleZ = 1;
|
|
if ( IsDefined( bAnimInWorldSpace ) && bAnimInWorldSpace )
|
|
{
|
|
animDelta2D = ( animDelta[0], animDelta[1], 0 );
|
|
animDeltaDir = VectorNormalize( animDelta2D );
|
|
if ( VectorDot( animDeltaDir, delta ) < 0 )
|
|
scaleXY = 0;
|
|
else if ( animXY > 0 )
|
|
scaleXY = distXY / animXY;
|
|
}
|
|
else if ( animXY > 0 )
|
|
scaleXY = distXY / animXY;
|
|
|
|
assert( scaleXY >= 0 );
|
|
|
|
if ( abs(animZ) > 0.001 && animZ * distZ >= 0 ) // animZ & distZ have to be same sign.
|
|
scaleZ = distZ / animZ;
|
|
|
|
assert( scaleZ >= 0 );
|
|
|
|
scaleFactors = SpawnStruct();
|
|
scaleFactors.xy = scaleXY;
|
|
scaleFactors.z = scaleZ;
|
|
|
|
return scaleFactors;
|
|
}
|
|
|
|
// -180, -135, -90, -45, 0, 45, 90, 135, 180
|
|
// favor underturning, unless you're within <threshold> degrees of the next one up.
|
|
GetAngleIndex( angle, threshold )
|
|
{
|
|
if ( !IsDefined( threshold ) )
|
|
threshold = 10;
|
|
|
|
if ( angle < 0 )
|
|
return int( ceil( ( 180 + angle - threshold ) / 45 ) );
|
|
else
|
|
return int( floor( ( 180 + angle + threshold ) / 45 ) );
|
|
}
|
|
|
|
|
|
DropPosToGround( position, drop_distance )
|
|
{
|
|
//droppedPos = GetGroundPosition( position, radius, 64, 64 );
|
|
|
|
assert( IsDefined( self.radius ) && IsDefined( self.height ) );
|
|
if ( !IsDefined( drop_distance ) )
|
|
drop_distance = 18;
|
|
|
|
startPos = position + (0, 0, drop_distance);
|
|
endPos = position + (0, 0, drop_distance * -1 );
|
|
|
|
droppedPos = self AIPhysicsTrace( startPos, endPos, self.radius, self.height, true );
|
|
|
|
if ( abs( droppedPos[2] - startPos[2] ) < 0.1 )
|
|
return undefined;
|
|
|
|
if ( abs( droppedPos[2] - endPos[2] ) < 0.1 )
|
|
return undefined;
|
|
|
|
return droppedPos;
|
|
}
|
|
|
|
|
|
TRACE_RADIUS_BUFFER = 4;
|
|
CanMovePointToPoint( startPos, endPos, stepSize )
|
|
{
|
|
if ( !isDefined( stepSize ) )
|
|
{
|
|
stepSize = 6;
|
|
}
|
|
|
|
step_offset = (0, 0, 1) * stepSize;
|
|
startPosRaised = startPos + step_offset;
|
|
endPosRaised = endPos + step_offset;
|
|
|
|
assert( IsDefined( self.radius ) && IsDefined( self.height ) );
|
|
assert( stepSize < self.height );
|
|
|
|
return self AIPhysicsTracePassed( startPosRaised, endPosRaised, self.radius, self.height - stepSize, true );
|
|
}
|
|
|
|
GetValidPointToPointMoveLocation( startPos, endPos, stepSize )
|
|
{
|
|
if ( !isDefined( stepSize ) )
|
|
{
|
|
stepSize = 6;
|
|
}
|
|
|
|
step_offset = (0, 0, 1) * stepSize;
|
|
startPosRaised = startPos + step_offset;
|
|
endPosRaised = endPos + step_offset;
|
|
|
|
assert( IsDefined( self.radius ) && IsDefined( self.height ) );
|
|
assert( stepSize < self.height );
|
|
|
|
return self AIPhysicsTrace( startPosRaised, endPosRaised, self.radius + TRACE_RADIUS_BUFFER, self.height - stepSize, true );
|
|
}
|
|
|
|
GetSafeAnimMoveDeltaPercentage( moveAnim )
|
|
{
|
|
animTranslation = GetMoveDelta( moveAnim );
|
|
endPos = self LocalToWorldCoords( animTranslation );
|
|
validMovePosition = GetValidPointToPointMoveLocation( self.origin, endPos );
|
|
validMoveDistance = Distance( self.origin, validMovePosition );
|
|
desiredMoveDistance = Distance( self.origin, endPos );
|
|
|
|
return Min( 1.0, validMoveDistance / desiredMoveDistance );
|
|
}
|
|
|
|
SafelyPlayAnimUntilNotetrack( animState, animLabel, notetrack, customFunction )
|
|
{
|
|
animIndex = GetRandomAnimEntry( animState );
|
|
SafelyPlayAnimNUntilNotetrack( animState, animIndex, animLabel, notetrack, customFunction );
|
|
}
|
|
|
|
SafelyPlayAnimAtRateUntilNotetrack( animState, animRate, animLabel, notetrack, customFunction )
|
|
{
|
|
animIndex = GetRandomAnimEntry( animState );
|
|
SafelyPlayAnimNAtRateUntilNotetrack( animState, animIndex, animRate, animLabel, notetrack, customFunction );
|
|
}
|
|
|
|
SafelyPlayAnimNAtRateUntilNotetrack( animState, animIndex, animRate, animLabel, notetrack, customFunction )
|
|
{
|
|
self SetAnimState( animState, animIndex, animRate );
|
|
SafelyPlayAnimNUntilNotetrack( animState, animIndex, animLabel, notetrack, customFunction );
|
|
}
|
|
|
|
SafelyPlayAnimNUntilNotetrack( animState, animIndex, animLabel, notetrack, customFunction )
|
|
{
|
|
animToPlay = self GetAnimEntry( animState, animIndex );
|
|
moveScale = GetSafeAnimMoveDeltaPercentage( animToPlay );
|
|
self ScrAgentSetAnimScale( moveScale, 1.0 );
|
|
self PlayAnimNUntilNotetrack( animState, animIndex, animLabel, notetrack, customFunction );
|
|
self ScrAgentSetAnimScale( 1.0, 1.0 );
|
|
}
|
|
|
|
GetRandomAnimEntry( state )
|
|
{
|
|
count = self GetAnimEntryCount( state );
|
|
return RandomInt( count );
|
|
}
|
|
|
|
GetAngleIndexFromSelfYaw( targetVector )
|
|
{
|
|
targetAngles = VectorToAngles( targetVector );
|
|
angleDiff = AngleClamp180( targetAngles[1] - self.angles[1] );
|
|
return GetAngleIndex( angleDiff );
|
|
} |