1415 lines
35 KiB
Plaintext
1415 lines
35 KiB
Plaintext
#include maps\_utility;
|
|
#include animscripts\Combat_utility;
|
|
#include animscripts\utility;
|
|
#include common_scripts\Utility;
|
|
|
|
#using_animtree( "generic_human" );
|
|
|
|
corner_think( direction, nodeAngleOffset )
|
|
{
|
|
self endon( "killanimscript" );
|
|
|
|
self.animArrayFuncs[ "exposed" ][ "stand" ] = animscripts\corner::set_standing_animarray_aiming;
|
|
self.animArrayFuncs[ "exposed" ][ "crouch" ] = animscripts\corner::set_crouching_animarray_aiming;
|
|
|
|
self.coverNode = self.node;
|
|
self.cornerDirection = direction;
|
|
self.a.cornerMode = "unknown";
|
|
|
|
self.a.aimIdleThread = undefined;
|
|
|
|
animscripts\cover_behavior::turnToMatchNodeDirection( nodeAngleOffset );
|
|
|
|
set_corner_anim_array();
|
|
|
|
self.isshooting = false;
|
|
self.tracking = false;
|
|
|
|
self.cornerAiming = false;
|
|
|
|
animscripts\shared::setAnimAimWeight( 0 );
|
|
|
|
self.haveGoneToCover = false;
|
|
|
|
behaviorCallbacks = spawnstruct();
|
|
|
|
if ( !self.fixedNode )
|
|
behaviorCallbacks.moveToNearByCover = animscripts\cover_behavior::moveToNearbyCover;
|
|
|
|
behaviorCallbacks.mainLoopStart = ::mainLoopStart;
|
|
behaviorCallbacks.reload = ::cornerReload;
|
|
behaviorCallbacks.leaveCoverAndShoot = ::stepOutAndShootEnemy;
|
|
behaviorCallbacks.look = ::lookForEnemy;
|
|
behaviorCallbacks.fastlook = ::fastlook;
|
|
behaviorCallbacks.idle = ::idle;
|
|
behaviorCallbacks.grenade = ::tryThrowingGrenade;
|
|
behaviorCallbacks.grenadehidden = ::tryThrowingGrenadeStayHidden;
|
|
behaviorCallbacks.blindfire = ::blindfire;
|
|
|
|
animscripts\cover_behavior::main( behaviorCallbacks );
|
|
}
|
|
|
|
end_script_corner()
|
|
{
|
|
self.stepOutYaw = undefined;
|
|
self.a.leanAim = undefined;
|
|
}
|
|
|
|
set_corner_anim_array()
|
|
{
|
|
if ( self.a.pose == "crouch" )
|
|
{
|
|
set_anim_array( "crouch" );
|
|
}
|
|
else if ( self.a.pose == "stand" )
|
|
{
|
|
set_anim_array( "stand" );
|
|
}
|
|
else
|
|
{
|
|
assert( self.a.pose == "prone" );
|
|
self ExitProneWrapper( 1 );
|
|
self.a.pose = "crouch";
|
|
self set_anim_array( "crouch" );
|
|
}
|
|
}
|
|
|
|
shouldChangeStanceForFun() // and for variety
|
|
{
|
|
if ( !isDefined( self.enemy ) )
|
|
return false;
|
|
|
|
if ( !isDefined( self.changeStanceForFunTime ) )
|
|
self.changeStanceForFunTime = gettime() + randomintrange( 5000, 20000 );
|
|
|
|
if ( gettime() > self.changeStanceForFunTime )
|
|
{
|
|
self.changeStanceForFunTime = gettime() + randomintrange( 5000, 20000 );
|
|
|
|
if ( isDefined( self.ramboChance ) && self.a.pose == "stand" )
|
|
return false;
|
|
|
|
self.a.prevAttack = undefined;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
mainLoopStart()
|
|
{
|
|
desiredStance = "stand";
|
|
|
|
if ( self.a.pose == "crouch" )
|
|
{
|
|
desiredStance = "crouch";
|
|
if ( self.coverNode doesNodeAllowStance( "stand" ) )
|
|
{
|
|
if ( !self.coverNode doesNodeAllowStance( "crouch" ) || shouldChangeStanceForFun() )
|
|
desiredStance = "stand";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( self.coverNode doesNodeAllowStance( "crouch" ) )
|
|
{
|
|
if ( !self.coverNode doesNodeAllowStance( "stand" ) || shouldChangeStanceForFun() )
|
|
desiredStance = "crouch";
|
|
}
|
|
}
|
|
|
|
/#
|
|
if ( getdvarint( "scr_cornerforcecrouch" ) == 1 )
|
|
desiredStance = "crouch";
|
|
#/
|
|
|
|
if ( self.haveGoneToCover )
|
|
{
|
|
self transitionToStance( desiredStance );
|
|
}
|
|
else
|
|
{
|
|
if ( self.a.pose == desiredStance )
|
|
{
|
|
GoToCover( animArray( "alert_idle" ), .3, .4 );
|
|
}
|
|
else
|
|
{
|
|
stanceChangeAnim = animarray( "stance_change" );
|
|
GoToCover( stanceChangeAnim, .3, getAnimLength( stanceChangeAnim ) );
|
|
set_anim_array( desiredStance );// ( sets anim_pose to stance )
|
|
}
|
|
assert( self.a.pose == desiredStance );
|
|
self.haveGoneToCover = true;
|
|
}
|
|
}
|
|
|
|
printYaws()
|
|
{
|
|
wait( 2 );
|
|
for ( ;; )
|
|
{
|
|
println( "coveryaw = ", self.coverNode GetYawToOrigin( getEnemyEyePos() ) );
|
|
printYawToEnemy();
|
|
wait( 0.05 );
|
|
}
|
|
}
|
|
|
|
// used within canSeeEnemyFromExposed() (in utility.gsc)
|
|
canSeePointFromExposedAtCorner( point, node )
|
|
{
|
|
yaw = node GetYawToOrigin( point );
|
|
if ( ( yaw > 60 ) || ( yaw < - 60 ) )
|
|
return false;
|
|
|
|
if ( ( node.type == "Cover Left" ) && yaw > 14 )
|
|
return false;
|
|
if ( ( node.type == "Cover Right" ) && yaw < - 12 )
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
shootPosOutsideLegalYawRange()
|
|
{
|
|
if ( !isdefined( self.shootPos ) )
|
|
return false;
|
|
|
|
yaw = self.coverNode GetYawToOrigin( self.shootPos );
|
|
|
|
if ( self.a.cornerMode == "over" )
|
|
return yaw < self.leftAimLimit || self.rightAimLimit < yaw;
|
|
|
|
if ( self.cornerDirection == "left" )
|
|
{
|
|
if ( self.a.cornerMode == "B" )
|
|
{
|
|
return yaw < 0 - self.ABangleCutoff || yaw > 14;
|
|
}
|
|
else if ( self.a.cornerMode == "A" )
|
|
{
|
|
return yaw > 0 - self.ABangleCutoff;
|
|
}
|
|
else
|
|
{
|
|
assert( self.a.cornerMode == "lean" );
|
|
return yaw < - 50 || yaw > 8;// TODO
|
|
}
|
|
}
|
|
else
|
|
{
|
|
assert( self.cornerDirection == "right" );
|
|
if ( self.a.cornerMode == "B" )
|
|
{
|
|
return yaw > self.ABangleCutoff || yaw < - 12;
|
|
}
|
|
else if ( self.a.cornerMode == "A" )
|
|
{
|
|
return yaw < self.ABangleCutoff;
|
|
}
|
|
else
|
|
{
|
|
assert( self.a.cornerMode == "lean" );
|
|
return yaw > 50 || yaw < - 8;// TODO
|
|
}
|
|
}
|
|
}
|
|
|
|
// getCornerMode will return "none" if no corner modes are acceptable.
|
|
getCornerMode( node, point )
|
|
{
|
|
noStepOut = false;
|
|
yaw = 0;
|
|
|
|
if ( isdefined( point ) )
|
|
yaw = node GetYawToOrigin( point );
|
|
|
|
modes = [];
|
|
|
|
// don't want to get cover peekouts for crouch while standing
|
|
if ( isdefined( node ) && self.a.pose == "crouch" && ( yaw > self.leftAimLimit && self.rightAimLimit > yaw ) )
|
|
modes = node GetValidCoverPeekOuts();
|
|
|
|
if ( self.cornerDirection == "left" )
|
|
{
|
|
if ( canLean( yaw, -40, 0 ) )
|
|
{
|
|
noStepOut = shouldLean();
|
|
modes[ modes.size ] = "lean";
|
|
}
|
|
|
|
if ( !noStepOut && yaw < 14 )
|
|
{
|
|
if ( yaw < 0 - self.ABangleCutoff )
|
|
modes[ modes.size ] = "A";
|
|
else
|
|
modes[ modes.size ] = "B";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
assert( self.cornerDirection == "right" );
|
|
|
|
if ( canLean( yaw, 0, 40 ) )
|
|
{
|
|
noStepOut = shouldLean();
|
|
modes[ modes.size ] = "lean";
|
|
}
|
|
|
|
if ( !noStepOut && yaw > -12 )
|
|
{
|
|
if ( yaw > self.ABangleCutoff )
|
|
modes[ modes.size ] = "A";
|
|
else
|
|
modes[ modes.size ] = "B";
|
|
}
|
|
}
|
|
|
|
return getRandomCoverMode( modes );
|
|
}
|
|
|
|
// getBestStepOutPos never returns "none".
|
|
// it returns the best stepoutpos that we can get to from our current one.
|
|
getBestStepOutPos()
|
|
{
|
|
yaw = 0;
|
|
if ( canSuppressEnemy() )
|
|
yaw = self.coverNode GetYawToOrigin( getEnemySightPos() );
|
|
else if ( self.doingAmbush && isdefined( self.shootPos ) )
|
|
yaw = self.coverNode GetYawToOrigin( self.shootPos );
|
|
|
|
/#
|
|
dvarval = getdvar( "scr_cornerforcestance" );
|
|
if ( dvarval == "lean" || dvarval == "a" || dvarval == "b" )
|
|
return dvarval;
|
|
#/
|
|
|
|
if ( self.a.cornerMode == "lean" )
|
|
return "lean";
|
|
if ( self.a.cornerMode == "over" )
|
|
return "over";
|
|
else if ( self.a.cornerMode == "B" )
|
|
{
|
|
if ( self.cornerDirection == "left" )
|
|
{
|
|
if ( yaw < 0 - self.ABangleCutoff )
|
|
return "A";
|
|
}
|
|
else if ( self.cornerDirection == "right" )
|
|
{
|
|
if ( yaw > self.ABangleCutoff )
|
|
return "A";
|
|
}
|
|
return "B";
|
|
}
|
|
else if ( self.a.cornerMode == "A" )
|
|
{
|
|
positionToSwitchTo = "B";
|
|
if ( self.cornerDirection == "left" )
|
|
{
|
|
if ( yaw > 0 - self.ABangleCutoff )
|
|
return "B";
|
|
}
|
|
else if ( self.cornerDirection == "right" )
|
|
{
|
|
if ( yaw < self.ABangleCutoff )
|
|
return "B";
|
|
}
|
|
return "A";
|
|
}
|
|
}
|
|
|
|
changeStepOutPos()
|
|
{
|
|
self endon( "killanimscript" );
|
|
|
|
positionToSwitchTo = getBestStepOutPos();
|
|
|
|
if ( positionToSwitchTo == self.a.cornerMode )
|
|
return false;
|
|
|
|
// can't switch between lean/over and other stepoutposes
|
|
// so if this assert fails then getBestStepOutPos gave us a bad return value
|
|
assert( self.a.cornerMode != "lean" && positionToSwitchTo != "lean" );
|
|
assert( self.a.cornerMode != "over" && positionToSwitchTo != "over" );
|
|
|
|
self.changingCoverPos = true; self notify( "done_changing_cover_pos" );
|
|
|
|
animname = self.a.cornerMode + "_to_" + positionToSwitchTo;
|
|
assert( animArrayAnyExist( animname ) );
|
|
switchanim = animArrayPickRandom( animname );
|
|
|
|
midpoint = getPredictedPathMidpoint();
|
|
if ( !self mayMoveToPoint( midpoint ) )
|
|
return false;
|
|
if ( !self mayMoveFromPointToPoint( midpoint, getAnimEndPos( switchanim ) ) )
|
|
return false;
|
|
|
|
self endAimIdleThread();
|
|
|
|
// turn off aiming while we move.
|
|
self StopAiming( .3 );
|
|
|
|
prev_anim_pose = self.a.pose;
|
|
|
|
self setanimlimited( animarray( "straight_level" ), 0, .2 );
|
|
|
|
self setFlaggedAnimKnob( "changeStepOutPos", switchanim, 1, .2, 1.2 );
|
|
self thread DoNoteTracksWithEndon( "changeStepOutPos" );
|
|
|
|
if ( animHasNotetrack( switchanim, "start_aim" ) )
|
|
{
|
|
self waittillmatch( "changeStepOutPos", "start_aim" );
|
|
}
|
|
else
|
|
{
|
|
/#println( "^1Corner position switch animation \"" + animname + "\" in corner_" + self.cornerDirection + " " + self.a.pose + " didn't have \"start_aim\" notetrack" );#/
|
|
self waittillmatch( "changeStepOutPos", "end" );
|
|
}
|
|
|
|
self thread StartAiming( undefined, false, .3 );
|
|
|
|
self waittillmatch( "changeStepOutPos", "end" );
|
|
self clearanim( switchanim, .1 );
|
|
self.a.cornerMode = positionToSwitchTo;
|
|
|
|
self.changingCoverPos = false;
|
|
self.coverPosEstablishedTime = gettime();
|
|
|
|
assert( self.a.pose == "stand" || self.a.pose == "crouch" );
|
|
if ( self.a.pose != prev_anim_pose )
|
|
set_anim_array( self.a.pose );// don't call this if we don't have to, because we don't want to reset %exposed_aiming
|
|
|
|
self thread ChangeAiming( undefined, true, .3 );
|
|
|
|
return true;
|
|
}
|
|
|
|
canLean( yaw, yawMin, yawMax )
|
|
{
|
|
if ( self.a.neverLean )
|
|
return false;
|
|
|
|
return ( yawMin <= yaw && yaw <= yawMax );
|
|
}
|
|
|
|
shouldLean()
|
|
{
|
|
if ( self.team == "allies" )
|
|
return true;
|
|
|
|
if ( self isPartiallySuppressedWrapper() )
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
DoNoteTracksWithEndon( animname )
|
|
{
|
|
self endon( "killanimscript" );
|
|
self animscripts\shared::DoNoteTracks( animname );
|
|
}
|
|
|
|
StartAiming( spot, fullbody, transtime )
|
|
{
|
|
assert( !self.cornerAiming );
|
|
self.cornerAiming = true;
|
|
if ( self.a.cornerMode == "lean" )
|
|
self.a.leanAim = true;
|
|
else
|
|
self.a.leanAim = undefined;
|
|
|
|
self SetAimingParams( spot, fullbody, transTime );
|
|
}
|
|
|
|
ChangeAiming( spot, fullbody, transtime )
|
|
{
|
|
assert( self.cornerAiming );
|
|
if ( self.a.cornerMode == "lean" )
|
|
self.a.leanAim = true;
|
|
else
|
|
self.a.leanAim = undefined;
|
|
|
|
self SetAimingParams( spot, fullbody, transTime );
|
|
}
|
|
|
|
StopAiming( transtime )
|
|
{
|
|
assert( self.cornerAiming );
|
|
self.cornerAiming = false;
|
|
|
|
// turn off shooting
|
|
self clearAnim( %add_fire, transtime );
|
|
// and turn off aiming
|
|
animscripts\shared::setAnimAimWeight( 0, transtime );
|
|
}
|
|
|
|
SetAimingParams( spot, fullbody, transTime )
|
|
{
|
|
assert( isdefined( fullbody ) );
|
|
|
|
self.spot = spot;// undefined is ok
|
|
|
|
self setanimlimited( %exposed_modern, 1, transTime );
|
|
self setanimlimited( %exposed_aiming, 1, transTime );
|
|
self setanimlimited( %add_idle, 1, transTime );
|
|
animscripts\shared::setAnimAimWeight( 1, transTime );
|
|
|
|
leanAnim = undefined;
|
|
if ( isdefined( self.a.array[ "lean_aim_straight" ] ) )
|
|
leanAnim = self.a.array[ "lean_aim_straight" ];
|
|
|
|
self thread aimIdleThread();
|
|
|
|
if ( isdefined( self.a.leanAim ) )
|
|
{
|
|
self setAnimLimited( leanAnim, 1, transTime );
|
|
self setAnimLimited( animArray( "straight_level" ), 0, 0 );
|
|
|
|
self setAnimKnobLimited( animArray( "lean_aim_left" ), 1, transTime );
|
|
self setAnimKnobLimited( animArray( "lean_aim_right" ), 1, transTime );
|
|
self setAnimKnobLimited( animArray( "lean_aim_up" ), 1, transTime );
|
|
self setAnimKnobLimited( animArray( "lean_aim_down" ), 1, transTime );
|
|
}
|
|
else if ( fullbody )
|
|
{
|
|
self setAnimLimited( animarray( "straight_level" ), 1, transTime );
|
|
if ( isdefined( leanAnim ) )
|
|
self setAnimLimited( leanAnim, 0, 0 );
|
|
|
|
self setAnimKnobLimited( animArray( "add_aim_up" ), 1, transTime );
|
|
self setAnimKnobLimited( animArray( "add_aim_down" ), 1, transTime );
|
|
self setAnimKnobLimited( animArray( "add_aim_left" ), 1, transTime );
|
|
self setAnimKnobLimited( animArray( "add_aim_right" ), 1, transTime );
|
|
}
|
|
else
|
|
{
|
|
self setAnimLimited( animarray( "straight_level" ), 0, transTime );
|
|
if ( isdefined( leanAnim ) )
|
|
self setAnimLimited( leanAnim, 0, 0 );
|
|
|
|
self setAnimKnobLimited( animArray( "add_turn_aim_up" ), 1, transTime );
|
|
self setAnimKnobLimited( animArray( "add_turn_aim_down" ), 1, transTime );
|
|
self setAnimKnobLimited( animArray( "add_turn_aim_left" ), 1, transTime );
|
|
self setAnimKnobLimited( animArray( "add_turn_aim_right" ), 1, transTime );
|
|
}
|
|
}
|
|
|
|
// These should be adjusted in animation data
|
|
stepOutAndHideSpeed()
|
|
{
|
|
if ( self.a.cornerMode == "over" )
|
|
return 1;
|
|
|
|
//if ( self.a.cornerMode == "B" )
|
|
// return 1;
|
|
|
|
return randomFasterAnimSpeed();
|
|
}
|
|
|
|
stepOut() /* bool */
|
|
{
|
|
self.a.cornerMode = "alert";
|
|
|
|
if ( self.goalRadius < 64 )
|
|
self.goalRadius = 64;
|
|
|
|
self animMode( "zonly_physics" );
|
|
|
|
if ( self.a.pose == "stand" )
|
|
{
|
|
self.ABangleCutoff = 38;
|
|
}
|
|
else
|
|
{
|
|
assert( self.a.pose == "crouch" );
|
|
self.ABangleCutoff = 31;
|
|
}
|
|
|
|
thisNodePose = self.a.pose;
|
|
set_anim_array( thisNodePose );
|
|
|
|
self setDefaultAimLimits(); // do exposed animations once stepped out
|
|
|
|
newCornerMode = "none";
|
|
if ( hasEnemySightPos() )
|
|
newCornerMode = getCornerMode( self.coverNode, getEnemySightPos() );
|
|
else
|
|
newCornerMode = getCornerMode( self.coverNode );
|
|
|
|
if ( !isdefined( newCornerMode ) )
|
|
return false;
|
|
|
|
animname = "alert_to_" + newCornerMode;
|
|
assert( animArrayAnyExist( animname ) );
|
|
switchanim = animArrayPickRandom( animname );
|
|
|
|
if ( newCornerMode == "lean" && !self isPeekOutPosClear() )
|
|
return false;
|
|
|
|
if ( newCornerMode != "over" && !isPathClear( switchanim, newCornerMode != "lean" ) )
|
|
return false;
|
|
|
|
self.a.cornerMode = newCornerMode;
|
|
self.a.prevAttack = newCornerMode;
|
|
|
|
if ( self.a.cornerMode == "lean" )
|
|
self setDefaultAimLimits( self.coverNode );
|
|
|
|
if ( newCornerMode == "A" || newCornerMode == "B" )
|
|
self.a.special = "cover_" + self.cornerDirection + "_" + self.a.pose + "_" + newCornerMode;
|
|
else if ( newCornerMode == "over" )
|
|
self.a.special = "cover_crouch_aim";
|
|
else
|
|
self.a.special = "none";
|
|
|
|
self.keepClaimedNodeIfValid = true;
|
|
|
|
hasStartAim = false;
|
|
|
|
self.changingCoverPos = true;
|
|
self notify( "done_changing_cover_pos" );
|
|
|
|
animRate = stepOutAndHideSpeed();
|
|
|
|
self.pushable = false;
|
|
|
|
self setFlaggedAnimKnobAllRestart( "stepout", switchanim, %root, 1, .2, animRate );
|
|
self thread DoNoteTracksWithEndon( "stepout" );
|
|
|
|
hasStartAim = animHasNotetrack( switchanim, "start_aim" );
|
|
if ( hasStartAim )
|
|
{
|
|
// Store our final step out angle so that we may use it when doing track loop aiming
|
|
self.stepOutYaw = self.angles[1] + getAngleDelta( switchanim, 0, 1 );
|
|
|
|
self waittillmatch( "stepout", "start_aim" );
|
|
}
|
|
else
|
|
{
|
|
/#println( "^1Corner stepout animation \"" + animname + "\" in corner_" + self.cornerDirection + " " + self.a.pose + " didn't have \"start_aim\" notetrack" );#/
|
|
self waittillmatch( "stepout", "end" );
|
|
}
|
|
|
|
if ( newCornerMode == "B" && coinToss() && self.cornerDirection == "right" )
|
|
self.a.special = "corner_right_martyrdom";
|
|
|
|
set_anim_array_aiming( thisNodePose );
|
|
|
|
fullbody = ( newCornerMode == "over" );
|
|
|
|
self StartAiming( undefined, fullbody, .3 );
|
|
self thread animscripts\shared::trackShootEntOrPos();
|
|
|
|
if ( hasStartAim )
|
|
{
|
|
self waittillmatch( "stepout", "end" );
|
|
|
|
// Clear the forced yaw after the animation is fully played
|
|
self.stepOutYaw = undefined;
|
|
}
|
|
|
|
self ChangeAiming( undefined, true, 0.2 );
|
|
self clearAnim( %cover, 0.1 );
|
|
self clearAnim( %corner, 0.1 );
|
|
|
|
self.changingCoverPos = false;
|
|
self.coverPosEstablishedTime = gettime();
|
|
|
|
self.pushable = true;
|
|
|
|
return true;
|
|
}
|
|
|
|
stepOutAndShootEnemy()
|
|
{
|
|
self.keepClaimedNodeIfValid = true;
|
|
|
|
// do rambo behavior sometimes on rambo AI guys. Normal AI never do rambo
|
|
if ( isdefined( self.ramboChance ) && randomFloat( 1 ) < self.ramboChance )
|
|
{
|
|
if ( rambo() )
|
|
return true;
|
|
}
|
|
|
|
if ( !StepOut() ) // may not be room to step out
|
|
return false;
|
|
|
|
shootAsTold();
|
|
|
|
if ( isDefined( self.shootPos ) )
|
|
{
|
|
distSqToShootPos = lengthsquared( self.origin - self.shootPos );
|
|
// too close for RPG or out of ammo
|
|
if ( usingRocketLauncher() && ( distSqToShootPos < squared( 512 ) || self.a.rockets < 1 ) )
|
|
{
|
|
if ( self.a.pose == "stand" )
|
|
animscripts\shared::throwDownWeapon( %RPG_stand_throw );
|
|
else
|
|
animscripts\shared::throwDownWeapon( %RPG_crouch_throw );
|
|
|
|
self thread runCombat();
|
|
return;
|
|
}
|
|
}
|
|
|
|
returnToCover();
|
|
|
|
self.keepClaimedNodeIfValid = false;
|
|
|
|
return true;
|
|
}
|
|
|
|
haventRamboedWithinTime( time )
|
|
{
|
|
if ( !isdefined( self.lastRamboTime ) )
|
|
return true;
|
|
return gettime() - self.lastRamboTime > time * 1000;
|
|
}
|
|
|
|
rambo()
|
|
{
|
|
if ( !hasEnemySightPos() )
|
|
return false;
|
|
|
|
ramboAimOffset = 0;
|
|
angle = 90;
|
|
yaw = self.coverNode GetYawToOrigin( getEnemySightPos() );
|
|
if ( self.cornerDirection == "left" )
|
|
yaw = 0 - yaw;
|
|
if ( yaw > 30 ) // this cutoff works better visually than 22.5
|
|
{
|
|
angle = 45;
|
|
if ( self.cornerDirection == "left" )
|
|
ramboAimOffset = 45;
|
|
else
|
|
ramboAimOffset = -45;
|
|
}
|
|
|
|
animType = "rambo" + angle;
|
|
if ( !animArrayAnyExist( animType ) )
|
|
return false;
|
|
|
|
// commented out so we see rambo a lot, might want to adjust this later
|
|
//if ( !haventRamboedWithinTime( 2 ) )
|
|
// return false;
|
|
|
|
// move check
|
|
ramboAnim = animArrayPickRandom( animType );
|
|
midpoint = getPredictedPathMidpoint( 48 );
|
|
if ( !self mayMoveToPoint( midpoint ) )
|
|
return false;
|
|
// no point doing this check, since the animation will end at the cover node.
|
|
//if ( !self mayMoveFromPointToPoint( midpoint, getAnimEndPos( ramboAnim ) ) )
|
|
// return false;
|
|
|
|
self.coverPosEstablishedTime = gettime();
|
|
|
|
self animMode( "zonly_physics" );
|
|
self.keepClaimedNodeIfValid = true;
|
|
self.isRambo = true;
|
|
self.a.prevAttack = "rambo";
|
|
|
|
self.changingCoverPos = true;
|
|
|
|
self thread animscripts\shared::ramboAim( ramboAimOffset );
|
|
|
|
self setFlaggedAnimKnobAllRestart( "rambo", ramboAnim, %body, 1, 0, 1 );
|
|
self animscripts\shared::DoNoteTracks( "rambo" );
|
|
|
|
self notify( "rambo_aim_end" );
|
|
|
|
self.changingCoverPos = false;
|
|
|
|
self.keepClaimedNodeIfValid = false;
|
|
self.lastRamboTime = getTime();
|
|
|
|
self.changingCoverPos = false;
|
|
self.isRambo = undefined;
|
|
|
|
return true;
|
|
}
|
|
|
|
shootAsTold()
|
|
{
|
|
self maps\_gameskill::didSomethingOtherThanShooting();
|
|
|
|
while ( 1 )
|
|
{
|
|
while ( 1 )
|
|
{
|
|
if ( isdefined( self.shouldReturnToCover ) )
|
|
break;
|
|
|
|
if ( !isdefined( self.shootPos ) ) {
|
|
assert( !isdefined( self.shootEnt ) );
|
|
// give shoot_behavior a chance to iterate
|
|
self waittill( "do_slow_things" );
|
|
waittillframeend;
|
|
if ( isdefined( self.shootPos ) )
|
|
continue;
|
|
break;
|
|
}
|
|
|
|
if ( !self.bulletsInClip )
|
|
break;
|
|
|
|
if ( shootPosOutsideLegalYawRange() )
|
|
{
|
|
if ( !changeStepOutPos() )
|
|
{
|
|
// if we failed because there's no better step out pos, give up
|
|
if ( getBestStepOutPos() == self.a.cornerMode )
|
|
break;
|
|
|
|
// couldn't change position, shoot for a short bit and we'll try again
|
|
shootUntilShootBehaviorChangeForTime( .2 );
|
|
continue;
|
|
}
|
|
|
|
// if they're moving back and forth too fast for us to respond intelligently to them,
|
|
// give up on firing at them for the moment
|
|
if ( shootPosOutsideLegalYawRange() )
|
|
break;
|
|
|
|
continue;
|
|
}
|
|
|
|
shootUntilShootBehaviorChange_corner( true );
|
|
|
|
self clearAnim( %add_fire, .2 );
|
|
}
|
|
|
|
if ( self canReturnToCover( self.a.cornerMode != "lean" ) )
|
|
break;
|
|
|
|
// couldn't return to cover. keep shooting and try again
|
|
|
|
// (change step out pos if necessary and possible)
|
|
if ( shootPosOutsideLegalYawRange() && changeStepOutPos() )
|
|
continue;
|
|
|
|
shootUntilShootBehaviorChangeForTime( .2 );
|
|
}
|
|
}
|
|
|
|
shootUntilShootBehaviorChangeForTime( time )
|
|
{
|
|
self thread notifyStopShootingAfterTime( time );
|
|
|
|
starttime = gettime();
|
|
|
|
shootUntilShootBehaviorChange_corner( false );
|
|
self notify( "stopNotifyStopShootingAfterTime" );
|
|
|
|
timepassed = ( gettime() - starttime ) / 1000;
|
|
if ( timepassed < time )
|
|
wait time - timepassed;
|
|
}
|
|
|
|
notifyStopShootingAfterTime( time )
|
|
{
|
|
self endon( "killanimscript" );
|
|
self endon( "stopNotifyStopShootingAfterTime" );
|
|
|
|
wait time;
|
|
|
|
self notify( "stopShooting" );
|
|
}
|
|
|
|
shootUntilShootBehaviorChange_corner( runAngleRangeThread )
|
|
{
|
|
self endon( "return_to_cover" );
|
|
|
|
if ( runAngleRangeThread )
|
|
self thread angleRangeThread();// gives stopShooting notify when shootPosOutsideLegalYawRange returns true
|
|
self thread aimIdleThread();
|
|
|
|
shootUntilShootBehaviorChange();
|
|
}
|
|
|
|
|
|
angleRangeThread()
|
|
{
|
|
self endon( "killanimscript" );
|
|
self notify( "newAngleRangeCheck" );
|
|
self endon( "newAngleRangeCheck" );
|
|
self endon( "take_cover_at_corner" );
|
|
|
|
while ( 1 )
|
|
{
|
|
if ( shootPosOutsideLegalYawRange() )
|
|
break;
|
|
wait( 0.1 );
|
|
}
|
|
|
|
self notify( "stopShooting" );// For changing shooting pose to compensate for player moving
|
|
}
|
|
|
|
showstate()
|
|
{
|
|
self.enemy endon( "death" );
|
|
self endon( "enemy" );
|
|
self endon( "stopshowstate" );
|
|
|
|
while ( 1 )
|
|
{
|
|
wait .05;
|
|
print3d( self.origin + ( 0, 0, 60 ), self.statetext );
|
|
}
|
|
}
|
|
|
|
canReturnToCover( doMidpointCheck )
|
|
{
|
|
if ( doMidpointCheck )
|
|
{
|
|
midpoint = getPredictedPathMidpoint();
|
|
|
|
if ( !self mayMoveToPoint( midpoint ) )
|
|
return false;
|
|
|
|
return self mayMoveFromPointToPoint( midpoint, self.coverNode.origin );
|
|
}
|
|
else
|
|
{
|
|
return self mayMoveToPoint( self.coverNode.origin );
|
|
}
|
|
}
|
|
|
|
returnToCover()
|
|
{
|
|
assert( self canReturnToCover( self.a.cornerMode != "lean" ) );
|
|
|
|
endFireAndAnimIdleThread();
|
|
|
|
// Go back into hiding.
|
|
suppressed = issuppressedWrapper();
|
|
self notify( "take_cover_at_corner" );// Stop doing the adjust - stance transition thread
|
|
|
|
self.changingCoverPos = true;
|
|
self notify( "done_changing_cover_pos" );
|
|
|
|
animname = self.a.cornerMode + "_to_alert";
|
|
assert( animArrayAnyExist( animname ) );
|
|
switchanim = animArrayPickRandom( animname );
|
|
|
|
self StopAiming( .3 );
|
|
|
|
reloading = false;
|
|
if ( self.a.cornerMode != "lean" && suppressed && animArrayAnyExist( animname + "_reload" ) && randomfloat( 100 ) < 75 )
|
|
{
|
|
switchanim = animArrayPickRandom( animname + "_reload" );
|
|
reloading = true;
|
|
}
|
|
|
|
rate = stepOutAndHideSpeed();
|
|
|
|
self clearanim( %body, 0.1 );
|
|
self setFlaggedAnimRestart( "hide", switchanim, 1, .1, rate );
|
|
self animscripts\shared::DoNoteTracks( "hide" );
|
|
|
|
if ( reloading )
|
|
self animscripts\weaponList::RefillClip();
|
|
|
|
self.changingCoverPos = false;
|
|
if ( self.cornerDirection == "left" )
|
|
self.a.special = "cover_left";
|
|
else
|
|
self.a.special = "cover_right";
|
|
|
|
self.keepClaimedNodeIfValid = false;
|
|
|
|
self clearAnim( switchanim, 0.2 );
|
|
}
|
|
|
|
blindfire()
|
|
{
|
|
if ( !animArrayAnyExist( "blind_fire" ) )
|
|
return false;
|
|
|
|
self animMode( "zonly_physics" );
|
|
self.keepClaimedNodeIfValid = true;
|
|
|
|
self setFlaggedAnimKnobAllRestart( "blindfire", animArrayPickRandom( "blind_fire" ), %body, 1, 0, 1 );
|
|
self animscripts\shared::DoNoteTracks( "blindfire" );
|
|
|
|
self.keepClaimedNodeIfValid = false;
|
|
|
|
return true;
|
|
}
|
|
|
|
linethread( a, b, col )
|
|
{
|
|
if ( !isdefined( col ) )
|
|
col = ( 1, 1, 1 );
|
|
for ( i = 0; i < 100; i++ )
|
|
{
|
|
line( a, b, col );
|
|
wait .05;
|
|
}
|
|
}
|
|
|
|
tryThrowingGrenadeStayHidden( throwAt )
|
|
{
|
|
return tryThrowingGrenade( throwAt, true );
|
|
}
|
|
|
|
tryThrowingGrenade( throwAt, safe )
|
|
{
|
|
if ( !self mayMoveToPoint( self getPredictedPathMidpoint() ) )
|
|
return false;
|
|
|
|
if ( isdefined( self.dontEverShoot ) || isdefined( throwAt.dontAttackMe ) )
|
|
return false;
|
|
|
|
theanim = undefined;
|
|
if ( isdefined( self.ramboChance ) && randomFloat( 1 ) < self.ramboChance )
|
|
{
|
|
if ( isdefined( self.a.array[ "grenade_rambo" ] ) )
|
|
theanim = animArray( "grenade_rambo" );
|
|
}
|
|
if ( !isdefined( theanim ) )
|
|
{
|
|
if ( isdefined( safe ) && safe )
|
|
{
|
|
if ( !isdefined( self.a.array[ "grenade_safe" ] ) )
|
|
return false;
|
|
theanim = animArray( "grenade_safe" );
|
|
}
|
|
else
|
|
{
|
|
if ( !isdefined( self.a.array[ "grenade_exposed" ] ) )
|
|
return false;
|
|
theanim = animArray( "grenade_exposed" );
|
|
}
|
|
}
|
|
assert( isdefined( theanim ) );
|
|
|
|
self animMode( "zonly_physics" );// Unlatch the feet
|
|
self.keepClaimedNodeIfValid = true;
|
|
|
|
threwGrenade = TryGrenade( throwAt, theanim );
|
|
|
|
self.keepClaimedNodeIfValid = false;
|
|
return threwGrenade;
|
|
}
|
|
|
|
printYawToEnemy()
|
|
{
|
|
println( "yaw: ", self getYawToEnemy() );
|
|
}
|
|
|
|
lookForEnemy( lookTime )
|
|
{
|
|
if ( !isdefined( self.a.array[ "alert_to_look" ] ) )
|
|
return false;
|
|
|
|
self animMode( "zonly_physics" );// Unlatch the feet
|
|
self.keepClaimedNodeIfValid = true;
|
|
|
|
// look out from alert
|
|
if ( !peekOut() )
|
|
return false;
|
|
|
|
animscripts\shared::playLookAnimation( animarray( "look_idle" ), lookTime, ::canStopPeeking );
|
|
|
|
lookanim = undefined;
|
|
if ( self isSuppressedWrapper() )
|
|
lookanim = animArray( "look_to_alert_fast" );
|
|
else
|
|
lookanim = animArray( "look_to_alert" );
|
|
|
|
self setflaggedanimknoballrestart( "looking_end", lookanim, %body, 1, .1, 1.0 );
|
|
animscripts\shared::DoNoteTracks( "looking_end" );
|
|
|
|
self animMode( "zonly_physics" );// Unlatch the feet
|
|
|
|
self.keepClaimedNodeIfValid = false;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
PEEKOUT_OFFSET = 30;
|
|
|
|
isPeekOutPosClear()
|
|
{
|
|
assert( isdefined( self.coverNode ) );
|
|
|
|
eyePos = self geteye();
|
|
rightDir = anglestoright( self.coverNode.angles );
|
|
if ( self.cornerDirection == "right" )
|
|
eyePos = eyePos + (rightDir * PEEKOUT_OFFSET);
|
|
else
|
|
eyePos = eyePos - (rightDir * PEEKOUT_OFFSET);
|
|
|
|
lookAtPos = eyePos + anglesToForward( self.coverNode.angles ) * PEEKOUT_OFFSET;
|
|
|
|
// /# thread debugLine( eyePos, lookAtPos, ( 1, 0, 0 ), 1.5 ); #/
|
|
|
|
return sightTracePassed( eyePos, lookAtPos, true, self );
|
|
}
|
|
|
|
|
|
peekOut()
|
|
{
|
|
if ( isdefined( self.coverNode.script_dontpeek ) )
|
|
return false;
|
|
|
|
if ( isdefined( self.nextPeekOutAttemptTime ) && gettime() < self.nextPeekOutAttemptTime )
|
|
return false;
|
|
|
|
if ( !self isPeekOutPosClear() )
|
|
{
|
|
self.nextPeekOutAttemptTime = gettime() + 3000;
|
|
return false;
|
|
}
|
|
|
|
peekanim = animArray( "alert_to_look" );
|
|
|
|
// assuming no delta, so no maymovetopoint check
|
|
//if ( !self mayMoveToPoint( getAnimEndPos( peekanim ) ) )
|
|
// return false;
|
|
|
|
// not safe to stop peeking in the middle because it will screw up our deltas
|
|
//self thread _peekStop();
|
|
//self endon ("stopPeeking");
|
|
|
|
self setflaggedanimknobAll( "looking_start", peekanim, %body, 1, .2, 1 );
|
|
animscripts\shared::DoNoteTracks( "looking_start" );
|
|
//self notify ("stopPeekCheckThread");
|
|
|
|
return true;
|
|
}
|
|
|
|
canStopPeeking()
|
|
{
|
|
return self mayMoveToPoint( self.coverNode.origin );
|
|
}
|
|
|
|
fastlook()
|
|
{
|
|
// corner fast look animations aren't set up right.
|
|
return false;
|
|
|
|
/*
|
|
if ( !isdefined( self.a.array["look"] ) )
|
|
return false;
|
|
|
|
self setFlaggedAnimKnobAllRestart( "look", animArray( "look" ), %body, 1, .1 );
|
|
self animscripts\shared::DoNoteTracks( "look" );
|
|
|
|
return true;
|
|
*/
|
|
}
|
|
|
|
cornerReload()
|
|
{
|
|
assert( animArrayAnyExist( "reload" ) );
|
|
|
|
reloadanim = animArrayPickRandom( "reload" );
|
|
self setFlaggedAnimKnobRestart( "cornerReload", reloadanim, 1, .2 );
|
|
|
|
self animscripts\shared::DoNoteTracks( "cornerReload" );
|
|
|
|
self animscripts\weaponList::RefillClip();
|
|
|
|
self setAnimRestart( animarray( "alert_idle" ), 1, .2 );
|
|
self clearAnim( reloadanim, .2 );
|
|
|
|
return true;
|
|
}
|
|
|
|
isPathClear( stepoutanim, doMidpointCheck )
|
|
{
|
|
if ( doMidpointCheck )
|
|
{
|
|
midpoint = getPredictedPathMidpoint();
|
|
|
|
if ( !self maymovetopoint( midpoint ) )
|
|
return false;
|
|
|
|
return self maymovefrompointtopoint( midpoint, getAnimEndPos( stepoutanim ) );
|
|
}
|
|
else
|
|
{
|
|
return self maymovetopoint( getAnimEndPos( stepoutanim ) );
|
|
}
|
|
}
|
|
|
|
getPredictedPathMidpoint( dist )
|
|
{
|
|
angles = self.coverNode.angles;
|
|
right = anglestoright( angles );
|
|
if ( !isdefined( dist ) )
|
|
dist = 36;
|
|
switch( self.script )
|
|
{
|
|
case "cover_left":
|
|
right = vector_multiply( right, 0-dist );
|
|
break;
|
|
|
|
case "cover_right":
|
|
right = vector_multiply( right, dist );
|
|
break;
|
|
|
|
default:
|
|
assertEx( 0, "What kind of node is this????" );
|
|
}
|
|
|
|
return self.coverNode.origin + ( right[ 0 ], right[ 1 ], 0 );
|
|
}
|
|
|
|
idle()
|
|
{
|
|
self endon( "end_idle" );
|
|
|
|
while ( 1 )
|
|
{
|
|
useTwitch = ( randomint( 2 ) == 0 && animArrayAnyExist( "alert_idle_twitch" ) );
|
|
if ( useTwitch )
|
|
idleanim = animArrayPickRandom( "alert_idle_twitch" );
|
|
else
|
|
idleanim = animarray( "alert_idle" );
|
|
|
|
playIdleAnimation( idleAnim, useTwitch );
|
|
}
|
|
}
|
|
|
|
flinch()
|
|
{
|
|
if ( !animArrayAnyExist( "alert_idle_flinch" ) )
|
|
return false;
|
|
|
|
playIdleAnimation( animArrayPickRandom( "alert_idle_flinch" ), true );
|
|
|
|
return true;
|
|
}
|
|
|
|
playIdleAnimation( idleAnim, needsRestart )
|
|
{
|
|
if ( needsRestart )
|
|
self setFlaggedAnimKnobAllRestart( "idle", idleAnim, %body, 1, .1, 1 );
|
|
else
|
|
self setFlaggedAnimKnobAll( "idle", idleAnim, %body, 1, .1, 1 );
|
|
|
|
self animscripts\shared::DoNoteTracks( "idle" );
|
|
}
|
|
|
|
|
|
set_anim_array( stance )
|
|
{
|
|
[[ self.animArrayFuncs[ "hiding" ][ stance ] ]]();
|
|
[[ self.animArrayFuncs[ "exposed" ][ stance ] ]]();
|
|
}
|
|
set_anim_array_aiming( stance )
|
|
{
|
|
[[ self.animArrayFuncs[ "exposed" ][ stance ] ]]();
|
|
}
|
|
|
|
transitionToStance( stance )
|
|
{
|
|
if ( self.a.pose == stance )
|
|
{
|
|
set_anim_array( stance );
|
|
return;
|
|
}
|
|
|
|
// self ExitProneWrapper(0.5);
|
|
self setFlaggedAnimKnobAllRestart( "changeStance", animarray( "stance_change" ), %body );
|
|
|
|
set_anim_array( stance );// ( sets anim_pose to stance )
|
|
|
|
self animscripts\shared::DoNoteTracks( "changeStance" );
|
|
assert( self.a.pose == stance );
|
|
wait( 0.2 );
|
|
}
|
|
|
|
GoToCover( coveranim, transTime, playTime )
|
|
{
|
|
cornerAngle = GetNodeDirection();
|
|
cornerOrigin = GetNodeOrigin();
|
|
|
|
desiredYaw = cornerAngle + self.hideyawoffset;
|
|
|
|
self OrientMode( "face angle", desiredYaw );
|
|
|
|
self animMode( "normal" );
|
|
|
|
assert( transTime <= playTime );
|
|
|
|
self thread animscripts\shared::moveToOriginOverTime( cornerOrigin, transTime );
|
|
self setFlaggedAnimKnobAllRestart( "coveranim", coveranim, %body, 1, transTime );
|
|
self animscripts\shared::DoNoteTracksForTime( playTime, "coveranim" );
|
|
|
|
while ( AbsAngleClamp180( self.angles[ 1 ] - desiredYaw ) > 1 )
|
|
{
|
|
self animscripts\shared::DoNoteTracksForTime( 0.1, "coveranim" );
|
|
}
|
|
|
|
self animMode( "zonly_physics" );
|
|
|
|
if ( self.cornerDirection == "left" )
|
|
self.a.special = "cover_left";
|
|
else
|
|
self.a.special = "cover_right";
|
|
}
|
|
|
|
drawoffset()
|
|
{
|
|
self endon( "killanimscript" );
|
|
for ( ;; )
|
|
{
|
|
line( self.node.origin + ( 0, 0, 20 ), ( 0, 0, 20 ) + self.node.origin + vector_multiply( anglestoright( self.node.angles + ( 0, 0, 0 ) ), 16 ) );
|
|
wait( 0.05 );
|
|
}
|
|
}
|
|
|
|
|
|
set_standing_animarray_aiming()
|
|
{
|
|
if ( !isdefined( self.a.array ) )
|
|
assertmsg( "set_standing_animarray_aiming_AandC::this function needs to be called after the initial corner set_ functions" );
|
|
|
|
self.a.array[ "add_aim_up" ] = %exposed_aim_8;
|
|
self.a.array[ "add_aim_down" ] = %exposed_aim_2;
|
|
self.a.array[ "add_aim_left" ] = %exposed_aim_4;
|
|
self.a.array[ "add_aim_right" ] = %exposed_aim_6;
|
|
self.a.array[ "add_turn_aim_up" ] = %exposed_turn_aim_8;
|
|
self.a.array[ "add_turn_aim_down" ] = %exposed_turn_aim_2;
|
|
self.a.array[ "add_turn_aim_left" ] = %exposed_turn_aim_4;
|
|
self.a.array[ "add_turn_aim_right" ] = %exposed_turn_aim_6;
|
|
self.a.array[ "straight_level" ] = %exposed_aim_5;
|
|
|
|
if ( self.a.cornerMode == "lean" )
|
|
{
|
|
// use the lean animations set up in cover_left and cover_right.gsc
|
|
leanfire = self.a.array[ "lean_fire" ];
|
|
leanSemiFire = self.a.array[ "lean_single" ];
|
|
self.a.array[ "fire" ] = leanfire;
|
|
self.a.array[ "single" ] = array( leanSemiFire );
|
|
|
|
self.a.array[ "semi2" ] = leanSemiFire;
|
|
self.a.array[ "semi3" ] = leanSemiFire;
|
|
self.a.array[ "semi4" ] = leanSemiFire;
|
|
self.a.array[ "semi5" ] = leanSemiFire;
|
|
|
|
self.a.array[ "burst2" ] = leanfire;
|
|
self.a.array[ "burst3" ] = leanfire;
|
|
self.a.array[ "burst4" ] = leanfire;
|
|
self.a.array[ "burst5" ] = leanfire;
|
|
self.a.array[ "burst6" ] = leanfire;
|
|
}
|
|
else
|
|
{
|
|
self.a.array[ "fire" ] = %exposed_shoot_auto_v2;
|
|
self.a.array[ "semi2" ] = %exposed_shoot_semi2;
|
|
self.a.array[ "semi3" ] = %exposed_shoot_semi3;
|
|
self.a.array[ "semi4" ] = %exposed_shoot_semi4;
|
|
self.a.array[ "semi5" ] = %exposed_shoot_semi5;
|
|
|
|
if ( weapon_pump_action_shotgun() )
|
|
self.a.array[ "single" ] = array( %shotgun_stand_fire_1A );
|
|
else
|
|
self.a.array[ "single" ] = array( %exposed_shoot_semi1 );
|
|
|
|
self.a.array[ "burst2" ] = %exposed_shoot_burst3;// ( will be limited to 2 shots )
|
|
self.a.array[ "burst3" ] = %exposed_shoot_burst3;
|
|
self.a.array[ "burst4" ] = %exposed_shoot_burst4;
|
|
self.a.array[ "burst5" ] = %exposed_shoot_burst5;
|
|
self.a.array[ "burst6" ] = %exposed_shoot_burst6;
|
|
}
|
|
self.a.array[ "exposed_idle" ] = array( %exposed_idle_alert_v1, %exposed_idle_alert_v2, %exposed_idle_alert_v3 );
|
|
}
|
|
|
|
set_crouching_animarray_aiming()
|
|
{
|
|
if ( !isdefined( self.a.array ) )
|
|
assertmsg( "set_standing_animarray_aiming_AandC::this function needs to be called after the initial corner set_ functions" );
|
|
|
|
if ( self.a.cornerMode == "over" )
|
|
{
|
|
self.a.array[ "add_aim_up" ] = %covercrouch_aim8_add;
|
|
self.a.array[ "add_aim_down" ] = %covercrouch_aim2_add;
|
|
self.a.array[ "add_aim_left" ] = %covercrouch_aim4_add;
|
|
self.a.array[ "add_aim_right" ] = %covercrouch_aim6_add;
|
|
self.a.array[ "straight_level" ] = %covercrouch_aim5;
|
|
|
|
anim_array[ "fire" ] = %exposed_shoot_auto_v2;
|
|
anim_array[ "semi2" ] = %exposed_shoot_semi2;
|
|
anim_array[ "semi3" ] = %exposed_shoot_semi3;
|
|
anim_array[ "semi4" ] = %exposed_shoot_semi4;
|
|
anim_array[ "semi5" ] = %exposed_shoot_semi5;
|
|
|
|
anim_array[ "burst2" ] = %exposed_shoot_burst3;// ( will be limited to 2 shots )
|
|
anim_array[ "burst3" ] = %exposed_shoot_burst3;
|
|
anim_array[ "burst4" ] = %exposed_shoot_burst4;
|
|
anim_array[ "burst5" ] = %exposed_shoot_burst5;
|
|
anim_array[ "burst6" ] = %exposed_shoot_burst6;
|
|
|
|
if ( weapon_pump_action_shotgun() )
|
|
anim_array[ "single" ] = array( %shotgun_crouch_fire );
|
|
else
|
|
anim_array[ "single" ] = array( %exposed_shoot_semi1 );
|
|
|
|
self.a.array[ "exposed_idle" ] = array( %exposed_idle_alert_v1, %exposed_idle_alert_v2, %exposed_idle_alert_v3 );
|
|
return;
|
|
}
|
|
|
|
if ( self.a.cornerMode == "lean" )
|
|
{
|
|
// use the lean animations set up in cover_left and cover_right.gsc
|
|
leanfire = self.a.array[ "lean_fire" ];
|
|
leanSemiFire = self.a.array[ "lean_single" ];
|
|
self.a.array[ "fire" ] = leanfire;
|
|
self.a.array[ "single" ] = array( leanSemiFire );
|
|
|
|
self.a.array[ "semi2" ] = leanSemiFire;
|
|
self.a.array[ "semi3" ] = leanSemiFire;
|
|
self.a.array[ "semi4" ] = leanSemiFire;
|
|
self.a.array[ "semi5" ] = leanSemiFire;
|
|
|
|
self.a.array[ "burst2" ] = leanfire;
|
|
self.a.array[ "burst3" ] = leanfire;
|
|
self.a.array[ "burst4" ] = leanfire;
|
|
self.a.array[ "burst5" ] = leanfire;
|
|
self.a.array[ "burst6" ] = leanfire;
|
|
}
|
|
else
|
|
{
|
|
self.a.array[ "fire" ] = %exposed_crouch_shoot_auto_v2;
|
|
self.a.array[ "semi2" ] = %exposed_crouch_shoot_semi2;
|
|
self.a.array[ "semi3" ] = %exposed_crouch_shoot_semi3;
|
|
self.a.array[ "semi4" ] = %exposed_crouch_shoot_semi4;
|
|
self.a.array[ "semi5" ] = %exposed_crouch_shoot_semi5;
|
|
|
|
if ( weapon_pump_action_shotgun() )
|
|
self.a.array[ "single" ] = array( %shotgun_crouch_fire );
|
|
else
|
|
self.a.array[ "single" ] = array( %exposed_crouch_shoot_semi1 );
|
|
|
|
self.a.array[ "burst2" ] = %exposed_crouch_shoot_burst3;// ( will be limited to 2 shots )
|
|
self.a.array[ "burst3" ] = %exposed_crouch_shoot_burst3;
|
|
self.a.array[ "burst4" ] = %exposed_crouch_shoot_burst4;
|
|
self.a.array[ "burst5" ] = %exposed_crouch_shoot_burst5;
|
|
self.a.array[ "burst6" ] = %exposed_crouch_shoot_burst6;
|
|
}
|
|
|
|
self.a.array[ "add_aim_up" ] = %exposed_crouch_aim_8;
|
|
self.a.array[ "add_aim_down" ] = %exposed_crouch_aim_2;
|
|
self.a.array[ "add_aim_left" ] = %exposed_crouch_aim_4;
|
|
self.a.array[ "add_aim_right" ] = %exposed_crouch_aim_6;
|
|
self.a.array[ "add_turn_aim_up" ] = %exposed_crouch_turn_aim_8;
|
|
self.a.array[ "add_turn_aim_down" ] = %exposed_crouch_turn_aim_2;
|
|
self.a.array[ "add_turn_aim_left" ] = %exposed_crouch_turn_aim_4;
|
|
self.a.array[ "add_turn_aim_right" ] = %exposed_crouch_turn_aim_6;
|
|
self.a.array[ "straight_level" ] = %exposed_crouch_aim_5;
|
|
|
|
self.a.array[ "exposed_idle" ] = array( %exposed_crouch_idle_alert_v1, %exposed_crouch_idle_alert_v2, %exposed_crouch_idle_alert_v3 );
|
|
}
|
|
|
|
runCombat()
|
|
{
|
|
self notify( "killanimscript" );
|
|
self thread animscripts\combat::main();
|
|
} |