IW4-Dump-Files/animscripts/door.gsc

302 lines
6.7 KiB
Plaintext

#include animscripts\combat_utility;
#include animscripts\utility;
#include animscripts\shared;
#include common_scripts\utility;
#include maps\_utility;
#using_animtree( "generic_human" );
doorGrenadeInterval = 5000;
maxDistDoorToEnemySq = 600 * 600;
doorEnterExitCheck()
{
self endon( "killanimscript" );
if ( isdefined( self.disableDoorBehavior ) )
return;
while ( 1 )
{
doorNode = self getDoorPathNode();
if ( isdefined( doorNode ) )
break;
wait 0.2;
}
goingInDoor = ( doorNode.type == "Door Interior" ) || self compareNodeDirToPathDir( doorNode );
if ( goingInDoor )
self doorEnter( doorNode );
else
self doorExit( doorNode );
// waittill doorNode changes
while ( 1 )
{
newDoorNode = self getDoorPathNode();
if ( !isdefined( newDoorNode ) || newDoorNode != doorNode )
break;
wait 0.2;
}
self thread doorEnterExitCheck();
}
teamFlashBangImmune()
{
self endon( "killanimscript" );
self.teamFlashbangImmunity = true;
wait 5;
self.teamFlashbangImmunity = undefined;
}
doDoorGrenadeThrow( node )
{
self thread teamFlashBangImmune();
if ( self.grenadeWeapon == "flash_grenade" )
self notify( "flashbang_thrown" );
self OrientMode( "face current" );
node.nextDoorGrenadeTime = gettime() + doorGrenadeInterval;
self.minInDoorTime = gettime() + 100000; // hack to not forget going indoor
self notify( "move_interrupt" );
self.update_move_anim_type = undefined;
self clearanim( %combatrun, 0.2 );
self.a.movement = "stop";
self waittill( "done_grenade_throw" );
self OrientMode( "face default" );
self.minInDoorTime = gettime() + 5000;
self.grenadeWeapon = self.oldGrenadeWeapon;
self.oldGrenadeWeapon = undefined;
self animscripts\run::endFaceEnemyAimTracking();
self thread animscripts\move::pathChangeCheck();
self thread animscripts\move::restartMoveLoop( true );
}
// try throwing grenade before entering door
doorEnter_TryGrenade( node, grenadeType, ricochet, minDistSq, checkInterval )
{
safeCheckDone = false;
throwAttempts = 3;
throwAnim = undefined;
throwAnim = %CQB_stand_grenade_throw;
doorForward = anglesToForward( node.angles );
if ( node.type == "Door Interior" && !( self compareNodeDirToPathDir( node ) ) )
doorForward = -1 * doorForward;
doorPos = ( node.origin[ 0 ], node.origin[ 1 ], node.origin[ 2 ] + 64 );
throwPos = doorPos;
if ( ricochet )
{
doorPlane = AnglesToRight( node.angles );
dirToDoor = node.origin - self.origin;
// upto 20 units to left or right of door depending on direction to door to make it likely to bounce off door edge
projLength = vectordot( doorPlane, dirToDoor );
if ( projLength > 20 )
projLength = 20;
else if ( projLength < - 20 )
projLength = -20;
throwPos = doorPos + projLength * doorPlane;
}
while ( throwAttempts > 0 )
{
if ( isdefined( self.grenade ) || !isdefined( self.enemy ) )
return;
if ( onSameSideOfDoor( node, doorForward ) )
return;
if ( !self seeRecently( self.enemy, 0.2 ) && self.a.pose == "stand" && distance2DAndHeightCheck( self.enemy.origin - node.origin, maxDistDoorToEnemySq, 128 * 128 ) )
{
if ( isdefined( node.nextDoorGrenadeTime ) && node.nextDoorGrenadeTime > gettime() )
return;
if ( self canShootEnemy() )
return;
// too close to door
dirToDoor = node.origin - self.origin;
if ( lengthSquared( dirToDoor ) < minDistSq )
return;
// don't throw backwards
if ( vectordot( dirToDoor, doorForward ) < 0 )
return;
self.oldGrenadeWeapon = self.grenadeWeapon;
self.grenadeWeapon = grenadeType;
self setActiveGrenadeTimer( self.enemy );
if ( !safeCheckDone )
{
checkPos = doorPos + ( doorForward * 100 );
if ( !( self isGrenadePosSafe( self.enemy, checkPos, 128 ) ) )
return;
}
safeCheckDone = true; // do this only once but do isGrenadePosSafe as late as possible
if ( TryGrenadeThrow( self.enemy, throwPos, throwAnim, getGrenadeThrowOffset( throwAnim ), true, false, true ) )
{
self doDoorGrenadeThrow( node );
return;
}
}
throwAttempts -- ;
wait checkInterval;
// check if door node has past
newNode = self getDoorPathNode();
if ( !isdefined( newNode ) || newNode != node )
return;
}
}
inDoorCqbToggleCheck()
{
self endon( "killanimscript" );
if ( isdefined( self.disableDoorBehavior ) )
return;
self.isInDoor = false;
while ( 1 )
{
if ( self isInDoor() && !self.doingAmbush )
{
doorEnter_enable_cqbwalk();
}
else if ( !isdefined( self.minInDoorTime ) || self.minInDoorTime < gettime() )
{
self.minInDoorTime = undefined;
doorExit_disable_cqbwalk();
}
wait 0.2;
}
}
// substitute for enable_cqbwalk so LD can always disable cqb
doorEnter_enable_cqbwalk()
{
if ( !isdefined( self.neverEnableCQB ) && !self.doingAmbush )
{
self.isInDoor = true;
if ( !isdefined( self.cqbWalking ) || !self.cqbWalking )
enable_cqbwalk( true );
}
}
// substitute for disable_cqbwalk so LD can force CQB even after exiting to outdoor
doorExit_disable_cqbwalk()
{
if ( !isdefined( self.cqbEnabled ) )
{
self.isInDoor = false;
if ( isdefined( self.cqbWalking ) && self.cqbWalking )
disable_cqbwalk();
}
}
maxFragDistSq = 750 * 750;
minFragDistSq = 550 * 550;
maxFlashDistSq = 192 * 192;
minFlashDistSq = 64 * 64;
maxFragHeightDiffSq = 160 * 160;
maxFlashHeightDiffSq = 80 * 80;
distance2DAndHeightCheck( vec, dist2DSq, heightSq )
{
return( ( vec[ 0 ] * vec[ 0 ] + vec[ 1 ] * vec[ 1 ] ) < dist2DSq ) && ( ( vec[ 2 ] * vec[ 2 ] ) < heightSq );
}
onSameSideOfDoor( node, doorForward )
{
assert( isdefined( self.enemy ) );
selfToDoor = node.origin - self.origin;
enemyToDoor = node.origin - self.enemy.origin;
return( vectordot( selfToDoor, doorForward ) * vectordot( enemyToDoor, doorForward ) > 0 );
}
doorEnter( node )
{
// try frag
while ( 1 )
{
if ( isdefined( self.doorFragChance ) && ( self.doorFragChance == 0 || self.doorFragChance < randomfloat( 1 ) ) )
break;
if ( distance2DAndHeightCheck( self.origin - node.origin, maxFragDistSq, maxFragHeightDiffSq ) )
{
self doorEnter_TryGrenade( node, "fraggrenade", false, minFragDistSq, 0.3 );
node = self getDoorPathNode();
if ( !isdefined( node ) )
return;
break;
}
wait 0.1;
}
// try flashbang
while ( 1 )
{
if ( distance2DAndHeightCheck( self.origin - node.origin, maxFlashDistSq, maxFlashHeightDiffSq ) )
{
self doorEnter_enable_cqbwalk();
self.minInDoorTime = gettime() + 6000;
if ( isdefined( self.doorFlashChance ) && ( self.doorFlashChance == 0 || self.doorFlashChance < randomfloat( 1 ) ) )
return;
self doorEnter_TryGrenade( node, "flash_grenade", true, minFlashDistSq, 0.2 );
return;
}
wait 0.1;
}
}
doorExit( node )
{
while ( 1 )
{
if ( !self.isInDoor || distanceSquared( self.origin, node.origin ) < 32 * 32 )
{
//self doorExit_disable_cqbwalk();
return;
}
wait 0.1;
}
}