800 lines
23 KiB
Plaintext
800 lines
23 KiB
Plaintext
#include maps\_utility;
|
|
#include animscripts\utility;
|
|
#include animscripts\Combat_utility;
|
|
#include animscripts\melee;
|
|
#include common_scripts\utility;
|
|
|
|
RIOTSHIELD_FACE_ENEMY_DIST = 1500;
|
|
RIOTSHIELD_FORCE_WALK_DIST = 500;
|
|
|
|
#using_animtree( "generic_human" );
|
|
|
|
init_riotshield_AI_anims()
|
|
{
|
|
anim.notetracks[ "detach shield" ] = ::noteTrackDetachShield;
|
|
|
|
animscripts\init_move_transitions::init_move_transition_arrays();
|
|
|
|
anim.coverTrans[ "riotshield" ] = [];
|
|
anim.coverTrans[ "riotshield" ][ 1 ] = %riotshield_run_approach_1;
|
|
anim.coverTrans[ "riotshield" ][ 2 ] = %riotshield_run_approach_2;
|
|
anim.coverTrans[ "riotshield" ][ 3 ] = %riotshield_run_approach_3;
|
|
anim.coverTrans[ "riotshield" ][ 4 ] = %riotshield_run_approach_4;
|
|
anim.coverTrans[ "riotshield" ][ 6 ] = %riotshield_run_approach_6;
|
|
anim.coverTrans[ "riotshield" ][ 7 ] = undefined;
|
|
anim.coverTrans[ "riotshield" ][ 8 ] = %riotshield_walk2crouch_8;
|
|
anim.coverTrans[ "riotshield" ][ 9 ] = undefined;
|
|
|
|
anim.coverTrans[ "riotshield_crouch" ] = [];
|
|
anim.coverTrans[ "riotshield_crouch" ][ 1 ] = %riotshield_walk_approach_1;
|
|
anim.coverTrans[ "riotshield_crouch" ][ 2 ] = %riotshield_walk_approach_2;
|
|
anim.coverTrans[ "riotshield_crouch" ][ 3 ] = %riotshield_walk_approach_3;
|
|
anim.coverTrans[ "riotshield_crouch" ][ 4 ] = %riotshield_walk_approach_4;
|
|
anim.coverTrans[ "riotshield_crouch" ][ 6 ] = %riotshield_walk_approach_6;
|
|
anim.coverTrans[ "riotshield_crouch" ][ 7 ] = undefined;
|
|
anim.coverTrans[ "riotshield_crouch" ][ 8 ] = %riotshield_walk2crouch_8;
|
|
anim.coverTrans[ "riotshield_crouch" ][ 9 ] = undefined;
|
|
|
|
riotshieldTransTypes = [];
|
|
riotshieldTransTypes[0] = "riotshield";
|
|
riotshieldTransTypes[1] = "riotshield_crouch";
|
|
|
|
for ( j = 0; j < riotshieldTransTypes.size; j++ )
|
|
{
|
|
trans = riotshieldTransTypes[ j ];
|
|
|
|
for ( i = 1; i <= 9; i++ )
|
|
{
|
|
if ( i == 5 )
|
|
continue;
|
|
|
|
if ( isdefined( anim.coverTrans[ trans ][ i ] ) )
|
|
{
|
|
anim.coverTransDist [ trans ][ i ] = getMoveDelta( anim.coverTrans[ trans ][ i ], 0, 1 );
|
|
}
|
|
}
|
|
}
|
|
|
|
anim.coverTransAngles[ "riotshield_crouch" ][ 1 ] = 45;
|
|
anim.coverTransAngles[ "riotshield_crouch" ][ 2 ] = 0;
|
|
anim.coverTransAngles[ "riotshield_crouch" ][ 3 ] = -45;
|
|
anim.coverTransAngles[ "riotshield_crouch" ][ 4 ] = 90;
|
|
anim.coverTransAngles[ "riotshield_crouch" ][ 6 ] = -90;
|
|
anim.coverTransAngles[ "riotshield_crouch" ][ 8 ] = 180;
|
|
|
|
anim.coverTransAngles[ "riotshield" ][ 1 ] = 45;
|
|
anim.coverTransAngles[ "riotshield" ][ 2 ] = 0;
|
|
anim.coverTransAngles[ "riotshield" ][ 3 ] = -45;
|
|
anim.coverTransAngles[ "riotshield" ][ 4 ] = 90;
|
|
anim.coverTransAngles[ "riotshield" ][ 6 ] = -90;
|
|
anim.coverTransAngles[ "riotshield" ][ 8 ] = 180;
|
|
|
|
anim.arrivalEndStance[ "riotshield" ] = "crouch";
|
|
anim.arrivalEndStance[ "riotshield_crouch" ] = "crouch";
|
|
|
|
|
|
addGrenadeThrowAnimOffset( %riotshield_crouch_grenade_toss, (-3.20014, 1.7098, 55.6886) );
|
|
}
|
|
|
|
noteTrackDetachShield( note, flagName )
|
|
{
|
|
self animscripts\shared::DropAIWeapon( self.secondaryWeapon );
|
|
self.secondaryWeapon = "none";
|
|
|
|
if ( isAlive( self ) )
|
|
riotshield_turn_into_regular_ai();
|
|
}
|
|
|
|
riotshield_approach_type()
|
|
{
|
|
if ( self.a.pose == "crouch" )
|
|
return "riotshield_crouch";
|
|
|
|
return "riotshield";
|
|
}
|
|
|
|
riotshield_approach_conditions( node )
|
|
{
|
|
// to allow approach while facing enemy and crouch walking
|
|
return true;
|
|
}
|
|
|
|
|
|
init_riotshield_AI()
|
|
{
|
|
//shieldModel = getWeaponModel( self.secondaryWeapon );
|
|
//self attach( shieldModel, "tag_weapon_left" );
|
|
|
|
animscripts\shared::placeWeaponOn( self.secondaryWeapon, "left", false );
|
|
|
|
self.subclass = "riotshield"; // incase guy didn't spawn as a "riotshield" ai
|
|
|
|
self.approachTypeFunc = ::riotshield_approach_type;
|
|
self.approachConditionCheckFunc = ::riotshield_approach_conditions;
|
|
|
|
self.faceEnemyArrival = true;
|
|
self.disableCoverArrivalsOnly = true;
|
|
self.pathRandomPercent = 0;
|
|
self.interval = 0;
|
|
self.disableDoorBehavior = true;
|
|
self.no_pistol_switch = true;
|
|
self.dontShootWhileMoving = true;
|
|
self.disableBulletWhizbyReaction = true;
|
|
self.disableFriendlyFireReaction = true;
|
|
self.neverSprintForVariation = true;
|
|
self.combatMode = "no_cover";
|
|
self.fixednode = false;
|
|
self.maxFaceEnemyDist = RIOTSHIELD_FACE_ENEMY_DIST;
|
|
self.noMeleeChargeDelay = true;
|
|
self.meleeChargeDistSq = squared( 256 );
|
|
self.meleePlayerWhileMoving = true;
|
|
self.useMuzzleSideOffset = true;
|
|
|
|
// fall over after getting hit this many times on the shield all within 0.3 seconds of each other
|
|
if ( level.gameSkill < 1 )
|
|
self.shieldBulletBlockLimit = randomintrange( 4, 8 );
|
|
else
|
|
self.shieldBulletBlockLimit = randomintrange( 8, 12 );
|
|
|
|
self.shieldBulletBlockCount = 0;
|
|
self.shieldBulletBlockTime = 0;
|
|
|
|
self.walkDist = RIOTSHIELD_FORCE_WALK_DIST;
|
|
self.walkDistFacingMotion = RIOTSHIELD_FORCE_WALK_DIST;
|
|
|
|
self.grenadeAwareness = 1;
|
|
self.frontShieldAngleCos = 0.5;
|
|
self.noGrenadeReturnThrow = true;
|
|
self.a.grenadeThrowPose = "crouch";
|
|
self.minExposedGrenadeDist = 400;
|
|
|
|
self.ignoresuppression = true;
|
|
|
|
self.specialMelee_Standard = ::riotshield_melee_standard;
|
|
self.specialMeleeChooseAction = ::riotshield_melee_AIvsAI;
|
|
|
|
self disable_turnAnims();
|
|
self disable_surprise();
|
|
self disable_cqbwalk();
|
|
|
|
init_riotshield_animsets();
|
|
|
|
if ( level.gameSkill < 1 )
|
|
self.bullet_resistance = 30;
|
|
else
|
|
self.bullet_resistance = 40;
|
|
|
|
self add_damage_function( maps\_spawner::bullet_resistance );
|
|
self add_damage_function( animscripts\pain::additive_pain );
|
|
}
|
|
|
|
|
|
riotshield_charge()
|
|
{
|
|
if ( !Melee_Standard_UpdateAndValidateTarget() )
|
|
return false;
|
|
|
|
// get from animation
|
|
delta = getMoveDelta( %riotshield_bashA_attack, 0, 1 );
|
|
rangeSq = lengthSquared( delta );
|
|
|
|
if ( distanceSquared( self.origin, self.melee.target.origin ) < rangeSq )
|
|
return true;
|
|
|
|
self animscripts\melee::Melee_PlayChargeSound();
|
|
|
|
sampleTime = 0.1;
|
|
firstTry = true;
|
|
|
|
while ( 1 )
|
|
{
|
|
assert( isdefined( self.melee.target ) );
|
|
|
|
// now that we moved a bit, see if our target moved before we check for valid melee
|
|
// it's possible something happened in the meantime that makes meleeing impossible.
|
|
if ( !Melee_Standard_UpdateAndValidateTarget() )
|
|
return false;
|
|
|
|
if ( firstTry )
|
|
{
|
|
self.a.pose = "stand";
|
|
self SetFlaggedAnimKnobAll( "chargeanim", %riotshield_sprint, %body, 1, .2, 1 );
|
|
firstTry = false;
|
|
}
|
|
|
|
self orientMode( "face point", self.melee.target.origin );
|
|
self animscripts\shared::DoNoteTracksForTime( sampleTime, "chargeanim" );
|
|
|
|
enemyDistanceSq = distanceSquared( self.origin, self.melee.target.origin );
|
|
|
|
// if we're done raising our gun, and starting a melee now will hit the guy, our preparation is finished
|
|
if ( enemyDistanceSq < rangeSq )
|
|
break;
|
|
|
|
// don't keep charging if we've been doing this for too long.
|
|
if ( gettime() >= self.melee.giveUpTime )
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
riotshield_melee_standard()
|
|
{
|
|
self animMode( "zonly_physics" );
|
|
|
|
animscripts\melee::Melee_Standard_ResetGiveUpTime();
|
|
|
|
while ( true )
|
|
{
|
|
if ( !riotshield_charge() )
|
|
{
|
|
// if we couldn't get in place to melee, don't try to charge for a little while and abort
|
|
self.nextMeleeChargeTime = getTime() + 1500;
|
|
self.nextMeleeChargeTarget = self.melee.target;
|
|
break;
|
|
}
|
|
|
|
assert( (self.a.pose == "stand") || (self.a.pose == "crouch") );
|
|
|
|
self animscripts\battleChatter_ai::evaluateMeleeEvent();
|
|
|
|
self orientMode( "face point", self.melee.target.origin );
|
|
self setflaggedanimknoballrestart( "meleeanim", %riotshield_bash_vs_player, %body, 1, .2, 1 );
|
|
|
|
self.melee.inProgress = true;
|
|
|
|
// If the attack loop returns false, we need to stop this melee
|
|
if( !animscripts\melee::Melee_Standard_PlayAttackLoop() )
|
|
{
|
|
// Since getting here means that we've done a melee but our attack is no longer valid, delay before we can do a standard attack again.
|
|
animscripts\melee::Melee_Standard_DelayStandardCharge( self.melee.target );
|
|
break;
|
|
}
|
|
|
|
self animMode( "none" );
|
|
}
|
|
|
|
self animMode( "none" );
|
|
}
|
|
|
|
riotshield_melee_AIvsAI()
|
|
{
|
|
assert( isDefined( self ) );
|
|
assert( isDefined( self.melee.target ) );
|
|
|
|
target = self.melee.target;
|
|
|
|
animscripts\melee::Melee_Decide_Winner();
|
|
|
|
// Choose which sequence to play based on angles
|
|
angleToEnemy = vectortoangles( target.origin - self.origin );
|
|
angleDiff = AngleClamp180( target.angles[ 1 ] - angleToEnemy[ 1 ] );
|
|
|
|
if ( abs( angleDiff ) > 100 ) // facing each other
|
|
{
|
|
if ( self.melee.winner )
|
|
{
|
|
if ( self.subclass == "riotshield" )
|
|
{
|
|
self.melee.animName = %riotshield_bashA_attack;
|
|
target.melee.animName = %riotshield_bashA_defend;
|
|
target.melee.surviveAnimName = %riotshield_bashA_defend_survive;
|
|
}
|
|
else
|
|
{
|
|
assert( target.subclass == "riotshield" );
|
|
self.melee.animName = %riotshield_bashB_defend;
|
|
target.melee.animName = %riotshield_bashB_attack;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( self.subclass == "riotshield" )
|
|
{
|
|
self.melee.animName = %riotshield_bashB_attack;
|
|
target.melee.animName = %riotshield_bashB_defend;
|
|
}
|
|
else
|
|
{
|
|
assert( target.subclass == "riotshield" );
|
|
self.melee.animName = %riotshield_bashA_defend;
|
|
target.melee.animName = %riotshield_bashA_attack;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
|
|
self.melee.startPos = getStartOrigin( target.origin, target.angles, self.melee.animName );
|
|
self.melee.startAngles = ( target.angles[0], AngleClamp180( target.angles[1] + 180 ), target.angles[2] );
|
|
|
|
self.lockOrientation = false;
|
|
target.lockOrientation = false;
|
|
|
|
// Make sure we can move to the selected point ( no re-try for now )
|
|
return Melee_UpdateAndValidateStartPos();
|
|
}
|
|
|
|
riotshield_startMoveTransition()
|
|
{
|
|
if ( isdefined( self.disableExits ) )
|
|
return;
|
|
|
|
self orientmode( "face angle", self.angles[1] );
|
|
self animmode( "zonly_physics", false );
|
|
|
|
if ( self.a.pose == "crouch" )
|
|
{
|
|
if ( isdefined( self.sprint ) || isdefined( self.fastwalk ) )
|
|
transAnim = %riotshield_crouch2stand;
|
|
else
|
|
transAnim = %riotshield_crouch2walk;
|
|
|
|
rate = randomfloatrange( 0.9, 1.1 );
|
|
self setFlaggedAnimKnobAllRestart( "startmove", transAnim, %body, 1, .1, rate );
|
|
self animscripts\shared::DoNoteTracks( "startmove" );
|
|
self clearanim( %riotshield_crouch2walk, 0.5 );
|
|
}
|
|
|
|
if ( isdefined( self.sprint ) || isdefined( self.fastwalk ) )
|
|
{
|
|
self allowedStances( "stand", "crouch" );
|
|
self.a.pose = "stand";
|
|
}
|
|
|
|
self orientmode( "face default" );
|
|
self animMode( "normal", false );
|
|
|
|
self thread riotshield_bullet_hit_shield();
|
|
}
|
|
|
|
riotshield_endMoveTransition()
|
|
{
|
|
if ( self.prevScript == "move" && self.a.pose == "crouch" )
|
|
{
|
|
self clearAnim( %root, .2 );
|
|
|
|
rate = randomfloatrange( 0.9, 1.1 );
|
|
self animmode( "zonly_physics" );
|
|
self setFlaggedAnimKnobAllRestart( "endmove", %riotshield_walk2crouch_8, %body, 1, .2, rate );
|
|
self animscripts\shared::DoNoteTracks( "endmove" );
|
|
self animMode( "normal" );
|
|
}
|
|
|
|
self allowedStances( "crouch" );
|
|
}
|
|
|
|
riotshield_startCombat()
|
|
{
|
|
//assertex( self.combatmode == "no_cover", "riotshield AI combat mode should be 'no_cover'" );
|
|
riotshield_endMoveTransition();
|
|
self.pushable = false;
|
|
self thread riotshield_bullet_hit_shield();
|
|
}
|
|
|
|
riotshield_bullet_hit_shield()
|
|
{
|
|
self endon( "killanimscript" );
|
|
|
|
while (1)
|
|
{
|
|
self waittill( "bullet_hitshield" );
|
|
|
|
time = gettime();
|
|
if ( time - self.shieldBulletBlockTime > 500 )
|
|
self.shieldBulletBlockCount = 0;
|
|
else
|
|
self.shieldBulletBlockCount++;
|
|
|
|
self.shieldBulletBlockTime = time;
|
|
if ( self.shieldBulletBlockCount > self.shieldBulletBlockLimit )
|
|
self doDamage( 1, ( 0, 0, 0 ) ); // do minimal damage to fall down
|
|
|
|
if ( cointoss() )
|
|
reactAnim = %riotshield_reactA;
|
|
else
|
|
reactAnim = %riotshield_reactB;
|
|
|
|
self notify( "new_hit_react" );
|
|
self setFlaggedAnimRestart( "hitreact", reactAnim, 1, 0.1, 1 );
|
|
self thread riotshield_bullet_hit_shield_clear();
|
|
}
|
|
}
|
|
|
|
|
|
riotshield_bullet_hit_shield_clear()
|
|
{
|
|
self endon( "killanimscript" );
|
|
self endon( "new_hit_react" );
|
|
|
|
self waittillmatch( "hitreact", "end" );
|
|
self clearanim( %riotshield_react, 0.1 );
|
|
}
|
|
|
|
|
|
riotshield_grenadeCower()
|
|
{
|
|
if ( self.a.pose == "stand" )
|
|
{
|
|
self clearanim( %root, .2 );
|
|
self setFlaggedAnimKnobAllRestart( "trans", %riotshield_walk2crouch_8, %body, 1, .2, 1.2 );
|
|
self animscripts\shared::DoNoteTracks( "trans" );
|
|
}
|
|
|
|
if ( isdefined( self.grenade ) )
|
|
{
|
|
faceGrenade = true;
|
|
dirToGrenade = self.grenade.origin - self.origin;
|
|
|
|
if ( isdefined( self.enemy ) )
|
|
{
|
|
dirToEnemy = self.enemy.origin - self.origin;
|
|
if ( vectorDot( dirToGrenade, dirToEnemy ) < 0 )
|
|
faceGrenade = false;
|
|
}
|
|
|
|
if ( faceGrenade )
|
|
{
|
|
relYaw = AngleClamp180( self.angles[ 1 ] - vectorToYaw( dirToGrenade ) );
|
|
|
|
if ( !isdefined( self.turnThreshold ) )
|
|
self.turnThreshold = 55;
|
|
|
|
while ( abs( relYaw ) > self.turnThreshold )
|
|
{
|
|
if ( !isdefined( self.a.array ) )
|
|
animscripts\combat::setup_anim_array();
|
|
|
|
if ( !self animscripts\combat::TurnToFaceRelativeYaw( relYaw ) )
|
|
break;
|
|
|
|
relYaw = AngleClamp180( self.angles[ 1 ] - vectorToYaw( dirToGrenade ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
self setAnimKnobAll( %riotshield_crouch_aim_5, %body, 1, 0.2, 1 );
|
|
self setFlaggedAnimKnobAllRestart( "grenadecower", %riotshield_crouch_idle_add, %add_idle, 1, 0.2, self.animplaybackrate );
|
|
self animscripts\shared::DoNoteTracks( "grenadecower" );
|
|
}
|
|
|
|
|
|
riotshield_flashbang()
|
|
{
|
|
self notify( "flashed" );
|
|
|
|
if ( !isdefined( self.a.onback ) )
|
|
{
|
|
rate = randomfloatrange( 0.9, 1.1 );
|
|
self.frontShieldAngleCos = 1;
|
|
|
|
flashArray = [];
|
|
flashArray[0] = %riotshield_crouch_grenade_flash1;
|
|
flashArray[1] = %riotshield_crouch_grenade_flash2;
|
|
flashArray[2] = %riotshield_crouch_grenade_flash3;
|
|
flashArray[3] = %riotshield_crouch_grenade_flash4;
|
|
flashAnim = flashArray[ randomint( flashArray.size ) ];
|
|
|
|
self setFlaggedAnimKnobAllRestart( "flashanim", flashAnim, %body, 1, .1, rate );
|
|
self.minPainDamage = 1000;
|
|
}
|
|
|
|
self animscripts\shared::DoNoteTracks( "flashanim" );
|
|
self.minPainDamage = 0;
|
|
self.frontShieldAngleCos = 0.5;
|
|
}
|
|
|
|
|
|
riotshield_pain()
|
|
{
|
|
// all the pain animations are in crouch
|
|
self.a.pose = "crouch";
|
|
|
|
if ( usingSideArm() )
|
|
forceUseWeapon( self.primaryweapon, "primary" );
|
|
|
|
if ( !isdefined( self.a.onback ) )
|
|
{
|
|
rate = randomfloatrange( 0.8, 1.15 );
|
|
self.frontShieldAngleCos = 1;
|
|
if ( ( self.damageYaw < -120 || self.damageYaw > 120 ) && isExplosiveDamageMOD( self.damageMOD ) )
|
|
{
|
|
painArray = [];
|
|
painArray[0] = %riotshield_crouch_grenade_blowback;
|
|
painArray[1] = %riotshield_crouch_grenade_blowbackL;
|
|
painArray[2] = %riotshield_crouch_grenade_blowbackR;
|
|
painAnim = painArray[ randomint( painArray.size ) ];
|
|
|
|
self setFlaggedAnimKnobAllRestart( "painanim", painAnim, %body, 1, .2, rate );
|
|
self.minPainDamage = 1000;
|
|
}
|
|
else
|
|
{
|
|
self setFlaggedAnimKnobAllRestart( "painanim", %riotshield_crouch_pain, %body, 1, .2, rate );
|
|
}
|
|
}
|
|
|
|
self animscripts\shared::DoNoteTracks( "painanim" );
|
|
self.minPainDamage = 0;
|
|
self.frontShieldAngleCos = 0.5;
|
|
}
|
|
|
|
riotshield_death()
|
|
{
|
|
if ( isdefined( self.a.onback ) && self.a.pose == "crouch" )
|
|
{
|
|
deathArray = [];
|
|
deathArray[0] = %dying_back_death_v2;
|
|
deathArray[1] = %dying_back_death_v3;
|
|
deathArray[2] = %dying_back_death_v4;
|
|
deathAnim = deathArray[ randomint( deathArray.size ) ];
|
|
|
|
self animscripts\death::playDeathAnim( deathAnim );
|
|
return true;
|
|
}
|
|
|
|
if ( self.prevScript == "pain" || self.prevScript == "flashed" )
|
|
doShieldDeath = randomInt( 2 ) == 0;
|
|
else
|
|
doShieldDeath = true;
|
|
|
|
if ( doShieldDeath )
|
|
{
|
|
if ( cointoss() )
|
|
deathAnim = %riotshield_crouch_death;
|
|
else
|
|
deathAnim = %riotshield_crouch_death_fallback;
|
|
|
|
self animscripts\death::playDeathAnim( deathAnim );
|
|
return true;
|
|
}
|
|
|
|
self.a.pose = "crouch";
|
|
return false;
|
|
}
|
|
|
|
init_riotshield_animsets()
|
|
{
|
|
// move animations
|
|
animset = [];
|
|
animset[ "sprint" ] = %riotshield_sprint;
|
|
animset[ "prone" ] = %prone_crawl;
|
|
|
|
animset[ "straight" ] = %riotshield_run_F;
|
|
|
|
animset[ "move_f" ] = %riotshield_run_F;
|
|
animset[ "move_l" ] = %riotshield_run_L;
|
|
animset[ "move_r" ] = %riotshield_run_R;
|
|
animset[ "move_b" ] = %riotshield_run_B;
|
|
|
|
animset[ "crouch" ] = %riotshield_crouchwalk_F;
|
|
animset[ "crouch_l" ] = %riotshield_crouchwalk_L;
|
|
animset[ "crouch_r" ] = %riotshield_crouchwalk_R;
|
|
animset[ "crouch_b" ] = %riotshield_crouchwalk_B;
|
|
|
|
animset[ "stairs_up" ] = %traverse_stair_run_01;
|
|
animset[ "stairs_down" ] = %traverse_stair_run_down;
|
|
|
|
self.customMoveAnimSet[ "run" ] = animset;
|
|
self.customMoveAnimSet[ "walk" ] = animset;
|
|
self.customMoveAnimSet[ "cqb" ] = animset;
|
|
|
|
self.customIdleAnimSet = [];
|
|
self.customIdleAnimSet[ "crouch" ] = %riotshield_crouch_aim_5;
|
|
self.customIdleAnimSet[ "crouch_add" ] = %riotshield_crouch_idle_add;
|
|
self.customIdleAnimSet[ "stand" ] = %riotshield_crouch_aim_5;
|
|
self.customIdleAnimSet[ "stand_add" ] = %riotshield_crouch_idle_add;
|
|
|
|
self.a.pose = "crouch";
|
|
self allowedStances( "crouch" );
|
|
|
|
// combat animations
|
|
animset = anim.animsets.defaultStand;
|
|
|
|
animset[ "add_aim_up" ] = %riotshield_crouch_aim_8;
|
|
animset[ "add_aim_down" ] = %riotshield_crouch_aim_2;
|
|
animset[ "add_aim_left" ] = %riotshield_crouch_aim_4;
|
|
animset[ "add_aim_right" ] = %riotshield_crouch_aim_6;
|
|
|
|
animset[ "straight_level" ] = %riotshield_crouch_aim_5;
|
|
|
|
animset[ "fire" ] = %riotshield_crouch_fire_auto;
|
|
animset[ "single" ] = array( %riotshield_crouch_fire_single );
|
|
|
|
// remove this burst, semi nonsense soon
|
|
animset[ "burst2" ] = %riotshield_crouch_fire_burst;
|
|
animset[ "burst3" ] = %riotshield_crouch_fire_burst;
|
|
animset[ "burst4" ] = %riotshield_crouch_fire_burst;
|
|
animset[ "burst5" ] = %riotshield_crouch_fire_burst;
|
|
animset[ "burst6" ] = %riotshield_crouch_fire_burst;
|
|
animset[ "semi2" ] = %riotshield_crouch_fire_burst;
|
|
animset[ "semi3" ] = %riotshield_crouch_fire_burst;
|
|
animset[ "semi4" ] = %riotshield_crouch_fire_burst;
|
|
animset[ "semi5" ] = %riotshield_crouch_fire_burst;
|
|
|
|
animset[ "exposed_idle" ] = array( %riotshield_crouch_idle_add, %riotshield_crouch_twitch );
|
|
animset[ "exposed_grenade" ] = array( %riotshield_crouch_grenade_toss );
|
|
|
|
animset[ "reload" ] = array( %riotshield_crouch_reload );
|
|
animset[ "reload_crouchhide" ] = array( %riotshield_crouch_reload );
|
|
|
|
animset[ "turn_left_45" ] = %riotshield_crouch_Lturn;
|
|
animset[ "turn_left_90" ] = %riotshield_crouch_Lturn;
|
|
animset[ "turn_left_135" ] = %riotshield_crouch_Lturn;
|
|
animset[ "turn_left_180" ] = %riotshield_crouch_Lturn;
|
|
animset[ "turn_right_45" ] = %riotshield_crouch_Rturn;
|
|
animset[ "turn_right_90" ] = %riotshield_crouch_Rturn;
|
|
animset[ "turn_right_135" ] = %riotshield_crouch_Rturn;
|
|
animset[ "turn_right_180" ] = %riotshield_crouch_Rturn;
|
|
|
|
animset[ "stand_2_crouch" ] = %riotshield_walk2crouch_8;
|
|
|
|
self animscripts\animset::init_animset_complete_custom_stand( animset );
|
|
self animscripts\animset::init_animset_complete_custom_crouch( animset );
|
|
|
|
self.choosePoseFunc = ::riotshield_choose_pose;
|
|
self.painFunction = ::riotshield_pain;
|
|
self.specialDeathFunc = ::riotshield_death;
|
|
self.specialFlashedFunc = ::riotshield_flashbang;
|
|
self.grenadeCowerFunction = ::riotshield_grenadeCower;
|
|
self.customMoveTransition = ::riotshield_startMoveTransition;
|
|
self.permanentCustomMoveTransition = true;
|
|
|
|
set_exception( "exposed", ::riotshield_startCombat );
|
|
//set_exception( "stop_immediate", ::riotshield_endMoveTransition );
|
|
}
|
|
|
|
riotshield_choose_pose( preferredPose )
|
|
{
|
|
if ( isdefined( self.grenade ) )
|
|
return "stand";
|
|
|
|
return self animscripts\utility::choosePose( preferredPose );
|
|
}
|
|
|
|
|
|
riotshield_sprint_on()
|
|
{
|
|
self.maxFaceEnemyDist = 128;
|
|
self.sprint = true;
|
|
self orientmode( "face default" );
|
|
self.lockorientation = false;
|
|
|
|
self.walkDist = 32;
|
|
self.walkDistFacingMotion = 32;
|
|
}
|
|
|
|
riotshield_fastwalk_on()
|
|
{
|
|
self.maxFaceEnemyDist = 128;
|
|
self.fastwalk = true;
|
|
|
|
self.walkDist = 32;
|
|
self.walkDistFacingMotion = 32;
|
|
}
|
|
|
|
|
|
riotshield_sprint_off()
|
|
{
|
|
self.maxFaceEnemyDist = RIOTSHIELD_FACE_ENEMY_DIST;
|
|
|
|
self.walkDist = RIOTSHIELD_FORCE_WALK_DIST;
|
|
self.walkDistFacingMotion = RIOTSHIELD_FORCE_WALK_DIST;
|
|
self.sprint = undefined;
|
|
self allowedStances( "crouch" );
|
|
}
|
|
|
|
riotshield_fastwalk_off()
|
|
{
|
|
self.maxFaceEnemyDist = RIOTSHIELD_FACE_ENEMY_DIST;
|
|
|
|
self.walkDist = RIOTSHIELD_FORCE_WALK_DIST;
|
|
self.walkDistFacingMotion = RIOTSHIELD_FORCE_WALK_DIST;
|
|
self.fastwalk = undefined;
|
|
self allowedStances( "crouch" );
|
|
}
|
|
|
|
null_func()
|
|
{
|
|
}
|
|
|
|
riotshield_init_flee()
|
|
{
|
|
// hack to restart move script
|
|
if ( self.script == "move" )
|
|
self animcustom( ::null_func );
|
|
|
|
self.customMoveTransition = ::riotshield_flee_and_drop_shield;
|
|
}
|
|
|
|
riotshield_flee_and_drop_shield()
|
|
{
|
|
// restore this incase flee gets interrupted
|
|
self.customMoveTransition = ::riotshield_startMoveTransition;
|
|
|
|
self animmode( "zonly_physics", false );
|
|
self orientmode( "face current" );
|
|
|
|
if ( !isdefined( self.dropShieldInPlace ) && isdefined( self.enemy ) && vectordot( self.lookaheadDir, anglesToForward( self.angles ) ) < 0 )
|
|
fleeAnim = %riotshield_crouch2walk_2flee;
|
|
else
|
|
fleeAnim = %riotshield_crouch2stand_shield_drop;
|
|
|
|
rate = randomFloatRange( 0.85, 1.1 );
|
|
self SetFlaggedAnimKnobAll( "fleeanim", fleeAnim, %root, 1, .1, rate );
|
|
self animscripts\shared::DoNoteTracks( "fleeanim" ); // return on code_move
|
|
|
|
self.maxFaceEnemyDist = 32;
|
|
self.lockOrientation = false;
|
|
self orientmode( "face default" );
|
|
self animmode( "normal", false );
|
|
self animscripts\shared::DoNoteTracks( "fleeanim" );
|
|
self clearanim( fleeAnim, 0.2 );
|
|
self.maxFaceEnemyDist = 128;
|
|
}
|
|
|
|
riotshield_turn_into_regular_ai()
|
|
{
|
|
self.subclass = "regular";
|
|
|
|
self.combatMode = "cover";
|
|
|
|
self.approachTypeFunc = undefined;
|
|
self.approachConditionCheckFunc = undefined;
|
|
self.faceEnemyArrival = undefined;
|
|
self.disableCoverArrivalsOnly = undefined;
|
|
self.pathRandomPercent = 0;
|
|
self.interval = 80;
|
|
self.disableDoorBehavior = undefined;
|
|
self.no_pistol_switch = undefined;
|
|
self.dontShootWhileMoving = undefined;
|
|
self.disableBulletWhizbyReaction = undefined;
|
|
self.disableFriendlyFireReaction = undefined;
|
|
self.neverSprintForVariation = undefined;
|
|
self.maxFaceEnemyDist = 128;
|
|
self.noMeleeChargeDelay = undefined;
|
|
self.meleeChargeDistSq = undefined;
|
|
self.meleePlayerWhileMoving = undefined;
|
|
self.useMuzzleSideOffset = undefined;
|
|
|
|
self.pathEnemyFightDist = 128;
|
|
self.pathenemylookahead = 128;
|
|
|
|
self.walkDist = 256;
|
|
self.walkDistFacingMotion = 64;
|
|
self.lockorientation = false;
|
|
|
|
self.frontShieldAngleCos = 1;
|
|
self.noGrenadeReturnThrow = false;
|
|
|
|
self.ignoresuppression = false;
|
|
self.sprint = undefined;
|
|
|
|
self allowedStances( "stand", "crouch", "prone" );
|
|
|
|
self.specialMelee_Standard = undefined;
|
|
self.specialMeleeChooseAction = undefined;
|
|
|
|
self enable_turnAnims();
|
|
|
|
self.bullet_resistance = undefined;
|
|
self remove_damage_function( maps\_spawner::bullet_resistance );
|
|
self remove_damage_function( animscripts\pain::additive_pain );
|
|
|
|
self animscripts\animset::clear_custom_animset();
|
|
|
|
self.choosePoseFunc = animscripts\utility::choosePose;
|
|
self.painFunction = undefined;
|
|
self.specialDeathFunc = undefined;
|
|
self.specialFlashedFunc = undefined;
|
|
self.grenadeCowerFunction = undefined;
|
|
self.customMoveTransition = undefined;
|
|
self.permanentCustomMoveTransition = undefined;
|
|
|
|
clear_exception( "exposed" );
|
|
clear_exception( "stop_immediate" );
|
|
} |