iw6-scripts-dev/maps/mp/agents/_scriptedagents.gsc
2024-12-11 11:28:08 +01:00

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