#include maps\mp\_utility; #include common_scripts\utility; init() { level.ac130_use_duration = 40; level.ac130_num_flares = 2; makeDvarServerInfo( "ui_ac130usetime", level.ac130_use_duration ); precacheShader( "black" ); precacheString( &"AC130_HUD_THERMAL_WHOT" ); precacheString( &"AC130_HUD_THERMAL_BHOT" ); precacheString( &"AC130_HUD_AGL" ); precacheString( &"MP_CIVILIAN_AIR_TRAFFIC" ); precacheMenu( "ac130timer" ); precacheModel( "vehicle_ac130_coop" ); precacheItem("ac130_25mm_mp"); precacheItem("ac130_40mm_mp"); precacheItem("ac130_105mm_mp"); PrecacheMiniMapIcon( "compass_objpoint_ac130_friendly" ); PrecacheMiniMapIcon( "compass_objpoint_ac130_enemy" ); precacheShellShock("ac130"); angelFlarePrecache(); level._effect[ "cloud" ] = loadfx( "misc/ac130_cloud" ); level._effect[ "beacon" ] = loadfx( "misc/ir_beacon_coop" ); level._effect[ "ac130_explode" ] = loadfx( "explosions/aerial_explosion_ac130_coop" ); level._effect[ "ac130_flare" ] = loadfx( "misc/flares_cobra" ); level._effect[ "ac130_light_red" ] = loadfx( "misc/aircraft_light_wingtip_red" ); level._effect[ "ac130_light_white_blink" ] = loadfx( "misc/aircraft_light_white_blink" ); level._effect[ "ac130_light_red_blink" ] = loadfx( "misc/aircraft_light_red_blink" ); level._effect[ "ac130_engineeffect" ] = loadfx( "fire/jet_engine_ac130" ); // ac130 muzzleflash effects for player on ground to see level._effect[ "coop_muzzleflash_105mm" ] = loadfx( "muzzleflashes/ac130_105mm" ); level._effect[ "coop_muzzleflash_40mm" ] = loadfx( "muzzleflashes/ac130_40mm" ); level.radioForcedTransmissionQueue = []; level.enemiesKilledInTimeWindow = 0; level.lastRadioTransmission = getTime(); level.color[ "white" ] = ( 1, 1, 1 ); level.color[ "red" ] = ( 1, 0, 0 ); level.color[ "blue" ] = ( .1, .3, 1 ); level.cosine = []; level.cosine[ "45" ] = cos( 45 ); level.cosine[ "5" ] = cos( 5 ); level.HUDItem = []; level.physicsSphereRadius[ "ac130_25mm_mp" ] = 60; level.physicsSphereRadius[ "ac130_40mm_mp" ] = 600; level.physicsSphereRadius[ "ac130_105mm_mp" ] = 1000; level.physicsSphereForce[ "ac130_25mm_mp" ] = 0; level.physicsSphereForce[ "ac130_40mm_mp" ] = 3.0; level.physicsSphereForce[ "ac130_105mm_mp" ] = 6.0; level.weaponReloadTime[ "ac130_25mm_mp" ] = 1.5; level.weaponReloadTime[ "ac130_40mm_mp" ] = 3.0; level.weaponReloadTime[ "ac130_105mm_mp" ] = 5.0; level.ac130_Speed[ "move" ] = 250; level.ac130_Speed[ "rotate" ] = 70; //flag_init( "ir_beakons_on" ); flag_init( "allow_context_sensative_dialog" ); flag_set( "allow_context_sensative_dialog" ); minimapOrigins = getEntArray( "minimap_corner", "targetname" ); ac130Origin = (0,0,0); if ( miniMapOrigins.size ) ac130Origin = maps\mp\gametypes\_spawnlogic::findBoxCenter( miniMapOrigins[0].origin, miniMapOrigins[1].origin ); level.ac130 = spawn( "script_model", ac130Origin ); level.ac130 setModel( "c130_zoomrig" ); level.ac130.angles = ( 0, 115, 0 ); level.ac130.owner = undefined; level.ac130 hide(); level.ac130InUse = false; init_sounds(); thread rotatePlane( "on" ); thread ac130_spawn(); thread onPlayerConnect(); thread handleIncomingStinger(); level.killstreakFuncs["ac130"] = ::tryUseAC130; level.ac130Queue = []; } tryUseAC130( lifeId ) { if ( isDefined( level.civilianJetFlyBy ) ) { self iPrintLnBold( &"MP_CIVILIAN_AIR_TRAFFIC" ); return false; } if ( isDefined( level.ac130player ) || level.ac130InUse ) { self iPrintLnBold( &"MP_AIR_SPACE_TOO_CROWDED" ); return false; } if ( self isUsingRemote() ) { return false; } level.ac130InUse = true; self setUsingRemote( "ac130" ); result = self maps\mp\killstreaks\_killstreaks::initRideKillstreak(); if ( result != "success" ) { if ( result != "disconnect" ) self clearUsingRemote(); level.ac130InUse = false; return false; } self maps\mp\_matchdata::logKillstreakEvent( "ac130", self.origin ); self.ac130LifeId = lifeId; level.ac130.planeModel.crashed = undefined; thread setAC130Player( self ); return true; } init_sounds() { setAC130Ambience( "ambient_ac130_int1" ); level.scr_sound["foo"]["bar"] = ""; //------------------------------------------------------------------------------------------------- //CONTEXT SENSATIVE DIALOG //------------------------------------------------------------------------------------------------- add_context_sensative_dialog( "ai", "in_sight", 0, "ac130_fco_moreenemy" ); // More enemy personnel. add_context_sensative_dialog( "ai", "in_sight", 1, "ac130_fco_getthatguy" ); // Get that guy. add_context_sensative_dialog( "ai", "in_sight", 2, "ac130_fco_guymovin" ); // Roger, guy movin'. add_context_sensative_dialog( "ai", "in_sight", 3, "ac130_fco_getperson" ); // Get that person. add_context_sensative_dialog( "ai", "in_sight", 4, "ac130_fco_guyrunnin" ); // Guy runnin'. add_context_sensative_dialog( "ai", "in_sight", 5, "ac130_fco_gotarunner" ); // Uh, we got a runner here. add_context_sensative_dialog( "ai", "in_sight", 6, "ac130_fco_backonthose" ); // Get back on those guys. add_context_sensative_dialog( "ai", "in_sight", 7, "ac130_fco_gonnagethim" ); // You gonna get him? add_context_sensative_dialog( "ai", "in_sight", 8, "ac130_fco_personnelthere" ); // Personnel right there. add_context_sensative_dialog( "ai", "in_sight", 9, "ac130_fco_nailthoseguys" ); // Nail those guys. add_context_sensative_dialog( "ai", "in_sight", 11, "ac130_fco_lightemup" ); // Light ‘em up. add_context_sensative_dialog( "ai", "in_sight", 12, "ac130_fco_takehimout" ); // Yeah take him out. add_context_sensative_dialog( "ai", "in_sight", 14, "ac130_plt_yeahcleared" ); // Yeah, cleared to engage. add_context_sensative_dialog( "ai", "in_sight", 15, "ac130_plt_copysmoke" ); // Copy, smoke ‘em. add_context_sensative_dialog( "ai", "in_sight", 16, "ac130_fco_rightthere" ); // Right there...tracking. add_context_sensative_dialog( "ai", "in_sight", 17, "ac130_fco_tracking" ); // Tracking. add_context_sensative_dialog( "ai", "wounded_crawl", 0, "ac130_fco_movingagain" ); // Ok he’s moving again. add_context_sensative_timeout( "ai", "wounded_crawl", undefined, 6 ); add_context_sensative_dialog( "ai", "wounded_pain", 0, "ac130_fco_doveonground" ); // Yeah, he just dove on the ground. add_context_sensative_dialog( "ai", "wounded_pain", 1, "ac130_fco_knockedwind" ); // Probably just knocked the wind out of him. add_context_sensative_dialog( "ai", "wounded_pain", 2, "ac130_fco_downstillmoving" ); // That guy's down but still moving. add_context_sensative_dialog( "ai", "wounded_pain", 3, "ac130_fco_gettinbackup" ); // He's gettin' back up. add_context_sensative_dialog( "ai", "wounded_pain", 4, "ac130_fco_yepstillmoving" ); // Yep, that guy’s still moving. add_context_sensative_dialog( "ai", "wounded_pain", 5, "ac130_fco_stillmoving" ); // He's still moving. add_context_sensative_timeout( "ai", "wounded_pain", undefined, 12 ); add_context_sensative_dialog( "weapons", "105mm_ready", 0, "ac130_gnr_gunready1" ); add_context_sensative_dialog( "weapons", "105mm_fired", 0, "ac130_gnr_shot1" ); add_context_sensative_dialog( "plane", "rolling_in", 0, "ac130_plt_rollinin" ); add_context_sensative_dialog( "explosion", "secondary", 0, "ac130_nav_secondaries1" ); add_context_sensative_dialog( "explosion", "secondary", 1, "ac130_tvo_directsecondary1" ); add_context_sensative_dialog( "explosion", "secondary", 1, "ac130_tvo_directsecondary2" ); add_context_sensative_timeout( "explosion", "secondary", undefined, 7 ); add_context_sensative_dialog( "kill", "single", 0, "ac130_plt_gottahurt" ); // Ooo that's gotta hurt. add_context_sensative_dialog( "kill", "single", 1, "ac130_fco_iseepieces" ); // Yeah, good kill. I see lots of little pieces down there. add_context_sensative_dialog( "kill", "single", 2, "ac130_fco_oopsiedaisy" ); // (chuckling) Oopsie-daisy. add_context_sensative_dialog( "kill", "single", 3, "ac130_fco_goodkill" ); // Good kill good kill. add_context_sensative_dialog( "kill", "single", 4, "ac130_fco_yougothim" ); // You got him. add_context_sensative_dialog( "kill", "single", 5, "ac130_fco_yougothim2" ); // You got him! add_context_sensative_dialog( "kill", "single", 6, "ac130_fco_thatsahit" ); // That's a hit. add_context_sensative_dialog( "kill", "single", 7, "ac130_fco_directhit" ); // Direct hit. add_context_sensative_dialog( "kill", "single", 8, "ac130_fco_rightontarget" ); // Yep, that was right on target. add_context_sensative_dialog( "kill", "single", 9, "ac130_fco_okyougothim" ); // Ok, you got him. Get back on the other guys. add_context_sensative_dialog( "kill", "single", 10, "ac130_fco_within2feet" ); // All right you got the guy. That might have been within two feet of him. add_context_sensative_dialog( "kill", "small_group", 0, "ac130_fco_nice" ); // (chuckling) Niiiice. add_context_sensative_dialog( "kill", "small_group", 1, "ac130_fco_directhits" ); // Yeah, direct hits right there. add_context_sensative_dialog( "kill", "small_group", 2, "ac130_fco_iseepieces" ); // Yeah, good kill. I see lots of little pieces down there. add_context_sensative_dialog( "kill", "small_group", 3, "ac130_fco_goodkill" ); // Good kill good kill. add_context_sensative_dialog( "kill", "small_group", 4, "ac130_fco_yougothim" ); // You got him. add_context_sensative_dialog( "kill", "small_group", 5, "ac130_fco_yougothim2" ); // You got him! add_context_sensative_dialog( "kill", "small_group", 6, "ac130_fco_thatsahit" ); // That's a hit. add_context_sensative_dialog( "kill", "small_group", 7, "ac130_fco_directhit" ); // Direct hit. add_context_sensative_dialog( "kill", "small_group", 8, "ac130_fco_rightontarget" );// Yep, that was right on target. add_context_sensative_dialog( "kill", "small_group", 9, "ac130_fco_okyougothim" ); // Ok, you got him. Get back on the other guys. add_context_sensative_dialog( "misc", "action", 0, "ac130_plt_scanrange" ); // Set scan range. add_context_sensative_timeout( "misc", "action", 0, 70 ); add_context_sensative_dialog( "misc", "action", 1, "ac130_plt_cleanup" ); // Clean up that signal. add_context_sensative_timeout( "misc", "action", 1, 80 ); add_context_sensative_dialog( "misc", "action", 2, "ac130_plt_targetreset" ); // Target reset. add_context_sensative_timeout( "misc", "action", 2, 55 ); add_context_sensative_dialog( "misc", "action", 3, "ac130_plt_azimuthsweep" ); // Recalibrate azimuth sweep angle. Adjust elevation scan. add_context_sensative_timeout( "misc", "action", 3, 100 ); } add_context_sensative_dialog( name1, name2, group, soundAlias ) { assert( isdefined( name1 ) ); assert( isdefined( name2 ) ); assert( isdefined( group ) ); assert( isdefined( soundAlias ) ); fullSoundAlias = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + soundAlias; assertex( soundexists( fullSoundAlias ), "ERROR: missing soundalias " + fullSoundAlias ); fullSoundAlias = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + soundAlias; assertex( soundexists( fullSoundAlias ), "ERROR: missing soundalias " + fullSoundAlias ); if( ( !isdefined( level.scr_sound[ name1 ] ) ) || ( !isdefined( level.scr_sound[ name1 ][ name2 ] ) ) || ( !isdefined( level.scr_sound[ name1 ][ name2 ][group] ) ) ) { // creating group for the first time level.scr_sound[ name1 ][ name2 ][group] = spawnStruct(); level.scr_sound[ name1 ][ name2 ][group].played = false; level.scr_sound[ name1 ][ name2 ][group].sounds = []; } //group exists, add the sound to the array index = level.scr_sound[ name1 ][ name2 ][group].sounds.size; level.scr_sound[ name1 ][ name2 ][group].sounds[index] = soundAlias; } add_context_sensative_timeout( name1, name2, groupNum, timeoutDuration ) { if( !isdefined( level.context_sensative_dialog_timeouts ) ) level.context_sensative_dialog_timeouts = []; createStruct = false; if ( !isdefined( level.context_sensative_dialog_timeouts[ name1 ] ) ) createStruct = true; else if ( !isdefined( level.context_sensative_dialog_timeouts[ name1 ][ name2 ] ) ) createStruct = true; if ( createStruct ) level.context_sensative_dialog_timeouts[ name1 ][ name2 ] = spawnStruct(); if ( isdefined( groupNum ) ) { level.context_sensative_dialog_timeouts[ name1 ][ name2 ].groups = []; level.context_sensative_dialog_timeouts[ name1 ][ name2 ].groups[ string( groupNum ) ] = spawnStruct(); level.context_sensative_dialog_timeouts[ name1 ][ name2 ].groups[ string( groupNum ) ].v["timeoutDuration"] = timeoutDuration * 1000; level.context_sensative_dialog_timeouts[ name1 ][ name2 ].groups[ string( groupNum ) ].v["lastPlayed"] = ( timeoutDuration * -1000 ); } else { level.context_sensative_dialog_timeouts[ name1 ][ name2 ].v["timeoutDuration"] = timeoutDuration * 1000; level.context_sensative_dialog_timeouts[ name1 ][ name2 ].v["lastPlayed"] = ( timeoutDuration * -1000 ); } } /* ============= ///ScriptDocBegin "Name: play_sound_on_entity( )" "Summary: Play the specified sound alias on an entity at it's origin" "Module: Sound" "CallOn: An entity" "MandatoryArg: : Sound alias to play" "Example: level.player play_sound_on_entity( "breathing_better" );" "SPMP: singleplayer" ///ScriptDocEnd ============= */ play_sound_on_entity( alias ) { play_sound_on_tag( alias ); } within_fov( start_origin, start_angles, end_origin, fov ) { normal = vectorNormalize( end_origin - start_origin ); forward = anglestoforward( start_angles ); dot = vectorDot( forward, normal ); return dot >= fov; } /* ============= ///ScriptDocBegin "Name: array_remove_nokeys( , )" "Summary: array_remove used on non keyed arrays doesn't flip the array " "Module: Utility" "CallOn: Level" "MandatoryArg: : array to remove from" "MandatoryArg: : thing to remove from the array" "Example: " "SPMP: singleplayer" ///ScriptDocEnd ============= */ array_remove_nokeys( ents, remover ) { newents = []; for ( i = 0; i < ents.size; i++ ) if ( ents[ i ] != remover ) newents[ newents.size ] = ents[ i ]; return newents; } array_remove_index( array, index ) { newArray = []; keys = getArrayKeys( array ); for ( i = ( keys.size - 1 );i >= 0 ; i -- ) { if ( keys[ i ] != index ) newArray[ newArray.size ] = array[ keys[ i ] ]; } return newArray; } string( num ) { return( "" + num ); } onPlayerConnect() { for(;;) { level waittill( "connected", player ); player thread onPlayerSpawned(); } } onPlayerSpawned() { self endon("disconnect"); for(;;) { self waittill("spawned_player"); } } deleteOnAC130PlayerRemoved() { level waittill ( "ac130player_removed" ); self delete(); } setAC130Player( player ) { self endon ( "ac130player_removed" ); assert( !isDefined( level.ac130player ) ); level.ac130player = player; level.ac130.owner = player; level.ac130.planeModel show(); level.ac130.planemodel thread playAC130Effects(); level.ac130.incomingMissile = false; level.ac130.planeModel playLoopSound( "veh_ac130_ext_dist" ); level.ac130.planeModel.maxhealth = 1000; level.ac130.planeModel.health = level.ac130.planeModel.maxhealth; objModel = spawnPlane( player, "script_model", level.ac130.planeModel.origin, "compass_objpoint_ac130_friendly", "compass_objpoint_ac130_enemy" ); objModel notSolid(); objModel linkTo( level.ac130, "tag_player", ( 0, 80, 32 ), ( 0, -90, 0 ) ); objModel thread deleteOnAC130PlayerRemoved(); player startAC130(); player openMenu( "ac130timer" ); level.ac130.numFlares = level.ac130_num_flares; /* result = player maps\mp\killstreaks\_killstreaks::initRideKillstreak(); if ( result != "success" ) { if ( result != "disconnect" ) { if ( result == "fail" ) player maps\mp\killstreaks\_killstreaks::giveKillstreak( "ac130", player.ac130LifeId == player.pers["deaths"], false ); level thread removeAC130Player( player, result == "disconnect" ); } return; } */ thread teamPlayerCardSplash( "used_ac130", player ); player VisionSetThermalForPlayer( "black_bw", 0 ); player ThermalVisionOn(); player ThermalVisionFOFOverlayOn(); if ( getDvarInt( "camera_thirdPerson" ) ) player setThirdPersonDOF( false ); player _giveWeapon("ac130_105mm_mp"); player _giveWeapon("ac130_40mm_mp"); player _giveWeapon("ac130_25mm_mp"); player SwitchToWeapon("ac130_105mm_mp"); player thread overlay( player ); player thread attachPlayer( player ); player thread changeWeapons(); player thread weaponFiredThread(); player thread thermalVision(); player thread context_Sensative_Dialog(); player thread shotFired(); player thread clouds(); //thread maps\_ac130_amb::main(); player thread removeAC130PlayerAfterTime( level.ac130_use_duration * player.killStreakScaler); player thread removeAC130PlayerOnDisconnect(); player thread removeAC130PlayerOnChangeTeams(); player thread removeAC130PlayerOnSpectate(); //player thread removeAC130PlayerOnDeath(); player thread removeAC130PlayerOnCrash(); //player thread removeAC130PlayerOnGameEnd(); player thread removeAC130PlayerOnGameCleanup(); thread AC130_AltScene(); } playAC130Effects() { wait .05; PlayFXOnTag( level._effect[ "ac130_light_red_blink" ] , self, "tag_light_belly" ); PlayFXOnTag( level._effect[ "ac130_engineeffect" ] , self, "tag_body" ); wait .5; PlayFXOnTag( level._effect[ "ac130_light_white_blink" ] , self, "tag_light_tail" ); PlayFXOnTag( level._effect[ "ac130_light_red" ] , self, "tag_light_top" ); } AC130_AltScene() { // need team check foreach ( player in level.players ) { if ( player != level.ac130player && player.team == level.ac130player.team ) player thread setAltSceneObj( level.ac130.cameraModel, "tag_origin", 20 ); } } removeAC130PlayerOnGameEnd() { self endon ( "ac130player_removed" ); level waittill ( "game_ended" ); level thread removeAC130Player( self, false ); } removeAC130PlayerOnGameCleanup() { self endon ( "ac130player_removed" ); level waittill ( "game_cleanup" ); level thread removeAC130Player( self, false ); } removeAC130PlayerOnDeath() { self endon ( "ac130player_removed" ); self waittill ( "death" ); level thread removeAC130Player( self, false ); } removeAC130PlayerOnCrash() { self endon ( "ac130player_removed" ); level.ac130.planeModel waittill ( "crashing" ); level thread removeAC130Player( self, false ); } removeAC130PlayerOnDisconnect() { self endon ( "ac130player_removed" ); self waittill ( "disconnect" ); level thread removeAC130Player( self, true ); } removeAC130PlayerOnChangeTeams() { self endon ( "ac130player_removed" ); self waittill ( "joined_team" ); level thread removeAC130Player( self, false); } removeAC130PlayerOnSpectate() { self endon ( "ac130player_removed" ); self waittill_any ( "joined_spectators", "spawned" ); level thread removeAC130Player( self, false); } removeAC130PlayerAfterTime( removeDelay ) { self endon ( "ac130player_removed" ); maps\mp\gametypes\_hostmigration::waitLongDurationWithHostMigrationPause( removeDelay ); level thread removeAC130Player( self, false ); } removeAC130Player( player, disconnected ) { player notify ( "ac130player_removed" ); level notify ( "ac130player_removed" ); level.ac130.cameraModel notify ( "death" ); waittillframeend; if ( !disconnected ) { player clearUsingRemote(); player stopLocalSound( "missile_incoming" ); player show(); player unlink(); player ThermalVisionOff(); player ThermalVisionFOFOverlayOff(); player visionSetThermalForPlayer( game["thermal_vision"], 0 ); player setBlurForPlayer( 0, 0 ); player stopAC130(); if ( getDvarInt( "camera_thirdPerson" ) ) player setThirdPersonDOF( true ); weaponList = player GetWeaponsListExclusives(); foreach ( weapon in weaponList ) player takeWeapon( weapon ); if ( isDefined( player.darkScreenOverlay ) ) player.darkScreenOverlay destroy(); keys = getArrayKeys( level.HUDItem ); foreach ( key in keys ) { level.HUDItem[key] destroy(); level.HUDItem[key] = undefined; } } // delay before AC130 can be used again wait ( 0.5 ); level.ac130.planeModel playSound( "veh_ac130_ext_dist_fade" ); wait ( 0.5 ); // TODO: this might already be undefined if the player disconnected... need a better solution. // we could set it to "true" or something... but we'll have to check places it is used for potential issues with that. level.ac130player = undefined; level.ac130.planeModel hide(); level.ac130.planeModel stopLoopSound(); if ( isDefined( level.ac130.planeModel.crashed ) ) { level.ac130InUse = false; return; } ac130model = spawn( "script_model", level.ac130.planeModel getTagOrigin( "tag_origin" ) ); ac130model.angles = level.ac130.planeModel.angles; ac130model setModel( "vehicle_ac130_coop" ); destPoint = ac130model.origin + vector_multiply( anglestoright( ac130model.angles ), 20000 ); ac130model thread playAC130Effects(); ac130model moveTo( destPoint, 40.0, 0.0, 0.0 ); ac130model thread deployFlares( true ); wait ( 5.0 ); ac130model thread deployFlares( true ); wait ( 5.0 ); ac130model thread deployFlares( true ); level.ac130InUse = false; wait ( 30.0 ); ac130model delete(); } damageTracker() { for ( ;; ) { self waittill ( "damage", damage, attacker, dir, point, type ); if ( isDefined( level.ac130player ) && level.teambased && isPlayer( attacker ) && attacker.team == level.ac130player.team && !isDefined( level.nukeDetonated ) ) { self.health += damage; continue; } if ( type == "MOD_RIFLE_BULLET" || type == "MOD_PISTOL_BULLET" || type == "MOD_EXPLOSIVE_BULLET" ) { self.health += damage; continue; } if ( isPlayer( attacker ) ) { attacker maps\mp\gametypes\_damagefeedback::updateDamageFeedback( "" ); if ( attacker _hasPerk( "specialty_armorpiercing" ) ) { damageAdd = damage*level.armorPiercingMod; self.health -= int(damageAdd); } } if ( self.health <= 0 ) { if ( isPlayer( attacker ) ) { thread maps\mp\gametypes\_missions::vehicleKilled( level.ac130player, self, undefined, attacker, damage, type ); thread teamPlayerCardSplash( "callout_destroyed_ac130", attacker ); attacker thread maps\mp\gametypes\_rank::giveRankXP( "kill", 400 ); attacker notify( "destroyed_killstreak" ); } level thread crashPlane( 10.0 ); } } } ac130_spawn() { wait 0.05; ac130model = spawn( "script_model", level.ac130 getTagOrigin( "tag_player" ) ); ac130model setModel( "vehicle_ac130_coop" ); ac130model setCanDamage( true ); ac130model.maxhealth = 1000; ac130model.health = ac130model.maxhealth; ac130model thread damageTracker(); //ac130model linkTo( level.ac130, "tag_player", ( 0, 0, 32 ), ( -25, 0, 0 ) ); ac130model linkTo( level.ac130, "tag_player", ( 0, 80, 32 ), ( -25, 0, 0 ) ); level.ac130.planeModel = ac130model; level.ac130.planeModel hide(); ac130CameraModel = spawn( "script_model", level.ac130 getTagOrigin( "tag_player" ) ); ac130CameraModel setModel( "tag_origin" ); ac130CameraModel hide(); ac130CameraModel linkTo( level.ac130, "tag_player", ( 0, 0, 32 ), ( -25, 0, 0 ) ); level.ac130.cameraModel = ac130CameraModel; level.ac130player = level.players[0]; } overlay( player ) { level.HUDItem = []; thermalEnabled = getIntProperty( "ac130_hud_text_thermal", 0 ); if ( thermalEnabled ) { level.HUDItem[ "thermal_mode" ] = newClientHudElem( player ); level.HUDItem[ "thermal_mode" ].x = -80; level.HUDItem[ "thermal_mode" ].y = 50; level.HUDItem[ "thermal_mode" ].alignX = "right"; level.HUDItem[ "thermal_mode" ].alignY = "top"; level.HUDItem[ "thermal_mode" ].horzAlign = "right"; level.HUDItem[ "thermal_mode" ].vertAlign = "top"; level.HUDItem[ "thermal_mode" ].fontScale = 2.5; level.HUDItem[ "thermal_mode" ] settext ( &"AC130_HUD_THERMAL_WHOT" ); level.HUDItem[ "thermal_mode" ].alpha = 1.0; } if( !level.splitscreen ) player thread overlay_coords(); if ( thermalEnabled ) { player setBlurForPlayer( 1.2, 0 ); } } hud_timer( duration ) { self endon ( "ac130player_removed" ); level.HUDItem[ "timer" ] = newClientHudElem( self ); level.HUDItem[ "timer" ].x = -100; level.HUDItem[ "timer" ].y = 0; level.HUDItem[ "timer" ].alignX = "right"; level.HUDItem[ "timer" ].alignY = "bottom"; level.HUDItem[ "timer" ].horzAlign = "right_adjustable"; level.HUDItem[ "timer" ].vertAlign = "bottom_adjustable"; level.HUDItem[ "timer" ].fontScale = 2.5; level.HUDItem[ "timer" ] setTimer( 1.0 ); level.HUDItem[ "timer" ].alpha = 1.0; level.HUDItem[ "timer" ] setTimer( duration ); } overlay_coords() { self endon ( "ac130player_removed" ); level.HUDItem[ "coordinate_long" ] = newClientHudElem( self ); level.HUDItem[ "coordinate_long" ].x = -100; level.HUDItem[ "coordinate_long" ].y = 0; level.HUDItem[ "coordinate_long" ].alignX = "right"; level.HUDItem[ "coordinate_long" ].alignY = "top"; level.HUDItem[ "coordinate_long" ].horzAlign = "right"; level.HUDItem[ "coordinate_long" ].vertAlign = "top"; level.HUDItem[ "coordinate_long" ].fontScale = 2.5; level.HUDItem[ "coordinate_long" ].alpha = 1.0; level.HUDItem[ "coordinate_lat" ] = newClientHudElem( self ); level.HUDItem[ "coordinate_lat" ].x = 0; level.HUDItem[ "coordinate_lat" ].y = 0; level.HUDItem[ "coordinate_lat" ].alignX = "right"; level.HUDItem[ "coordinate_lat" ].alignY = "top"; level.HUDItem[ "coordinate_lat" ].horzAlign = "right"; level.HUDItem[ "coordinate_lat" ].vertAlign = "top"; level.HUDItem[ "coordinate_lat" ].fontScale = 2.5; level.HUDItem[ "coordinate_lat" ].alpha = 1.0; level.HUDItem[ "coordinate_agl" ] = newClientHudElem( self ); level.HUDItem[ "coordinate_agl" ].x = 0; level.HUDItem[ "coordinate_agl" ].y = 20; level.HUDItem[ "coordinate_agl" ].alignX = "right"; level.HUDItem[ "coordinate_agl" ].alignY = "top"; level.HUDItem[ "coordinate_agl" ].horzAlign = "right"; level.HUDItem[ "coordinate_agl" ].vertAlign = "top"; level.HUDItem[ "coordinate_agl" ].fontScale = 2.5; level.HUDItem[ "coordinate_agl" ].label = ( &"AC130_HUD_AGL" ); level.HUDItem[ "coordinate_agl" ].alpha = 1.0; wait 0.05; for(;;) { level.HUDItem[ "coordinate_long" ] setValue( abs( int( self.origin[0] ) ) ); level.HUDItem[ "coordinate_lat" ] setValue( abs( int( self.origin[1] ) ) ); pos = physicstrace( self.origin, self.origin - ( 0, 0, 100000 ) ); if( ( isdefined( pos ) ) && ( isdefined( pos[2] ) ) ) { alt = ( ( self.origin[2] - pos[2] ) * 1.5 ); level.HUDItem[ "coordinate_agl" ] setValue( abs( int( alt ) ) ); } wait ( 0.75 + randomfloat( 2 ) ); } } ac130ShellShock() { self endon ( "ac130player_removed" ); level endon( "post_effects_disabled" ); duration = 5; for (;;) { self shellshock( "ac130", duration ); wait duration; } } rotatePlane( toggle ) { level notify("stop_rotatePlane_thread"); level endon("stop_rotatePlane_thread"); if (toggle == "on") { rampupDegrees = 10; rotateTime = ( level.ac130_Speed[ "rotate" ] / 360 ) * rampupDegrees; level.ac130 rotateyaw( level.ac130.angles[ 2 ] + rampupDegrees, rotateTime, rotateTime, 0 ); for (;;) { level.ac130 rotateyaw( 360, level.ac130_Speed[ "rotate" ] ); wait level.ac130_Speed[ "rotate" ]; } } else if (toggle == "off") { slowdownDegrees = 10; rotateTime = ( level.ac130_Speed[ "rotate" ] / 360 ) * slowdownDegrees; level.ac130 rotateyaw( level.ac130.angles[ 2 ] + slowdownDegrees, rotateTime, 0, rotateTime ); } } attachPlayer( player ) { self PlayerLinkWeaponviewToDelta( level.ac130, "tag_player", 1.0, 35, 35, 35, 35 ); self setPlayerAngles( level.ac130 getTagAngles( "tag_player" ) ); } changeWeapons() { self endon ( "ac130player_removed" ); wait( 0.05 ); self EnableWeapons(); for(;;) { self waittill ( "change_weapon", newWeapon ); self thread play_sound_on_entity( "ac130_weapon_switch" ); } } weaponFiredThread() { self endon ( "ac130player_removed" ); for(;;) { self waittill( "weapon_fired" ); weapon = self getCurrentWeapon(); if ( weapon == "ac130_105mm_mp" ) { self thread gun_fired_and_ready_105mm(); earthquake (0.2, 1, level.ac130.planeModel.origin, 1000); } else if ( weapon == "ac130_40mm_mp" ) { earthquake (0.1, 0.5, level.ac130.planeModel.origin, 1000); } if ( self getWeaponAmmoClip( weapon ) ) continue; self thread weaponReload( weapon ); } } weaponReload( weapon ) { self endon ( "ac130player_removed" ); wait level.weaponReloadTime[ weapon ]; self setWeaponAmmoClip( weapon, 9999 ); // force the reload to stop if we're currently using the weapon if ( self getCurrentWeapon() == weapon ) { self takeWeapon( weapon ); self _giveWeapon( weapon ); self switchToWeapon( weapon ); } } thermalVision() { self endon ( "ac130player_removed" ); if ( getIntProperty( "ac130_thermal_enabled", 1 ) == 0 ) return; inverted = false; self visionSetThermalForPlayer( game["thermal_vision"], 1 ); self notifyOnPlayerCommand( "switch thermal", "+activate" ); for (;;) { self waittill ( "switch thermal" ); if ( !inverted ) { self visionSetThermalForPlayer( "missilecam", 0.62 ); if ( isdefined( level.HUDItem[ "thermal_mode" ] ) ) level.HUDItem[ "thermal_mode" ] settext ( &"AC130_HUD_THERMAL_BHOT" ); } else { self visionSetThermalForPlayer( game["thermal_vision"], 0.51 ); if ( isdefined( level.HUDItem[ "thermal_mode" ] ) ) level.HUDItem[ "thermal_mode" ] settext ( &"AC130_HUD_THERMAL_WHOT" ); } inverted = !inverted; } } clouds() { self endon ( "ac130player_removed" ); wait 6; clouds_create(); for(;;) { wait( randomfloatrange( 40, 80 ) ); clouds_create(); } } clouds_create() { if ( ( isdefined( level.playerWeapon ) ) && ( issubstr( tolower( level.playerWeapon ), "25" ) ) ) return; playfxontagforclients( level._effect[ "cloud" ], level.ac130, "tag_player", level.ac130player ); } gun_fired_and_ready_105mm() { self endon ( "ac130player_removed" ); level notify( "gun_fired_and_ready_105mm" ); level endon( "gun_fired_and_ready_105mm" ); wait 0.5; if ( randomint( 2 ) == 0 ) thread context_Sensative_Dialog_Play_Random_Group_Sound( "weapons", "105mm_fired" ); wait 5.0; thread context_Sensative_Dialog_Play_Random_Group_Sound( "weapons", "105mm_ready" ); } shotFired() { self endon ( "ac130player_removed" ); for (;;) { self waittill( "projectile_impact", weaponName, position, radius ); if ( issubstr( tolower( weaponName ), "105" ) ) { earthquake( 0.4, 1.0, position, 3500 ); self thread shotFiredDarkScreenOverlay(); } else if ( issubstr( tolower( weaponName ), "40" ) ) { earthquake( 0.2, 0.5, position, 2000 ); } if ( getIntProperty( "ac130_ragdoll_deaths", 0 ) ) thread shotFiredPhysicsSphere( position, weaponName ); wait 0.05; } } shotFiredPhysicsSphere( center, weapon ) { wait 0.1; physicsExplosionSphere( center, level.physicsSphereRadius[ weapon ], level.physicsSphereRadius[ weapon ] / 2, level.physicsSphereForce[ weapon ] ); } shotFiredDarkScreenOverlay() { self endon( "ac130player_removed" ); self notify( "darkScreenOverlay" ); self endon( "darkScreenOverlay" ); if ( !isdefined( self.darkScreenOverlay ) ) { self.darkScreenOverlay = newClientHudElem( self ); self.darkScreenOverlay.x = 0; self.darkScreenOverlay.y = 0; self.darkScreenOverlay.alignX = "left"; self.darkScreenOverlay.alignY = "top"; self.darkScreenOverlay.horzAlign = "fullscreen"; self.darkScreenOverlay.vertAlign = "fullscreen"; self.darkScreenOverlay setshader ( "black", 640, 480 ); self.darkScreenOverlay.sort = -10; self.darkScreenOverlay.alpha = 0.0; } self.darkScreenOverlay.alpha = 0.0; self.darkScreenOverlay fadeOverTime( 0.2 ); self.darkScreenOverlay.alpha = 0.6; wait 0.4; self.darkScreenOverlay fadeOverTime( 0.8 ); self.darkScreenOverlay.alpha = 0.0; } add_beacon_effect() { self endon( "death" ); flashDelay = 0.75; wait randomfloat(3.0); for (;;) { if ( level.ac130player ) playfxontagforclients( level._effect[ "beacon" ], self, "j_spine4", level.ac130player ); wait flashDelay; } } context_Sensative_Dialog() { thread enemy_killed_thread(); thread context_Sensative_Dialog_Guy_In_Sight(); thread context_Sensative_Dialog_Guy_Crawling(); thread context_Sensative_Dialog_Guy_Pain(); thread context_Sensative_Dialog_Secondary_Explosion_Vehicle(); thread context_Sensative_Dialog_Kill_Thread(); thread context_Sensative_Dialog_Locations(); thread context_Sensative_Dialog_Filler(); } context_Sensative_Dialog_Guy_In_Sight() { self endon ( "ac130player_removed" ); for (;;) { if ( context_Sensative_Dialog_Guy_In_Sight_Check() ) thread context_Sensative_Dialog_Play_Random_Group_Sound( "ai", "in_sight" ); wait randomfloatrange( 1, 3 ); } } context_Sensative_Dialog_Guy_In_Sight_Check() { prof_begin( "AI_in_sight_check" ); //enemies = getaiarray( "axis" ); //replace with level of enemy team members? enemies = []; for( i = 0 ; i < enemies.size ; i++ ) { if ( !isdefined( enemies[ i ] ) ) continue; if ( !isalive( enemies[ i ] ) ) continue; if ( within_fov( level.ac130player getEye(), level.ac130player getPlayerAngles(), enemies[ i ].origin, level.cosine[ "5" ] ) ) { prof_end( "AI_in_sight_check" ); return true; } wait 0.05; } prof_end( "AI_in_sight_check" ); return false; } context_Sensative_Dialog_Guy_Crawling() { self endon ( "ac130player_removed" ); for (;;) { level waittill ( "ai_crawling", guy ); /# if ( ( isdefined( guy ) ) && ( isdefined( guy.origin ) ) ) { if ( getdvar( "ac130_debug_context_sensative_dialog", 0 ) == "1" ) thread debug_line(level.ac130player.origin, guy.origin, 5.0, ( 0, 1, 0 ) ); } #/ thread context_Sensative_Dialog_Play_Random_Group_Sound( "ai", "wounded_crawl" ); } } context_Sensative_Dialog_Guy_Pain() { self endon ( "ac130player_removed" ); for (;;) { level waittill ( "ai_pain", guy ); /# if ( ( isdefined( guy ) ) && ( isdefined( guy.origin ) ) ) { if ( getdvar( "ac130_debug_context_sensative_dialog" ) == "1" ) thread debug_line( level.ac130player.origin, guy.origin, 5.0, ( 1, 0, 0 ) ); } #/ thread context_Sensative_Dialog_Play_Random_Group_Sound( "ai", "wounded_pain" ); } } context_Sensative_Dialog_Secondary_Explosion_Vehicle() { self endon ( "ac130player_removed" ); for (;;) { level waittill ( "player_destroyed_car", player, vehicle_origin ); wait 1; /# if ( isdefined( vehicle_origin ) ) { if ( getdvar( "ac130_debug_context_sensative_dialog" ) == "1" ) thread debug_line( level.ac130player.origin, vehicle_origin, 5.0, ( 0, 0, 1 ) ); } #/ thread context_Sensative_Dialog_Play_Random_Group_Sound( "explosion", "secondary" ); } } enemy_killed_thread() { self endon ( "ac130player_removed" ); for ( ;; ) { level waittill ( "ai_killed", guy ); // context kill dialog thread context_Sensative_Dialog_Kill( guy, level.ac130player ); } } context_Sensative_Dialog_Kill( guy, attacker ) { if ( !isdefined( attacker ) ) return; if ( !isplayer( attacker ) ) return; level.enemiesKilledInTimeWindow++; level notify ( "enemy_killed" ); /# if ( ( isdefined( guy ) ) && ( isdefined( guy.origin ) ) ) { if ( getdvar( "ac130_debug_context_sensative_dialog" ) == "1" ) thread debug_line( level.ac130player.origin, guy.origin, 5.0, ( 1, 1, 0 ) ); } #/ } context_Sensative_Dialog_Kill_Thread() { self endon ( "ac130player_removed" ); timeWindow = 1; for (;;) { level waittill ( "enemy_killed" ); wait timeWindow; println ( "guys killed in time window: " ); println ( level.enemiesKilledInTimeWindow ); soundAlias1 = "kill"; soundAlias2 = undefined; if ( level.enemiesKilledInTimeWindow >= 2 ) soundAlias2 = "small_group"; else { soundAlias2 = "single"; if ( randomint( 3 ) != 1 ) { level.enemiesKilledInTimeWindow = 0; continue; } } level.enemiesKilledInTimeWindow = 0; assert( isdefined( soundAlias2 ) ); thread context_Sensative_Dialog_Play_Random_Group_Sound( soundAlias1, soundAlias2, true ); } } context_Sensative_Dialog_Locations() { array_thread( getentarray( "context_dialog_car", "targetname" ), ::context_Sensative_Dialog_Locations_Add_Notify_Event, "car" ); array_thread( getentarray( "context_dialog_truck", "targetname" ), ::context_Sensative_Dialog_Locations_Add_Notify_Event, "truck" ); array_thread( getentarray( "context_dialog_building", "targetname" ), ::context_Sensative_Dialog_Locations_Add_Notify_Event, "building" ); array_thread( getentarray( "context_dialog_wall", "targetname" ), ::context_Sensative_Dialog_Locations_Add_Notify_Event, "wall" ); array_thread( getentarray( "context_dialog_field", "targetname" ), ::context_Sensative_Dialog_Locations_Add_Notify_Event, "field" ); array_thread( getentarray( "context_dialog_road", "targetname" ), ::context_Sensative_Dialog_Locations_Add_Notify_Event, "road" ); array_thread( getentarray( "context_dialog_church", "targetname" ), ::context_Sensative_Dialog_Locations_Add_Notify_Event, "church" ); array_thread( getentarray( "context_dialog_ditch", "targetname" ), ::context_Sensative_Dialog_Locations_Add_Notify_Event, "ditch" ); thread context_Sensative_Dialog_Locations_Thread(); } context_Sensative_Dialog_Locations_Thread() { self endon ( "ac130player_removed" ); for (;;) { level waittill ( "context_location", locationType ); if ( !isdefined( locationType ) ) { assertMsg( "LocationType " + locationType + " is not valid" ); continue; } if ( !flag( "allow_context_sensative_dialog" ) ) continue; thread context_Sensative_Dialog_Play_Random_Group_Sound( "location", locationType ); wait ( 5 + randomfloat( 10 ) ); } } context_Sensative_Dialog_Locations_Add_Notify_Event( locationType ) { self endon ( "ac130player_removed" ); for (;;) { self waittill ( "trigger", triggerer ); if ( !isdefined( triggerer ) ) continue; if ( ( !isdefined( triggerer.team) ) || ( triggerer.team != "axis" ) ) continue; level notify ( "context_location", locationType ); wait 5; } } context_Sensative_Dialog_VehicleSpawn( vehicle ) { if ( vehicle.script_team != "axis" ) return; thread context_Sensative_Dialog_VehicleDeath( vehicle ); vehicle endon( "death" ); while( !within_fov( level.ac130player getEye(), level.ac130player getPlayerAngles(), vehicle.origin, level.cosine[ "45" ] ) ) wait 0.5; context_Sensative_Dialog_Play_Random_Group_Sound( "vehicle", "incoming" ); } context_Sensative_Dialog_VehicleDeath( vehicle ) { vehicle waittill( "death" ); thread context_Sensative_Dialog_Play_Random_Group_Sound( "vehicle", "death" ); } context_Sensative_Dialog_Filler() { self endon ( "ac130player_removed" ); for(;;) { if( ( isdefined( level.radio_in_use ) ) && ( level.radio_in_use == true ) ) level waittill ( "radio_not_in_use" ); // if 3 seconds has passed and nothing has been transmitted then play a sound currentTime = getTime(); if ( ( currentTime - level.lastRadioTransmission ) >= 3000 ) { level.lastRadioTransmission = currentTime; thread context_Sensative_Dialog_Play_Random_Group_Sound( "misc", "action" ); } wait 0.25; } } context_Sensative_Dialog_Play_Random_Group_Sound( name1, name2, force_transmit_on_turn ) { level endon ( "ac130player_removed" ); assert( isdefined( level.scr_sound[ name1 ] ) ); assert( isdefined( level.scr_sound[ name1 ][ name2 ] ) ); if ( !isdefined( force_transmit_on_turn ) ) force_transmit_on_turn = false; if ( !flag( "allow_context_sensative_dialog" ) ) { if ( force_transmit_on_turn ) flag_wait( "allow_context_sensative_dialog" ); else return; } validGroupNum = undefined; randGroup = randomint( level.scr_sound[ name1 ][ name2 ].size ); // if randGroup has already played if ( level.scr_sound[ name1 ][ name2 ][ randGroup ].played == true ) { //loop through all groups and use the next one that hasn't played yet for( i = 0 ; i < level.scr_sound[ name1 ][ name2 ].size ; i++ ) { randGroup++; if ( randGroup >= level.scr_sound[ name1 ][ name2 ].size ) randGroup = 0; if ( level.scr_sound[ name1 ][ name2 ][ randGroup ].played == true ) continue; validGroupNum = randGroup; break; } // all groups have been played, reset all groups to false and pick a new random one if ( !isdefined( validGroupNum ) ) { for( i = 0 ; i < level.scr_sound[ name1 ][ name2 ].size ; i++ ) level.scr_sound[ name1 ][ name2 ][ i ].played = false; validGroupNum = randomint( level.scr_sound[ name1 ][ name2 ].size ); } } else validGroupNum = randGroup; assert( isdefined( validGroupNum ) ); assert( validGroupNum >= 0 ); if ( context_Sensative_Dialog_Timedout( name1, name2, validGroupNum ) ) return; level.scr_sound[ name1 ][ name2 ][ validGroupNum ].played = true; randSound = randomint( level.scr_sound[ name1 ][ name2 ][ validGroupNum ].size ); playSoundOverRadio( level.scr_sound[ name1 ][ name2 ][ validGroupNum ].sounds[ randSound ], force_transmit_on_turn ); } context_Sensative_Dialog_Timedout( name1, name2, groupNum ) { // dont play this sound if it has a timeout specified and the timeout has not expired if( !isdefined( level.context_sensative_dialog_timeouts ) ) return false; if( !isdefined( level.context_sensative_dialog_timeouts[ name1 ] ) ) return false; if( !isdefined( level.context_sensative_dialog_timeouts[ name1 ][name2 ] ) ) return false; if( isdefined( level.context_sensative_dialog_timeouts[ name1 ][ name2 ].groups ) && isdefined( level.context_sensative_dialog_timeouts[ name1 ][ name2 ].groups[ string( groupNum ) ] ) ) { assert( isdefined( level.context_sensative_dialog_timeouts[ name1 ][ name2 ].groups[ string( groupNum ) ].v[ "timeoutDuration" ] ) ); assert( isdefined( level.context_sensative_dialog_timeouts[ name1 ][ name2 ].groups[ string( groupNum ) ].v[ "lastPlayed" ] ) ); currentTime = getTime(); if( ( currentTime - level.context_sensative_dialog_timeouts[ name1 ][ name2 ].groups[ string( groupNum ) ].v[ "lastPlayed" ] ) < level.context_sensative_dialog_timeouts[ name1 ][ name2 ].groups[ string( groupNum ) ].v[ "timeoutDuration" ] ) return true; level.context_sensative_dialog_timeouts[ name1 ][ name2 ].groups[ string( groupNum ) ].v[ "lastPlayed" ] = currentTime; } else if ( isdefined( level.context_sensative_dialog_timeouts[ name1 ][ name2 ].v ) ) { assert( isdefined( level.context_sensative_dialog_timeouts[ name1 ][ name2 ].v[ "timeoutDuration" ] ) ); assert( isdefined( level.context_sensative_dialog_timeouts[ name1 ][ name2 ].v[ "lastPlayed" ] ) ); currentTime = getTime(); if( ( currentTime - level.context_sensative_dialog_timeouts[ name1 ][ name2 ].v[ "lastPlayed" ] ) < level.context_sensative_dialog_timeouts[ name1 ][ name2 ].v[ "timeoutDuration" ] ) return true; level.context_sensative_dialog_timeouts[ name1 ][ name2 ].v[ "lastPlayed" ] = currentTime; } return false; } playSoundOverRadio( soundAlias, force_transmit_on_turn, timeout ) { if ( !isdefined( level.radio_in_use ) ) level.radio_in_use = false; if ( !isdefined( force_transmit_on_turn ) ) force_transmit_on_turn = false; if ( !isdefined( timeout ) ) timeout = 0; timeout = timeout * 1000; soundQueueTime = gettime(); soundPlayed = false; soundPlayed = playAliasOverRadio( soundAlias ); if ( soundPlayed ) return; // Dont make the sound wait to be played if force transmit wasn't set to true if ( !force_transmit_on_turn ) return; level.radioForcedTransmissionQueue[ level.radioForcedTransmissionQueue.size ] = soundAlias; while( !soundPlayed ) { if ( level.radio_in_use ) level waittill ( "radio_not_in_use" ); if ( ( timeout > 0 ) && ( getTime() - soundQueueTime > timeout ) ) break; if ( !isDefined( level.ac130player ) ) break; soundPlayed = playAliasOverRadio( level.radioForcedTransmissionQueue[ 0 ] ); if ( !level.radio_in_use && isDefined( level.ac130player ) && !soundPlayed ) assertMsg( "The radio wasn't in use but the sound still did not play. This should never happen." ); } level.radioForcedTransmissionQueue = array_remove_index( level.radioForcedTransmissionQueue, 0 ); } playAliasOverRadio( soundAlias ) { if ( level.radio_in_use ) return false; if ( !isDefined( level.ac130player ) ) return false; level.radio_in_use = true; if ( self.team == "allies" || self.team == "axis" ) { soundAlias = maps\mp\gametypes\_teams::getTeamVoicePrefix( self.team ) + soundAlias; level.ac130player playLocalSound( soundAlias ); } wait ( 4.0 ); level.radio_in_use = false; level.lastRadioTransmission = getTime(); level notify ( "radio_not_in_use" ); return true; } debug_circle(center, radius, duration, color, startDelay, fillCenter) { circle_sides = 16; angleFrac = 360/circle_sides; circlepoints = []; for(i=0;i= 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; } } handleIncomingStinger() { level endon ( "game_ended" ); for ( ;; ) { level waittill ( "stinger_fired", player, missile, lockTarget ); if ( !IsDefined( lockTarget ) || (lockTarget != level.ac130.planeModel) ) continue; missile thread stingerProximityDetonate( player, player.team ); } } deleteAfterTime( delay ) { wait ( delay ); self delete(); } stingerProximityDetonate( player, missileTeam ) { self endon ( "death" ); if ( isDefined( level.ac130player ) ) level.ac130player playLocalSound( "missile_incoming" ); level.ac130.incomingMissile = true; missileTarget = level.ac130.planeModel; self Missile_SetTargetEnt( missileTarget ); didSeatbelts = false; minDist = distance( self.origin, missileTarget GetPointInBounds( 0, 0, 0 ) ); for ( ;; ) { center = missileTarget GetPointInBounds( 0, 0, 0 ); curDist = distance( self.origin, center ); if ( !isDefined( level.ac130player ) ) { self Missile_SetTargetPos( level.ac130.origin + (0,0,100000) ); return; } if ( curDist < 3000 && missileTarget == level.ac130.planeModel && level.ac130.numFlares > 0 ) { level.ac130.numFlares--; newTarget = missileTarget deployFlares(); self Missile_SetTargetEnt( newTarget ); missileTarget = newTarget; if ( isDefined( level.ac130player ) ) level.ac130player stopLocalSound( "missile_incoming" ); } if ( curDist < minDist ) { speedPerFrame = (minDist - curDist) * 20; eta = (curDist / speedPerFrame); if ( eta < 1.5 && !didSeatbelts && missileTarget == level.ac130.planeModel ) { if ( isDefined( level.ac130player ) ) level.ac130player playLocalSound( "fasten_seatbelts" ); didSeatbelts = true; } minDist = curDist; } if ( curDist > minDist ) { if ( curDist > 1536 ) return; if ( isDefined( level.ac130player ) ) { level.ac130player stopLocalSound( "missile_incoming" ); if ( level.ac130player.team != missileTeam ) radiusDamage( self.origin, 1000, 1000, 1000, player ); } /* playFx( level.stingerFXid, self.origin ); //thread crashPlane( 20.0 ); self playSound( "remotemissile_explode" ); */ self hide(); wait ( 0.05 ); self delete(); } wait ( 0.05 ); } } crashPlane( crashTime ) { level.ac130.planeModel notify ( "crashing" ); level.ac130.planeModel.crashed = true; playFxOnTag( level._effect[ "ac130_explode" ], level.ac130.planeModel, "tag_deathfx" ); wait .25; level.ac130.planeModel hide(); } playFlareFx( flareCount ) { for ( i = 0; i < flareCount; i++ ) { self thread angel_flare(); wait ( randomFloatRange( 0.1, 0.25 ) ); } } deployFlares( fxOnly ) { self playSound( "ac130_flare_burst" ); if ( !isDefined( fxOnly ) ) { flareObject = spawn( "script_origin", level.ac130.planemodel.origin ); flareObject.angles = level.ac130.planemodel.angles; flareObject moveGravity( (0, 0, 0), 5.0 ); self thread playFlareFx( 10 ); flareObject thread deleteAfterTime( 5.0 ); return flareObject; } else { self thread playFlareFx( 5 ); } } angelFlarePrecache() { precacheModel( "angel_flare_rig" ); precacheMpAnim( "ac130_angel_flares01" ); precacheMpAnim( "ac130_angel_flares02" ); precacheMpAnim( "ac130_angel_flares03" ); level._effect[ "angel_flare_geotrail" ] = loadfx( "smoke/angel_flare_geotrail" ); level._effect[ "angel_flare_swirl" ] = loadfx( "smoke/angel_flare_swirl_runner" ); } angel_flare() { rig = spawn( "script_model", self.origin ); rig setModel( "angel_flare_rig" ); rig.origin = self getTagOrigin( "tag_flash_flares" ); rig.angles = self getTagAngles( "tag_flash_flares" ); rig.angles = (rig.angles[0],rig.angles[1] + 180,rig.angles[2] + -90); fx_id = level._effect[ "angel_flare_geotrail" ]; rig ScriptModelPlayAnim( "ac130_angel_flares0" + (randomInt( 3 )+1) ); wait 0.1; PlayFXOnTag( fx_id, rig, "flare_left_top" ); PlayFXOnTag( fx_id, rig, "flare_right_top" ); wait 0.05; PlayFXOnTag( fx_id, rig, "flare_left_bot" ); PlayFXOnTag( fx_id, rig, "flare_right_bot" ); //rig waittillmatch( "flare_anim", "end" ); wait ( 3.0 ); StopFXOnTag( fx_id, rig, "flare_left_top" ); StopFXOnTag( fx_id, rig, "flare_right_top" ); StopFXOnTag( fx_id, rig, "flare_left_bot" ); StopFXOnTag( fx_id, rig, "flare_right_bot" ); rig delete(); } /* #using_animtree( "script_model" ); angel_flare_rig_anims() { level.scr_animtree[ "angel_flare_rig" ] = #animtree; level.scr_model[ "angel_flare_rig" ] = "angel_flare_rig"; level.scr_anim[ "angel_flare_rig" ][ "ac130_angel_flares" ][0] = %ac130_angel_flares01; level.scr_anim[ "angel_flare_rig" ][ "ac130_angel_flares" ][1] = %ac130_angel_flares02; level.scr_anim[ "angel_flare_rig" ][ "ac130_angel_flares" ][2] = %ac130_angel_flares03; } assign_model() { AssertEx( IsDefined( level.scr_model[ self.animname ] ), "There is no level.scr_model for animname " + self.animname ); if ( IsArray( level.scr_model[ self.animname ] ) ) { randIndex = RandomInt( level.scr_model[ self.animname ].size ); self SetModel( level.scr_model[ self.animname ][ randIndex ] ); } else self SetModel( level.scr_model[ self.animname ] ); } assign_animtree( animname ) { if ( IsDefined( animname ) ) self.animname = animname; AssertEx( IsDefined( level.scr_animtree[ self.animname ] ), "There is no level.scr_animtree for animname " + self.animname ); self UseAnimTree( level.scr_animtree[ self.animname ] ); } spawn_anim_model( animname, origin ) { if ( !isdefined( origin ) ) origin = ( 0, 0, 0 ); model = Spawn( "script_model", origin ); model.animname = animname; model assign_animtree(); model assign_model(); return model; } angel_flare_burst( flare_count ) { // Angel Flare Swirl PlayFXOnTag( getfx( "angel_flare_swirl" ), self, "tag_flash_flares" ); // Angel Flare Trails for( i=0; i