982 lines
21 KiB
Plaintext
982 lines
21 KiB
Plaintext
#include common_scripts\utility;
|
|
#include maps\_utility;
|
|
#include maps\_hud_util;
|
|
#include maps\_anim;
|
|
|
|
|
|
create_overlay_element( shader_name, start_alpha )
|
|
{
|
|
overlay = newHudElem();
|
|
overlay.x = 0;
|
|
overlay.y = 0;
|
|
overlay setshader( shader_name, 640, 480 );
|
|
overlay.alignX = "left";
|
|
overlay.alignY = "top";
|
|
overlay.sort = 1;
|
|
overlay.horzAlign = "fullscreen";
|
|
overlay.vertAlign = "fullscreen";
|
|
overlay.alpha = start_alpha;
|
|
overlay.foreground = true;
|
|
return overlay;
|
|
}
|
|
|
|
hide_geo()
|
|
{
|
|
self hide();
|
|
self notsolid();
|
|
if ( self.spawnflags & 1 )
|
|
self connectpaths();
|
|
}
|
|
|
|
hideAll( stuffToHide )
|
|
{
|
|
if ( !isdefined( stuffToHide ) )
|
|
stuffToHide = getentarray( "hide", "script_noteworthy" );
|
|
for ( i = 0;i < stuffToHide.size;i++ )
|
|
{
|
|
entity = stuffToHide[ i ];
|
|
switch( entity.classname )
|
|
{
|
|
case"script_vehicle":
|
|
entity delete();
|
|
break;
|
|
case"script_model":
|
|
entity hide();
|
|
break;
|
|
case "script_brushmodel":
|
|
entity hide();
|
|
entity notsolid();
|
|
if ( entity.spawnflags & 1 )
|
|
entity connectpaths();
|
|
break;
|
|
case "trigger_radius":
|
|
case "trigger_multiple":
|
|
case "trigger_use":
|
|
case "trigger_use_touch":
|
|
case "trigger_multiple_flag_set":
|
|
case "trigger_multiple_breachIcon":
|
|
case "trigger_multiple_flag_lookat":
|
|
case "trigger_multiple_flag_looking":
|
|
entity trigger_off();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
ai_notify( sNotify, duration )
|
|
{
|
|
self endon( "death" );
|
|
duration = int( duration * 1000 );
|
|
|
|
startTime = getTime();
|
|
curTime = getTime();
|
|
|
|
while ( curTime < startTime + duration )
|
|
{
|
|
wait( 0.05 );
|
|
curTime = getTime();
|
|
self notify( sNotify );
|
|
}
|
|
|
|
self notify( "ai_notify_complete" );
|
|
|
|
}
|
|
|
|
get_all_ents_in_chain( sEntityType )
|
|
{
|
|
aChain = [];
|
|
ePathpoint = self;
|
|
i = 0;
|
|
while ( isdefined( ePathpoint.target ) )
|
|
{
|
|
wait( 0.05 );
|
|
if ( isdefined( ePathpoint.target ) )
|
|
{
|
|
switch( sEntityType )
|
|
{
|
|
case "vehiclenode":
|
|
ePathpoint = getvehiclenode( ePathpoint.target, "targetname" );
|
|
break;
|
|
case "pathnode":
|
|
ePathpoint = getnode( ePathpoint.target, "targetname" );
|
|
break;
|
|
case "ent":
|
|
ePathpoint = getent( ePathpoint.target, "targetname" );
|
|
break;
|
|
default:
|
|
assertmsg( "sEntityType needs to be 'vehiclenode', 'pathnode' or 'ent'" );
|
|
}
|
|
aChain[ aChain.size ] = ePathpoint;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
if ( aChain.size > 0 )
|
|
return aChain;
|
|
else
|
|
return undefined;
|
|
}
|
|
|
|
|
|
wait_for_level_notify_or_timeout( msg1, timer )
|
|
{
|
|
level endon( msg1 );
|
|
wait( timer );
|
|
}
|
|
|
|
get_ai_within_radius( fRadius, org, sTeam )
|
|
{
|
|
if ( isdefined( sTeam ) )
|
|
ai = getaiarray( sTeam );
|
|
else
|
|
ai = getaiarray();
|
|
|
|
aDudes = [];
|
|
for ( i = 0;i < ai.size;i++ )
|
|
{
|
|
if ( distance( org, self.origin ) <= fRadius )
|
|
array_add( aDudes, ai[ i ] );
|
|
}
|
|
return aDudes;
|
|
}
|
|
|
|
AI_stun( fAmount )
|
|
{
|
|
self endon( "death" );
|
|
if ( ( isdefined( self ) ) && ( isalive( self ) ) && ( self flashBangIsActive() ) )
|
|
self flashBangStart( fAmount );
|
|
}
|
|
|
|
start_teleport( eNode )
|
|
{
|
|
self forceTeleport( eNode.origin, eNode.angles );
|
|
self setgoalpos( self.origin );
|
|
//self setgoalradius (eNode.radius);
|
|
self setgoalnode( eNode );
|
|
}
|
|
|
|
waittill_player_in_range( origin, range )
|
|
{
|
|
while ( true )
|
|
{
|
|
if ( distance( origin, level.player.origin ) <= range )
|
|
break;
|
|
wait .5;
|
|
}
|
|
}
|
|
|
|
vehicle_go_to_end_and_delete( sPath, sVehicleType )
|
|
{
|
|
eStartNode = getvehiclenode( sPath, "targetname" );
|
|
assertEx( ( isdefined( eStartNode ) ), "No vehicle node found with this name: " + sPath );
|
|
sVehicleModel = "";
|
|
switch( sVehicleType )
|
|
{
|
|
case "truck":
|
|
sVehicleModel = "vehicle_pickup_4door";
|
|
break;
|
|
case "bmp":
|
|
sVehicleModel = "vehicle_bmp";
|
|
break;
|
|
default:
|
|
assertmsg( "you need to define a valid sVehicletype" );
|
|
}
|
|
|
|
eVehicle = spawnvehicle( sVehicleModel, "plane", "truck", eStartNode.origin, eStartNode.angles );
|
|
if ( sVehicleType == "truck" )
|
|
eVehicle truck_headlights_on();
|
|
eVehicle attachpath( eStartNode );
|
|
eVehicle startpath();
|
|
eVehicle Vehicle_SetSpeed( 23, 20 );
|
|
eVehicle waittill( "reached_end_node" );
|
|
eVehicle delete();
|
|
}
|
|
|
|
truck_headlights_on()
|
|
{
|
|
//self ==> the truck entity
|
|
playfxontag( level._effect[ "headlight_truck" ], self, "tag_headlight_left" );
|
|
playfxontag( level._effect[ "headlight_truck" ], self, "tag_headlight_right" );
|
|
}
|
|
|
|
set_goalvolume( sVolumeName, eVolume )
|
|
{
|
|
self endon( "death" );
|
|
if ( isDefined( sVolumeName ) )
|
|
eVolume = getent( sVolumeName, "targetname" );
|
|
|
|
assertEx( ( isdefined( eVolume ) ), "Need to pass a valid room volume" );
|
|
|
|
eNode = getnode( eVolume.target, "targetname" );
|
|
assertEx( ( isdefined( eNode ) ), "The volume at " + eVolume.origin + " is not targeting a node" );
|
|
|
|
self.goalvolume = eVolume;
|
|
self setgoalnode( eNode );
|
|
self.goalradius = eNode.radius;
|
|
self setgoalvolume( eVolume );
|
|
}
|
|
|
|
waittill_touching_entity( eEnt )
|
|
{
|
|
self endon( "death" );
|
|
|
|
while ( !self istouching( eEnt ) )
|
|
wait( 0.05 );
|
|
}
|
|
|
|
reset_goalvolume()
|
|
{
|
|
self endon( "death" );
|
|
self setgoalpos( self.origin );
|
|
self.goalvolume = undefined;
|
|
}
|
|
|
|
print3Dthread( sMessage, org, fSize, zOffset )
|
|
{
|
|
self endon( "death" );
|
|
if ( !isdefined( fSize ) )
|
|
fSize = 0.25;
|
|
if ( !isdefined( zOffset ) )
|
|
zOffset = 0;
|
|
|
|
if ( !isdefined( org ) )
|
|
{
|
|
self notify( "stop_3dprint" );
|
|
self endon( "stop_3dprint" );
|
|
self endon( "death" );
|
|
|
|
|
|
for ( ;; )
|
|
{
|
|
if ( isdefined( self ) )
|
|
print3d( self.origin + ( 0, 0, zOffset ), sMessage, ( 1, 1, 1 ), 1, fSize );
|
|
wait( 0.05 );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for ( ;; )
|
|
{
|
|
print3d( org, sMessage, ( 1, 1, 1 ), 1, fSize );
|
|
wait( 0.05 );
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
smoke_detect()
|
|
{
|
|
//"self" = the room volume you are checking
|
|
self endon( "smoke_has_been_thrown" );
|
|
self.smokethrown = false;
|
|
while ( self.smokethrown == false )
|
|
{
|
|
wait( 0.05 );
|
|
grenades = getentarray( "grenade", "classname" );
|
|
for ( i = 0;i < grenades.size;i++ )
|
|
{
|
|
if ( grenades[ i ].model == "projectile_us_smoke_grenade" )
|
|
{
|
|
if ( grenades[ i ] istouching( self ) )
|
|
{
|
|
self.smokethrown = true;
|
|
self notify( "smoke_has_been_thrown" );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/****************************************************************************
|
|
DIALOGUE FUNCTIONS
|
|
****************************************************************************/
|
|
|
|
dialogue_execute( sLineToExecute )
|
|
{
|
|
self endon( "death" );
|
|
|
|
self dialogue_queue( sLineToExecute );
|
|
|
|
}
|
|
|
|
trigArrayWait( sTrig )
|
|
{
|
|
aTriggers = getEntarray( sTrig, "targetname" );
|
|
assert( aTriggers.size > 0 );
|
|
|
|
if ( aTriggers.size == 1 )
|
|
trigWait( sTrig );
|
|
else
|
|
{
|
|
for ( i = 0;i < aTriggers.size;i++ )
|
|
aTriggers[ i ] thread trigArrayWait2( aTriggers );
|
|
|
|
//wait for the first one to get notified
|
|
aTriggers[ 0 ] waittill( "trigger" );
|
|
}
|
|
}
|
|
|
|
trigArrayWait2( aTrigArray )
|
|
{
|
|
self waittill( "trigger" );
|
|
|
|
//turn off all of the other triggers
|
|
for ( i = 0;i < aTrigArray.size;i++ )
|
|
{
|
|
aTrigArray[ i ] notify( "trigger" );
|
|
aTrigArray[ i ] trigger_off();
|
|
}
|
|
}
|
|
|
|
trigWait( sTrig )
|
|
{
|
|
trigger = getent( sTrig, "targetname" );
|
|
assert( isdefined( trigger ) );
|
|
trigger waittill( "trigger" );
|
|
trigger trigger_off();
|
|
}
|
|
|
|
triggersEnable( triggerName, noteworthyOrTargetname, bool )
|
|
{
|
|
assertEX( isdefined( bool ), "Must specify true/false parameter for triggersEnable() function" );
|
|
aTriggers = getentarray( triggername, noteworthyOrTargetname );
|
|
assertEx( isDefined( aTriggers ), triggerName + " does not exist" );
|
|
if ( bool == true )
|
|
array_thread( aTriggers, ::trigger_on );
|
|
else
|
|
array_thread( aTriggers, ::trigger_off );
|
|
}
|
|
|
|
triggerActivate( sTriggerName ) // Activate a trigger, then delete it
|
|
{
|
|
eTrig = getent( sTriggerName, "targetname" );
|
|
assert( isdefined( eTrig ) );
|
|
eTrig notify( "trigger", level.player );
|
|
eTrig trigger_off();
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
AI HOUSEKEEPING FUNCTIONS
|
|
****************************************************************************/
|
|
AA_AI_functions()
|
|
{
|
|
//empty function
|
|
}
|
|
|
|
look_at_position( eEnt )
|
|
{
|
|
yaw = VectorToAngles( self.origin - eEnt.origin );
|
|
self setpotentialthreat( yaw[ 1 ] );
|
|
}
|
|
|
|
set_threatbias( iNumber )
|
|
{
|
|
if ( !isdefined( self.old_threatbias ) )
|
|
self.old_threatbias = self.threatbias;
|
|
self.threatbias = iNumber;
|
|
}
|
|
|
|
reset_threatbias()
|
|
{
|
|
if ( isdefined( self.old_threatbias ) )
|
|
self.threatbias = self.old_threatbias;
|
|
self.old_threatbias = undefined;
|
|
}
|
|
|
|
|
|
|
|
set_walkdist( dist )
|
|
{
|
|
if ( !isdefined( self.old_walkdist ) )
|
|
self.old_walkdist = self.walkdist;
|
|
self.walkdist = dist;
|
|
}
|
|
|
|
reset_walkdist()
|
|
{
|
|
if ( isdefined( self.old_walkdist ) )
|
|
self.walkdist = self.old_walkdist;
|
|
self.old_walkdist = undefined;
|
|
}
|
|
|
|
set_health( iHealth )
|
|
{
|
|
self.old_health = self.health;
|
|
self.health = iHealth;
|
|
}
|
|
|
|
reset_health()
|
|
{
|
|
if ( isdefined( self.old_health ) )
|
|
self.health = self.old_health;
|
|
}
|
|
|
|
|
|
set_animname( animname )
|
|
{
|
|
if ( !isdefined( self.old_animname ) )
|
|
self.old_animname = self.animname;
|
|
self.animname = animname;
|
|
}
|
|
|
|
reset_animname()
|
|
{
|
|
if ( isdefined( self.old_animname ) )
|
|
self.animname = self.old_animname;
|
|
self.old_animname = undefined;
|
|
}
|
|
|
|
|
|
set_maxsightdistsqrd( iNumber )
|
|
{
|
|
if ( !isdefined( self.old_maxsightdistsqrd ) )
|
|
self.old_maxsightdistsqrd = self.maxsightdistsqrd;
|
|
self.maxsightdistsqrd = iNumber;
|
|
}
|
|
|
|
reset_maxsightdistsqrd()
|
|
{
|
|
if ( isdefined( self.old_maxsightdistsqrd ) )
|
|
self.maxsightdistsqrd = self.old_maxsightdistsqrd;
|
|
self.old_maxsightdistsqrd = undefined;
|
|
}
|
|
|
|
set_threatbiasgroup( sName )
|
|
{
|
|
if ( !threatbiasgroupexists( sName ) )
|
|
assertmsg( "Threatbias group name does not exist: " + sName );
|
|
|
|
if ( !isdefined( self.old_threatBiasGroupName ) )
|
|
self.old_threatBiasGroupName = self.threatBiasGroupName;
|
|
|
|
self.threatBiasGroupName = sName;
|
|
self setThreatBiasGroup( sName );
|
|
}
|
|
|
|
reset_threatbiasgroup()
|
|
{
|
|
if ( isdefined( self.old_threatBiasGroupName ) )
|
|
{
|
|
self.threatBiasGroupName = self.old_threatBiasGroupName;
|
|
self setThreatBiasGroup( self.old_threatBiasGroupName );
|
|
if ( !threatbiasgroupexists( self.old_threatBiasGroupName ) )
|
|
assertmsg( "Threatbias group name does not exist: " + self.old_threatBiasGroupName );
|
|
}
|
|
else
|
|
{
|
|
self.threatBiasGroupName = undefined;
|
|
self setThreatBiasGroup();
|
|
}
|
|
|
|
self.old_threatBiasGroupName = undefined;
|
|
}
|
|
|
|
|
|
|
|
|
|
setGoalRadius( fRadius )
|
|
{
|
|
if ( !isdefined( self.old_goalradius ) )
|
|
self.old_goalradius = self.goalradius;
|
|
self.goalradius = fRadius;
|
|
}
|
|
|
|
resetGoalRadius()
|
|
{
|
|
if ( isdefined( self.old_goalradius ) )
|
|
self.goalradius = self.old_goalradius;
|
|
self.old_goalradius = undefined;
|
|
}
|
|
|
|
setInterval( iInterval )
|
|
{
|
|
if ( !isdefined( self.old_interval ) )
|
|
self.old_interval = self.interval;
|
|
self.interval = iInterval;
|
|
}
|
|
resetInterval()
|
|
{
|
|
if ( isdefined( self.old_interval ) )
|
|
self.interval = self.old_interval;
|
|
self.old_interval = undefined;
|
|
}
|
|
|
|
set_accuracy( fAccuracy )
|
|
{
|
|
if ( !isdefined( self.old_accuracy ) )
|
|
self.old_accuracy = self.baseaccuracy;
|
|
self.baseaccuracy = fAccuracy;
|
|
}
|
|
|
|
reset_accuracy()
|
|
{
|
|
if ( isdefined( self.old_accuracy ) )
|
|
self.baseaccuracy = self.old_accuracy;
|
|
self.old_accuracy = undefined;
|
|
}
|
|
|
|
|
|
get_closest_ally( eEnt )
|
|
{
|
|
guy = undefined;
|
|
|
|
if ( !isdefined( eEnt ) )
|
|
org = level.player getorigin();
|
|
else
|
|
org = eEnt getorigin();
|
|
|
|
if ( isdefined( level.excludedAi ) )
|
|
guy = get_closest_ai_exclude( org, "allies", level.excludedAi );
|
|
else
|
|
guy = get_closest_ai( org, "allies" );
|
|
|
|
return guy;
|
|
}
|
|
|
|
|
|
get_closest_axis()
|
|
{
|
|
guy = get_closest_ai( level.player getorigin(), "axis" );
|
|
return guy;
|
|
}
|
|
|
|
|
|
groupWarp( aGroupToBeWarped, sNodesToWarpTo )
|
|
{
|
|
aNodes = getnodearray( sNodesToWarpTo, "targetname" );
|
|
assert( isdefined( aNodes ) );
|
|
|
|
for ( i = 0;i < aGroupToBeWarped.size;i++ )
|
|
{
|
|
if ( isdefined( aNodes[ i ] ) )
|
|
{
|
|
aGroupToBeWarped[ i ] teleport( aNodes[ i ].origin );
|
|
}
|
|
}
|
|
}
|
|
getAIarrayTouchingVolume( sTeamName, sVolumeName, eVolume )
|
|
{
|
|
if ( !isdefined( eVolume ) )
|
|
{
|
|
eVolume = getent( sVolumeName, "targetname" );
|
|
assertEx( isDefined( eVolume ), sVolumeName + " does not exist" );
|
|
}
|
|
|
|
if ( sTeamName == "all" )
|
|
aTeam = getaiarray();
|
|
else
|
|
aTeam = getaiarray( sTeamName );
|
|
|
|
aGuysTouchingVolume = [];
|
|
for ( i = 0;i < aTeam.size;i++ )
|
|
{
|
|
if ( aTeam[ i ] isTouching( eVolume ) )
|
|
aGuysTouchingVolume[ aGuysTouchingVolume.size ] = aTeam[ i ];
|
|
}
|
|
|
|
return aGuysTouchingVolume;
|
|
}
|
|
|
|
// delete all ai touching a given volume - specify 'all' 'axis' 'allies' or 'neutral'
|
|
npcDelete( sVolumeName, sNPCtype, boolKill, aExclude )
|
|
{
|
|
if ( !isdefined( aExclude ) )
|
|
{
|
|
aExclude = [];
|
|
aExclude[ 0 ] = level.price;
|
|
}
|
|
|
|
volume = getEnt( sVolumeName, "targetname" );
|
|
assertEx( isdefined( volume ), sVolumeName + " volume does not exist" );
|
|
|
|
if ( !isdefined( boolKill ) )
|
|
boolKill = false;
|
|
|
|
ai = undefined;
|
|
if ( sNPCtype == "all" )
|
|
ai = getaiarray();
|
|
else
|
|
ai = getaiarray( sNPCtype );
|
|
|
|
assertEx( isdefined( ai ), "Need to specify 'all' 'axis' 'allies' or 'neutral' for this function" );
|
|
|
|
//If an array was passed of dudes to exclude, remove them from the array
|
|
if ( isdefined( aExclude ) )
|
|
{
|
|
for ( i = 0;i < aExclude.size;i++ )
|
|
{
|
|
if ( is_in_array( ai, aExclude[ i ] ) )
|
|
ai = array_remove( ai, aExclude[ i ] );
|
|
}
|
|
}
|
|
|
|
|
|
for ( i = 0;i < ai.size;i++ )
|
|
{
|
|
if ( ai[ i ] isTouching( volume ) )
|
|
{
|
|
//regardless of what we do, turn off magic bullet shield
|
|
ai[ i ] invulnerable( false );
|
|
//decide weather to kill or delete
|
|
if ( boolKill == true )
|
|
ai[ i ] kill( ( 0, 0, 0 ) );
|
|
else
|
|
ai[ i ] delete();
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// //Delete alll the hostages
|
|
// if ( (sNPCtype == "all") || (sNPCtype == "neutral") )
|
|
// {
|
|
// aHostages = getentarray("actor_civilian", "classname");
|
|
// for(i=0;i<aHostages.size;i++)
|
|
// {
|
|
// if(aHostages[i] isTouching(volume))
|
|
// aHostages[i] delete();
|
|
// }
|
|
// }
|
|
|
|
}
|
|
|
|
getDudeFromArray( aSpawnArray, sScript_Noteworthy )
|
|
{
|
|
dude = undefined;
|
|
//loop through the array and find the guy with that script_noteworthy
|
|
for ( i = 0;i < aSpawnArray.size;i++ )
|
|
{
|
|
if ( isDefined( aSpawnArray[ i ].script_noteworthy ) && aSpawnArray[ i ].script_noteworthy == sScript_Noteworthy )
|
|
dude = aSpawnArray[ i ];
|
|
}
|
|
|
|
assertEX( isdefined( dude ), sScript_Noteworthy + " does not exist in this array" );
|
|
//Return a reference to the guy
|
|
return dude;
|
|
}
|
|
|
|
getDudesFromArray( aSpawnArray, sScript_Noteworthy )
|
|
{
|
|
aDudes = [];
|
|
//loop through the array and find the guy with that script_noteworthy
|
|
|
|
if ( isDefined( sScript_Noteworthy ) )
|
|
{
|
|
for ( i = 0;i < aSpawnArray.size;i++ )
|
|
{
|
|
if ( isDefined( aSpawnArray[ i ].script_noteworthy ) && aSpawnArray[ i ].script_noteworthy == sScript_Noteworthy )
|
|
aDudes[ aDudes.size ] = aSpawnArray[ i ];
|
|
}
|
|
}
|
|
|
|
else
|
|
assertmsg( "You need to pass a script_noteworthy to this function" );
|
|
|
|
if ( aDudes.size > 0 )
|
|
return aDudes;
|
|
else
|
|
return undefined;
|
|
|
|
}
|
|
|
|
goToNode( sNode )
|
|
{
|
|
self endon( "death" );
|
|
|
|
node = getnode( sNode, "targetname" );
|
|
assertEx( isdefined( node ), sNode + "node does not exist" );
|
|
|
|
self setGoalRadius( node.radius );
|
|
self setgoalnode( node );
|
|
|
|
self waittill( "goal" );
|
|
self resetGoalRadius();
|
|
}
|
|
|
|
|
|
|
|
goToNodeAndDelete( sNode )
|
|
{
|
|
if ( !isdefined( self ) )
|
|
return;
|
|
if ( !isalive( self ) )
|
|
return;
|
|
|
|
self endon( "death" );
|
|
|
|
node = getnode( sNode, "targetname" );
|
|
assert( isdefined( node ) );
|
|
|
|
self setgoalnode( node );
|
|
self setGoalRadius( node.radius );
|
|
|
|
self waittill( "goal" );
|
|
|
|
self delete();
|
|
}
|
|
|
|
goToNodeAndWait( sNode )
|
|
{
|
|
if ( !isdefined( self ) )
|
|
return;
|
|
if ( !isalive( self ) )
|
|
return;
|
|
|
|
self endon( "death" );
|
|
|
|
eNode = getnode( sNode, "targetname" );
|
|
assert( isdefined( eNode ) );
|
|
|
|
self setgoalnode( eNode );
|
|
self setGoalRadius( eNode.radius );
|
|
|
|
self waittill( "goal" );
|
|
|
|
self set_animname( "guy" );
|
|
|
|
|
|
self waittill( "stop_waiting_at_node" );
|
|
|
|
self resetGoalRadius();
|
|
|
|
}
|
|
|
|
forceToNode( sNode )
|
|
{
|
|
self endon( "death" );
|
|
|
|
node = getnode( sNode, "targetname" );
|
|
assertEx( isdefined( node ), sNode + "node does not exist" );
|
|
self pushplayer( true );
|
|
|
|
self setgoalnode( node );
|
|
|
|
self waittill( "goal" );
|
|
|
|
self pushplayer( false );
|
|
|
|
self resetGoalRadius();
|
|
|
|
}
|
|
|
|
setPosture( posture )
|
|
{
|
|
if ( posture == "all" )
|
|
self allowedStances( "stand", "crouch", "prone" );
|
|
else
|
|
self allowedStances( posture );
|
|
|
|
}
|
|
|
|
invulnerable( bool )
|
|
{
|
|
if ( bool == false )
|
|
{
|
|
if ( isdefined( self.magic_bullet_shield ) )
|
|
self stop_magic_bullet_shield();
|
|
}
|
|
else
|
|
{
|
|
if ( !isdefined( self.magic_bullet_shield ) )
|
|
self thread magic_bullet_shield();
|
|
}
|
|
|
|
|
|
self.a.disablePain = bool;
|
|
}
|
|
|
|
killEntity()
|
|
{
|
|
self endon( "death" );
|
|
|
|
if ( !isdefined( self ) )
|
|
return;
|
|
if ( !isalive( self ) )
|
|
return;
|
|
|
|
self.allowdeath = true;
|
|
self invulnerable( false );
|
|
self kill();
|
|
}
|
|
|
|
goToVolume( sVolumeName )
|
|
{
|
|
self endon( "death" );
|
|
goalVolume = getEnt( sVolumeName, "targetname" );
|
|
goalNode = getNode( goalVolume.target, "targetname" );
|
|
assertEx( isdefined( goalVolume ), "Need to specify a valid volume name vor this function" );
|
|
assertEx( isdefined( goalNode ), "The volume needs to target a node for this function to work properly" );
|
|
|
|
self setGoalNode( goalNode );
|
|
self setGoalVolume( goalVolume );
|
|
self.goalradius = goalNode.radius;
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
UTILITY FUNCTIONS: SPAWNING
|
|
****************************************************************************/
|
|
AA_spawning_functions()
|
|
{
|
|
//empty
|
|
}
|
|
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
DOOR FUNCTIONS
|
|
****************************************************************************/
|
|
AA_door_functions()
|
|
{
|
|
//empty
|
|
}
|
|
|
|
door_open( sType, bPlaySound, bPlayDefaultFx )
|
|
{
|
|
/*-----------------------
|
|
VARIABLE SETUP
|
|
-------------------------*/
|
|
if ( !isDefined( bPlaySound ) )
|
|
bPlaySound = true;
|
|
if ( !isDefined( bPlayDefaultFx ) )
|
|
bPlayDefaultFx = true;
|
|
if ( bPlaysound == true )
|
|
self playsound( level.scr_sound[ "snd_wood_door_kick" ] );
|
|
|
|
if ( self.classname == "script_brushmodel" )
|
|
{
|
|
eExploder = getent( self.target, "targetname" );
|
|
assertex( isdefined( eExploder ), "A script_brushmodel door needs to target an exploder to play particles when opened. Targetname: " + self.targetname );
|
|
}
|
|
else
|
|
{
|
|
blocker = getent( self.target, "targetname" );
|
|
assertex( isdefined( blocker ), "A script_model door needs to target a script_brushmodel that blocks the door." );
|
|
eExploder = getent( blocker.script_linkto, "script_linkname" );
|
|
assertex( isdefined( eExploder ), "A script_model door blocker needs to script_linkTo an exploder to play particles when opened. Targetname: " + self.targetname );
|
|
}
|
|
/*-----------------------
|
|
OPEN DOOR, CONNECT PATHS, PLAY FX
|
|
-------------------------*/
|
|
switch( sType )
|
|
{
|
|
case "explosive":
|
|
self thread door_fall_over();
|
|
self door_connectpaths( bPlayDefaultFx );
|
|
self playsound( level.scr_sound[ "snd_breach_wooden_door" ] );
|
|
earthquake( 0.4, 1, self.origin, 1000 );
|
|
radiusdamage( self.origin, 56, level.maxDetpackDamage, level.minDetpackDamage );
|
|
break;
|
|
case "kicked": // Rotate away from kick
|
|
self rotateyaw( -175, 0.5 );
|
|
self door_connectpaths( bPlayDefaultFx );
|
|
break;
|
|
case "kicked_down":
|
|
self thread door_fall_over();
|
|
self door_connectpaths( bPlayDefaultFx );
|
|
//if (bPlayDefaultFx)
|
|
//playfx(level._effect["door_kicked_dust01"], eExploder.origin, anglestoforward(eExploder.angles));
|
|
break;
|
|
default:
|
|
self rotateyaw( -175, 0.5 );
|
|
self door_connectpaths();
|
|
break;
|
|
}
|
|
/*-----------------------
|
|
PLAY EXPLODER IN CASE FX ARTISTS WANT TO ADD
|
|
-------------------------*/
|
|
iExploderNum = eExploder.script_exploder;
|
|
assertEx( ( isdefined( iExploderNum ) ), "There is no exploder number in the key 'script_exploder'" );
|
|
exploder( iExploderNum );
|
|
}
|
|
|
|
door_connectpaths( bPlayDefaultFx )
|
|
{
|
|
if ( self.classname == "script_brushmodel" )
|
|
self connectpaths();
|
|
else
|
|
{
|
|
blocker = getent( self.target, "targetname" );
|
|
assertex( isdefined( blocker ), "A script_model door needs to target a script_brushmodel that blocks the door." );
|
|
blocker hide();
|
|
blocker notsolid();
|
|
blocker connectpaths();
|
|
}
|
|
}
|
|
|
|
door_fall_over()
|
|
{
|
|
vector = anglestoforward( self.angles );
|
|
dist = ( vector[ 0 ] * 20, vector[ 1 ] * 20, vector[ 2 ] * 20 );
|
|
|
|
self moveto( self.origin + dist, .5, 0, .5 );
|
|
self rotatepitch( 90, 0.45, 0.40 );
|
|
wait 0.449;
|
|
self rotatepitch( -4, 0.2, 0, 0.2 );
|
|
wait 0.2;
|
|
self rotatepitch( 4, 0.15, 0.15 );
|
|
}
|
|
|
|
debug_circle( center, radius, duration, color, startDelay, fillCenter )
|
|
{
|
|
circle_sides = 16;
|
|
|
|
angleFrac = 360 / circle_sides;
|
|
circlepoints = [];
|
|
for ( i = 0;i < circle_sides;i++ )
|
|
{
|
|
angle = ( angleFrac * i );
|
|
xAdd = cos( angle ) * radius;
|
|
yAdd = sin( angle ) * radius;
|
|
x = center[ 0 ] + xAdd;
|
|
y = center[ 1 ] + yAdd;
|
|
z = center[ 2 ];
|
|
circlepoints[ circlepoints.size ] = ( x, y, z );
|
|
}
|
|
|
|
if ( isdefined( startDelay ) )
|
|
wait startDelay;
|
|
|
|
thread debug_circle_drawlines( circlepoints, duration, color, fillCenter, center );
|
|
}
|
|
|
|
debug_circle_drawlines( circlepoints, duration, color, fillCenter, center )
|
|
{
|
|
if ( !isdefined( fillCenter ) )
|
|
fillCenter = false;
|
|
if ( !isdefined( center ) )
|
|
fillCenter = false;
|
|
|
|
for ( i = 0 ; i < circlepoints.size ; i++ )
|
|
{
|
|
start = circlepoints[ i ];
|
|
if ( i + 1 >= circlepoints.size )
|
|
end = circlepoints[ 0 ];
|
|
else
|
|
end = circlepoints[ i + 1 ];
|
|
|
|
thread debug_line( start, end, duration, color );
|
|
|
|
if ( fillCenter )
|
|
thread debug_line( center, start, duration, color );
|
|
}
|
|
}
|
|
|
|
debug_line( start, end, duration, color )
|
|
{
|
|
if ( !isdefined( color ) )
|
|
color = ( 1, 1, 1 );
|
|
|
|
for ( i = 0; i < ( duration * 20 );i++ )
|
|
{
|
|
line( start, end, color );
|
|
wait 0.05;
|
|
}
|
|
}
|
|
|
|
|