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