diff options
Diffstat (limited to 'Northstar.CustomServers/mod/scripts')
46 files changed, 7284 insertions, 54 deletions
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/_harvester.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_harvester.gnut index 3bdb1d8a..191c3b24 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/_harvester.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/_harvester.gnut @@ -12,7 +12,6 @@ global struct HarvesterStruct { bool harvesterShieldDown float harvesterDamageTaken bool havesterWasDamaged - } HarvesterStruct function SpawnHarvester( vector origin, vector angles, int health, int shieldHealth, int team ) @@ -32,14 +31,20 @@ HarvesterStruct function SpawnHarvester( vector origin, vector angles, int healt SetObjectCanBeMeleed( harvester, true ) SetVisibleEntitiesInConeQueriableEnabled( harvester, true ) SetTeam(harvester,team) - + // create dangerous area to all AI because we dont want any AI clipping into the harvester ever + // radius of 90 cos thats like 7.5 metres? AI shouldnt rally need to get closer than that (except nuke titans and stalkers) + // stalkers dont care about dangerous areas + // nuke titan detonation radius is larger than 90 + AI_CreateDangerousArea_Static( harvester, null, 90, TEAM_INVALID, true, true, origin ) DispatchSpawn( harvester ) + SetGlobalNetEnt( "FD_activeHarvester", harvester ) entity blackbox = CreatePropDynamic( MODEL_HARVESTER_TOWER_COLLISION, origin, angles, 0 ) blackbox.Hide() blackbox.Solid() // blackbox.kv.CollisionGroup = TRACE_COLLISION_GROUP_PLAYER + ToggleNPCPathsForEntity( blackbox, false ) entity rings = CreatePropDynamic( MODEL_HARVESTER_TOWER_RINGS, origin, angles, 6 ) thread PlayAnim( rings, "generator_cycle_fast" ) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/_loadouts_mp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_loadouts_mp.gnut index 76cb4ac4..24dbb62d 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/_loadouts_mp.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/_loadouts_mp.gnut @@ -3,6 +3,7 @@ global function SvLoadoutsMP_Init global function SetLoadoutGracePeriodEnabled global function SetWeaponDropsEnabled +global function SetAllowLoadoutChangeFunc global function AddCallback_OnTryGetTitanLoadout global function GetTitanLoadoutForPlayer @@ -22,6 +23,8 @@ struct { array< TryGetTitanLoadoutCallbackType > onTryGetTitanLoadoutCallbacks array<entity> dirtyLoadouts + + bool functionref( entity ) allowChangeLoadoutFunc = null } file void function SvLoadoutsMP_Init() @@ -60,6 +63,11 @@ void function SetLoadoutGracePeriodEnabled( bool enabled ) file.loadoutGracePeriodEnabled = enabled } +void function SetAllowLoadoutChangeFunc( bool functionref( entity ) func ) +{ + file.allowChangeLoadoutFunc = func +} + void function SetWeaponDropsEnabled( bool enabled ) { file.weaponDropsEnabled = enabled @@ -303,7 +311,7 @@ void function TryGivePilotLoadoutForGracePeriod( entity player ) else respawnTimeReal = expect float( player.s.respawnTime ) - if ( ( ( Time() - respawnTimeReal <= CLASS_CHANGE_GRACE_PERIOD || GetGameState() < eGameState.Playing ) && file.loadoutGracePeriodEnabled ) || player.p.usingLoadoutCrate ) + if ( ( ( Time() - respawnTimeReal <= CLASS_CHANGE_GRACE_PERIOD || GetGameState() < eGameState.Playing ) && file.loadoutGracePeriodEnabled ) || player.p.usingLoadoutCrate || ( file.allowChangeLoadoutFunc != null && file.allowChangeLoadoutFunc( player ) ) ) { if ( !Loadouts_CanGivePilotLoadout( player ) && player.GetParent() != null && ( HasCinematicFlag( player, CE_FLAG_INTRO ) || HasCinematicFlag( player, CE_FLAG_CLASSIC_MP_SPAWNING ) || HasCinematicFlag( player, CE_FLAG_WAVE_SPAWNING ) ) ) thread GiveLoadoutWhenIntroOver( player ) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_cloak_drone.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_cloak_drone.gnut index e3addf81..a71b71f1 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_cloak_drone.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_cloak_drone.gnut @@ -219,7 +219,7 @@ void function CloakedDronePathThink( entity cloakedDrone ) continue //Don't cloak arc titans - if ( guy.GetTargetName() == "empTitan" ) + if ( IsEMPTitan( guy ) ) continue if ( IsSniperSpectre( guy ) ) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_emp_titans.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_emp_titans.gnut index 638166c8..2792d617 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_emp_titans.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_emp_titans.gnut @@ -3,6 +3,7 @@ untyped global function EmpTitans_Init global function EMPTitanThinkConstant +global function IsEMPTitan const DAMAGE_AGAINST_TITANS = 150 const DAMAGE_AGAINST_PILOTS = 40 @@ -11,6 +12,11 @@ const EMP_DAMAGE_TICK_RATE = 0.3 const FX_EMP_FIELD = $"P_xo_emp_field" const FX_EMP_FIELD_1P = $"P_body_emp_1P" +struct +{ + array<entity> empTitans +} file + function EmpTitans_Init() { AddDamageCallbackSourceID( eDamageSourceId.titanEmpField, EmpField_DamagedEntity ) @@ -31,7 +37,8 @@ void function EMPTitanThinkConstant( entity titan ) DisableTitanRodeo( titan ) //Used to identify this titan as an arc titan - SetTargetName( titan, "empTitan" ) + // SetTargetName( titan, "empTitan" ) // unable to do this due to FD reasons + file.empTitans.append( titan ) //Wait for titan to stand up and exit bubble shield before deploying arc ability. WaitTillHotDropComplete( titan ) @@ -88,6 +95,8 @@ void function EMPTitanThinkConstant( entity titan ) { StopSoundOnEntity( titan, "EMP_Titan_Electrical_Field" ) EnableTitanRodeo( titan ) //Make the arc titan rodeoable now that it is no longer electrified. + if (file.empTitans.find( titan ) ) + file.empTitans.remove( file.empTitans.find( titan ) ) } foreach ( particleSystem in particles ) @@ -108,7 +117,7 @@ void function EMPTitanThinkConstant( entity titan ) { origin = titan.GetAttachmentOrigin( attachID ) - RadiusDamage( + RadiusDamage( origin, // center titan, // attacker titan, // inflictor @@ -134,7 +143,7 @@ void function EmpField_DamagedEntity( entity target, var damageInfo ) entity titan = DamageInfo_GetAttacker( damageInfo ) if ( !IsValid( titan ) ) - return + return local className = target.GetClassName() if ( className == "rpg_missile" || className == "npc_turret_sentry" || className == "grenade" ) @@ -178,4 +187,9 @@ void function EmpField_DamagedEntity( entity target, var damageInfo ) string function GetEMPAttachmentForTitan( entity titan ) { return "hijack" -}
\ No newline at end of file +} + +bool function IsEMPTitan( entity titan ) +{ + return file.empTitans.find( titan ) != -1 ? true : false +} diff --git a/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_mortar_spectres.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_mortar_spectres.gnut index 080e2f68..c63d9dd2 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_mortar_spectres.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_mortar_spectres.gnut @@ -1,7 +1,237 @@ +untyped + global function MortarSpectreGetSquadFiringPositions +global function MortarSpectreSquadThink + +global function SpectresPlayAnim + +const float MORTAR_SPECTRE_ABORT_ATTACK_HEALTH_FRAC = 0.50 // will stop mortar attack if any of the spectres health gets below 50% of their current health. +const float MORTAR_SPECTRE_POSITION_SEARCH_RANGE = 6144 //3072 // How far away from their spawn point a mortar spectre squad will look for positions to mortar from. +const float MORTAR_SPECTRE_ENGAGE_DELAY = 3.0 // How long before a mortar spectre squad start to attack the generator if interrupted getting to their mortar position. +const float MORTAR_SPECTRE_REENGAGE_DELAY = 7.0 // How long before a mortar spectre squad goes back to attacking the generator after breaking of an attack. + +const float MORTAR_SPECTRE_TRACKER_SHIELD_MAX = 1000.0 // just using 1000 for now, doesnt really matter as long as the shieldFrac is accurate enough + +const array<vector> MORTAR_SPECTRE_POSITION_OFFSETS = [ < 60, 0, 0 >, < 0, 60, 0 >, < -60, 0, 0 >, < 0, -60, 0 > ] // guessing + array<vector> function MortarSpectreGetSquadFiringPositions( vector origin, vector testTarget ) { - array< vector > ret + array<vector> ret + foreach ( vector position in MORTAR_SPECTRE_POSITION_OFFSETS ) + { + ret.append( OriginToGround( testTarget + position + < 0, 0, 100 > ) ) // offsetting by 100 up so that OriginToGround doesnt put it down a floor + } return ret -}
\ No newline at end of file +} + +// -------------------------------------------------------------------- +// MORTAR SPECTRE LOGIC +// -------------------------------------------------------------------- + +void function MortarSpectreSquadThink( array< entity > spectres, entity harvester ) +{ + if ( spectres.len() == 0) + return + + // get the closest available stationary position for mortar spectres + StationaryAIPosition ornull mortarPosition = GetClosestAvailableStationaryPosition( /* spectres[0] isnt ideal but the spectres all spawn in the same position atm */ spectres[0].GetOrigin(), MORTAR_SPECTRE_POSITION_SEARCH_RANGE, eStationaryAIPositionTypes.MORTAR_SPECTRE ) + while ( mortarPosition == null ) + { + // in case all stationary spectre positions are in use wait for one to become available + wait 5 + // should change this to use an average position or the start position or something but for now this is fine + mortarPosition = GetClosestAvailableStationaryPosition( spectres[0].GetOrigin(), MORTAR_SPECTRE_POSITION_SEARCH_RANGE, eStationaryAIPositionTypes.MORTAR_SPECTRE ) + } + // create the entity responsible for managing this squad of spectres + // note: client shows the ui thing for this entity if the y angle is not 0 + // it also shows the set up time thing based on the shield frac of the entity? weird + entity squadMarker = CreatePropScript( $"models/dev/empty_model.mdl", expect StationaryAIPosition( mortarPosition ).origin + < 0, 0, 150 >, < 0, 1, 0 > ) + SetTargetName( squadMarker, "mortarPosition" ) + squadMarker.SetShieldHealthMax( MORTAR_SPECTRE_TRACKER_SHIELD_MAX ) + squadMarker.Minimap_SetCustomState( eMinimapObject_prop_script.FD_MORTAR_POSITION ) + + thread MortarSpectreSquadDeathThink( spectres, squadMarker ) + + // wait until at least 1 spectre has reached their position + int i = 0 + foreach( entity spectre in spectres ) + { + thread MortarSpectreMoveToMortarPosition( spectre, squadMarker, OriginToGround( expect StationaryAIPosition( mortarPosition ).origin + MORTAR_SPECTRE_POSITION_OFFSETS[i] + < 0, 0, 100 > ) ) + + if ( i++ >= MORTAR_SPECTRE_POSITION_OFFSETS.len() ) + { + i = 0 + } + } + squadMarker.WaitSignal( "BeginMortarAttack" ) + // show the ui thing + squadMarker.SetAngles( < 0, 0, 0 > ) + // start the setup timer + float setupEndTime = Time() + GetCurrentPlaylistVarFloat( "fd_mortar_spectre_setup_time", 5 ) // default to 5 seconds + // wait for setup timer + while ( Time() < setupEndTime ) + { + if ( !IsValid( squadMarker ) ) + { + break + } + float timeRemainingFrac = ( setupEndTime - Time() ) / GetCurrentPlaylistVarFloat( "fd_mortar_spectre_setup_time", 5 ) // default to 5 seconds + squadMarker.SetShieldHealth( ( 1 - timeRemainingFrac ) * MORTAR_SPECTRE_TRACKER_SHIELD_MAX ) + WaitFrame() + } + + + if ( GetCurrentPlaylistVarFloat( "fd_grunt_shield_captains", 1 ) ) // idk if correct or not? doest seem to be a playlist var for mortar spectre shield + { + // create shield here + + } + + foreach( entity spectre in spectres ) + { + if ( IsValid( spectre ) ) + thread MortarSpectreAttack( spectre, harvester, squadMarker ) + } +} + +void function MortarSpectreAttack( entity spectre, entity harvester, entity signaler ) +{ + spectre.EndSignal( "OnSyncedMeleeVictim" ) + spectre.EndSignal( "OnDeath" ) + spectre.EndSignal( "OnDestroy" ) + + string originalWeaponClassName + array<string> originalWeaponMods + + spectre.ai.mortarTarget = harvester + + thread MortarSpectreInterruptThink( spectre, harvester, signaler ) + + while( true ) + { + array<entity> weapons = spectre.GetMainWeapons() + if ( weapons.len() == 0 ) + break + entity weapon = weapons[0] + if ( !IsValid( weapon ) ) + break + originalWeaponClassName = weapon.GetWeaponClassName() + originalWeaponMods = weapon.GetMods() + + spectre.TakeWeaponNow( weapon.GetWeaponClassName() ) + spectre.GiveWeapon( "mp_weapon_rocket_launcher", [ "fd_mortar_mode" ] ) + thread MortarSpectreAttacksHarvester( spectre, harvester, signaler ) + + spectre.WaitSignal( "InterruptMortarAttack" ) + + spectre.TakeWeaponNow( "mp_weapon_rocket_launcher" ) + spectre.GiveWeapon( originalWeaponClassName, originalWeaponMods ) + + + wait MORTAR_SPECTRE_REENGAGE_DELAY + if ( !IsValid( spectre ) ) + break + } +} + +// this should hopefully be replaced with an animation that fires the mortar rockets properly, but i cant find it, so this will have to do +void function MortarSpectreAttacksHarvester( entity spectre, entity harvester, entity signaler ) +{ + spectre.EndSignal( "InterruptMortarAttack" ) + spectre.EndSignal( "OnSyncedMeleeVictim" ) + spectre.EndSignal( "OnDeath" ) + spectre.EndSignal( "OnDestroy" ) + + entity weapon = spectre.GetActiveWeapon() + wait RandomFloatRange( 0, 4 ) // this is a complete guess, idk how long it takes for them to shoot normally + while ( true ) + { + // if the spectre drops the weapon, or if something somehow steals it, we should stop firing missiles from it + if ( weapon.GetWeaponOwner() != spectre ) + break + entity missile = weapon.FireWeaponMissile( spectre.GetOrigin(), < 0, 0, 90 >, 1800.0, damageTypes.projectileImpact, damageTypes.explosive, false, PROJECTILE_NOT_PREDICTED ) + weapon.SetWeaponPrimaryAmmoCount( weapon.GetWeaponPrimaryAmmoCount() - 1 ) // remove the ammo manually + MortarMissileFiredCallback( missile, spectre ) + wait RandomFloatRange( 6, 10 ) // this is a complete guess, idk how long it takes for them to shoot normally + } +} + +void function MortarSpectreSquadDeathThink( array< entity > spectres, entity signaler ) +{ + int numAlive = spectres.len() // assume all alive at start + while ( numAlive != 0 ) + { + WaitFrame() + numAlive = spectres.len() + foreach ( entity spectre in spectres ) + { + if ( IsValid( spectre ) && IsAlive( spectre ) ) + continue + numAlive-- + } + } + signaler.Destroy() +} + +void function MortarSpectreMoveToMortarPosition( entity spectre, entity signaler, vector position ) +{ + spectre.EndSignal( "OnSyncedMeleeVictim" ) + spectre.EndSignal( "OnDeath" ) + spectre.EndSignal( "OnDestroy" ) + + spectre.AssaultPoint( position ) + spectre.AssaultSetGoalRadius( spectre.GetMinGoalRadius() ) + spectre.AssaultSetFightRadius( 0 ) + + table result = spectre.WaitSignal( "OnFinishedAssault", "OnFailedToPath" ) + if ( result.signal == "OnFinishedAssault" ) + signaler.Signal( "BeginMortarAttack" ) +} + +void function MortarSpectreInterruptThink( entity spectre, entity harvester, entity signaler ) +{ + spectre.EndSignal( "OnSyncedMeleeVictim" ) + spectre.EndSignal( "OnDeath" ) + spectre.EndSignal( "OnDestroy" ) + + float oldHealth = spectre.GetHealth().tofloat() + + while ( true ) + { + WaitFrame() + // check if we have taken enough damage to warrant an interruption, and we are close enough to the mortar position + if ( spectre.GetHealth().tofloat() / oldHealth < MORTAR_SPECTRE_ABORT_ATTACK_HEALTH_FRAC && Distance2D( spectre.GetOrigin(), signaler.GetOrigin() ) <= 80 ) // random magic 80 for now + { + oldHealth = spectre.GetHealth().tofloat() + spectre.Signal( "InterruptMortarAttack" ) + continue + } + + if ( IsValid( spectre.GetEnemy() ) && spectre.CanSee( spectre.GetEnemy() ) && !IsCloaked( spectre.GetEnemy() ) ) + { + oldHealth = spectre.GetHealth().tofloat() + spectre.Signal( "InterruptMortarAttack" ) + } + } +} + +void function SpectresPlayAnim( string anim ) +{ + foreach (entity spectre in GetNPCArrayByClass("npc_spectre")) + { + thread thing( anim, spectre) + } +} + +void function thing( string anim, entity spectre ) +{ + try + { + PlayAnim( spectre, anim) + } + catch (ex) + { + print(ex) + } +} diff --git a/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_mortar_titans.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_mortar_titans.gnut index 08598808..f23c05f9 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_mortar_titans.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_mortar_titans.gnut @@ -100,14 +100,14 @@ void function MortarMissileThink( entity missile, entity weaponOwner ) { float frac = min( 1, pow( ( Time() - startTime ) / estTravelTime, 2.0 ) ) - if ( frac > 1.0 ) - break + if ( frac > 1.0 ) + break float homingSpeed = GraphCapped( frac, 0, 1, homingSpeedMin, homingSpeedMax ) - missile.SetHomingSpeeds( homingSpeed, 0 ) + missile.SetHomingSpeeds( homingSpeed, 0 ) - wait 0.25 + wait 0.25 } missile.ClearMissileTargetPosition() @@ -304,12 +304,12 @@ void function MortarTitanThink( entity titan, entity generator ) WaitTillHotDropComplete( titan ) float minEngagementDuration = 5 - StationaryAIPosition ornull mortarPosition = GetRandomStationaryPosition( titan.GetOrigin(), MORTAR_TITAN_POSITION_SEARCH_RANGE, eStationaryAIPositionTypes.MORTAR_TITAN ) + StationaryAIPosition ornull mortarPosition = GetClosestAvailableStationaryPosition( titan.GetOrigin(), MORTAR_TITAN_POSITION_SEARCH_RANGE, eStationaryAIPositionTypes.MORTAR_TITAN ) while ( mortarPosition == null ) { // incase all stationary titan positions are in use wait for one to become available wait 5 - mortarPosition = GetRandomStationaryPosition( titan.GetOrigin(), MORTAR_TITAN_POSITION_SEARCH_RANGE, eStationaryAIPositionTypes.MORTAR_TITAN ) + mortarPosition = GetClosestAvailableStationaryPosition( titan.GetOrigin(), MORTAR_TITAN_POSITION_SEARCH_RANGE, eStationaryAIPositionTypes.MORTAR_TITAN ) } expect StationaryAIPosition( mortarPosition ) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_nuke_titans.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_nuke_titans.gnut index 0d4b43c9..1e8ec316 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_nuke_titans.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_nuke_titans.gnut @@ -33,6 +33,9 @@ void function NukeTitanSeekOutGenerator( entity titan, entity generator ) titan.EndSignal( "OnDeath" ) titan.EndSignal( "OnDestroy" ) titan.EndSignal( "Doomed" ) + // should fix crash with invalid generator? + generator.EndSignal( "OnDeath" ) + generator.EndSignal( "OnDestroy" ) WaitSignal( titan, "FD_ReachedHarvester", "OnFailedToPath" ) @@ -58,7 +61,7 @@ void function NukeTitanSeekOutGenerator( entity titan, entity generator ) { titan.SetEnemy( generator ) thread AssaultOrigin( titan, validPos[0], goalRadius ) - titan.AssaultSetFightRadius( goalRadius ) + titan.AssaultSetFightRadius( 0 ) // dont want to set a fight radius because then the nuke titan will stop and shoot wait 0.5 diff --git a/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_sniper_titans.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_sniper_titans.gnut index 37b89169..b1ff4fa2 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_sniper_titans.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_sniper_titans.gnut @@ -1 +1,226 @@ -//fuck
\ No newline at end of file +untyped + +global function MoveToSniperPosition +global function SniperTitanThink + +const float SNIPER_TITAN_POSITION_SEARCH_RANGE = 4120 + + + +void function MoveToSniperPosition( entity titan, vector origin, entity target ) +{ + titan.EndSignal( "OnSyncedMeleeVictim" ) + titan.EndSignal( "OnDeath" ) + titan.EndSignal( "OnDestroy" ) + target.EndSignal( "OnDeath" ) + target.EndSignal( "OnDestroy" ) + + titan.EnableNPCMoveFlag( NPCMF_PREFER_SPRINT ) + + float goalRadius = titan.GetMinGoalRadius() + + OnThreadEnd( + function() : ( titan ) + { + if ( !IsValid( titan ) ) + return + + local classname = titan.GetClassName() + titan.DisableNPCMoveFlag( NPCMF_PREFER_SPRINT ) + } + ) + + local tries = 0 + while( true ) + { + local dist = Distance( titan.GetOrigin(), origin ) + if ( dist <= goalRadius * 2 ) + break + + printt( "Sniper titan moving toward his goal", dist, tries++ ) + titan.AssaultPoint( origin ) + titan.AssaultSetGoalRadius( goalRadius ) + titan.AssaultSetFightRadius( 0 ) + local result = WaitSignal( titan, "OnFinishedAssault", "OnEnterGoalRadius" ) + printt( "Sniper titan done moving into position") + } +} + +void function SniperTitanThink( entity titan, entity generator) +{ + titan.EndSignal( "OnSyncedMeleeVictim" ) + titan.EndSignal( "OnDeath" ) + titan.EndSignal( "OnDestroy" ) + generator.EndSignal( "OnDeath" ) + generator.EndSignal( "OnDestroy" ) + + entity soul = titan.GetTitanSoul() + soul.EndSignal( "OnDestroy" ) + + titan.SetScriptName( "sniper_titan" ) + + WaitTillHotDropComplete( titan ) + + float minEngagementDuration = 5 + StationaryAIPosition ornull sniperPosition = GetClosestAvailableStationaryPosition( titan.GetOrigin(), SNIPER_TITAN_POSITION_SEARCH_RANGE, eStationaryAIPositionTypes.SNIPER_TITAN ) + while ( sniperPosition == null ) + { + // incase all stationary titan positions are in use wait for one to become available + wait 5 + sniperPosition = GetClosestAvailableStationaryPosition( titan.GetOrigin(), SNIPER_TITAN_POSITION_SEARCH_RANGE, eStationaryAIPositionTypes.SNIPER_TITAN ) + } + + expect StationaryAIPosition( sniperPosition ) + + ClaimStationaryAIPosition( sniperPosition ) + + OnThreadEnd( + function() : ( sniperPosition ) + { + // release sniper position when dead + ReleaseStationaryAIPosition( sniperPosition ) + } + ) + titan.SetEnemyChangeCallback( EnemyChanged) + thread CheckEnemy( titan ,generator) + while( true ) + { + WaitFrame() + vector origin = sniperPosition.origin + waitthread MoveToSniperPosition( titan, origin, generator ) + + thread SniperTitanAttack( titan, generator ) + + waitthread WaitForInterruption( titan ,generator) + } +} +// check if titan can see enemy +void function CheckEnemy(entity titan,entity generator) +{ + titan.EndSignal( "OnSyncedMeleeVictim" ) + titan.EndSignal( "OnDeath" ) + titan.EndSignal( "OnDestroy" ) + generator.EndSignal( "OnDeath" ) + generator.EndSignal( "OnDestroy" ) + + while (IsValid(titan)) + { + wait 1 + if (!IsValid(titan.GetEnemy())) + continue + + if (!titan.CanSee(titan.GetEnemy()) && titan.GetEnemy() == generator) + { + waitthread CreateSniperTarget( titan , generator) + wait 1 // wait for 1 second so the signal doesn't get called too soon + table result = WaitSignal( titan, "SniperSwitchedEnemy" ) + } + } +} + +void function CreateSniperTarget(entity titan,entity generator) +{ + titan.EndSignal( "OnSyncedMeleeVictim" ) + titan.EndSignal( "OnDeath" ) + titan.EndSignal( "OnDestroy" ) + generator.EndSignal( "OnDeath" ) + generator.EndSignal( "OnDestroy" ) + + vector origin = titan.EyePosition() + TraceResults result = TraceLine( origin, generator.GetOrigin() + <0, 0, 250>, titan , TRACE_MASK_BLOCKLOS, TRACE_COLLISION_GROUP_NONE ) + // check if the endPos is too near the titan + while (Distance(result.endPos, origin) < 200 || Distance(result.endPos, generator.GetOrigin()) < 200) + { + wait 2.0 + origin = titan.EyePosition() + result = TraceLine( origin, generator.GetOrigin() + <0, 0, 250>, titan ) + } + entity snipertarget = CreateEntity( "info_target" ) + DispatchSpawn( snipertarget ) + snipertarget.SetOrigin( result.endPos ) // in front of the harvester i hope + SetTeam( snipertarget, TEAM_MILITIA ) + snipertarget.EnableAttackableByAI( 40, 0, AI_AP_FLAG_NONE ) + titan.SetEnemy( snipertarget ) + wait 1 // wait for 1 second so the signal doesn't get called too soon + titan.WaitSignal( "SniperSwitchedEnemy" ) + + OnThreadEnd( + function() : ( snipertarget ) + { + if ( !IsValid( snipertarget ) ) + return + + snipertarget.Destroy() + } + ) +} + +void function EnemyChanged( entity titan) +{ + titan.Signal( "SniperSwitchedEnemy" ) + entity enemy = titan.GetEnemy() + if ( !IsValid( enemy ) ) // if you have no enemy, focus on attacking the harvester + { + thread SniperTitanAttack( titan, fd_harvester.harvester) + enemy = fd_harvester.harvester + } +} + +function SniperTitanAttack( entity titan, entity target ) +{ + titan.EndSignal( "OnSyncedMeleeVictim" ) + titan.EndSignal( "OnDeath" ) + titan.EndSignal( "OnDestroy" ) + + OnThreadEnd( + function() : ( titan ) + { + if ( !IsValid( titan ) ) + return + } + ) + + titan.SetEnemy( target ) +} + +void function WaitForInterruption( entity titan ,entity generator) +{ + Assert( IsNewThread(), "Must be threaded off" ) + + titan.EndSignal( "OnSyncedMeleeVictim" ) + titan.EndSignal( "OnDeath" ) + titan.EndSignal( "OnDestroy" ) + generator.EndSignal( "OnDeath" ) + generator.EndSignal( "OnDestroy" ) + + entity soul = titan.GetTitanSoul() + soul.EndSignal( "OnDestroy" ) + + float playerProximityDistSqr = pow( 256, 2 ) + float healthBreakOff = ( titan.GetHealth() + soul.GetShieldHealth() ) * 0.9 + + while( true ) + { + if ( IsEnemyWithinDist( titan, playerProximityDistSqr ) ) + break + if ( ( titan.GetHealth() + soul.GetShieldHealth() ) < healthBreakOff ) + break + wait 1 + } + + titan.ClearEnemy() +} + +bool function IsEnemyWithinDist( entity titan, float dist ) +{ + vector origin = titan.GetOrigin() + array<entity> players = GetPlayerArrayOfEnemies_Alive( titan.GetTeam() ) + + foreach( player in players ) + { + if ( DistanceSqr( player.GetOrigin(), origin ) < dist ) + return true + } + + return false +} diff --git a/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_spawn.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_spawn.gnut index 7e4d2cdd..8599f429 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_spawn.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_spawn.gnut @@ -223,7 +223,7 @@ entity function CreateOgre( int team, vector origin, vector angles, array<string entity function CreateArcTitan( int team, vector origin, vector angles, array<string> settingsMods = [] ) { entity npc = CreateNPCTitan( "titan_stryder", team, origin, angles, settingsMods ) - SetSpawnOption_AISettings( npc, "npc_titan_arc" ) + SetSpawnOption_AISettings( npc, "npc_titan_stryder_leadwall_arc" ) return npc } diff --git a/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_stalker.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_stalker.gnut index f49560e0..0b4d6a9a 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_stalker.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_stalker.gnut @@ -1,7 +1,9 @@ +untyped global function AiStalker_Init global function GetDeathForce global function StalkerGearOverloads global function StalkerMeltingDown +global function FDStalkerThink global function IsStalkerLimbBlownOff @@ -157,6 +159,95 @@ void function StalkerOnDamaged_Internal( entity npc, var damageInfo ) npc.SetActivityModifier( ACT_MODIFIER_STAGGER, true ) } } + if( GameRules_GetGameMode() == FD ) + thread StalkerSprint( npc, damageInfo ) +} + +void function StalkerSprint( entity npc, var damageInfo ) +{ + npc.EndSignal("OnDeath") + npc.EndSignal("OnDestroy") + float damage = DamageInfo_GetDamage( damageInfo ) + + if (!IsCrawling(npc)&&( npc.GetHealth() - damage < 50 || npc.GetHealth() <= 80)) + { + entity weapon = npc.GetActiveWeapon() + if (IsValid(weapon)) + npc.TakeActiveWeapon() // when stalkers fall over on harvester they will randomly shoot their guns, we don't want that. + npc.EnableNPCMoveFlag( NPCMF_PREFER_SPRINT ) + npc.SetCapabilityFlag( bits_CAP_MOVE_SHOOT | bits_CAP_WEAPON_RANGE_ATTACK1 | bits_CAP_AIM_GUN, false ) + npc.SetNPCFlag( NPC_IGNORE_ALL, true ) + npc.SetNPCFlag( NPC_DISABLE_SENSING, true ) + npc.SetNoTarget( true ) + npc.ClearMoveAnim() + npc.SetMoveAnim("sp_spectre_sprint_F") + npc.s.isSprinting = true + } +} + +void function FDStalkerThink( entity npc, entity generator ) +{ + npc.EndSignal( "OnDeath" ) + npc.EndSignal( "OnDestroy" ) + generator.EndSignal( "OnDeath" ) + generator.EndSignal( "OnDestroy" ) + npc.s.isSprinting <- false + thread FDStalkerGetsStunned( npc , generator ) + while ( IsAlive( npc ) ) + { + WaitFrame() + + // cant sprint with 1 leg + // also upped to 1800 so that stalkers sprint from roughly their vanilla positions, could probably do it based on % of distance left to go? + if ( DistanceSqr( npc.GetOrigin(), generator.GetOrigin() ) < (1800 * 1800) ) + { + if(!IsCrawling( npc ) && !npc.s.isSprinting) + { + entity weapon = npc.GetActiveWeapon() + if (IsValid(weapon)) + npc.TakeActiveWeapon() // when stalkers fall over on harvester they will randomly shoot their guns, we don't want that. + npc.EnableNPCMoveFlag( NPCMF_PREFER_SPRINT ) + npc.SetCapabilityFlag( bits_CAP_MOVE_SHOOT | bits_CAP_WEAPON_RANGE_ATTACK1 | bits_CAP_AIM_GUN, false ) + npc.EnableNPCFlag( NPC_DISABLE_SENSING | NPC_IGNORE_ALL ) + npc.ClearMoveAnim() + npc.SetMoveAnim("sp_spectre_sprint_F") + npc.SetNoTarget( true ) + // stalkers were just going to the final node and stopping, meaning they never actually reached the harvester + npc.s.isSprinting = true + } + npc.AssaultPoint(generator.GetOrigin()) + } + + // upped from 230 to more accurately mimic vanilla i think? + if ( DistanceSqr( npc.GetOrigin(), generator.GetOrigin() ) > (275 * 275) ) + continue + + break + } + + thread StalkerGearOverloads( npc ) +} + +void function FDStalkerGetsStunned( entity npc , entity generator ) +{ + npc.EndSignal( "OnDeath" ) + npc.EndSignal( "OnDestroy" ) + npc.WaitSignal( "ArcStunned" ) + print("arc trapped...") + + if(IsCrawling(npc)) + return + + entity weapon = npc.GetActiveWeapon() + if (IsValid(weapon)) + npc.TakeActiveWeapon() // when stalkers fall over on harvester they will randomly shoot their guns, we don't want that. + npc.EnableNPCMoveFlag( NPCMF_PREFER_SPRINT ) + npc.SetCapabilityFlag( bits_CAP_MOVE_SHOOT | bits_CAP_WEAPON_RANGE_ATTACK1 | bits_CAP_AIM_GUN, false ) + npc.EnableNPCFlag( NPC_DISABLE_SENSING | NPC_IGNORE_ALL ) + npc.ClearMoveAnim() + npc.SetMoveAnim("sp_spectre_sprint_F") + npc.SetNoTarget( true ) // stop keeping track of any player and instead go for the harvester + npc.s.isSprinting = true } bool function TryDismemberStalker( entity npc, var damageInfo, entity attacker, int hitGroup ) @@ -603,4 +694,4 @@ vector function GetDeathForce() vector angles = <RandomFloatRange(-45,-75),RandomFloat(360),0> vector forward = AnglesToForward( angles ) return forward * RandomFloatRange( 0.25, 0.75 ) -}
\ No newline at end of file +} diff --git a/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_stationary_firing_positions.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_stationary_firing_positions.gnut index 50b6cc75..430de58a 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_stationary_firing_positions.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_stationary_firing_positions.gnut @@ -5,6 +5,7 @@ global function GetRandomStationaryPosition global function GetClosestAvailableStationaryPosition global function ClaimStationaryAIPosition global function ReleaseStationaryAIPosition +global function DebugDrawStationaryAiPositions global enum eStationaryAIPositionTypes { @@ -258,4 +259,44 @@ int function DistanceCompareClosestForStationaryAIPosition( ArrayDistanceEntryFo return -1 return 0; -}
\ No newline at end of file +} + + +void function DebugDrawStationaryAiPositions( int typeMask ) +{ + thread DebugDrawStationaryAiPositions_thread( typeMask ) +} + + +void function DebugDrawStationaryAiPositions_thread( int typeMask ) +{ + while( true ) + { + for( int i = 0; i < 4; i++ ) + { + if( ( 1 << i ) & typeMask ) + foreach( StationaryAIPosition a in file.stationaryPositions[i] ) + { + switch( i ) + { + case 0: + DebugDrawSphere( a.origin, 50, 255, 255, 0,false, 0.5 ) + case 1: + DebugDrawSphere( a.origin, 50, 0, 255, 255, false, 0.5 ) + case 2: + DebugDrawSphere( a.origin, 50, 0, 0, 255, false, 0.5 ) + case 3: + DebugDrawSphere( a.origin, 50, 255, 0, 255, false, 0.5 ) + } + + if( a.inUse ) + DebugDrawSphere( a.origin, 40, 255, 0, 0, false, 0.5 ) + else + DebugDrawSphere( a.origin, 40, 0, 255, 0, false, 0.5 ) + + } + } + wait 0.4 + } + +} diff --git a/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_turret.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_turret.gnut index 73813385..08d76f7d 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_turret.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_turret.gnut @@ -1,11 +1,16 @@ +untyped global function AiTurret_Init global function GetMegaTurretLinkedToPanel global function MegaTurretUsabilityFunc global function SetUsePromptForPanel +global function IsTurretActive +global function TurretRefundThink +global function RevivableTurret_DamageCallback +global function RevivableTurret_Revive void function AiTurret_Init() { - + RegisterSignal( "TurretOffline" ) } entity function GetMegaTurretLinkedToPanel( entity panel ) @@ -21,4 +26,108 @@ string function MegaTurretUsabilityFunc( var turret, var panel ) void function SetUsePromptForPanel( var panel, var turret ) { -}
\ No newline at end of file +} + +bool function IsTurretActive( entity turret ) +{ + // ----- Turret State ----- // + // TURRET_SEARCHING , TURRET_INACTIVE , TURRET_ACTIVE , TURRET_DEPLOYING , TURRET_RETIRING , TURRET_DEAD // + + bool turretsActive = turret.GetTurretState() == TURRET_DEPLOYING + turretsActive = turretsActive || turret.GetTurretState() == TURRET_SEARCHING + turretsActive = turretsActive || turret.GetTurretState() == TURRET_ACTIVE + return turretsActive +} + +void function TurretRefundThink( entity turret ) +{ + turret.EndSignal( "OnDestroy" ) + turret.EndSignal( "OnDeath" ) + turret.EndSignal( "CancelRefund" ) + turret.EndSignal( "TurretOffline" ) + + while( turret.e.burnReward == "" || !IsTurretActive( turret ) ){ + WaitFrame() + } + turret.SetUsable() + turret.SetUsableByGroup( "owner pilot" ) + turret.SetUsePrompts( "#REFUND_HOLD_USE", "#REFUND_PRESS_USE" ) + + entity player = expect entity( turret.WaitSignal( "OnPlayerUse" ).player ) + + if ( turret.e.burnReward == "" ) + return + + BurnMeter_GiveRewardDirect( player, turret.e.burnReward ) + entity weapon = player.GetOffhandWeapon( OFFHAND_INVENTORY ) + + // Defensive: meaning the boost didn't make it to the inventory for some reason + if ( weapon == null ) + return + + weapon.w.savedKillCount = int( turret.kv.killCount ) + turret.DisableTurret() + turret.Signal( "StopTurretLaser" ) + weapon.e.fd_roundDeployed = turret.e.fd_roundDeployed + + EmitSoundAtPosition( TEAM_UNASSIGNED, turret.GetOrigin(), "Emplacement_Move_Dissolve" ) + turret.Signal( "BoostRefunded" ) + turret.UnsetUsable() + turret.SetInvulnerable() + turret.Dissolve( ENTITY_DISSOLVE_CORE, Vector( 0, 0, 0 ), 100 ) +} + +void function RevivableTurret_DamageCallback( entity turret, var damageInfo ) +{ + if( turret.GetHealth() <= DamageInfo_GetDamage( damageInfo ) ) + { + turret.Signal( "TurretOffline" ) + turret.SetHealth( 1 ) + turret.SetUsable() + turret.SetUsableByGroup( "friendlies pilot" ) + turret.SetUsePrompts( "#TURRET_WAKEUP_HOLD_USE", "#TURRET_WAKEUP_PRESS_USE" ) + turret.useFunction = RevivableTurret_UseFunction + thread RevivableTurret_Kill( turret ) + DamageInfo_SetDamage( damageInfo, 0.0 ) + } +} + +function RevivableTurret_UseFunction( player , turret ) +{ + entity tur = expect entity( turret ) + entity ent = expect entity( player ) + entity owner = tur.GetBossPlayer() + if( ent != owner ) + { + int ownerEHandle = owner.GetEncodedEHandle() + AddPlayerScore( ent, "FDRepairTurret" ) + MessageToTeam( TEAM_MILITIA,eEventNotifications.FD_TurretRepair, null, ent, ownerEHandle ) + } + thread RevivableTurret_Revive( tur ) + return true +} + + +void function RevivableTurret_Revive( entity turret ) +{ + turret.UnsetUsable() + turret.SetHealth( turret.GetMaxHealth() ) + turret.ClearInvulnerable() + turret.Anim_ScriptedPlay( "deploy" ) + wait 1.0 + turret.EnableTurret() + turret.DisableNPCFlag( NPC_IGNORE_ALL ) + turret.SetNoTarget( false ) + thread TurretRefundThink( turret ) +} + +void function RevivableTurret_Kill( entity turret ) +{ + turret.EnableNPCFlag( NPC_IGNORE_ALL ) + turret.SetNoTarget( true ) + turret.SetInvulnerable() + turret.Anim_ScriptedPlay( "undeploy" ) + wait 1 + turret.SetNoTarget( true ) + turret.DisableTurret() +} diff --git a/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_turret_sentry.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_turret_sentry.gnut index e34b3082..5d0cff0a 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_turret_sentry.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_turret_sentry.gnut @@ -8,13 +8,14 @@ const SENTRY_TURRET_AIM_FX_BLUE = $"P_wpn_lasercannon_aim_short_blue" void function AiTurretSentry_Init() { PrecacheParticleSystem( DEAD_SENTRY_TURRET_FX ) - //PrecacheParticleSystem( SENTRY_TURRET_AIM_FX_RED ) - //PrecacheParticleSystem( SENTRY_TURRET_AIM_FX_BLUE ) + PrecacheParticleSystem( SENTRY_TURRET_AIM_FX_RED ) + PrecacheParticleSystem( SENTRY_TURRET_AIM_FX_BLUE ) //PrecacheParticleSystem( SENTRY_TURRET_AIM_FX2 ) AddSpawnCallback( "npc_turret_sentry", LightTurretSpawnFunction ) AddDeathCallback( "npc_turret_sentry", LightTurretDeathFX ) + RegisterSignal( "StopTurretLaser" ) //RegisterSignal( "TurretDisabled" ) //RegisterSignal( "HandleTargetDeath" ) //RegisterSignal( "OnPlayerDisconnectResetTurret" ) @@ -55,6 +56,7 @@ void function LightTurretSpawnFunction( entity turret ) void function SentryTurretAimLaser( entity turret ) { + EndSignal( turret, "StopTurretLaser" ) entity fx1 = PlayLoopFXOnEntity( SENTRY_TURRET_AIM_FX_RED, turret, "camera_glow", null, null, ENTITY_VISIBLE_TO_ENEMY ) entity fx2 = PlayLoopFXOnEntity( SENTRY_TURRET_AIM_FX_BLUE, turret, "camera_glow", null, null, ENTITY_VISIBLE_TO_FRIENDLY ) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/burnmeter/_burnmeter.gnut b/Northstar.CustomServers/mod/scripts/vscripts/burnmeter/_burnmeter.gnut index 56750352..eb4e111c 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/burnmeter/_burnmeter.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/burnmeter/_burnmeter.gnut @@ -67,6 +67,7 @@ void function BurnMeter_Init() AddCallback_OnClientConnected( InitBurncardsForLateJoiner )
AddCallback_OnPlayerRespawned( StartPhaseRewindLifetime )
+ AddCallback_OnPlayerRespawned( InitialisePermenantAmpedWeaponsForPlayer )
AddCallback_OnTitanBecomesPilot( RemoveAmpedWeaponsForTitanPilot )
// necessary signals
@@ -347,9 +348,10 @@ void function PlayerUsesAmpedWeaponsBurncardThreaded( entity player ) void function RemoveAmpedWeaponsForTitanPilot( entity player, entity titan )
{
- foreach ( entity weapon in player.GetMainWeapons() )
- foreach ( string mod in GetWeaponBurnMods( weapon.GetWeaponClassName() ) )
- weapon.RemoveMod( mod )
+ if ( !( "hasPermenantAmpedWeapons" in player.s ) || !player.s.hasPermenantAmpedWeapons )
+ foreach ( entity weapon in player.GetMainWeapons() )
+ foreach ( string mod in GetWeaponBurnMods( weapon.GetWeaponClassName() ) )
+ weapon.RemoveMod( mod )
}
void function PlayerUsesSmartPistolBurncard( entity player )
@@ -570,8 +572,15 @@ void function PlayerUsesNukeBurncardThreaded( entity player ) thread TitanEjectPlayer( titan, true )
}
+void function InitialisePermenantAmpedWeaponsForPlayer( entity player )
+{
+ player.s.hasPermenantAmpedWeapons <- false
+}
+
void function PlayerUsesPermanentAmpedWeaponsBurncard( entity player )
{
+ player.s.hasPermenantAmpedWeapons = true
+
array<entity> weapons = player.GetMainWeapons()
//weapons.extend( player.GetOffhandWeapons() ) // idk? unsure of vanilla behaviour here
foreach ( entity weapon in weapons )
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd.nut index 8a6b8bf0..a730eb90 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd.nut @@ -1,12 +1,2007 @@ +untyped + global function GamemodeFD_Init global function RateSpawnpoints_FD +global function startHarvester +global function IsHarvesterAlive +global function GetTargetNameForID + +global function DisableTitanSelection +global function DisableTitanSelectionForPlayer +global function EnableTitanSelection +global function EnableTitanSelectionForPlayer +global function FD_DropshipSetAnimationOverride + +enum eDropshipState{ + Idle, + InProgress, + Returning + _count_ +} + + + + +struct player_struct_fd{ + bool diedThisRound + int scoreThisRound + int moneyThisRound + array< entity > deployedEntityThisRound + /* + int totalMVPs + int mortarUnitsKilled + int moneySpend + int coresUsed + float longestTitanLife + int turretsRepaired + int moneyShared + float timeNearHarvester //dont know how to track + float longestLife + int heals //dont know what to track + int titanKills + float damageDealt + int harvesterHeals + int turretKills + */ + float lastRespawn + float lastTitanDrop + float lastNearHarvester + bool leaveHarvester +} + +global HarvesterStruct& fd_harvester +global vector shopPosition +global vector shopAngles = < 0, 0, 0 > +global vector FD_spawnPosition +global vector FD_spawnAngles = < 0, 0, 0 > +global table< string, array<vector> > routes +global array<entity> routeNodes +global array<entity> spawnedNPCs + + + + +struct { + array<entity> aiSpawnpoints + array<entity> smokePoints + array<float> harvesterDamageSource + bool havesterWasDamaged + bool harvesterShieldDown + float harvesterDamageTaken + table<entity, player_struct_fd> players + table<entity, table<string, float> > playerAwardStats + entity harvester_info + bool playersHaveTitans = false + bool waveRestart = false + + string animationOverride = "" + int dropshipState + int playersInShip + entity dropship + array<entity> playersInDropship +}file + + +const array<string> DROPSHIP_IDLE_ANIMS_POV = [ + + "ptpov_ds_coop_side_intro_gen_idle_B", + "ptpov_ds_coop_side_intro_gen_idle_A", + "ptpov_ds_coop_side_intro_gen_idle_C", + "ptpov_ds_coop_side_intro_gen_idle_D" +] + +const array<string> DROPSHIP_IDLE_ANIMS = [ + + "pt_ds_coop_side_intro_gen_idle_B", + "pt_ds_coop_side_intro_gen_idle_A", + "pt_ds_coop_side_intro_gen_idle_C", + "pt_ds_coop_side_intro_gen_idle_D" +] + +const array<string> DROPSHIP_EXIT_ANIMS_POV = [ + "ptpov_ds_coop_side_intro_gen_exit_B", + "ptpov_ds_coop_side_intro_gen_exit_A", + "ptpov_ds_coop_side_intro_gen_exit_C", + "ptpov_ds_coop_side_intro_gen_exit_D" +] + +const array<string> DROPSHIP_EXIT_ANIMS = [ + "pt_ds_coop_side_intro_gen_exit_B", + "pt_ds_coop_side_intro_gen_exit_A", + "pt_ds_coop_side_intro_gen_exit_C", + "pt_ds_coop_side_intro_gen_exit_D" +] void function GamemodeFD_Init() { PrecacheModel( MODEL_ATTRITION_BANK ) + PrecacheModel( $"models/humans/grunts/imc_grunt_shield_captain.mdl" ) + PrecacheParticleSystem( $"P_smokescreen_FD" ) + + RegisterSignal( "SniperSwitchedEnemy" ) // for use in SniperTitanThink behavior. + RegisterSignal( "FD_ReachedHarvester" ) + RegisterSignal( "OnFailedToPath" ) + + SetRoundBased( true ) + SetShouldUseRoundWinningKillReplay( false ) + Riff_ForceBoostAvailability( eBoostAvailability.Disabled ) + PlayerEarnMeter_SetEnabled( false ) + SetShouldUsePickLoadoutScreen( true ) + SetAllowLoadoutChangeFunc( FD_ShouldAllowChangeLoadout ) + SetGetDifficultyFunc( FD_GetDifficultyLevel ) + TeamTitanSelectMenu_Init() // show the titan select menu in this mode + + //general Callbacks + AddCallback_EntitiesDidLoad( LoadEntities ) + AddCallback_GameStateEnter( eGameState.Prematch,FD_createHarvester ) + AddCallback_GameStateEnter( eGameState.Playing, startMainGameLoop ) + AddCallback_OnRoundEndCleanup( FD_NPCCleanup ) + AddCallback_OnClientConnected( GamemodeFD_InitPlayer ) + AddCallback_OnClientDisconnected( OnPlayerDisconnectedOrDestroyed ) + AddCallback_OnPlayerGetsNewPilotLoadout( FD_OnPlayerGetsNewPilotLoadout ) + ClassicMP_SetEpilogue( FD_SetupEpilogue ) + + //Damage Callbacks + AddDamageByCallback( "player", FD_DamageByPlayerCallback) + AddDamageCallback( "player", DamageScaleByDifficulty ) + AddDamageCallback( "npc_titan", DamageScaleByDifficulty ) + AddDamageCallback( "npc_turret_sentry", DamageScaleByDifficulty ) + AddDamageCallback( "npc_turret_sentry",RevivableTurret_DamageCallback) + //Spawn Callbacks + AddSpawnCallback( "npc_titan", HealthScaleByDifficulty ) + AddSpawnCallback( "npc_super_spectre", HealthScaleByDifficulty ) + AddCallback_OnPlayerRespawned( FD_PlayerRespawnCallback ) + AddSpawnCallback("npc_turret_sentry", AddTurretSentry ) + //death Callbacks + AddCallback_OnNPCKilled( OnNpcDeath ) + AddCallback_OnPlayerKilled( GamemodeFD_OnPlayerKilled ) + AddDeathCallback( "npc_frag_drone", OnTickDeath ) // ticks dont come up in the other callback because of course they dont + + //Command Callbacks + AddClientCommandCallback( "FD_ToggleReady", ClientCommandCallbackToggleReady ) + AddClientCommandCallback( "FD_UseHarvesterShieldBoost", useShieldBoost ) + + //shop Callback + SetBoostPurchaseCallback( FD_BoostPurchaseCallback ) + SetTeamReserveInteractCallback( FD_TeamReserveDepositOrWithdrawCallback ) + + //earn meter + ScoreEvent_SetupEarnMeterValuesForMixedModes() + + //Data Collection + AddStunLaserHealCallback( FD_StunLaserHealTeammate ) + AddBatteryHealCallback( FD_BatteryHealTeammate ) + AddSmokeHealCallback( FD_SmokeHealTeammate ) + SetUsedCoreCallback( FD_UsedCoreCallback ) + + //todo:are pointValueOverride exist? + //Score Event + AddArcTrapTriggeredCallback( FD_OnArcTrapTriggered ) + AddArcWaveDamageCallback( FD_OnArcWaveDamage ) + AddOnTetherCallback( FD_OnTetherTrapTriggered ) + AddSonarStartCallback( FD_OnSonarStart ) +} + +// this might need updating when we do dropship things +bool function FD_ShouldAllowChangeLoadout( entity player ) +{ + return GetGlobalNetTime( "FD_nextWaveStartTime" ) > Time() +} + +void function FD_BoostPurchaseCallback( entity player, BoostStoreData data ) +{ + file.playerAwardStats[player]["moneySpent"] += float( data.cost ) +} + +void function FD_PlayerRespawnCallback( entity player ) +{ + if( player in file.players ) + file.players[player].lastRespawn = Time() + + if( GetCurrentPlaylistVarInt( "fd_at_unlimited_ammo", 1 ) ) + FD_GivePlayerInfiniteAntiTitanAmmo( player ) + + if ( !file.playersHaveTitans ) + { + // why in the fuck do i need to WaitFrame() here, this sucks + thread PlayerEarnMeter_SetMode_Threaded( player, 0 ) + } + + if( file.dropshipState == eDropshipState.Returning ) + return + if( GetGameState() != eGameState.Playing) + return + + if( player.GetPersistentVar( "spawnAsTitan" ) ) + return + + player.SetInvulnerable() + if( file.dropshipState == eDropshipState.Idle ) + { + thread FD_DropshipSpawnDropship() + } + //Attach player + FirstPersonSequenceStruct idleSequence + idleSequence.firstPersonAnim = DROPSHIP_IDLE_ANIMS_POV[ file.playersInShip ] + idleSequence.thirdPersonAnim = DROPSHIP_IDLE_ANIMS[ file.playersInShip++ ] + idleSequence.attachment = "ORIGIN" + idleSequence.teleport = true + idleSequence.viewConeFunction = ViewConeFree + idleSequence.hideProxy = true + thread FirstPersonSequence( idleSequence, player, file.dropship ) + file.playersInDropship.append( player ) +} + + +void function PlayerEarnMeter_SetMode_Threaded( entity player, int mode ) +{ + WaitFrame() + if ( IsValid( player ) ) + PlayerEarnMeter_SetMode( player, mode ) +} + +void function FD_OnPlayerGetsNewPilotLoadout( entity player, PilotLoadoutDef loadout ) +{ + if( GetCurrentPlaylistVarInt( "fd_at_unlimited_ammo", 1 ) ) + FD_GivePlayerInfiniteAntiTitanAmmo( player ) +} + +void function FD_GivePlayerInfiniteAntiTitanAmmo( entity player ) +{ + array<entity> weapons = player.GetMainWeapons() + foreach ( entity weaponEnt in weapons ) + { + if ( weaponEnt.GetWeaponInfoFileKeyField( "menu_category" ) != "at" ) + continue + + if( !weaponEnt.HasMod( "at_unlimited_ammo" ) ) + { + array<string> mods = weaponEnt.GetMods() + mods.append( "at_unlimited_ammo" ) + weaponEnt.SetMods( mods ) + } + } +} + +void function FD_TeamReserveDepositOrWithdrawCallback( entity player, string action, int amount ) +{ + switch( action ) + { + case"deposit": + file.playerAwardStats[player]["moneyShared"] += float( amount ) + break + case"withdraw": + file.playerAwardStats[player]["moneyShared"] -= float( amount ) + break + } +} +void function GamemodeFD_OnPlayerKilled( entity victim, entity attacker, var damageInfo ) +{ + //set longest Time alive for end awards + float timeAlive = Time() - file.players[victim].lastRespawn + if(timeAlive>file.playerAwardStats[victim]["longestLife"]) + file.playerAwardStats[victim]["longestLife"] = timeAlive + + //set died this round for round end money boni + file.players[victim].diedThisRound = true + + //play voicelines for amount of players alive + array<entity> militiaplayers = GetPlayerArrayOfTeam( TEAM_MILITIA ) + int deaths = 0 + foreach ( entity player in militiaplayers ) + if ( !IsAlive( player ) ) + deaths++ + + foreach( entity player in GetPlayerArray() ) + { + if ( player == victim || player.GetTeam() != TEAM_MILITIA ) + continue + + if ( deaths == 1 ) // only one pilot died + PlayFactionDialogueToPlayer( "fd_singlePilotDown", player ) + else if ( deaths > 1 && deaths < militiaplayers.len() - 1 ) // multiple pilots died but at least one alive + PlayFactionDialogueToPlayer( "fd_multiPilotDown", player ) + else if ( deaths == militiaplayers.len() - 1 ) // ur shit out of luck ur the only survivor + PlayFactionDialogueToPlayer( "fd_onlyPlayerIsAlive", player ) + } +} + +void function FD_UsedCoreCallback( entity titan, entity weapon ) +{ + if( !( titan in file.players ) ) + { + return + } + file.playerAwardStats[titan]["coresUsed"] += 1 +} + +void function GamemodeFD_InitPlayer( entity player ) +{ + player_struct_fd data + data.diedThisRound = false + data.leaveHarvester = true + file.players[player] <- data + table<string, float> awardStats + foreach( string statRef in GetFDStatRefs() ) + { + awardStats[statRef] <- 0.0 + } + file.playerAwardStats[player] <- awardStats + thread SetTurretSettings_threaded( player ) + // only start the highlight when we start playing, not during dropship + if ( GetGameState() >= eGameState.Playing ) + Highlight_SetFriendlyHighlight( player, "sp_friendly_hero" ) + + if( file.playersHaveTitans ) // first wave is index 0 + { + PlayerEarnMeter_AddEarnedAndOwned( player, 1.0, 1.0 ) + } + // unfortunate that i cant seem to find a nice callback for them exiting that menu but thisll have to do + thread TryDisableTitanSelectionForPlayerAfterDelay( player, TEAM_TITAN_SELECT_DURATION_MIDGAME ) + thread TrackDeployedArcTrapThisRound( player ) +} + +void function TrackDeployedArcTrapThisRound( entity player ) +{ + player.EndSignal( "OnDestroy" ) + + OnThreadEnd( + function() : ( player ) + { + if ( IsValid( player ) ) + OnPlayerDisconnectedOrDestroyed( player ) + else + ClearInValidTurret() + } + ) + + while( IsValid( player ) ) + { + entity ArcTrap = expect entity ( player.WaitSignal( "DeployArcTrap" ).projectile ) + file.players[ player ].deployedEntityThisRound.append( ArcTrap ) + AddEntityDestroyedCallback( ArcTrap, FD_OnEntityDestroyed ) + } +} + +void function TryDisableTitanSelectionForPlayerAfterDelay( entity player, float waitAmount ) +{ + player.EndSignal( "OnDestroy" )//Do a crash protect when wait delay + + OnThreadEnd( + function() : ( player ) + { + if( IsValid( player ) ) + { + DisableTitanSelectionForPlayer( player ) + } + } + ) + + wait waitAmount + if ( file.playersHaveTitans ) + DisableTitanSelectionForPlayer( player ) +} + +void function SetTurretSettings_threaded( entity player ) +{ //has to be delayed because PlayerConnect callbacks get called in wrong order + WaitFrame() + DeployableTurret_SetAISettingsForPlayer_AP( player, "npc_turret_sentry_burn_card_ap_fd" ) + DeployableTurret_SetAISettingsForPlayer_AT( player, "npc_turret_sentry_burn_card_at_fd" ) +} + +void function OnTickDeath( entity victim, var damageInfo ) +{ + int findIndex = spawnedNPCs.find( victim ) + if ( findIndex != -1 ) + { + spawnedNPCs.remove( findIndex ) + + SetGlobalNetInt( "FD_AICount_Ticks", GetGlobalNetInt( "FD_AICount_Ticks" ) -1 ) + + SetGlobalNetInt( "FD_AICount_Current", GetGlobalNetInt( "FD_AICount_Current" ) -1 ) + } +} + +void function OnNpcDeath( entity victim, entity attacker, var damageInfo ) +{ + if( attacker.GetClassName() == "npc_turret_sentry" && IsValidPlayer( attacker.GetBossPlayer() ) ) + { + file.playerAwardStats[ attacker.GetBossPlayer() ]["turretKills"]++ + } + if( victim.IsTitan() && attacker in file.players ) + file.playerAwardStats[attacker]["titanKills"]++ + int victimTypeID = FD_GetAITypeID_ByString( victim.GetTargetName() ) + if( ( victimTypeID == eFD_AITypeIDs.TITAN_MORTAR ) || ( victimTypeID == eFD_AITypeIDs.SPECTRE_MORTAR ) ) + if( attacker in file.players ) + file.playerAwardStats[attacker]["mortarUnitsKilled"]++ + int findIndex = spawnedNPCs.find( victim ) + if ( findIndex != -1 ) + { + spawnedNPCs.remove( findIndex ) + + string netIndex = GetAiNetIdFromTargetName( victim.GetTargetName() ) + if( netIndex != "" ) + SetGlobalNetInt( netIndex, GetGlobalNetInt( netIndex ) - 1 ) + + SetGlobalNetInt( "FD_AICount_Current", GetGlobalNetInt( "FD_AICount_Current" ) - 1 ) + } + + if ( victim.GetOwner() == attacker || !attacker.IsPlayer() || ( attacker == victim ) || ( victim.GetBossPlayer() == attacker ) || victim.GetClassName() == "npc_turret_sentry" ) + return + + int playerScore = 0 + int money = 0 + int scriptDamageType = DamageInfo_GetCustomDamageType( damageInfo ) + int damageSourceId = DamageInfo_GetDamageSourceIdentifier( damageInfo ) + + if ( victim.IsNPC() ) + { + string eventName = FD_GetScoreEventName( victim.GetClassName() ) + playerScore = ScoreEvent_GetPointValue( GetScoreEvent( eventName ) ) + + switch ( victim.GetClassName() ) + { + case "npc_soldier": + money = 5 + break + case "npc_drone": + case "npc_spectre": + money = 10 + break + case "npc_stalker": + money = 15 + break + case "npc_super_spectre": + money = 20 + break + default: + money = 0 // titans seem to total up to 50 money undoomed health + } + foreach( player in GetPlayerArray() ) + Remote_CallFunction_NonReplay( player, "ServerCallback_OnTitanKilled", attacker.GetEncodedEHandle(), victim.GetEncodedEHandle(), scriptDamageType, damageSourceId ) + } + if ( money != 0 ) + AddMoneyToPlayer( attacker , money ) + + attacker.AddToPlayerGameStat( PGS_ASSAULT_SCORE, playerScore ) // seems to be how combat score is counted + file.players[attacker].scoreThisRound += playerScore + table<int, bool> alreadyAssisted + foreach( DamageHistoryStruct attackerInfo in victim.e.recentDamageHistory ) + { + if ( !IsValid( attackerInfo.attacker ) || !attackerInfo.attacker.IsPlayer() || attackerInfo.attacker == victim ) + continue + + bool exists = attackerInfo.attacker.GetEncodedEHandle() in alreadyAssisted ? true : false + if( attackerInfo.attacker != attacker && !exists ) + { + alreadyAssisted[attackerInfo.attacker.GetEncodedEHandle()] <- true + attackerInfo.attacker.AddToPlayerGameStat( PGS_DEFENSE_SCORE, playerScore ) // i assume this is how support score gets added + } + } + + +} + +void function RateSpawnpoints_FD( int _0, array<entity> _1, int _2, entity _3 ) +{ + +} + +bool function useShieldBoost( entity player, array<string> args ) +{ + if( ( GetGlobalNetTime( "FD_harvesterInvulTime" ) < Time() ) && ( player.GetPlayerNetInt( "numHarvesterShieldBoost" ) > 0 ) ) + { + fd_harvester.harvester.SetShieldHealth( fd_harvester.harvester.GetShieldHealthMax() ) + SetGlobalNetTime( "FD_harvesterInvulTime", Time() + 5 ) + AddPlayerScore( player, "FDShieldHarvester" ) + MessageToTeam( TEAM_MILITIA,eEventNotifications.FD_PlayerBoostedHarvesterShield, null, player ) + player.SetPlayerNetInt( "numHarvesterShieldBoost", player.GetPlayerNetInt( "numHarvesterShieldBoost" ) - 1 ) + file.playerAwardStats[player]["harvesterHeals"]++ + } + return true +} + +void function startMainGameLoop() +{ + // only start the highlight when we start playing, not during dropship + foreach ( entity player in GetPlayerArray() ) + Highlight_SetFriendlyHighlight( player, "sp_friendly_hero" ) + + thread mainGameLoop() +} + +void function mainGameLoop() +{ + startHarvester() + + bool showShop = false + for( int i = GetGlobalNetInt( "FD_currentWave" ); i < waveEvents.len(); i++ ) + { + if( file.waveRestart ) + { + showShop = true + foreach( entity player in GetPlayerArray() ) + { + SetMoneyForPlayer( player, file.players[player].moneyThisRound ) + player.SetPlayerNetInt( "numHarvesterShieldBoost", 0 ) + player.SetPlayerNetInt( "numSuperRodeoGrenades", 0 ) + PlayerInventory_TakeAllInventoryItems( player ) + } + SetGlobalNetTime( "FD_nextWaveStartTime", Time() + 75 ) + } + + if( !runWave( i, showShop ) ) + break + + if( i == 0 ) + { + PlayerEarnMeter_SetEnabled( true ) + showShop = true + foreach( entity player in GetPlayerArray() ) + { + PlayerEarnMeter_SetMode( player, 1 ) // show the earn meter + PlayerEarnMeter_AddEarnedAndOwned( player, 1.0, 1.0 ) + } + file.playersHaveTitans = true + DisableTitanSelection() + } + } + + // end of game + EnableTitanSelection() + +} + + + +array<int> function getHighestEnemyAmountsForWave( int waveIndex ) +{ + table<int,int> npcs + npcs[eFD_AITypeIDs.TITAN] <- 0 + npcs[eFD_AITypeIDs.TITAN_NUKE] <- 0 + npcs[eFD_AITypeIDs.TITAN_ARC] <- 0 + npcs[eFD_AITypeIDs.TITAN_MORTAR] <- 0 + npcs[eFD_AITypeIDs.GRUNT] <- 0 + npcs[eFD_AITypeIDs.SPECTRE] <- 0 + npcs[eFD_AITypeIDs.SPECTRE_MORTAR] <- 0 + npcs[eFD_AITypeIDs.STALKER] <- 0 + npcs[eFD_AITypeIDs.REAPER] <- 0 + npcs[eFD_AITypeIDs.TICK] <- 0 + npcs[eFD_AITypeIDs.DRONE] <- 0 + npcs[eFD_AITypeIDs.DRONE_CLOAK] <- 0 + // npcs[eFD_AITypeIDs.RONIN] <- 0 + // npcs[eFD_AITypeIDs.NORTHSTAR] <- 0 + // npcs[eFD_AITypeIDs.SCORCH] <- 0 + // npcs[eFD_AITypeIDs.LEGION] <- 0 + // npcs[eFD_AITypeIDs.TONE] <- 0 + // npcs[eFD_AITypeIDs.ION] <- 0 + // npcs[eFD_AITypeIDs.MONARCH] <- 0 + // npcs[eFD_AITypeIDs.TITAN_SNIPER] <- 0 + + + foreach( WaveEvent e in waveEvents[waveIndex] ) + { + if( e.spawnEvent.spawnAmount == 0 ) + continue + switch( e.spawnEvent.spawnType ) + { + case( eFD_AITypeIDs.TITAN ): + case( eFD_AITypeIDs.RONIN ): + case( eFD_AITypeIDs.NORTHSTAR ): + case( eFD_AITypeIDs.SCORCH ): + case( eFD_AITypeIDs.TONE ): + case( eFD_AITypeIDs.ION ): + case( eFD_AITypeIDs.MONARCH ): + case( eFD_AITypeIDs.LEGION ): + case( eFD_AITypeIDs.TITAN_SNIPER ): + npcs[eFD_AITypeIDs.TITAN] += e.spawnEvent.spawnAmount + break + default: + npcs[e.spawnEvent.spawnType] += e.spawnEvent.spawnAmount + } + } + array<int> ret = [ -1, -1, -1, -1, -1, -1, -1, -1, -1 ] + foreach( int key, int value in npcs ) + { + if( value == 0 ) + continue + int lowestArrayIndex = 0 + bool keyIsSet = false + foreach( index, int arrayValue in ret ) + { + if( arrayValue == -1 ) + { + ret[index] = key + keyIsSet = true + break + } + if( npcs[ ret[lowestArrayIndex] ] > npcs[ ret[index] ] ) + lowestArrayIndex = index + } + if( ( !keyIsSet ) && ( npcs[ ret[lowestArrayIndex] ] < value ) ) + ret[lowestArrayIndex] = key + } + foreach( int val in ret ) + { + printt( "ArrayVal", val ) + } + return ret + +} +void function SetEnemyAmountNetVars( int waveIndex ) +{ + int total = 0 + table<int,int> npcs + npcs[eFD_AITypeIDs.TITAN] <- 0 + npcs[eFD_AITypeIDs.TITAN_NUKE] <- 0 + npcs[eFD_AITypeIDs.TITAN_ARC] <- 0 + npcs[eFD_AITypeIDs.TITAN_MORTAR] <- 0 + npcs[eFD_AITypeIDs.GRUNT] <- 0 + npcs[eFD_AITypeIDs.SPECTRE] <- 0 + npcs[eFD_AITypeIDs.SPECTRE_MORTAR] <- 0 + npcs[eFD_AITypeIDs.STALKER] <- 0 + npcs[eFD_AITypeIDs.REAPER] <- 0 + npcs[eFD_AITypeIDs.TICK] <- 0 + npcs[eFD_AITypeIDs.DRONE] <- 0 + npcs[eFD_AITypeIDs.DRONE_CLOAK] <- 0 + // npcs[eFD_AITypeIDs.RONIN] <- 0 + // npcs[eFD_AITypeIDs.NORTHSTAR] <- 0 + // npcs[eFD_AITypeIDs.SCORCH] <- 0 + // npcs[eFD_AITypeIDs.LEGION] <- 0 + // npcs[eFD_AITypeIDs.TONE] <- 0 + // npcs[eFD_AITypeIDs.ION] <- 0 + // npcs[eFD_AITypeIDs.MONARCH] <- 0 + // npcs[eFD_AITypeIDs.TITAN_SNIPER] <- 0 + + + foreach( WaveEvent e in waveEvents[waveIndex] ) + { + if( e.spawnEvent.spawnAmount == 0 ) + continue + switch( e.spawnEvent.spawnType ) + { + case( eFD_AITypeIDs.TITAN ): + case( eFD_AITypeIDs.RONIN ): + case( eFD_AITypeIDs.NORTHSTAR ): + case( eFD_AITypeIDs.SCORCH ): + case( eFD_AITypeIDs.TONE ): + case( eFD_AITypeIDs.ION ): + case( eFD_AITypeIDs.MONARCH ): + case( eFD_AITypeIDs.LEGION ): + case( eFD_AITypeIDs.TITAN_SNIPER ): + npcs[eFD_AITypeIDs.TITAN] += e.spawnEvent.spawnAmount + break + default: + npcs[e.spawnEvent.spawnType] += e.spawnEvent.spawnAmount + + } + total+= e.spawnEvent.spawnAmount + } + SetGlobalNetInt( "FD_AICount_Titan", npcs[eFD_AITypeIDs.TITAN] ) + SetGlobalNetInt( "FD_AICount_Titan_Nuke", npcs[eFD_AITypeIDs.TITAN_NUKE] ) + SetGlobalNetInt( "FD_AICount_Titan_Mortar", npcs[eFD_AITypeIDs.TITAN_MORTAR] ) + SetGlobalNetInt( "FD_AICount_Titan_Arc", npcs[eFD_AITypeIDs.TITAN_ARC] ) + SetGlobalNetInt( "FD_AICount_Grunt", npcs[eFD_AITypeIDs.GRUNT] ) + SetGlobalNetInt( "FD_AICount_Spectre", npcs[eFD_AITypeIDs.SPECTRE] ) + SetGlobalNetInt( "FD_AICount_Spectre_Mortar", npcs[eFD_AITypeIDs.SPECTRE_MORTAR] ) + SetGlobalNetInt( "FD_AICount_Stalker", npcs[eFD_AITypeIDs.STALKER] ) + SetGlobalNetInt( "FD_AICount_Reaper", npcs[eFD_AITypeIDs.REAPER] ) + SetGlobalNetInt( "FD_AICount_Ticks", npcs[eFD_AITypeIDs.TICK] ) + SetGlobalNetInt( "FD_AICount_Drone", npcs[eFD_AITypeIDs.DRONE] ) + SetGlobalNetInt( "FD_AICount_Drone_Cloak", npcs[eFD_AITypeIDs.DRONE_CLOAK] ) + SetGlobalNetInt( "FD_AICount_Current", total ) + SetGlobalNetInt( "FD_AICount_Total", total ) + +} + + + +bool function runWave( int waveIndex, bool shouldDoBuyTime ) +{ + + SetGlobalNetInt( "FD_currentWave", waveIndex ) + file.havesterWasDamaged = false + file.harvesterShieldDown = false + SetEnemyAmountNetVars( waveIndex ) + for( int i = 0; i < 20; i++ )//Number of npc type ids + { + file.harvesterDamageSource.append( 0.0 ) + } + foreach( entity player in GetPlayerArray() ) + { + file.players[player].diedThisRound = false + file.players[player].scoreThisRound = 0 + file.players[player].moneyThisRound = GetPlayerMoney( player ) + file.players[ player ].deployedEntityThisRound.clear() + } + array<int> enemys = getHighestEnemyAmountsForWave( waveIndex ) + + foreach( entity player in GetPlayerArray() ) + { + Remote_CallFunction_NonReplay( player, "ServerCallback_FD_AnnouncePreParty", enemys[0], enemys[1], enemys[2], enemys[3], enemys[4], enemys[5], enemys[6], enemys[7], enemys[8] ) + } + if( file.waveRestart ) + { + file.waveRestart = false + MessageToTeam( TEAM_MILITIA,eEventNotifications.FD_WaveRestart ) + } + if( shouldDoBuyTime ) + { + SetGlobalNetInt( "FD_waveState", WAVE_STATE_BREAK ) + OpenBoostStores() + entity parentCrate = GetBoostStores()[0].GetParent() + parentCrate.Minimap_AlwaysShow( TEAM_MILITIA, null ) + Minimap_PingForTeam( TEAM_MILITIA, shopPosition, 150, 5, TEAM_COLOR_YOU / 255.0, 5 ) + foreach( entity player in GetPlayerArray() ) + Remote_CallFunction_NonReplay( player, "ServerCallback_FD_NotifyStoreOpen" ) + while( Time() < GetGlobalNetTime( "FD_nextWaveStartTime" ) ) + { + if( allPlayersReady() ) + SetGlobalNetTime( "FD_nextWaveStartTime", Time() ) + WaitFrame() + } + parentCrate.Minimap_Hide( TEAM_MILITIA, null ) + CloseBoostStores() + MessageToTeam( TEAM_MILITIA, eEventNotifications.FD_StoreClosing ) + } + + //SetGlobalNetTime("FD_nextWaveStartTime",Time()+10) + wait 10 + SetGlobalNetInt( "FD_waveState", WAVE_STATE_INCOMING ) + foreach( entity player in GetPlayerArray() ) + { + Remote_CallFunction_NonReplay( player, "ServerCallback_FD_ClearPreParty" ) + player.SetPlayerNetBool( "FD_readyForNextWave", false ) + } + SetGlobalNetBool( "FD_waveActive", true ) + MessageToTeam( TEAM_MILITIA, eEventNotifications.FD_AnnounceWaveStart ) + SetGlobalNetInt( "FD_waveState", WAVE_STATE_BREAK ) + + //main wave loop + thread SetWaveStateReady() + executeWave() + SetGlobalNetInt( "FD_waveState", WAVE_STATE_COMPLETE ) + if( !IsHarvesterAlive( fd_harvester.harvester ) ) + { + float totalDamage = 0.0 + array<float> highestDamage = [ 0.0, 0.0, 0.0 ] + array<int> highestDamageSource = [ -1, -1, -1 ] + foreach(index,float damage in file.harvesterDamageSource) + { + totalDamage += damage + if( highestDamage[0] < damage ) + { + highestDamage[2] = highestDamage[1] + highestDamageSource[2] = highestDamageSource[1] + highestDamage[1] = highestDamage[0] + highestDamageSource[1] = highestDamageSource[0] + highestDamageSource[0] = index + highestDamage[0] = damage + } + else if( highestDamage[1] < damage ) + { + highestDamage[2] = highestDamage[1] + highestDamageSource[2] = highestDamageSource[1] + highestDamage[1] = damage + highestDamageSource[1] = index + } + else if( highestDamage[2] < damage ) + { + highestDamage[2] = damage + highestDamageSource[2] = index + } + } + + foreach( entity player in GetPlayerArray() ) + { + Remote_CallFunction_NonReplay( player, "ServerCallback_FD_DisplayHarvesterKiller", GetGlobalNetInt( "FD_restartsRemaining" ), getHintForTypeId( highestDamageSource[0] ), highestDamageSource[0], highestDamage[0] / totalDamage, highestDamageSource[1], highestDamage[1] / totalDamage , highestDamageSource[2], highestDamage[2] / totalDamage ) + } + + if( GetGlobalNetInt( "FD_restartsRemaining" ) > 0 ) + FD_DecrementRestarts() + else + SetRoundBased(false) + + file.waveRestart = true //wave restart point + SetWinner( TEAM_IMC )//restart round + spawnedNPCs = [] // reset npcs count + restetWaveEvents() + foreach( player in GetPlayerArray() ) + PlayerEarnMeter_AddEarnedAndOwned( player, 1.0, 1.0 ) + return false + } + + + wait 2 + //wave end + + SetGlobalNetBool( "FD_waveActive", false ) + MessageToTeam( TEAM_MILITIA, eEventNotifications.FD_AnnounceWaveEnd ) + + if ( isFinalWave() && IsHarvesterAlive( fd_harvester.harvester ) ) + { + //Game won code + MessageToTeam( TEAM_MILITIA, eEventNotifications.FD_AnnounceWaveEnd ) + foreach( entity player in GetPlayerArray() ) + { + AddPlayerScore( player, "FDTeamWave" ) + } + wait 1 + int highestScore = 0; + entity highestScore_player = GetPlayerArray()[0] + foreach( entity player in GetPlayerArray() ) + { + + if( !file.players[player].diedThisRound ) + AddPlayerScore( player, "FDDidntDie" ) + if( highestScore < file.players[player].scoreThisRound ) + { + highestScore = file.players[player].scoreThisRound + highestScore_player = player + } + + } + file.playerAwardStats[highestScore_player]["mvp"]++ + AddPlayerScore( highestScore_player, "FDWaveMVP" ) + wait 1 + foreach( entity player in GetPlayerArray() ) + if( !file.havesterWasDamaged ) + AddPlayerScore( player, "FDTeamFlawlessWave" ) + + foreach(entity player in GetPlayerArray() ) + { + if( IsAlive( player ) ) + { + float timeAlive = Time() - file.players[player].lastRespawn + if(timeAlive>file.playerAwardStats[player]["longestLife"]) + file.playerAwardStats[player]["longestLife"] = timeAlive + } + if( IsValid( player.GetPetTitan ) ) + { + float timeAlive = Time() - file.players[player].lastTitanDrop + if(timeAlive>file.playerAwardStats[player]["longestTitanLife"]) + file.playerAwardStats[player]["longestTitanLife"] = timeAlive + } + } + + + + SetRoundBased(false) + SetWinner(TEAM_MILITIA) + PlayFactionDialogueToTeam( "fd_matchVictory", TEAM_MILITIA ) + return true + } + + if(!file.havesterWasDamaged) + { + PlayFactionDialogueToTeam( "fd_waveRecapPerfect", TEAM_MILITIA ) + wait 5 + } + else + { + float damagepercent = ( ( file.harvesterDamageTaken / fd_harvester.harvester.GetMaxHealth().tofloat() ) * 100 ) + float healthpercent = ( ( fd_harvester.harvester.GetHealth().tofloat() / fd_harvester.harvester.GetMaxHealth() ) * 100 ) + if ( damagepercent < 5 ) // if less than 5% damage taken + PlayFactionDialogueToTeam( "fd_waveRecapNearPerfect", TEAM_MILITIA ) + else if ( healthpercent < 15 ) // if less than 15% health remains and more than 5% damage taken + PlayFactionDialogueToTeam( "fd_waveRecapLowHealth", TEAM_MILITIA ) + wait 5 + } + + if ( isSecondWave() ) + { + // supposed to add dialogues like "GOOD WORK TEAM" then "YOUR TITAN IS READY" + // done ^ + PlayFactionDialogueToTeam( "fd_titanReadyNag" , TEAM_MILITIA ) + wait 5 + } + + //Player scoring + MessageToTeam( TEAM_MILITIA, eEventNotifications.FD_NotifyWaveBonusIncoming ) + wait 2 + foreach( entity player in GetPlayerArray() ) + { + if ( isSecondWave() ) + PlayFactionDialogueToPlayer( "fd_wavePayoutFirst", player ) + else + PlayFactionDialogueToPlayer( "fd_wavePayoutAddtnl", player ) + AddPlayerScore( player, "FDTeamWave" ) + AddMoneyToPlayer( player, GetCurrentPlaylistVarInt( "fd_money_per_round", 600 ) ) + // is this in the right place? do we want to be adding for each player? + // this function is called "Set" but in reality it is "Add" + SetJoinInProgressBonus( GetCurrentPlaylistVarInt( "fd_money_per_round" ,600 ) ) + EmitSoundOnEntityOnlyToPlayer( player, player, "HUD_MP_BountyHunt_BankBonusPts_Deposit_Start_1P" ) + } + wait 1 + foreach( entity player in GetPlayerArray() ) + { + if( !file.players[player].diedThisRound ) + { + AddPlayerScore( player, "FDDidntDie" ) + player.AddToPlayerGameStat( PGS_ASSAULT_SCORE, FD_SCORE_DIDNT_DIE ) + } + AddMoneyToPlayer( player, 100 ) + EmitSoundOnEntityOnlyToPlayer( player, player, "HUD_MP_BountyHunt_BankBonusPts_Deposit_Start_1P" ) + } + wait 1 + int highestScore = 0; + entity highestScore_player = GetPlayerArray()[0] + foreach( entity player in GetPlayerArray() ) + { + if( highestScore < file.players[player].scoreThisRound ) + { + highestScore = file.players[player].scoreThisRound + highestScore_player = player + } + } + file.playerAwardStats[highestScore_player]["mvp"]++ + AddPlayerScore( highestScore_player, "FDWaveMVP" ) + AddMoneyToPlayer( highestScore_player, 100 ) + highestScore_player.AddToPlayerGameStat( PGS_ASSAULT_SCORE, FD_SCORE_MVP ) + EmitSoundOnEntityOnlyToPlayer( highestScore_player, highestScore_player, "HUD_MP_BountyHunt_BankBonusPts_Deposit_Start_1P" ) + foreach( entity player in GetPlayerArray() ) + { + Remote_CallFunction_NonReplay( player, "ServerCallback_FD_NotifyMVP", highestScore_player.GetEncodedEHandle() ) + } + wait 1 + foreach( entity player in GetPlayerArray() ) + { + + if( !file.havesterWasDamaged ) + { + AddPlayerScore( player, "FDTeamFlawlessWave" ) + AddMoneyToPlayer( player, 100 ) + player.AddToPlayerGameStat( PGS_ASSAULT_SCORE, FD_SCORE_TEAM_FLAWLESS_WAVE ) + EmitSoundOnEntityOnlyToPlayer( player, player, "HUD_MP_BountyHunt_BankBonusPts_Deposit_Start_1P" ) + } + } + + wait 1 + + if( waveIndex<waveEvents.len() ) + SetGlobalNetTime( "FD_nextWaveStartTime", Time() + 75 ) + + return true + +} + +void function SetWaveStateReady() +{ + wait 5 + SetGlobalNetInt( "FD_waveState", WAVE_STATE_IN_PROGRESS ) +} + +void function FD_StunLaserHealTeammate( entity player, entity target, int shieldRestoreAmount ) +{ + if( IsValid( player ) && player in file.players ){ + file.playerAwardStats[player]["heals"] += float( shieldRestoreAmount ) + player.AddToPlayerGameStat( PGS_DEFENSE_SCORE, shieldRestoreAmount / 100 ) + file.players[ player ].scoreThisRound += shieldRestoreAmount / 100 + } +} + +void function FD_SmokeHealTeammate( entity player, entity target, int shieldRestoreAmount ) +{ + if( IsValid( player ) && player in file.players ){ + file.playerAwardStats[player]["heals"] += float( shieldRestoreAmount ) + player.AddToPlayerGameStat( PGS_DEFENSE_SCORE, shieldRestoreAmount / 100 ) + file.players[ player ].scoreThisRound += shieldRestoreAmount / 100 + } +} + +void function FD_BatteryHealTeammate( entity battery, entity titan, int shieldRestoreAmount, int healthRestoreAmount ) +{ + if( !IsValid( battery ) ) + return + + entity BatteryParent = battery.GetParent() + entity TargetTitan + int currentHeal + int currentHealScore + + if( titan.IsPlayer() ) + TargetTitan = titan + else if( titan.GetBossPlayer() != null ) + TargetTitan = titan.GetBossPlayer() + else + return + + if( BatteryParent == TargetTitan ) + return + + if( IsValid( BatteryParent ) && BatteryParent in file.players ){ + AddPlayerScore( BatteryParent, "FDTeamHeal" ) + currentHeal = shieldRestoreAmount + healthRestoreAmount + currentHealScore = currentHeal / 100 + file.playerAwardStats[BatteryParent]["heals"] += float( currentHeal ) + BatteryParent.AddToPlayerGameStat( PGS_DEFENSE_SCORE, currentHealScore ) + file.players[ BatteryParent ].scoreThisRound += currentHealScore + } +} + +void function FD_OnArcTrapTriggered( entity victim, var damageInfo ) +{ + entity owner = DamageInfo_GetAttacker( damageInfo ) + + if( !IsValidPlayer( owner ) ) + return + + AddPlayerScore( owner, "FDArcTrapTriggered" ) +} + +void function FD_OnArcWaveDamage( entity ent, var damageInfo ) +{ + entity attacker = DamageInfo_GetAttacker( damageInfo ) + + if( !IsValidPlayer( attacker ) ) + return + + AddPlayerScore( attacker, "FDArcWave" ) +} + +void function FD_OnTetherTrapTriggered( entity owner, entity endEnt ) +{ + if( !IsValidPlayer( owner ) ) + return + + AddPlayerScore( owner, "FDTetherTriggered" ) +} + +void function FD_OnSonarStart( entity ent, vector position, int sonarTeam, entity sonarOwner ) +{ + if( !IsValidPlayer( sonarOwner ) ) + return + + AddPlayerScore( sonarOwner, "FDSonarPulse" )//should only triggered once during sonar time? } -void function RateSpawnpoints_FD(int _0, array<entity> _1, int _2, entity _3) +void function FD_SetupEpilogue() { + AddCallback_GameStateEnter( eGameState.Epilogue, FD_Epilogue ) +} + +void function FD_Epilogue() +{ + thread FD_Epilogue_threaded() +} + +void function FD_Epilogue_threaded() +{ + table<string,entity> awardOwners + table<string,float> awardValues + wait 5 + foreach(entity player in GetPlayerArray() ) + { + player.FreezeControlsOnServer() + ScreenFadeToBlackForever( player, 6.0 ) + + foreach( string ref in GetFDStatRefs() ) + { + if( !( ref in awardOwners ) ) + { + awardOwners[ref] <- player + awardValues[ref] <- file.playerAwardStats[player][ref] + } + else if( awardValues[ref] < file.playerAwardStats[player][ref] ) + { + awardOwners[ref] = player + awardValues[ref] = file.playerAwardStats[player][ref] + } + } + } + table<entity, string> awardResults + table<entity, float> awardResultValues + + foreach(string ref,entity player in awardOwners) + { + + if( awardValues[ref] > GetFDStatData( ref ).validityCheckValue ) //might be >= + { + awardResults[player] <- ref + awardResultValues[player] <- awardValues[ref] + } + + } + + int gameMode = PersistenceGetEnumIndexForItemName( "gamemodes", GAMETYPE ) + int map = PersistenceGetEnumIndexForItemName( "maps", GetMapName() ) + int myIndex + int numPlayers = GetPlayerArray().len() + + foreach( entity player in GetPlayerArray() ) + { + if( !( player in awardResults ) ) + { + awardResults[player] <- "damageDealt" + awardResultValues[player] <- file.playerAwardStats[player]["damageDealt"] + } + } + + foreach( entity player in GetPlayerArray() ) + { + if( !IsValid( player ) ) + continue + + int i = 0 + myIndex = player.GetPlayerIndex() + + player.SetPersistentVar( "postGameDataFD.gameMode", gameMode ) + player.SetPersistentVar( "postGameDataFD.map", map ) + player.SetPersistentVar( "postGameDataFD.myIndex", myIndex ) + player.SetPersistentVar( "postGameDataFD.numPlayers", numPlayers ) + + foreach( entity medalPlayer, string ref in awardResults ) + { + if( !IsValid( medalPlayer ) ) + continue + + if( i == numPlayers ) + break + + int targetIndex = medalPlayer.GetPlayerIndex() + if( targetIndex >= 4 ) + continue + + string name = medalPlayer.GetPlayerName() + string xuid = medalPlayer.GetUID() + int awardId = GetFDStatData( ref ).index + float awardValue = awardResultValues[medalPlayer] + int suitIndex = GetPersistentSpawnLoadoutIndex( medalPlayer, "titan" ) + int playerEHandle = medalPlayer.GetEncodedEHandle() -}
\ No newline at end of file + player.SetPersistentVar( "postGameDataFD.players[" + targetIndex + "].name", name ) + player.SetPersistentVar( "postGameDataFD.players[" + targetIndex + "].xuid", xuid ) + player.SetPersistentVar( "postGameDataFD.players[" + targetIndex + "].awardId", awardId ) + player.SetPersistentVar( "postGameDataFD.players[" + targetIndex + "].awardValue", awardValue ) + player.SetPersistentVar( "postGameDataFD.players[" + targetIndex + "].suitIndex", suitIndex ) + Remote_CallFunction_NonReplay( player, "ServerCallback_UpdateGameStats", playerEHandle, awardId, awardValue, suitIndex ) + i++ + } + Remote_CallFunction_NonReplay( player, "ServerCallback_ShowGameStats", Time() + 19 ) + } + /* //debugging prints + foreach( entity player, table< string, float > data in file.playerAwardStats) + { + printt("Stats for", player) + foreach( string ref, float val in data ) + { + printt(" ",ref,val) + } + } + foreach( string ref, entity player in awardOwners ) + { + printt( player, ref, awardValues[ref] ) + } + */ + wait 20 + SetGameState(eGameState.Postmatch) +} + +void function IncrementPlayerstat_TurretRevives( entity player ) +{ + file.playerAwardStats[player]["turretsRepaired"]++ +} + +void function SpawnCallback_SafeTitanSpawnTime( entity ent ) +{ + if( ent.IsTitan() && IsValid( GetPetTitanOwner( ent ) ) ) + { + entity player = GetPetTitanOwner( ent ) + file.players[player].lastTitanDrop = Time() + } +} + +void function DeathCallback_CalculateTitanAliveTime( entity ent ) +{ + if( ent.IsTitan() && IsValid( GetPetTitanOwner( ent ) ) ) + { + entity player = GetPetTitanOwner( ent ) + float aliveTime = file.players[player].lastTitanDrop - Time() + if( aliveTime > file.playerAwardStats[player]["longestTitanLife"] ) + file.playerAwardStats[player]["longestTitanLife"] = aliveTime + } +} + +void function OnHarvesterDamaged( entity harvester, var damageInfo ) +{ + if ( !IsValid( harvester ) ) + return + + if( fd_harvester.harvester != harvester ) + return + + if ( GetGlobalNetTime( "FD_harvesterInvulTime" ) > Time() ) + { + harvester.SetShieldHealth( harvester.GetShieldHealthMax() ) + return + } + + int damageSourceID = DamageInfo_GetDamageSourceIdentifier( damageInfo ) + entity attacker = DamageInfo_GetAttacker( damageInfo ) + float damageAmount = DamageInfo_GetDamage( damageInfo ) + + if ( !damageSourceID && !damageAmount && !attacker ) + return + + fd_harvester.lastDamage = Time() + + damageAmount = ( damageAmount * GetCurrentPlaylistVarFloat( "fd_player_damage_scalar", 1.0 ) ) + + + + float shieldPercent = ( ( harvester.GetShieldHealth().tofloat() / harvester.GetShieldHealthMax() ) * 100 ) + if ( shieldPercent < 100 && !file.harvesterShieldDown ) + PlayFactionDialogueToTeam( "fd_baseShieldTakingDmg", TEAM_MILITIA ) + + if ( shieldPercent < 35 && !file.harvesterShieldDown ) // idk i made this up + PlayFactionDialogueToTeam( "fd_baseShieldLow", TEAM_MILITIA ) + + if ( harvester.GetShieldHealth() == 0 ) + { + if( !file.harvesterShieldDown ) + { + PlayFactionDialogueToTeam( "fd_baseShieldDown", TEAM_MILITIA ) + file.harvesterShieldDown = true // prevent shield dialogues from repeating + } + file.harvesterDamageTaken = file.harvesterDamageTaken + damageAmount // track damage for wave recaps + float newHealth = harvester.GetHealth() - damageAmount + float oldhealthpercent = ( ( harvester.GetHealth().tofloat() / harvester.GetMaxHealth() ) * 100 ) + float healthpercent = ( ( newHealth / harvester.GetMaxHealth() ) * 100 ) + + if ( healthpercent <= 75 && oldhealthpercent > 75 ) // we don't want the dialogue to keep saying "Harvester is below 75% health" everytime they take additional damage + PlayFactionDialogueToTeam( "fd_baseHealth75", TEAM_MILITIA ) + + if ( healthpercent <= 50 && oldhealthpercent > 50 ) + PlayFactionDialogueToTeam( "fd_baseHealth50", TEAM_MILITIA ) + + if ( healthpercent <= 25 && oldhealthpercent > 25 ) + PlayFactionDialogueToTeam( "fd_baseHealth25", TEAM_MILITIA ) + + if( healthpercent <= 10 ) + PlayFactionDialogueToTeam( "fd_baseLowHealth", TEAM_MILITIA ) + + if( newHealth <= 0 ) + { + EmitSoundAtPosition( TEAM_UNASSIGNED, fd_harvester.harvester.GetOrigin(), "coop_generator_destroyed" ) + newHealth = 1 + harvester.SetInvulnerable() + DamageInfo_SetDamage( damageInfo, 0.0 ) + PlayFactionDialogueToTeam( "fd_baseDeath", TEAM_MILITIA ) + fd_harvester.rings.Anim_Stop() + } + harvester.SetHealth( newHealth ) + file.havesterWasDamaged = true + } + + if ( DamageInfo_GetDamageSourceIdentifier( damageInfo ) == eDamageSourceId.mp_titancore_laser_cannon ) + DamageInfo_SetDamage( damageInfo, DamageInfo_GetDamage( damageInfo ) / 10 ) // laser core shreds super well for some reason + + if ( attacker.IsPlayer() ) + attacker.NotifyDidDamage( harvester, DamageInfo_GetHitBox( damageInfo ), DamageInfo_GetDamagePosition( damageInfo ), DamageInfo_GetCustomDamageType( damageInfo ), DamageInfo_GetDamage( damageInfo ), DamageInfo_GetDamageFlags( damageInfo ), DamageInfo_GetHitGroup( damageInfo ), DamageInfo_GetWeapon( damageInfo ), DamageInfo_GetDistFromAttackOrigin( damageInfo ) ) +} + +void function FD_NPCCleanup() +{ + foreach( entity player in GetPlayerArray() ) + { + foreach ( entity ent in file.players[ player ].deployedEntityThisRound ) + { + if ( IsValid( ent ) ) + ent.Destroy() + } + } + foreach ( entity npc in GetEntArrayByClass_Expensive( "C_AI_BaseNPC" ) ) + { + entity BossPlayer = npc.GetBossPlayer() + if( IsValidPlayer( BossPlayer ) && !file.players[ BossPlayer ].deployedEntityThisRound.contains( npc ) ) + continue + + if ( IsValid( npc ) ) + npc.Destroy() + } + if( IsValid( fd_harvester.harvester ) ) + fd_harvester.harvester.Destroy()//Destroy harvester after match over +} + +void function HarvesterThink() +{ + entity harvester = fd_harvester.harvester + + + EmitSoundOnEntity( harvester, "coop_generator_startup" ) + + float lastTime = Time() + wait 4 + int lastShieldHealth = harvester.GetShieldHealth() + generateBeamFX( fd_harvester ) + generateShieldFX( fd_harvester ) + + EmitSoundOnEntity( harvester, "coop_generator_ambient_healthy" ) + + bool isRegening = false // stops the regenning sound to keep stacking on top of each other + + while ( IsHarvesterAlive( harvester ) ) + { + float currentTime = Time() + float deltaTime = currentTime -lastTime + + if ( IsValid( fd_harvester.particleShield ) ) + { + vector shieldColor = GetShieldTriLerpColor( 1.0 - ( harvester.GetShieldHealth().tofloat() / harvester.GetShieldHealthMax().tofloat() ) ) + EffectSetControlPointVector( fd_harvester.particleShield, 1, shieldColor ) + } + + if( IsValid( fd_harvester.particleBeam ) ) + { + vector beamColor = GetShieldTriLerpColor( 1.0 - ( harvester.GetHealth().tofloat() / harvester.GetMaxHealth().tofloat() ) ) + EffectSetControlPointVector( fd_harvester.particleBeam, 1, beamColor ) + } + + if ( fd_harvester.harvester.GetShieldHealth() == 0 ) + if( IsValid( fd_harvester.particleShield ) ) + fd_harvester.particleShield.Destroy() + + if ( ( ( currentTime-fd_harvester.lastDamage ) >= GENERATOR_SHIELD_REGEN_DELAY ) && ( harvester.GetShieldHealth() < harvester.GetShieldHealthMax() ) ) + { + if( !IsValid( fd_harvester.particleShield ) ) + generateShieldFX( fd_harvester ) + + //printt((currentTime-fd_harvester.lastDamage)) + + if( harvester.GetShieldHealth() == 0 ) + EmitSoundOnEntity( harvester, "coop_generator_shieldrecharge_start" ) + + if (!isRegening) + { + EmitSoundOnEntity( harvester, "coop_generator_shieldrecharge_resume" ) + file.harvesterShieldDown = false + if (GetGlobalNetBool( "FD_waveActive" ) ) + PlayFactionDialogueToTeam( "fd_baseShieldRecharging", TEAM_MILITIA ) + else + PlayFactionDialogueToTeam( "fd_baseShieldRechargingShort", TEAM_MILITIA ) + isRegening = true + } + + float newShieldHealth = ( harvester.GetShieldHealthMax() / GENERATOR_SHIELD_REGEN_TIME * deltaTime ) + harvester.GetShieldHealth() + + if ( newShieldHealth >= harvester.GetShieldHealthMax() ) + { + StopSoundOnEntity( harvester, "coop_generator_shieldrecharge_resume" ) + harvester.SetShieldHealth( harvester.GetShieldHealthMax() ) + EmitSoundOnEntity( harvester, "coop_generator_shieldrecharge_end" ) + if( GetGlobalNetBool( "FD_waveActive" ) ) + PlayFactionDialogueToTeam( "fd_baseShieldUp", TEAM_MILITIA ) + isRegening = false + } + else + { + harvester.SetShieldHealth( newShieldHealth ) + } + } else if ( ( ( currentTime-fd_harvester.lastDamage ) < GENERATOR_SHIELD_REGEN_DELAY ) && ( harvester.GetShieldHealth() < harvester.GetShieldHealthMax() ) ) + isRegening = false + + if ( ( lastShieldHealth > 0 ) && ( harvester.GetShieldHealth() == 0 ) ) + EmitSoundOnEntity( harvester, "coop_generator_shielddown" ) + + lastShieldHealth = harvester.GetShieldHealth() + lastTime = currentTime + WaitFrame() + } + +} + +void function startHarvester() +{ + + thread HarvesterThink() + thread HarvesterAlarm() + +} + +void function HarvesterAlarm() +{ + while( IsHarvesterAlive( fd_harvester.harvester ) ) + { + if( fd_harvester.harvester.GetShieldHealth() == 0 ) + { + wait EmitSoundOnEntity( fd_harvester.harvester, "coop_generator_underattack_alarm" ) + } + else + { + WaitFrame() + } + } +} + +void function initNetVars() +{ + SetGlobalNetInt( "FD_totalWaves", waveEvents.len() ) + SetGlobalNetInt( "burn_turretLimit", 2 ) + if(!FD_HasRestarted()) + { + bool showShop = false + SetGlobalNetInt( "FD_currentWave", 0 ) + if( FD_IsDifficultyLevelOrHigher( eFDDifficultyLevel.INSANE ) ) + FD_SetNumAllowedRestarts( 0 ) + else + FD_SetNumAllowedRestarts( 2 ) + } + + +} + +void function FD_DamageByPlayerCallback( entity victim, var damageInfo ) +{ + entity player = DamageInfo_GetAttacker( damageInfo ) + if( !( player in file.players ) ) + return + float damage = DamageInfo_GetDamage( damageInfo ) + file.playerAwardStats[player]["damageDealt"] += damage + file.players[ player ].scoreThisRound += damage.tointeger() //TODO NOT HOW SCORE WORKS + if( victim.IsTitan() ) + { + //TODO Money and score for titan damage + } + +} + +void function DamageScaleByDifficulty( entity ent, var damageInfo ) +{ + entity attacker = DamageInfo_GetAttacker( damageInfo ) + + if ( !attacker ) + return + + if ( ent.GetTeam() != TEAM_MILITIA ) + return + + int damageSourceID = DamageInfo_GetDamageSourceIdentifier( damageInfo ) + float damageAmount = DamageInfo_GetDamage( damageInfo ) + + if ( !damageSourceID && !damageAmount ) + return + + if ( attacker.IsPlayer() && attacker.GetTeam() == TEAM_IMC ) // in case we ever want a PvP in Frontier Defense, don't scale their damage + return + + + if ( attacker == ent ) // dont scale self damage + return + + + DamageInfo_SetDamage( damageInfo, ( damageAmount * GetCurrentPlaylistVarFloat( "fd_player_damage_scalar", 1.0 ) ) ) + + + +} + + + +void function HealthScaleByDifficulty( entity ent ) +{ + + if ( ent.GetTeam() != TEAM_IMC ) + return + + + if (ent.IsTitan()&& IsValid(GetPetTitanOwner( ent ) ) ) // in case we ever want pvp in FD + return + + if ( ent.IsTitan() ) + ent.SetMaxHealth( ent.GetMaxHealth() + GetCurrentPlaylistVarInt( "fd_titan_health_adjust", 0 ) ) + else + ent.SetMaxHealth( ent.GetMaxHealth() + GetCurrentPlaylistVarInt( "fd_reaper_health_adjust", 0 ) ) + + if( GetCurrentPlaylistVarInt( "fd_pro_titan_shields", 0 ) && ent.IsTitan() ) + { + entity soul = ent.GetTitanSoul() + if( IsValid( soul ) ) + { + soul.SetShieldHealthMax( 2500 ) + soul.SetShieldHealth( 2500 ) + } + } + + +} + +void function FD_createHarvester() +{ + + fd_harvester = SpawnHarvester( file.harvester_info.GetOrigin(), file.harvester_info.GetAngles(), GetCurrentPlaylistVarInt( "fd_harvester_health", 25000 ), GetCurrentPlaylistVarInt( "fd_harvester_shield", 6000 ), TEAM_MILITIA ) + fd_harvester.harvester.Minimap_SetAlignUpright( true ) + fd_harvester.harvester.Minimap_AlwaysShow( TEAM_IMC, null ) + fd_harvester.harvester.Minimap_AlwaysShow( TEAM_MILITIA, null ) + fd_harvester.harvester.Minimap_SetHeightTracking( true ) + fd_harvester.harvester.Minimap_SetZOrder( MINIMAP_Z_OBJECT ) + fd_harvester.harvester.Minimap_SetCustomState( eMinimapObject_prop_script.FD_HARVESTER ) + AddEntityCallback_OnDamaged( fd_harvester.harvester, OnHarvesterDamaged ) + thread CreateHarvesterHintTrigger( fd_harvester.harvester ) +} + +bool function IsHarvesterAlive( entity harvester ) +{ + if ( harvester == null ) + return false + if ( !harvester.IsValidInternal() ) + return false + if( !harvester.IsEntAlive() ) + return false + + return harvester.GetHealth() > 1 +} + +void function CreateHarvesterHintTrigger( entity harvester ) +{ + entity trig = CreateEntity( "trigger_cylinder" ) + trig.SetRadius( 1000 ) //Test setting + trig.SetAboveHeight( 2500 ) //Test setting + trig.SetBelowHeight( 2500 ) //Test setting + trig.SetOrigin( harvester.GetOrigin() ) + trig.kv.triggerFilterNpc = "none" + trig.kv.triggerFilterPlayer = "all" + + SetTeam( trig, harvester.GetTeam() ) + DispatchSpawn( trig ) + trig.SetEnterCallback( OnEnterNearHarvesterTrigger ) + trig.SetLeaveCallback( OnLeaveNearHarvesterTrigger ) + + harvester.EndSignal( "OnDestroy" ) + trig.EndSignal( "OnDestroy" ) + + OnThreadEnd( + function() : ( trig ) + { + if ( IsValid( trig ) ) + trig.Destroy() + } + ) + + WaitForever() +} + +void function OnEnterNearHarvesterTrigger( entity trig, entity activator ) +{ + if( !( activator in file.players ) ) + return + + if( GetGlobalNetInt( "FD_waveState" ) != WAVE_STATE_IN_PROGRESS ) + return + + if ( activator != null && activator.IsPlayer() && activator.GetTeam() == trig.GetTeam() && file.players[activator].leaveHarvester == true ) + { + file.players[activator].lastNearHarvester = Time() + file.players[activator].leaveHarvester = false + } +} + +void function OnLeaveNearHarvesterTrigger( entity trig, entity activator ) +{ + if( !( activator in file.players ) ) + return + + if( GetGlobalNetInt( "FD_waveState" ) != WAVE_STATE_IN_PROGRESS ) + return + + float CurrentTime = Time() - file.players[activator].lastNearHarvester + + if ( activator != null && activator.IsPlayer() && activator.GetTeam() == trig.GetTeam() && file.players[activator].leaveHarvester == false ) + { + file.playerAwardStats[activator]["timeNearHarvester"] += CurrentTime + file.players[activator].leaveHarvester = true + } +} + +bool function isFinalWave() +{ + return ( ( GetGlobalNetInt( "FD_currentWave" ) + 1 ) == GetGlobalNetInt( "FD_totalWaves" ) ) +} + +bool function isSecondWave() +{ + return ( (GetGlobalNetInt( "FD_currentWave" ) + 1 ) == 1 ) +} + +void function LoadEntities() +{ + CreateBoostStoreLocation( TEAM_MILITIA, shopPosition, shopAngles ) + foreach ( entity info_target in GetEntArrayByClass_Expensive( "info_target" ) ) + { + + if ( GameModeRemove( info_target ) ) + continue + + if( info_target.HasKey( "editorclass" ) ) + { + switch( info_target.kv.editorclass ) + { + case "info_fd_harvester": + file.harvester_info = info_target + break + case "info_fd_mode_model": + entity prop = CreatePropDynamic( info_target.GetModelName(), info_target.GetOrigin(), info_target.GetAngles(), 6 ) + break + case "info_fd_ai_position": + AddStationaryAIPosition( info_target.GetOrigin(), int( info_target.kv.aiType ) ) + break + case "info_fd_route_node": + routeNodes.append( info_target ) + break + case "info_fd_smoke_screen": + file.smokePoints.append( info_target ) + break + } + } + } + ValidateAndFinalizePendingStationaryPositions() + initNetVars() + SetTeam( GetTeamEnt( TEAM_IMC ), TEAM_IMC ) +} + + +bool function allPlayersReady() +{ + foreach( entity player in GetPlayerArray() ) + { + if( !player.GetPlayerNetBool( "FD_readyForNextWave" ) ) + return false + } + return true +} + +void function CheckLastPlayerReady() +{ + int readyplayers = 0 + entity notready + foreach( entity player in GetPlayerArray() ) + { + if( player.GetPlayerNetBool( "FD_readyForNextWave" ) ) + readyplayers++ + else + notready = player // keep a track of this player + } + if ( readyplayers == GetPlayerArray().len() - 1 ) + PlayFactionDialogueToPlayer( "fd_playerNeedsToReadyUp", notready ) // ready up i swear there's one player like this in every match i've played +} + +bool function ClientCommandCallbackToggleReady( entity player, array<string> args ) +{ + if( args[0] == "true" ) + { + player.SetPlayerNetBool( "FD_readyForNextWave", true ) + MessageToTeam( TEAM_MILITIA,eEventNotifications.FD_PlayerReady, null, player ) + } + if( args[0] == "false" ) + player.SetPlayerNetBool( "FD_readyForNextWave", false ) + + CheckLastPlayerReady() + return true +} + +int function getHintForTypeId( int typeId ) +{ + //this is maybe a bit of an naive aproch + switch( typeId ) + { + case eFD_AITypeIDs.TITAN_NUKE: + return ( 348 + RandomIntRangeInclusive( 0, 1 ) ) + case eFD_AITypeIDs.TITAN_ARC: + return ( 350 + RandomIntRangeInclusive( 0, 1 ) ) + case eFD_AITypeIDs.TITAN_MORTAR: + return ( 352 + RandomIntRangeInclusive( 0, 1 ) ) + case eFD_AITypeIDs.GRUNT: + return 354 + case eFD_AITypeIDs.SPECTRE: + return 355 + case eFD_AITypeIDs.SPECTRE_MORTAR: + return ( 356 + RandomIntRangeInclusive( 0, 1 ) ) + case eFD_AITypeIDs.STALKER: + if( RandomIntRangeInclusive( 0, 1 ) == 0 ) + return 358 + else + return 361 + case eFD_AITypeIDs.REAPER: + return ( 359 + RandomIntRangeInclusive( 0, 1 ) ) + case eFD_AITypeIDs.DRONE: + return 362 + case eFD_AITypeIDs.TITAN_SNIPER: + return ( 371 + RandomIntRangeInclusive( 0, 2 ) ) + default: + return ( 363 + RandomIntRangeInclusive( 0, 7 ) ) + } + unreachable +} + +string function GetTargetNameForID( int typeId ) +{ + switch( typeId ) + { + case eFD_AITypeIDs.TITAN_NUKE: + return "npc_titan_nuke" + case eFD_AITypeIDs.LEGION: + return "npc_titan_ogre_minigun" + case eFD_AITypeIDs.TITAN_ARC: + return "empTitan" + case eFD_AITypeIDs.RONIN: + return "npc_titan_stryder_leadwall" + case eFD_AITypeIDs.TITAN_MORTAR: + return "npc_titan_mortar" + case eFD_AITypeIDs.TONE: + return "npc_titan_atlas_tracker" + case eFD_AITypeIDs.TITAN_SNIPER: + return "npc_titan_sniper" + case eFD_AITypeIDs.NORTHSTAR: + return "npc_titan_stryder_sniper" + case eFD_AITypeIDs.ION: + return "npc_titan_atlas_stickybomb" + case eFD_AITypeIDs.SCORCH: + return "npc_titan_ogre_meteor" + case eFD_AITypeIDs.MONARCH: + return "npc_titan_atlas_vanguard" + case eFD_AITypeIDs.GRUNT: + return "grunt" + case eFD_AITypeIDs.SPECTRE: + return "spectre" + case eFD_AITypeIDs.SPECTRE_MORTAR: + return "mortar_spectre" + case eFD_AITypeIDs.STALKER: + return "stalker" + case eFD_AITypeIDs.REAPER: + return "reaper" + case eFD_AITypeIDs.TICK: + return "tick" + case eFD_AITypeIDs.DRONE: + return "drone" + case eFD_AITypeIDs.DRONE_CLOAK: + return "Cloak Drone" // have to be like this for some reason in cl_gamemode_fd + default: + return "titan" + } + unreachable +} + +string function GetAiNetIdFromTargetName( string targetName ) +{ + switch ( targetName ) + { + case "titan": + case "sniperTitan": + case "npc_titan_ogre_meteor_boss_fd": + case "npc_titan_ogre_meteor": + case "npc_titan_ogre_minigun_boss_fd": + case "npc_titan_ogre_minigun": + case "npc_titan_atlas_stickybomb_boss_fd": + case "npc_titan_atlas_stickybomb": + case "npc_titan_atlas_tracker_boss_fd": + case "npc_titan_atlas_tracker": + case "npc_titan_stryder_leadwall_boss_fd": + case "npc_titan_stryder_leadwall": + case "npc_titan_stryder_sniper_boss_fd": + case "npc_titan_stryder_sniper": + case "npc_titan_sniper": + case "npc_titan_sniper_tone": + case "npc_titan_atlas_vanguard_boss_fd": + case "npc_titan_atlas_vanguard": + return "FD_AICount_Titan" + case "empTitan": + case "npc_titan_arc": + return "FD_AICount_Titan_Arc" + case "mortarTitan": + case "npc_titan_mortar": + return "FD_AICount_Titan_Mortar" + case "nukeTitan": + case "npc_titan_nuke": + return "FD_AICount_Titan_Nuke" + case "npc_soldier": + case "grunt": + return "FD_AICount_Grunt" + case "spectre": + return "FD_AICount_Spectre" + case "mortar_spectre": + return "FD_AICount_Spectre_Mortar" + case "npc_stalker": + case "stalker": + return "FD_AICount_Stalker" + case "npc_super_spectre": + case "reaper": + return "FD_AICount_Reaper" + case "npc_drone": + case "drone": + return "FD_AICount_Drone" + case "cloakedDrone": + case "Cloak Drone": + return "FD_AICount_Drone_Cloak" + case "tick": + return "FD_AICount_Ticks" + } + printt( "unknown target name ", targetName ) + return "" +} + + + +void function AddTurretSentry( entity turret ) +{ + turret.Minimap_AlwaysShow( TEAM_IMC, null ) + turret.Minimap_AlwaysShow( TEAM_MILITIA, null ) + turret.Minimap_SetHeightTracking( true ) + turret.Minimap_SetCustomState( eMinimapObject_npc.FD_TURRET ) + entity player = turret.GetBossPlayer() + file.players[ player ].deployedEntityThisRound.append( turret ) + AddEntityDestroyedCallback( turret, FD_OnEntityDestroyed ) + thread TurretRefundThink( turret ) +} + +function FD_OnEntityDestroyed( ent ) +{ + expect entity( ent ) + + Assert( ent.IsValidInternal() ) + entity player = IsTurret( ent ) ? ent.GetBossPlayer() : ent.GetOwner() + + if( !IsValid( player ) ) + return + + if( file.players[ player ].deployedEntityThisRound.contains( ent ) ) + file.players[ player ].deployedEntityThisRound.fastremovebyvalue( ent ) +} + +void function OnPlayerDisconnectedOrDestroyed( entity player ) +{ + if( !IsValid( player ) ) + { + ClearInValidTurret() + return + } + + foreach ( entity npc in GetEntArrayByClass_Expensive( "C_AI_BaseNPC" ) ) + { + entity BossPlayer = npc.GetBossPlayer() + if ( IsValidPlayer( BossPlayer ) && IsValid( npc ) && player == BossPlayer ) + npc.Destroy() + } + file.players[ player ].deployedEntityThisRound.clear() +} + +void function ClearInValidTurret() +{ + foreach( entity turret in GetNPCArrayByClass( "npc_turret_sentry" ) ) + { + entity BossPlayer = turret.GetBossPlayer() + if ( !IsValidPlayer( BossPlayer ) && IsValid( turret ) ) + turret.Destroy() + } +} + +void function DisableTitanSelection() +{ + foreach ( entity player in GetPlayerArray() ) + { + DisableTitanSelectionForPlayer( player ) + } +} + +void function EnableTitanSelection() +{ + foreach ( entity player in GetPlayerArray() ) + { + EnableTitanSelectionForPlayer( player ) + } +} + +void function EnableTitanSelectionForPlayer( entity player ) +{ + int enumCount = PersistenceGetEnumCount( "titanClasses" ) + + if( !IsValid( player ) ) + return + + for ( int i = 0; i < enumCount; i++ ) + { + string enumName = PersistenceGetEnumItemNameForIndex( "titanClasses", i ) + if ( enumName != "" ) + player.SetPersistentVar( "titanClassLockState[" + enumName + "]", TITAN_CLASS_LOCK_STATE_AVAILABLE ) + + } +} + +void function DisableTitanSelectionForPlayer( entity player ) +{ + int enumCount = PersistenceGetEnumCount( "titanClasses" ) + + if( !IsValid( player ) ) + return + + for ( int i = 0; i < enumCount; i++ ) + { + string enumName = PersistenceGetEnumItemNameForIndex( "titanClasses", i ) + string selectedEnumName = PersistenceGetEnumItemNameForIndex( "titanClasses", player.GetPersistentVarAsInt("activeTitanLoadoutIndex") ) + if ( enumName != "" && enumName != selectedEnumName ) + player.SetPersistentVar( "titanClassLockState[" + enumName + "]", TITAN_CLASS_LOCK_STATE_LOCKED ) + } +} + + + + +void function FD_DropshipSpawnDropship() +{ + file.playersInShip = 0 + file.dropshipState = eDropshipState.InProgress + file.dropship = CreateDropship( TEAM_MILITIA, FD_spawnPosition , FD_spawnAngles ) + + + file.dropship.SetModel( $"models/vehicle/crow_dropship/crow_dropship_hero.mdl" ) + file.dropship.SetValueForModelKey( $"models/vehicle/crow_dropship/crow_dropship_hero.mdl" ) + + DispatchSpawn( file.dropship ) + file.dropship.SetModel( $"models/vehicle/crow_dropship/crow_dropship_hero.mdl" ) + file.dropship.SetInvulnerable() + file.dropship.SetNoTarget( true ) + + thread PlayAnim(file.dropship, FD_DropshipGetAnimation()) + + array<string> anims = GetRandomDropshipDropoffAnims() + + //thread WarpinEffect( $"models/vehicle/crow_dropship/crow_dropship.mdl", anims[0], file.dropship.GetOrigin(),f ile.dropship.GetAngles() ) //this does not work + file.dropship.WaitSignal( "deploy" ) + file.dropshipState = eDropshipState.Returning + foreach(int i,entity player in file.playersInDropship) + { + thread FD_DropshipDropPlayer( player, i ) + } + file.playersInDropship.clear() + + wait 8 + file.dropshipState = eDropshipState.Idle +} + +void function FD_DropshipDropPlayer(entity player,int playerDropshipIndex) +{ + player.EndSignal( "OnDestroy" ) + FirstPersonSequenceStruct jumpSequence + jumpSequence.firstPersonAnim = DROPSHIP_EXIT_ANIMS_POV[ playerDropshipIndex ] + jumpSequence.thirdPersonAnim = DROPSHIP_EXIT_ANIMS[ playerDropshipIndex ] + jumpSequence.attachment = "ORIGIN" + jumpSequence.blendTime = 0.0 + jumpSequence.viewConeFunction = ViewConeFree + + thread FirstPersonSequence( jumpSequence, player, file.dropship ) + + //check the player + if( IsValid( player ) ) + { + WaittillAnimDone( player ) + player.ClearParent() + ClearPlayerAnimViewEntity( player ) + player.ClearInvulnerable() + } +} + +void function FD_DropshipSetAnimationOverride(string animation) +{ + file.animationOverride = animation +} + +string function FD_DropshipGetAnimation() +{ + if(file.animationOverride!="") + return file.animationOverride + + switch( GetMapName() ) + { + case "mp_homestead": + return "dropship_coop_respawn_homestead" + case "mp_lagoon": + return "dropship_coop_respawn_lagoon" + case "mp_overlook": + return "dropship_coop_respawn_overlook" + case "mp_outpost": + return "dropship_coop_respawn_outpost" + case "mp_wargames": + return "dropship_coop_respawn_wargames" + case "mp_digsite": + return "dropship_coop_respawn_digsite" + } + return "dropship_coop_respawn" +} diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd_events.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd_events.nut new file mode 100644 index 00000000..e73b73c5 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd_events.nut @@ -0,0 +1,1349 @@ +global function CreateSmokeEvent +global function CreateArcTitanEvent +global function CreateWaitForTimeEvent +global function CreateSuperSpectreEvent +global function CreateSuperSpectreEventWithMinion +global function CreateDroppodGruntEvent +global function CreateNukeTitanEvent +global function CreateMortarTitanEvent +global function CreateGenericSpawnEvent +global function CreateGenericTitanSpawnWithAiSettingsEvent +global function CreateDroppodStalkerEvent +global function CreateDroppodSpectreMortarEvent +global function CreateWaitUntilAliveEvent +global function CreateWaitUntilAliveWeightedEvent +global function CreateCloakDroneEvent +global function CreateDroppodTickEvent +global function CreateSpawnDroneEvent +global function CreateToneSniperTitanEvent +global function CreateNorthstarSniperTitanEvent //northstars are always sniper titans +global function CreateIonTitanEvent +global function CreateScorchTitanEvent +global function CreateRoninTitanEvent +global function CreateToneTitanEvent +global function CreateLegionTitanEvent +global function CreateMonarchTitanEvent +global function CreateWarningEvent +global function executeWave +global function restetWaveEvents +global function WinWave + +global struct SmokeEvent{ + vector position + float lifetime +} + +global struct SpawnEvent{ + vector origin + vector angles + string route //defines route taken by the ai + int skippedRouteNodes //defines how many route nodes will be skipped + int spawnType //Just used for Wave Info but can be used for spawn too should contain aid of spawned enemys + int spawnAmount //Just used for Wave Info but can be used for spawn too should contain amound of spawned enemys + string npcClassName + string aiSettings + string entityGlobalKey + bool shouldLoop = false +} + +global struct FlowControlEvent{ + float waitTime + int splitNextEventIndex + int waitAmount + int waitEntityType + array<string> waitGlobalDataKey +} + +global struct SoundEvent{ + string soundEventName +} + +global struct WaveEvent{ + void functionref(SmokeEvent,SpawnEvent,FlowControlEvent,SoundEvent) eventFunction + bool shouldThread + int executeOnThisCall //will actually be executed when called this many times + int timesExecuted + int nextEventIndex + SmokeEvent smokeEvent + SpawnEvent spawnEvent + FlowControlEvent flowControlEvent + SoundEvent soundEvent + +} + +global enum FD_IncomingWarnings +{ + CloakDrone, + ArcTitan, + Reaper, + MortarTitan, + NukeTitan +} + +global table< string, entity > GlobalEventEntitys +global array< array<WaveEvent> > waveEvents + + + +void function executeWave() +{ + print( "executeWave Start" ) + thread runEvents( 0 ) + while( IsHarvesterAlive( fd_harvester.harvester ) && ( !allEventsExecuted( GetGlobalNetInt( "FD_currentWave" ) ) ) ) + WaitFrame() + wait 5 //incase droppod is last event so all npc are spawned + waitUntilLessThanAmountAlive( 0 ) + waitUntilLessThanAmountAlive_expensive( 0 ) + + foreach (entity ent in GetEntArrayByClass_Expensive( "npc_turret_sentry" ) ) + RevivableTurret_Revive( ent ) +} + +bool function allEventsExecuted( int waveIndex ) +{ + foreach( WaveEvent e in waveEvents[waveIndex] ) + { + if( e.executeOnThisCall > e.timesExecuted ) + return false + } + return true +} + +void function runEvents( int firstExecuteIndex ) +{ + print( "runEvents Start" ) + WaveEvent currentEvent = waveEvents[GetGlobalNetInt( "FD_currentWave" )][firstExecuteIndex] + + while(true) + { + currentEvent.timesExecuted++ + if(currentEvent.timesExecuted!=currentEvent.executeOnThisCall) + { + print( "not on this call" ) + return + } + if( !IsHarvesterAlive(fd_harvester.harvester ) ) + { + print( "harvesterDead" ) + return + } + if( currentEvent.shouldThread ) + { + print( "execute with thread" ) + thread currentEvent.eventFunction( currentEvent.smokeEvent, currentEvent.spawnEvent, currentEvent.flowControlEvent, currentEvent.soundEvent ) + } + else + { + print( "execute without thread" ) + currentEvent.eventFunction( currentEvent.smokeEvent, currentEvent.spawnEvent, currentEvent.flowControlEvent, currentEvent.soundEvent ) + } + if( currentEvent.nextEventIndex == 0 ) + { + print( "zero index" ) + return + } + currentEvent = waveEvents[GetGlobalNetInt( "FD_currentWave" )][currentEvent.nextEventIndex] + } + print( "runEvents End" ) +} + +void function restetWaveEvents() +{ + foreach( WaveEvent event in waveEvents[GetGlobalNetInt( "FD_currentWave" )] ) + { + event.timesExecuted = 0 + } +} + + + + + + + +/****************************************************************************************************************\ +####### # # ####### # # ####### ##### ####### # # ####### ###### # ####### ####### ###### +# # # # ## # # # # # ## # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # +##### # # ##### # # # # # #### ##### # # # ##### ###### # # # # # ###### +# # # # # # # # # # # # # # # # # ####### # # # # # +# # # # # ## # # # # # ## # # # # # # # # # # +####### # ####### # # # ##### ####### # # ####### # # # # # ####### # # +\*****************************************************************************************************************/ + +WaveEvent function CreateSmokeEvent( vector position, float lifetime, int nextEventIndex, int executeOnThisCall = 1 ) +{ + WaveEvent event + event.eventFunction = spawnSmoke + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.smokeEvent.position = position + event.smokeEvent.lifetime = lifetime + return event +} + +WaveEvent function CreateArcTitanEvent( vector origin, vector angles, string route, int nextEventIndex, int executeOnThisCall = 1, string entityGlobalKey = "" ) +{ + WaveEvent event + event.eventFunction = spawnArcTitan + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.TITAN_ARC + event.spawnEvent.spawnAmount = 1 + event.spawnEvent.origin = origin + event.spawnEvent.angles = angles + event.spawnEvent.route = route + event.spawnEvent.entityGlobalKey = entityGlobalKey + return event +} + +WaveEvent function CreateSuperSpectreEvent( vector origin, vector angles, string route, int nextEventIndex, int executeOnThisCall = 1, string entityGlobalKey = "" ) +{ + WaveEvent event + event.eventFunction = spawnSuperSpectre + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.REAPER + event.spawnEvent.spawnAmount = 1 + event.spawnEvent.origin = origin + event.spawnEvent.angles = angles + event.spawnEvent.route = route + event.spawnEvent.entityGlobalKey = entityGlobalKey + return event +} + +WaveEvent function CreateSuperSpectreEventWithMinion( vector origin, vector angles, string route, int nextEventIndex, int executeOnThisCall = 1, string entityGlobalKey = "" ) +{ + WaveEvent event + event.eventFunction = spawnSuperSpectreWithMinion + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.REAPER + event.spawnEvent.spawnAmount = 1 + event.spawnEvent.origin = origin + event.spawnEvent.angles = angles + event.spawnEvent.route = route + event.spawnEvent.entityGlobalKey = entityGlobalKey + return event +} + +WaveEvent function CreateDroppodGruntEvent( vector origin, string route, int nextEventIndex, int executeOnThisCall = 1, string entityGlobalKey = "" ) +{ + WaveEvent event + event.eventFunction = spawnDroppodGrunts + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.GRUNT + event.spawnEvent.spawnAmount = 4 + event.spawnEvent.origin = origin + event.spawnEvent.route = route + event.spawnEvent.entityGlobalKey = entityGlobalKey + return event +} + +WaveEvent function CreateDroppodStalkerEvent( vector origin, string route, int nextEventIndex, int executeOnThisCall = 1, string entityGlobalKey = "" ) +{ + WaveEvent event + event.eventFunction = spawnDroppodStalker + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.STALKER + event.spawnEvent.spawnAmount = 4 + event.spawnEvent.origin = origin + event.spawnEvent.route = route + event.spawnEvent.entityGlobalKey = entityGlobalKey + return event +} + +WaveEvent function CreateDroppodSpectreMortarEvent( vector origin, string route, int nextEventIndex, int executeOnThisCall = 1, string entityGlobalKey = "" ) +{ + WaveEvent event + event.eventFunction = spawnDroppodSpectreMortar + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.SPECTRE_MORTAR + event.spawnEvent.spawnAmount = 4 + event.spawnEvent.origin = origin + event.spawnEvent.route = route + event.spawnEvent.entityGlobalKey = entityGlobalKey + return event +} + +WaveEvent function CreateWaitForTimeEvent( float waitTime, int nextEventIndex, int executeOnThisCall = 1 ) +{ + WaveEvent event + event.shouldThread = false + event.eventFunction = waitForTime + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.flowControlEvent.waitTime = waitTime + return event +} + +WaveEvent function CreateWaitUntilAliveEvent( int amount, int nextEventIndex, int executeOnThisCall = 1 ) +{ + WaveEvent event + event.eventFunction = waitUntilLessThanAmountAliveEvent + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = false + event.flowControlEvent.waitAmount = amount + return event +} + +WaveEvent function CreateWaitUntilAliveWeightedEvent( int amount, int nextEventIndex, int executeOnThisCall = 1 ) +{ + WaveEvent event + event.eventFunction = waitUntilLessThanAmountAliveEventWeighted + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = false + event.flowControlEvent.waitAmount = amount + return event +} + +WaveEvent function CreateGenericSpawnEvent( string npcClassName, vector origin, vector angles, string route, int spawnType, int spawnAmount, int nextEventIndex, int executeOnThisCall = 1, string entityGlobalKey = "" ) +{ + WaveEvent event + event.eventFunction = spawnGenericNPC + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.npcClassName = npcClassName + event.spawnEvent.origin = origin + event.spawnEvent.angles = angles + event.spawnEvent.route = route + event.spawnEvent.spawnType = spawnType + event.spawnEvent.spawnAmount = spawnAmount + event.spawnEvent.entityGlobalKey = entityGlobalKey + return event +} + +WaveEvent function CreateGenericTitanSpawnWithAiSettingsEvent( string npcClassName, string aiSettings, vector origin, vector angles, string route, int spawnType, int spawnAmount, int nextEventIndex, int executeOnThisCall = 1, string entityGlobalKey = "" ) +{ + WaveEvent event + event.eventFunction = spawnGenericNPCTitanwithSettings + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.npcClassName = npcClassName + event.spawnEvent.aiSettings = aiSettings + event.spawnEvent.origin = origin + event.spawnEvent.angles = angles + event.spawnEvent.route = route + event.spawnEvent.spawnType = spawnType + event.spawnEvent.spawnAmount = spawnAmount + event.spawnEvent.entityGlobalKey = entityGlobalKey + return event +} + +WaveEvent function CreateNukeTitanEvent( vector origin, vector angles, string route, int nextEventIndex, int executeOnThisCall = 1, string entityGlobalKey = "" ) +{ + WaveEvent event + event.eventFunction = spawnNukeTitan + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.TITAN_NUKE + event.spawnEvent.spawnAmount = 1 + event.spawnEvent.origin = origin + event.spawnEvent.angles = angles + event.spawnEvent.route = route + event.spawnEvent.entityGlobalKey = entityGlobalKey + return event +} + +WaveEvent function CreateMortarTitanEvent( vector origin, vector angles, int nextEventIndex, int executeOnThisCall = 1, string entityGlobalKey = "" ) +{ + WaveEvent event + event.eventFunction = spawnMortarTitan + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.TITAN_MORTAR + event.spawnEvent.spawnAmount = 1 + event.spawnEvent.origin = origin + event.spawnEvent.angles = angles + event.spawnEvent.entityGlobalKey = entityGlobalKey + return event +} + +WaveEvent function CreateCloakDroneEvent( vector origin, vector angles, int nextEventIndex, int executeOnThisCall = 1, string entityGlobalKey = "" ) +{ + WaveEvent event + event.eventFunction = fd_spawnCloakDrone + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.DRONE_CLOAK + event.spawnEvent.spawnAmount = 1 + event.spawnEvent.origin = origin + event.spawnEvent.angles = angles + event.spawnEvent.entityGlobalKey = entityGlobalKey + return event +} + +WaveEvent function CreateDroppodTickEvent( vector origin, int amount, string route, int nextEventIndex, int executeOnThisCall = 1, string entityGlobalKey = "" ) +{ + WaveEvent event + event.eventFunction = SpawnTick + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.TICK + event.spawnEvent.spawnAmount = amount + event.spawnEvent.origin = origin + event.spawnEvent.entityGlobalKey = entityGlobalKey + return event +} + +WaveEvent function CreateNorthstarSniperTitanEvent( vector origin, vector angles, int nextEventIndex, int executeOnThisCall = 1, string entityGlobalKey = "" ) +{ + WaveEvent event + event.eventFunction = spawnSniperTitan + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.TITAN_SNIPER + event.spawnEvent.spawnAmount = 1 + event.spawnEvent.origin = origin + event.spawnEvent.angles = angles + event.spawnEvent.entityGlobalKey = entityGlobalKey + return event +} + +WaveEvent function CreateToneSniperTitanEvent( vector origin, vector angles, int nextEventIndex, int executeOnThisCall = 1, string entityGlobalKey = "" ) +{ + WaveEvent event + event.eventFunction = SpawnToneSniperTitan + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.TITAN_SNIPER + event.spawnEvent.spawnAmount = 1 + event.spawnEvent.origin = origin + event.spawnEvent.angles = angles + event.spawnEvent.entityGlobalKey = entityGlobalKey + return event +} + + +WaveEvent function CreateIonTitanEvent( vector origin, vector angles, string route, int nextEventIndex, int executeOnThisCall = 1, string entityGlobalKey = "" ) +{ + WaveEvent event + event.eventFunction = SpawnIonTitan + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.ION + event.spawnEvent.spawnAmount = 1 + event.spawnEvent.origin = origin + event.spawnEvent.angles = angles + event.spawnEvent.route = route + event.spawnEvent.entityGlobalKey = entityGlobalKey + return event +} + +WaveEvent function CreateScorchTitanEvent( vector origin, vector angles, string route, int nextEventIndex, int executeOnThisCall = 1, string entityGlobalKey = "" ) +{ + WaveEvent event + event.eventFunction = SpawnScorchTitan + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.SCORCH + event.spawnEvent.spawnAmount = 1 + event.spawnEvent.origin = origin + event.spawnEvent.angles = angles + event.spawnEvent.route = route + event.spawnEvent.entityGlobalKey = entityGlobalKey + return event +} + +WaveEvent function CreateRoninTitanEvent( vector origin, vector angles, string route, int nextEventIndex, int executeOnThisCall = 1, string entityGlobalKey = "" ) +{ + WaveEvent event + event.eventFunction = SpawnRoninTitan + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.RONIN + event.spawnEvent.spawnAmount = 1 + event.spawnEvent.origin = origin + event.spawnEvent.angles = angles + event.spawnEvent.route = route + event.spawnEvent.entityGlobalKey = entityGlobalKey + return event +} + +WaveEvent function CreateToneTitanEvent( vector origin, vector angles, string route, int nextEventIndex, int executeOnThisCall = 1, string entityGlobalKey = "" ) +{ + WaveEvent event + event.eventFunction = SpawnToneTitan + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.TONE + event.spawnEvent.spawnAmount = 1 + event.spawnEvent.origin = origin + event.spawnEvent.angles = angles + event.spawnEvent.route = route + event.spawnEvent.entityGlobalKey = entityGlobalKey + return event +} + +WaveEvent function CreateLegionTitanEvent( vector origin, vector angles, string route, int nextEventIndex, int executeOnThisCall = 1, string entityGlobalKey = "" ) +{ + WaveEvent event + event.eventFunction = SpawnLegionTitan + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.LEGION + event.spawnEvent.spawnAmount = 1 + event.spawnEvent.origin = origin + event.spawnEvent.angles = angles + event.spawnEvent.route = route + event.spawnEvent.entityGlobalKey = entityGlobalKey + return event +} + +WaveEvent function CreateMonarchTitanEvent( vector origin, vector angles, string route, int nextEventIndex, int executeOnThisCall = 1, string entityGlobalKey = "" ) +{ + WaveEvent event + event.eventFunction = SpawnMonarchTitan + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.MONARCH + event.spawnEvent.spawnAmount = 1 + event.spawnEvent.origin = origin + event.spawnEvent.angles = angles + event.spawnEvent.route = route + event.spawnEvent.entityGlobalKey = entityGlobalKey + return event +} + +WaveEvent function CreateWaitForDeathOfEntitysEvent( array<string> waitGlobalDataKey, int nextEventIndex, int executeOnThisCall = 1 ) +{ + WaveEvent event + event.eventFunction = waitForDeathOfEntitys + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event. shouldThread = false + event.flowControlEvent.waitGlobalDataKey = waitGlobalDataKey + return event +} + +WaveEvent function CreateWaitForLessThanTypedEvent(int aiTypeId,int amount,int nextEventIndex,int executeOnThisCall = 1 ) +{ + WaveEvent event + event.eventFunction = waitForLessThanAliveTyped + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = false + event.flowControlEvent.waitAmount = amount + event.flowControlEvent.waitEntityType = aiTypeId + return event +} + +WaveEvent function CreateSpawnDroneEvent(vector origin,vector angles,string route,int nextEventIndex, bool shouldLoop = true, int executeOnThisCall = 1,string entityGlobalKey="") +{ + WaveEvent event + event.eventFunction = spawnDrones + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = true + event.spawnEvent.spawnType= eFD_AITypeIDs.DRONE + event.spawnEvent.spawnAmount = 4 + event.spawnEvent.origin = origin + event.spawnEvent.entityGlobalKey = entityGlobalKey + event.spawnEvent.route = route + event.spawnEvent.shouldLoop = shouldLoop + return event +} + + + +WaveEvent function CreateWarningEvent( int warningType, int nextEventIndex, int executeOnThisCall = 1 ) +{ + WaveEvent event + event.eventFunction = PlayWarning + event.executeOnThisCall = executeOnThisCall + event.nextEventIndex = nextEventIndex + event.shouldThread = false + + event.soundEvent.soundEventName = "fd_inc" + ["CloakDrone", "ArcTitan", "Reaper", "TitansMortar", "TitansNuke"][warningType] + "Clump" + return event +} + +/************************************************************************************************************\ +####### # # ####### # # ####### ####### # # # # ##### ####### ### ####### # # ##### +# # # # ## # # # # # ## # # # # # # # ## # # # +# # # # # # # # # # # # # # # # # # # # # # # +##### # # ##### # # # # ##### # # # # # # # # # # # # # ##### +# # # # # # # # # # # # # # # # # # # # # # # +# # # # # ## # # # # # ## # # # # # # # ## # # +####### # ####### # # # # ##### # # ##### # ### ####### # # ##### +\************************************************************************************************************/ + +void function PlayWarning( SmokeEvent smokeEvent, SpawnEvent spawnEvent, FlowControlEvent flowControlEvent, SoundEvent soundEvent ) +{ + PlayFactionDialogueToTeam( soundEvent.soundEventName, TEAM_MILITIA ) +} + +void function spawnSmoke( SmokeEvent smokeEvent, SpawnEvent spawnEvent, FlowControlEvent flowControlEvent, SoundEvent soundEvent ) +{ + printt( "smoke" ) + SmokescreenStruct smokescreen + smokescreen.smokescreenFX = $"P_smokescreen_FD" + smokescreen.isElectric = false + smokescreen.origin = smokeEvent.position + < 0, 0, 100 > + smokescreen.angles = < 0, 0, 0 > + smokescreen.lifetime = smokeEvent.lifetime + smokescreen.fxXYRadius = 150 + smokescreen.fxZRadius = 120 + smokescreen.fxOffsets = [ < 130.0, 0.0, 0.0 >, < 0.0, 130.0, 0.0 >, < 0.0, 0.0, 0.0 >, < 0.0, -130.0, 0.0 >, < -130.0, 0.0, 0.0 >, < 0.0, 100.0, 0.0 > ] + + Smokescreen(smokescreen) +} + +void function spawnDrones( SmokeEvent smokeEvent, SpawnEvent spawnEvent, FlowControlEvent flowControlEvent, SoundEvent soundEvent ) +{ + //TODO + PingMinimap( spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0 ) + array<vector> offsets = [ < 0, 32, 0 >, < 32, 0, 0 >, < 0, -32, 0 >, < -32, 0, 0 > ] + + + string squadName = MakeSquadName( TEAM_IMC, UniqueString( "ZiplineTable" ) ) + + for ( int i = 0; i < spawnEvent.spawnAmount; i++ ) + { + entity guy + + guy = CreateGenericDrone( TEAM_IMC, spawnEvent.origin + offsets[i], spawnEvent.angles ) + SetSpawnOption_AISettings( guy, "npc_drone_plasma_fd" ) + + if( spawnEvent.entityGlobalKey != "" ) + GlobalEventEntitys[ spawnEvent.entityGlobalKey + i.tostring() ] <- guy + SetTeam( guy, TEAM_IMC ) + guy.DisableNPCFlag( NPC_ALLOW_INVESTIGATE ) + guy.EnableNPCFlag( NPC_STAY_CLOSE_TO_SQUAD ) + guy.EnableNPCMoveFlag( NPCMF_WALK_ALWAYS | NPCMF_PREFER_SPRINT ) + DispatchSpawn( guy ) + + //guy.GiveWeapon("mp_weapon_engineer_combat_drone") + + SetSquad( guy, squadName ) + + SetTargetName( guy, GetTargetNameForID( eFD_AITypeIDs.DRONE ) ) + AddMinimapForHumans( guy ) + spawnedNPCs.append( guy ) + thread droneNav_thread(guy, spawnEvent.route, 0, 500, spawnEvent.shouldLoop ) + } + + +} + +void function waitForDeathOfEntitys( SmokeEvent smokeEvent, SpawnEvent spawnEvent, FlowControlEvent flowControlEvent, SoundEvent soundEvent ) +{ + while( IsHarvesterAlive( fd_harvester.harvester ) ) + { + bool anyoneAlive = false + foreach( string key in flowControlEvent.waitGlobalDataKey ) + { + if( !( key in GlobalEventEntitys ) ) + continue + if( IsAlive( GlobalEventEntitys[key] ) ) + anyoneAlive = true + } + if( !anyoneAlive ) + break + } +} + +void function waitForLessThanAliveTyped( SmokeEvent smokeEvent, SpawnEvent spawnEvent, FlowControlEvent flowControlEvent, SoundEvent soundEvent ) +{ + while( IsHarvesterAlive( fd_harvester.harvester ) ) + { + int amount + foreach( entity npc in spawnedNPCs ) + { + if( FD_GetAITypeID_ByString( npc.GetTargetName() ) ) //TODO getaitypeid_bystring does not contain all possible strings + amount++ + } + if( amount <= flowControlEvent.waitAmount ) + break + WaitFrame() + } + +} + +void function spawnArcTitan( SmokeEvent smokeEvent, SpawnEvent spawnEvent, FlowControlEvent flowControlEvent, SoundEvent soundEvent ) +{ + PingMinimap( spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0 ) + entity npc = CreateArcTitan( TEAM_IMC, spawnEvent.origin, spawnEvent.angles ) + npc.DisableNPCFlag( NPC_ALLOW_INVESTIGATE | NPC_USE_SHOOTING_COVER | NPC_ALLOW_PATROL ) + SetSpawnOption_Titanfall( npc ) + SetTargetName( npc, GetTargetNameForID( spawnEvent.spawnType ) ) // required for client to create icons + SetSpawnOption_AISettings( npc, "npc_titan_stryder_leadwall_arc" ) + spawnedNPCs.append( npc ) + DispatchSpawn( npc ) + AddMinimapForTitans( npc ) + npc.WaitSignal( "TitanHotDropComplete" ) + npc.GetTitanSoul().SetTitanSoulNetBool( "showOverheadIcon", true ) + npc.AssaultSetFightRadius( 0 ) + GlobalEventEntitys[spawnEvent.entityGlobalKey] <- npc + thread singleNav_thread( npc, spawnEvent.route ) + thread EMPTitanThinkConstant( npc ) + +} + +void function waitForTime( SmokeEvent smokeEvent, SpawnEvent spawnEvent, FlowControlEvent flowControlEvent, SoundEvent soundEvent ) +{ + float waitUntil = Time() + flowControlEvent.waitTime + while( Time() < waitUntil ) + { + if( !IsHarvesterAlive( fd_harvester.harvester ) ) + return + WaitFrame() + } +} + +void function waitUntilLessThanAmountAliveEvent( SmokeEvent smokeEvent, SpawnEvent spawnEvent, FlowControlEvent flowControlEvent, SoundEvent soundEvent ) +{ + waitUntilLessThanAmountAlive( flowControlEvent.waitAmount ) +} +void function waitUntilLessThanAmountAliveEventWeighted( SmokeEvent smokeEvent, SpawnEvent spawnEvent, FlowControlEvent flowControlEvent, SoundEvent soundEvent ) +{ + waitUntilLessThanAmountAliveWeighted( flowControlEvent.waitAmount ) +} + +void function spawnSuperSpectre( SmokeEvent smokeEvent, SpawnEvent spawnEvent, FlowControlEvent flowControlEvent, SoundEvent soundEvent ) +{ + PingMinimap( spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0 ) + wait 4.7 + + entity npc = CreateSuperSpectre( TEAM_IMC, spawnEvent.origin, spawnEvent.angles ) + SetSpawnOption_AISettings( npc, "npc_super_spectre_fd" ) + spawnedNPCs.append( npc ) + if( spawnEvent.entityGlobalKey != "" ) + GlobalEventEntitys[spawnEvent.entityGlobalKey] <- npc + DispatchSpawn( npc ) + SetTargetName( npc, GetTargetNameForID( spawnEvent.spawnType ) ) + AddMinimapForHumans( npc ) + thread SuperSpectre_WarpFall( npc ) + npc.WaitSignal( "WarpfallComplete" ) + thread singleNav_thread( npc, spawnEvent.route ) +} + +void function spawnSuperSpectreWithMinion( SmokeEvent smokeEvent, SpawnEvent spawnEvent, FlowControlEvent flowControlEvent, SoundEvent soundEvent ) +{ + PingMinimap( spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0 ) + wait 4.7 + + entity npc = CreateSuperSpectre( TEAM_IMC, spawnEvent.origin,spawnEvent.angles ) + SetSpawnOption_AISettings( npc, "npc_super_spectre_fd" ) + spawnedNPCs.append( npc ) + if( spawnEvent.entityGlobalKey != "" ) + GlobalEventEntitys[spawnEvent.entityGlobalKey] <- npc + DispatchSpawn( npc ) + SetTargetName( npc, GetTargetNameForID( spawnEvent.spawnType ) ) + AddMinimapForHumans( npc ) + thread SuperSpectre_WarpFall( npc ) + npc.WaitSignal( "WarpfallComplete" ) + thread ReaperMinionLauncherThink( npc ) + +} + +void function spawnDroppodGrunts( SmokeEvent smokeEvent, SpawnEvent spawnEvent, FlowControlEvent flowControlEvent, SoundEvent soundEvent ) +{ + PingMinimap( spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0 ) + entity pod = CreateDropPod( spawnEvent.origin, < 0, 0, 0 > ) + SetTeam( pod, TEAM_IMC ) + InitFireteamDropPod( pod ) + waitthread LaunchAnimDropPod( pod, "pod_testpath", spawnEvent.origin, < 0, 0, 0 > ) + + string squadName = MakeSquadName( TEAM_IMC, UniqueString( "ZiplineTable" ) ) + array<entity> guys + + for ( int i = 0; i < spawnEvent.spawnAmount; i++ ) + { + entity guy = CreateSoldier( TEAM_IMC, spawnEvent.origin, < 0, 0, 0 > ) + + if( spawnEvent.entityGlobalKey != "" ) + GlobalEventEntitys[ spawnEvent.entityGlobalKey+ i.tostring() ] <- guy + SetTeam( guy, TEAM_IMC ) + guy.EnableNPCFlag( NPC_ALLOW_INVESTIGATE | NPC_ALLOW_HAND_SIGNALS | NPC_ALLOW_FLEE ) + guy.DisableNPCFlag( NPC_ALLOW_PATROL ) + DispatchSpawn( guy ) + + // should this grunt be a shield captain? + if (i < GetCurrentPlaylistVarInt( "fd_grunt_shield_captains", 0 ) ) + thread ActivatePersonalShield( guy ) + + guy.SetParent( pod, "ATTACH", true ) + SetSquad( guy, squadName ) + + // should this grunt have an anti titan weapon instead of its normal weapon? + if ( i < GetCurrentPlaylistVarInt( "fd_grunt_at_weapon_users", 0 ) ) + { + guy.GiveWeapon( "mp_weapon_defender" ) // do grunts ever get a different anti titan weapon? - yes, TODO + // atm they arent using their AT weapons ever, but they do in fact get them, in fact some grunts are getting 2 since they already get a rocket_launcher + // this seems to be a problem elsewhere as opposed to something that is wrong here + } + + SetTargetName( guy, GetTargetNameForID( eFD_AITypeIDs.GRUNT ) ) // do shield captains get their own target name in vanilla? + AddMinimapForHumans( guy ) + spawnedNPCs.append( guy ) + guys.append( guy ) + } + + ActivateFireteamDropPod( pod, guys ) + thread SquadNav_Thread( guys,spawnEvent.route ) +} + +void function spawnDroppodStalker( SmokeEvent smokeEvent, SpawnEvent spawnEvent, FlowControlEvent flowControlEvent, SoundEvent soundEvent ) +{ + PingMinimap( spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0 ) + entity pod = CreateDropPod( spawnEvent.origin, < 0, 0, 0 > ) + SetTeam( pod, TEAM_IMC ) + InitFireteamDropPod( pod ) + waitthread LaunchAnimDropPod( pod, "pod_testpath", spawnEvent.origin, < 0, 0, 0 > ) + + string squadName = MakeSquadName( TEAM_IMC, UniqueString( "ZiplineTable" ) ) + array<entity> guys + int difficultyLevel = FD_GetDifficultyLevel() + + for ( int i = 0; i < spawnEvent.spawnAmount; i++ ) + { + entity guy = CreateStalker( TEAM_IMC, spawnEvent.origin, < 0, 0, 0 > ) + if( spawnEvent.entityGlobalKey != "" ) + GlobalEventEntitys[ spawnEvent.entityGlobalKey + i.tostring() ] <- guy + SetTeam( guy, TEAM_IMC ) + guy.EnableNPCFlag( NPC_ALLOW_INVESTIGATE | NPC_ALLOW_HAND_SIGNALS | NPC_ALLOW_FLEE ) + guy.DisableNPCFlag( NPC_ALLOW_PATROL) + SetSpawnOption_AISettings( guy, "npc_stalker_fd" ) + DispatchSpawn( guy ) + + SetSquad( guy, squadName ) + guy.AssaultSetFightRadius( 0 ) // makes them keep moving instead of stopping to shoot you. + AddMinimapForHumans( guy ) + spawnedNPCs.append( guy ) + SetTargetName( guy, GetTargetNameForID( eFD_AITypeIDs.STALKER ) ) + thread FDStalkerThink( guy , fd_harvester.harvester ) + guys.append( guy ) + } + + switch ( difficultyLevel ) + { + case eFDDifficultyLevel.EASY: + case eFDDifficultyLevel.NORMAL: // easy and normal stalkers have no weapons + foreach( npc in guys ) + { + npc.TakeActiveWeapon() + npc.SetNoTarget( false ) + npc.EnableNPCFlag( NPC_DISABLE_SENSING | NPC_IGNORE_ALL ) + npc.SetEnemy( fd_harvester.harvester ) + } + break + case eFDDifficultyLevel.HARD: + case eFDDifficultyLevel.MASTER: + case eFDDifficultyLevel.INSANE: // give all EPGs + foreach( npc in guys ) + { + npc.TakeActiveWeapon() + npc.GiveWeapon( "mp_weapon_epg", [] ) + npc.SetActiveWeaponByName( "mp_weapon_epg" ) + } + break + + default: + unreachable + + } + + ActivateFireteamDropPod( pod, guys ) + SquadNav_Thread( guys, spawnEvent.route ) + +} + +void function spawnDroppodSpectreMortar( SmokeEvent smokeEvent, SpawnEvent spawnEvent, FlowControlEvent flowControlEvent, SoundEvent soundEvent ) +{ + PingMinimap( spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0 ) + entity pod = CreateDropPod( spawnEvent.origin, < 0, 0, 0 > ) + SetTeam( pod, TEAM_IMC ) + InitFireteamDropPod( pod ) + waitthread LaunchAnimDropPod( pod, "pod_testpath", spawnEvent.origin, < 0, 0, 0 > ) + + string squadName = MakeSquadName( TEAM_IMC, UniqueString( "ZiplineTable" ) ) + array<entity> guys + + for ( int i = 0; i < 4; i++ ) + { + entity guy = CreateSpectre( TEAM_IMC, spawnEvent.origin,< 0, 0, 0 > ) + SetSpawnOption_AISettings( guy, "npc_spectre_mortar" ) + if( spawnEvent.entityGlobalKey != "" ) + GlobalEventEntitys[ spawnEvent.entityGlobalKey + i.tostring() ] <- guy + SetTeam( guy, TEAM_IMC ) + DispatchSpawn( guy ) + spawnedNPCs.append(guy) + SetSquad( guy, squadName ) + SetTargetName( guy, GetTargetNameForID(eFD_AITypeIDs.SPECTRE_MORTAR)) + AddMinimapForHumans(guy) + guys.append( guy ) + } + + ActivateFireteamDropPod( pod, guys ) + + thread MortarSpectreSquadThink( guys, fd_harvester.harvester ) + +} + +void function spawnGenericNPC( SmokeEvent smokeEvent, SpawnEvent spawnEvent, FlowControlEvent flowControlEvent, SoundEvent soundEvent ) +{ + PingMinimap( spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0 ) + entity npc = CreateNPC( spawnEvent.npcClassName, TEAM_IMC, spawnEvent.origin, spawnEvent.angles ) + if( spawnEvent.entityGlobalKey != "" ) + GlobalEventEntitys[spawnEvent.entityGlobalKey] <- npc + DispatchSpawn( npc ) +} + +void function spawnGenericNPCTitanwithSettings( SmokeEvent smokeEvent, SpawnEvent spawnEvent, FlowControlEvent flowControlEvent, SoundEvent soundEvent ) +{ + PingMinimap( spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0 ) + entity npc = CreateNPCTitan( spawnEvent.npcClassName, TEAM_IMC, spawnEvent.origin, spawnEvent.angles ) + if( spawnEvent.aiSettings == "npc_titan_atlas_tracker_fd_sniper" ) + SetTargetName( npc, "npc_titan_atlas_tracker" ) // required for client to create icons + SetSpawnOption_AISettings( npc, spawnEvent.aiSettings ) + SetSpawnOption_Titanfall( npc ) + DispatchSpawn( npc ) + if( spawnEvent.entityGlobalKey != "" ) + GlobalEventEntitys[spawnEvent.entityGlobalKey] <- npc + spawnedNPCs.append( npc ) + AddMinimapForTitans( npc ) + npc.WaitSignal( "TitanHotDropComplete" ) + npc.GetTitanSoul().SetTitanSoulNetBool( "showOverheadIcon", true ) +} + + +void function SpawnIonTitan( SmokeEvent smokeEvent, SpawnEvent spawnEvent, FlowControlEvent flowControlEvent, SoundEvent soundEvent ) +{ + PingMinimap( spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0 ) + entity npc = CreateNPCTitan( "titan_atlas", TEAM_IMC, spawnEvent.origin, spawnEvent.angles) + SetSpawnOption_AISettings( npc, "npc_titan_atlas_stickybomb_boss_fd" ) + SetSpawnOption_Titanfall( npc ) + SetTargetName( npc, GetTargetNameForID( spawnEvent.spawnType ) ) // required for client to create icons + DispatchSpawn( npc ) + if( spawnEvent.entityGlobalKey != "" ) + GlobalEventEntitys[spawnEvent.entityGlobalKey] <- npc + spawnedNPCs.append( npc ) + AddMinimapForTitans( npc ) + npc.WaitSignal( "TitanHotDropComplete" ) + npc.GetTitanSoul().SetTitanSoulNetBool( "showOverheadIcon", true ) + thread singleNav_thread( npc, spawnEvent.route ) +} + +void function SpawnScorchTitan( SmokeEvent smokeEvent, SpawnEvent spawnEvent, FlowControlEvent flowControlEvent, SoundEvent soundEvent ) +{ + PingMinimap( spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0 ) + entity npc = CreateNPCTitan( "titan_ogre", TEAM_IMC, spawnEvent.origin, spawnEvent.angles ) + SetSpawnOption_AISettings( npc, "npc_titan_ogre_meteor_boss_fd" ) + SetSpawnOption_Titanfall( npc ) + SetTargetName( npc, GetTargetNameForID( spawnEvent.spawnType ) ) // required for client to create icons + DispatchSpawn( npc ) + if( spawnEvent.entityGlobalKey != "" ) + GlobalEventEntitys[spawnEvent.entityGlobalKey] <- npc + spawnedNPCs.append( npc ) + AddMinimapForTitans( npc ) + npc.WaitSignal( "TitanHotDropComplete" ) + npc.GetTitanSoul().SetTitanSoulNetBool( "showOverheadIcon", true ) + thread singleNav_thread( npc, spawnEvent.route ) +} + +void function SpawnRoninTitan( SmokeEvent smokeEvent, SpawnEvent spawnEvent, FlowControlEvent flowControlEvent, SoundEvent soundEvent ) +{ + PingMinimap( spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0 ) + entity npc = CreateNPCTitan( "titan_stryder", TEAM_IMC, spawnEvent.origin, spawnEvent.angles) + SetSpawnOption_AISettings (npc, "npc_titan_stryder_leadwall_boss_fd" ) + SetSpawnOption_Titanfall( npc ) + SetTargetName( npc, GetTargetNameForID( spawnEvent.spawnType ) ) // required for client to create icons + DispatchSpawn( npc ) + if( spawnEvent.entityGlobalKey != "" ) + GlobalEventEntitys[spawnEvent.entityGlobalKey] <- npc + spawnedNPCs.append( npc ) + AddMinimapForTitans( npc ) + npc.WaitSignal( "TitanHotDropComplete" ) + npc.GetTitanSoul().SetTitanSoulNetBool( "showOverheadIcon", true ) + thread singleNav_thread( npc, spawnEvent.route ) +} + +void function SpawnToneTitan( SmokeEvent smokeEvent, SpawnEvent spawnEvent, FlowControlEvent flowControlEvent, SoundEvent soundEvent ) +{ + PingMinimap( spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0 ) + entity npc = CreateNPCTitan( "titan_atlas", TEAM_IMC, spawnEvent.origin, spawnEvent.angles) + SetSpawnOption_AISettings( npc, "npc_titan_atlas_tracker_boss_fd" ) + SetSpawnOption_Titanfall( npc ) + SetTargetName( npc, GetTargetNameForID( spawnEvent.spawnType ) ) // required for client to create icons + DispatchSpawn( npc ) + if( spawnEvent.entityGlobalKey != "" ) + GlobalEventEntitys[spawnEvent.entityGlobalKey] <- npc + spawnedNPCs.append( npc ) + AddMinimapForTitans( npc ) + npc.WaitSignal( "TitanHotDropComplete" ) + npc.GetTitanSoul().SetTitanSoulNetBool( "showOverheadIcon", true ) + thread singleNav_thread( npc, spawnEvent.route ) +} + +void function SpawnLegionTitan( SmokeEvent smokeEvent, SpawnEvent spawnEvent, FlowControlEvent flowControlEvent, SoundEvent soundEvent ) +{ + PingMinimap( spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0 ) + entity npc = CreateNPCTitan( "titan_ogre", TEAM_IMC, spawnEvent.origin, spawnEvent.angles ) + SetSpawnOption_AISettings( npc, "npc_titan_ogre_minigun_boss_fd" ) + SetSpawnOption_Titanfall( npc ) + SetTargetName( npc, GetTargetNameForID( spawnEvent.spawnType ) ) // required for client to create icons + DispatchSpawn( npc ) + if( spawnEvent.entityGlobalKey != "" ) + GlobalEventEntitys[spawnEvent.entityGlobalKey] <- npc + spawnedNPCs.append( npc ) + AddMinimapForTitans( npc ) + npc.WaitSignal( "TitanHotDropComplete" ) + npc.GetTitanSoul().SetTitanSoulNetBool( "showOverheadIcon", true ) + thread singleNav_thread( npc, spawnEvent.route ) +} + +void function SpawnMonarchTitan( SmokeEvent smokeEvent, SpawnEvent spawnEvent, FlowControlEvent flowControlEvent, SoundEvent soundEvent ) +{ + PingMinimap( spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0 ) + entity npc = CreateNPCTitan( "titan_atlas", TEAM_IMC, spawnEvent.origin, spawnEvent.angles ) + SetSpawnOption_AISettings( npc,"npc_titan_atlas_vanguard_boss_fd" ) + SetSpawnOption_Titanfall( npc ) + SetTargetName( npc, GetTargetNameForID( spawnEvent.spawnType ) ) // required for client to create icons + DispatchSpawn( npc ) + if( spawnEvent.entityGlobalKey != "" ) + GlobalEventEntitys[spawnEvent.entityGlobalKey] <- npc + spawnedNPCs.append( npc ) + AddMinimapForTitans( npc ) + npc.WaitSignal( "TitanHotDropComplete" ) + npc.GetTitanSoul().SetTitanSoulNetBool( "showOverheadIcon", true ) + thread singleNav_thread( npc, spawnEvent.route ) +} + +void function spawnNukeTitan( SmokeEvent smokeEvent, SpawnEvent spawnEvent, FlowControlEvent flowControlEvent, SoundEvent soundEvent ) +{ + PingMinimap( spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0 ) + entity npc = CreateNPCTitan( "titan_ogre", TEAM_IMC, spawnEvent.origin, spawnEvent.angles ) + SetSpawnOption_AISettings( npc, "npc_titan_ogre_minigun_nuke" ) + SetSpawnOption_Titanfall( npc ) + SetTargetName( npc, GetTargetNameForID( spawnEvent.spawnType ) ) // required for client to create icons + npc.EnableNPCMoveFlag( NPCMF_WALK_ALWAYS ) + npc.AssaultSetFightRadius( 0 ) + DispatchSpawn( npc ) + if( spawnEvent.entityGlobalKey != "" ) + GlobalEventEntitys[spawnEvent.entityGlobalKey] <- npc + spawnedNPCs.append( npc ) + AddMinimapForTitans( npc ) + npc.WaitSignal( "TitanHotDropComplete" ) + npc.GetTitanSoul().SetTitanSoulNetBool( "showOverheadIcon", true ) + thread singleNav_thread( npc, spawnEvent.route ) + thread NukeTitanThink( npc, fd_harvester.harvester ) + +} + +void function spawnMortarTitan( SmokeEvent smokeEvent, SpawnEvent spawnEvent, FlowControlEvent flowControlEvent, SoundEvent soundEvent ) +{ + PingMinimap( spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0 ) + entity npc = CreateNPCTitan( "titan_atlas", TEAM_IMC, spawnEvent.origin, spawnEvent.angles ) + SetSpawnOption_AISettings( npc, "npc_titan_atlas_tracker_mortar" ) + SetSpawnOption_Titanfall( npc ) + SetTargetName( npc, GetTargetNameForID( spawnEvent.spawnType ) ) // required for client to create icons + DispatchSpawn( npc ) + if( spawnEvent.entityGlobalKey != "" ) + GlobalEventEntitys[spawnEvent.entityGlobalKey] <- npc + spawnedNPCs.append( npc ) + AddMinimapForTitans( npc ) + npc.WaitSignal( "TitanHotDropComplete" ) + npc.GetTitanSoul().SetTitanSoulNetBool( "showOverheadIcon", true ) + thread MortarTitanThink( npc, fd_harvester.harvester ) +} + +void function spawnSniperTitan( SmokeEvent smokeEvent, SpawnEvent spawnEvent, FlowControlEvent flowControlEvent, SoundEvent soundEvent ) +{ + PingMinimap( spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0 ) + entity npc = CreateNPCTitan( "titan_stryder", TEAM_IMC, spawnEvent.origin, spawnEvent.angles) + SetSpawnOption_AISettings( npc, "npc_titan_stryder_sniper_fd" ) + SetSpawnOption_Titanfall( npc ) + SetTargetName( npc, GetTargetNameForID( spawnEvent.spawnType ) ) // required for client to create icons + DispatchSpawn( npc ) + if( spawnEvent.entityGlobalKey != "" ) + GlobalEventEntitys[spawnEvent.entityGlobalKey] <- npc + spawnedNPCs.append( npc ) + AddMinimapForTitans( npc ) + npc.WaitSignal( "TitanHotDropComplete" ) + npc.GetTitanSoul().SetTitanSoulNetBool( "showOverheadIcon", true ) + thread SniperTitanThink( npc, fd_harvester.harvester ) + +} + +void function SpawnToneSniperTitan( SmokeEvent smokeEvent, SpawnEvent spawnEvent, FlowControlEvent flowControlEvent, SoundEvent soundEvent ) +{ + PingMinimap( spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0 ) + entity npc = CreateNPCTitan( "titan_atlas", TEAM_IMC, spawnEvent.origin, spawnEvent.angles ) + SetSpawnOption_AISettings( npc, "npc_titan_atlas_tracker_fd_sniper" ) + SetSpawnOption_Titanfall( npc ) + SetTargetName( npc, GetTargetNameForID( spawnEvent.spawnType ) ) // required for client to create icons + DispatchSpawn( npc ) + if( spawnEvent.entityGlobalKey != "" ) + GlobalEventEntitys[spawnEvent.entityGlobalKey] <- npc + npc.AssaultSetFightRadius( 0 ) + spawnedNPCs.append( npc ) + AddMinimapForTitans( npc ) + npc.WaitSignal( "TitanHotDropComplete" ) + npc.GetTitanSoul().SetTitanSoulNetBool( "showOverheadIcon", true ) + thread SniperTitanThink( npc, fd_harvester.harvester ) +} + +void function fd_spawnCloakDrone( SmokeEvent smokeEvent, SpawnEvent spawnEvent,FlowControlEvent flowControlEvent,SoundEvent soundEvent ) +{ + entity npc = SpawnCloakDrone( TEAM_IMC, spawnEvent.origin, spawnEvent.angles, fd_harvester.harvester.GetOrigin() ) + spawnedNPCs.append( npc ) + if( spawnEvent.entityGlobalKey != "" ) + GlobalEventEntitys[spawnEvent.entityGlobalKey] <- npc + SetTargetName( npc, GetTargetNameForID( spawnEvent.spawnType ) ) + AddMinimapForHumans( npc ) +} + +void function SpawnTick( SmokeEvent smokeEvent, SpawnEvent spawnEvent, FlowControlEvent flowControlEvent, SoundEvent soundEvent ) +{ + PingMinimap( spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0 ) + entity pod = CreateDropPod( spawnEvent.origin, < 0, 0, 0 > ) + SetTeam( pod, TEAM_IMC ) + InitFireteamDropPod( pod ) + waitthread LaunchAnimDropPod( pod, "pod_testpath", spawnEvent.origin, < 0, 0, 0 > ) + + string squadName = MakeSquadName( TEAM_IMC, UniqueString( "ZiplineTable" ) ) + array<entity> guys + + for ( int i = 0; i < spawnEvent.spawnAmount; i++ ) + { + entity guy = CreateFragDrone( TEAM_IMC, spawnEvent.origin, < 0, 0, 0 > ) + if( spawnEvent.entityGlobalKey != "" ) + GlobalEventEntitys[ spawnEvent.entityGlobalKey + i.tostring() ] <- guy + SetSpawnOption_AISettings( guy, "npc_frag_drone_fd" ) + SetTeam( guy, TEAM_IMC ) + guy.EnableNPCFlag( NPC_ALLOW_INVESTIGATE ) + DispatchSpawn( guy ) + AddMinimapForHumans( guy ) + SetTargetName( guy, GetTargetNameForID( eFD_AITypeIDs.TICK ) ) + SetSquad( guy, squadName ) + spawnedNPCs.append( guy ) + guy.AssaultSetFightRadius( expect int( guy.Dev_GetAISettingByKeyField( "LookDistDefault_Combat" ) ) ) // make the ticks target players very aggressively + guys.append( guy ) + } + + ActivateFireteamDropPod( pod, guys ) + thread SquadNav_Thread( guys, spawnEvent.route ) +} + + + +/****************************************************************************************\ +####### # # ####### # # ####### # # ####### # ###### ####### ###### +# # # # ## # # # # # # # # # # # +# # # # # # # # # # # # # # # # # +##### # # ##### # # # # ####### ##### # ###### ##### ###### +# # # # # # # # # # # # # # # # +# # # # # ## # # # # # # # # # +####### # ####### # # # # # ####### ####### # ####### # # +\****************************************************************************************/ + + +void function PingMinimap( float x, float y, float duration, float spreadRadius, float ringRadius, int colorIndex ) +{ + foreach( entity player in GetPlayerArray() ) + { + Remote_CallFunction_NonReplay( player, "ServerCallback_FD_PingMinimap", x, y, duration, spreadRadius, ringRadius, colorIndex ) + } +} + +void function waitUntilLessThanAmountAlive( int amount ) +{ + int deduct = 0 + foreach ( entity npc in spawnedNPCs ) + { + if( !IsValid(npc) ) + { + deduct++ + continue + } + if( IsValid( GetPetTitanOwner( npc ) ) ) + { + deduct++ + continue + } + if( npc.GetTeam() == TEAM_MILITIA ) + { + deduct++ + continue + } + } + int aliveNPCs = spawnedNPCs.len() - deduct + while( aliveNPCs > amount ) + { + WaitFrame() + deduct = 0 + foreach ( entity npc in spawnedNPCs ) + { + if( !IsValid( npc ) ) + { + deduct++ + continue + } + if( IsValid( GetPetTitanOwner( npc ) ) ) + { + deduct++ + continue + } + if( npc.GetTeam() == TEAM_MILITIA ) + { + deduct++ + continue + } + } + aliveNPCs = spawnedNPCs.len() - deduct + + if( !IsHarvesterAlive( fd_harvester.harvester ) ) + return + } +} + +void function waitUntilLessThanAmountAliveWeighted( int amount, int humanWeight = 1, int reaperWeight = 3, int titanWeight = 5 ) +{ + + int aliveNPCsWeighted = 0; + foreach( npc in spawnedNPCs ) + { + if( !IsValid( npc ) ) + continue + + if( IsValid( GetPetTitanOwner( npc ) ) ) + continue + + if( npc.GetTeam() == TEAM_MILITIA ) + continue + + if( npc.IsTitan() ) + aliveNPCsWeighted += titanWeight + else if( npc.GetTargetName() == "reaper" ) + aliveNPCsWeighted += reaperWeight + else + aliveNPCsWeighted += humanWeight + } + while( aliveNPCsWeighted > amount ) + { + WaitFrame() + aliveNPCsWeighted = 0; + foreach( npc in spawnedNPCs ) + { + if( !IsValid( npc ) ) + continue + + if( IsValid( GetPetTitanOwner( npc ) ) ) + continue + + if( npc.GetTeam() == TEAM_MILITIA ) + continue + + if( npc.IsTitan() ) + aliveNPCsWeighted += titanWeight + else if( npc.GetTargetName() == "reaper" ) + aliveNPCsWeighted += reaperWeight + else + aliveNPCsWeighted += humanWeight + } + if( !IsHarvesterAlive( fd_harvester.harvester ) ) + return + } +} + +void function waitUntilLessThanAmountAlive_expensive( int amount ) +{ + + array<entity> npcs = GetNPCArray() + int deduct = 0 + foreach ( entity npc in npcs ) + { + if( IsValid( GetPetTitanOwner( npc ) ) ) + { + deduct++ + continue + } + if( npc.GetTeam() == TEAM_MILITIA ) + { + deduct++ + continue + } + } + foreach( entity ent in GetEntArrayByClass_Expensive( "npc_drone" ) ) + ent.Die() + int aliveTitans = npcs.len() - deduct + while( aliveTitans > amount ) + { + WaitFrame() + npcs = GetNPCArray() + deduct = 0 + foreach( entity npc in npcs ) + { + if( IsValid( GetPetTitanOwner( npc ) ) ) + { + deduct++ + continue + } + if( npc.GetTeam() == TEAM_MILITIA ) + { + deduct++ + continue + } + } + aliveTitans = GetNPCArray().len() - deduct + if( !IsHarvesterAlive( fd_harvester.harvester ) ) + return + } +} + +void function AddMinimapForTitans( entity titan ) +{ + titan.Minimap_SetAlignUpright( true ) + titan.Minimap_AlwaysShow( TEAM_IMC, null ) + titan.Minimap_AlwaysShow( TEAM_MILITIA, null ) + titan.Minimap_SetHeightTracking( true ) + titan.Minimap_SetCustomState( eMinimapObject_npc_titan.AT_BOUNTY_BOSS ) +} + +// including drones +void function AddMinimapForHumans( entity human ) +{ + human.Minimap_SetAlignUpright( true ) + human.Minimap_AlwaysShow( TEAM_IMC, null ) + human.Minimap_AlwaysShow( TEAM_MILITIA, null ) + human.Minimap_SetHeightTracking( true ) + human.Minimap_SetCustomState( eMinimapObject_npc.AI_TDM_AI ) +} + + + +void function WinWave() +{ + foreach( WaveEvent e in waveEvents[GetGlobalNetInt( "FD_currentWave" )] ) + { + e.timesExecuted = e.executeOnThisCall + } +} + diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd_nav.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd_nav.nut new file mode 100644 index 00000000..1948ac6b --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd_nav.nut @@ -0,0 +1,271 @@ +global function singleNav_thread +global function SquadNav_Thread +global function droneNav_thread +global function getRoute +global function Dev_MarkRoute + + + +void function singleNav_thread( entity npc, string routeName, int nodesToSkip= 0, float nextDistance = -1.0, bool shouldLoop = false ) +{ + npc.EndSignal( "OnDeath" ) + npc.EndSignal( "OnDestroy" ) + + + + if( !npc.IsNPC() ) + return + if ( nextDistance == -1 ) + nextDistance = npc.GetMinGoalRadius() + + + /*array<entity> routeArray = getRoute(routeName) + WaitFrame()//so other code setting up what happens on signals is run before this + if(routeArray.len()==0) + { + + npc.Signal("OnFailedToPath") + return + } + int skippedNodes = 0 + foreach(entity node in routeArray) + { + if(!IsHarvesterAlive(fd_harvester.harvester)) + return + if(skippedNodes < nodesToSkip) + { + skippedNodes++ + continue + } + npc.AssaultPoint(node.GetOrigin()) + npc.AssaultSetGoalRadius( 50 ) + int i = 0 + table result = npc.WaitSignal("OnFinishedAssault","OnFailedToPath") + if(result.signal == "OnFailedToPath") + break + }*/ + + // NEW STUFF + WaitFrame() // so other code setting up what happens on signals is run before this + + entity targetNode + if ( routeName == "" ) + { + float dist = 1000000000 + foreach ( entity node in routeNodes ) + { + if( !node.HasKey( "route_name" ) ) + continue + if ( Distance( npc.GetOrigin(), node.GetOrigin() ) < dist ) + { + dist = Distance( npc.GetOrigin(), node.GetOrigin() ) + targetNode = node + } + } + printt("Entity had no route defined: using nearest node: " + targetNode.kv.route_name) + } + else + { + targetNode = GetRouteStart( routeName ) + } + + // skip nodes + for ( int i = 0; i < nodesToSkip; i++ ) + { + targetNode = targetNode.GetLinkEnt() + } + + + while ( targetNode != null ) + { + if( !IsHarvesterAlive( fd_harvester.harvester ) ) + return + npc.AssaultPoint( targetNode.GetOrigin() ) + npc.AssaultSetGoalRadius( nextDistance ) + npc.AssaultSetFightRadius( 0 ) + + table result = npc.WaitSignal( "OnFinishedAssault", "OnEnterGoalRadius", "OnFailedToPath" ) + + targetNode = targetNode.GetLinkEnt() + } + + npc.Signal( "FD_ReachedHarvester" ) +} + +void function SquadNav_Thread( array<entity> npcs, string routeName, int nodesToSkip = 0, float nextDistance = 200.0 ) +{ + //TODO this function wont stop when noone alive anymore also it only works half of the time + /* + array<entity> routeArray = getRoute(routeName) + WaitFrame()//so other code setting up what happens on signals is run before this + if(routeArray.len()==0) + return + + int nodeIndex = 0 + foreach(entity node in routeArray) + { + if(!IsHarvesterAlive(fd_harvester.harvester)) + return + if(nodeIndex++ < nodesToSkip) + continue + + SquadAssaultOrigin(npcs,node.GetOrigin(),nextDistance) + + }*/ + // NEW STUFF + WaitFrame() // so other code setting up what happens on signals is run before this + + entity targetNode + if ( routeName == "" ) + { + float dist = 1000000000 + foreach ( entity node in routeNodes ) + { + if( !node.HasKey( "route_name" ) ) + continue + if ( Distance( npcs[0].GetOrigin(), node.GetOrigin() ) < dist ) + { + dist = Distance( npcs[0].GetOrigin(), node.GetOrigin() ) + targetNode = node + } + } + printt("Entity had no route defined: using nearest node: " + targetNode.kv.route_name) + } + else + { + targetNode = GetRouteStart( routeName ) + } + + // skip nodes + for ( int i = 0; i < nodesToSkip; i++ ) + { + targetNode = targetNode.GetLinkEnt() + } + + while ( targetNode != null ) + { + if( !IsHarvesterAlive( fd_harvester.harvester ) ) + return + + SquadAssaultOrigin( npcs, targetNode.GetOrigin(), nextDistance ) + + targetNode = targetNode.GetLinkEnt() + } + +} + +void function droneNav_thread( entity npc, string routeName,int nodesToSkip= 0,float nextDistance = 500.0, bool shouldLoop = false ) +{ + npc.EndSignal( "OnDeath" ) + npc.EndSignal( "OnDestroy" ) + + if( !npc.IsNPC() ) + return + + + // NEW STUFF + WaitFrame() // so other code setting up what happens on signals is run before this + + entity targetNode + entity firstNode + if ( routeName == "" ) + { + float dist = 1000000000 + foreach ( entity node in routeNodes ) + { + if( !node.HasKey( "route_name" ) ) + continue + if ( Distance( npc.GetOrigin(), node.GetOrigin() ) < dist ) + { + dist = Distance( npc.GetOrigin(), node.GetOrigin() ) + targetNode = node + firstNode = node + } + } + printt( "Entity had no route defined: using nearest node: " + targetNode.kv.route_name ) + } + else + { + targetNode = GetRouteStart( routeName ) + } + + // skip nodes + for ( int i = 0; i < nodesToSkip; i++ ) + { + targetNode = targetNode.GetLinkEnt() + firstNode = targetNode.GetLinkEnt() + } + + + while ( targetNode != null ) + { + if( !IsHarvesterAlive( fd_harvester.harvester ) ) + return + npc.AssaultPoint( targetNode.GetOrigin() + <0, 0, 300> ) + npc.AssaultSetGoalRadius( nextDistance ) + npc.AssaultSetGoalHeight( 100 ) + npc.AssaultSetFightRadius( 0 ) + + table result = npc.WaitSignal( "OnFinishedAssault", "OnEnterGoalRadius", "OnFailedToPath" ) + + targetNode = targetNode.GetLinkEnt() + if ( targetNode == null ) + printt( "drone finished pathing" ) + if ( targetNode == null && shouldLoop ) + { + printt( "drone reached end of loop, looping" ) + targetNode = firstNode + } + } + + npc.Signal( "FD_ReachedHarvester" ) +} + +entity function GetRouteStart( string routeName ) +{ + foreach( entity node in routeNodes ) + { + if( !node.HasKey( "route_name" ) ) + continue + if( expect string( node.kv.route_name ) == routeName ) + { + return node + } + } +} + +array<entity> function getRoute( string routeName ) +{ + array<entity> ret + array<entity> currentNode = [] + foreach(entity node in routeNodes) + { + if( !node.HasKey( "route_name" ) ) + continue + if( node.kv.route_name == routeName ) + { + currentNode = [node] + break + } + + } + if( currentNode.len() == 0 ) + { + printt( "Route not found" ) + return [] + } + while( currentNode.len() != 0 ) + { + ret.append( currentNode[0] ) + currentNode = currentNode[0].GetLinkEntArray() + } + return ret +} + +void function Dev_MarkRoute( string routename ) +{ + foreach( entity e in getRoute( routename ) ) + { + DebugDrawSphere( e.GetOrigin(), 30.0, 255, 0, 255, false, 40 ) + } +}
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/item_inventory/sv_item_inventory.gnut b/Northstar.CustomServers/mod/scripts/vscripts/item_inventory/sv_item_inventory.gnut index 9057f7d8..60bad8d1 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/item_inventory/sv_item_inventory.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/item_inventory/sv_item_inventory.gnut @@ -112,6 +112,10 @@ void function PlayerInventory_GiveInventoryItem( entity player, InventoryItem in player.TakeWeaponNow( preexistingWeapon.GetWeaponClassName() ) player.GiveOffhandWeapon( inventoryItem.weaponRef, OFFHAND_INVENTORY, mods ) + if ( inventoryItem.itemType == eInventoryItemType.burnmeter ) { + entity weapon = player.GetOffhandWeapon(OFFHAND_INVENTORY) + weapon.e.burnReward = inventoryItem.burnReward.ref + } } void function PlayerInventory_PushInventoryItem( entity player, InventoryItem inventoryItem ) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_ai_mp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_ai_mp.gnut index 1102aae1..ce9227a2 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_ai_mp.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_ai_mp.gnut @@ -12,13 +12,13 @@ void function MpInitAILoadouts() void function SetProficiency( entity npc ) { - // unsure what the logic for deciding this should be so just going to default good - npc.kv.WeaponProficiency = eWeaponProficiency.VERYGOOD + // i think this is correct? iirc grunts and stuff in attrition are *really* bad so having poor as their proficiency makes sense + npc.kv.WeaponProficiency = GetDifficultyLevel() } void function SPMP_UpdateNPCProficiency( entity npc ) { - + SetProficiency( npc ) // this seems bad? dont see why they should be any different unless SP should use a different function } bool function IsAutoPopulateEnabled( var team = null ) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_angel_city.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_angel_city.nut index 8b2a4060..1781a21f 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_angel_city.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_angel_city.nut @@ -25,6 +25,12 @@ void function CodeCallback_MapInit() // there are some really busted titan startspawns that are on the fucking other side of the map from where they should be, so we remove them AddSpawnCallback( "info_spawnpoint_titan_start", TrimBadTitanStartSpawns ) AddSpawnCallback( "sky_camera", FixSkycamFog ) + + + // Load Frontier Defense Data + if( GameRules_GetGameMode() == "fd" ) + initFrontierDefenseData() + } void function FixBatterySpawns( entity spawn ) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_angel_city_fd.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_angel_city_fd.nut index 37b89169..cd3e2822 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_angel_city_fd.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_angel_city_fd.nut @@ -1 +1,23 @@ -//fuck
\ No newline at end of file +global function initFrontierDefenseData +void function initFrontierDefenseData() +{ + shopPosition = <0,0,0> + + + array<WaveEvent> wave0 + array<WaveEvent> wave1 + array<WaveEvent> wave2 + array<WaveEvent> wave3 + array<WaveEvent> wave4 + + + + + + + waveEvents.append(wave0) + waveEvents.append(wave1) + waveEvents.append(wave2) + waveEvents.append(wave3) + waveEvents.append(wave4) +}
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_black_water_canal.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_black_water_canal.nut index 2e35417f..46525cea 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_black_water_canal.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_black_water_canal.nut @@ -4,6 +4,11 @@ void function CodeCallback_MapInit() { // there are some really busted titan startspawns that are on the fucking other side of the map from where they should be, so we remove them AddSpawnCallback( "info_spawnpoint_titan_start", TrimBadTitanStartSpawns ) + + // Load Frontier Defense Data + if( GameRules_GetGameMode() == "fd" ) + initFrontierDefenseData() + } void function TrimBadTitanStartSpawns( entity spawn ) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_black_water_canal_fd.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_black_water_canal_fd.nut index 37b89169..cd3e2822 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_black_water_canal_fd.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_black_water_canal_fd.nut @@ -1 +1,23 @@ -//fuck
\ No newline at end of file +global function initFrontierDefenseData +void function initFrontierDefenseData() +{ + shopPosition = <0,0,0> + + + array<WaveEvent> wave0 + array<WaveEvent> wave1 + array<WaveEvent> wave2 + array<WaveEvent> wave3 + array<WaveEvent> wave4 + + + + + + + waveEvents.append(wave0) + waveEvents.append(wave1) + waveEvents.append(wave2) + waveEvents.append(wave3) + waveEvents.append(wave4) +}
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_colony02.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_colony02.nut index 0079d7e9..f0c17dcf 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_colony02.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_colony02.nut @@ -3,6 +3,10 @@ global function CodeCallback_MapInit void function CodeCallback_MapInit() { AddCallback_EntitiesDidLoad( CreateEvacNodes ) + + // Load Frontier Defense Data + if( GameRules_GetGameMode() == "fd" ) + initFrontierDefenseData() } void function CreateEvacNodes() diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_colony02_fd.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_colony02_fd.nut index 37b89169..cd3e2822 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_colony02_fd.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_colony02_fd.nut @@ -1 +1,23 @@ -//fuck
\ No newline at end of file +global function initFrontierDefenseData +void function initFrontierDefenseData() +{ + shopPosition = <0,0,0> + + + array<WaveEvent> wave0 + array<WaveEvent> wave1 + array<WaveEvent> wave2 + array<WaveEvent> wave3 + array<WaveEvent> wave4 + + + + + + + waveEvents.append(wave0) + waveEvents.append(wave1) + waveEvents.append(wave2) + waveEvents.append(wave3) + waveEvents.append(wave4) +}
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_drydock.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_drydock.nut index 37b89169..e6eb493d 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_drydock.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_drydock.nut @@ -1 +1,8 @@ -//fuck
\ No newline at end of file +global function CodeCallback_MapInit + +void function CodeCallback_MapInit() +{ + // Load Frontier Defense Data + if( GameRules_GetGameMode() == "fd" ) + initFrontierDefenseData() +}
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_drydock_fd.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_drydock_fd.nut index 37b89169..cd3e2822 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_drydock_fd.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_drydock_fd.nut @@ -1 +1,23 @@ -//fuck
\ No newline at end of file +global function initFrontierDefenseData +void function initFrontierDefenseData() +{ + shopPosition = <0,0,0> + + + array<WaveEvent> wave0 + array<WaveEvent> wave1 + array<WaveEvent> wave2 + array<WaveEvent> wave3 + array<WaveEvent> wave4 + + + + + + + waveEvents.append(wave0) + waveEvents.append(wave1) + waveEvents.append(wave2) + waveEvents.append(wave3) + waveEvents.append(wave4) +}
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_forwardbase_kodai.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_forwardbase_kodai.nut index 345a86d9..99965a1b 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_forwardbase_kodai.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_forwardbase_kodai.nut @@ -1,5 +1,6 @@ global function CodeCallback_MapInit + struct { int batteryIndex = 0 } file @@ -14,6 +15,10 @@ void function CodeCallback_MapInit() { // Battery spawns (in LTS/Free Agents) are in old locations, so we move them to the proper locations AddSpawnCallbackEditorClass( "script_ref", "script_power_up_other", FixBatterySpawns ) + + // Load Frontier Defense Data + if( GameRules_GetGameMode() == "fd" ) + initFrontierDefenseData() } void function FixBatterySpawns( entity spawn ) @@ -24,4 +29,4 @@ void function FixBatterySpawns( entity spawn ) PowerUp powerupDef = GetPowerUpFromItemRef( expect string( spawn.kv.powerUpType ) ) if ( powerupDef.spawnFunc() ) spawn.SetOrigin( BATTERY_SPAWNS[file.batteryIndex++] ) -}
\ No newline at end of file +} diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_forwardbase_kodai_fd.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_forwardbase_kodai_fd.nut index 37b89169..65278f6d 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_forwardbase_kodai_fd.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_forwardbase_kodai_fd.nut @@ -1 +1,631 @@ -//fuck
\ No newline at end of file +global function initFrontierDefenseData + + +void function initFrontierDefenseData() +{ + shopPosition = < -3862.13, 1267.69, 1060.06 > + FD_spawnPosition = < -838.6, 2629.63, 1592 > + FD_spawnAngles = < 0, 180, 0 > + + int index = 1 + + array< WaveEvent > wave1 + wave1.append( CreateSmokeEvent( < -12, 1720, 1540 >, 90, index++ ) ) + wave1.append( CreateWaitForTimeEvent( 0.2, index++ ) ) + wave1.append( CreateSmokeEvent( < -64, 964, 1540 >, 90, index++ ) ) + wave1.append( CreateWaitForTimeEvent( 0.4, index++ ) ) + wave1.append( CreateDroppodGruntEvent( < 864.625000, 693.750000, 1379.910034 >, "hillRouteClose", index++ ) ) + wave1.append( CreateWaitForTimeEvent( 0.9332962, index++ ) ) + wave1.append( CreateDroppodGruntEvent( < 884.625000, 1721.750000, 1377.410034 >, "hillRouteClose", index++ ) ) + wave1.append( CreateWaitForTimeEvent( 1.1667023, index++ ) ) + wave1.append( CreateDroppodGruntEvent( < 1226.410034, 1391.130005, 1334.689941 >, "hillRouteClose", index++ ) ) + wave1.append( CreateWaitForTimeEvent( 1.0499954, index++ ) ) + wave1.append( CreateDroppodGruntEvent( < 1258.060059, 921.593994, 1330.750000 >, "hillRouteClose", index++ ) ) + wave1.append( CreateWaitForTimeEvent( 1.0, index++ ) ) + wave1.append( CreateDroppodGruntEvent( < 1116.630005, 329.750000, 1372.280029 >, "hillRouteClose", index++ ) ) + wave1.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave1.append( CreateWaitUntilAliveWeightedEvent( 8, index++ ) ) + wave1.append( CreateDroppodGruntEvent( < 864.625000, 693.750000, 1379.910034 >, "hillRouteClose", index++ ) ) + wave1.append( CreateWaitForTimeEvent( 1.1669998, index++ ) ) + wave1.append( CreateDroppodGruntEvent( < 884.625000, 1721.750000, 1377.410034 >, "hillRouteClose", index++ ) ) + wave1.append( CreateWaitForTimeEvent( 0.6159973, index++ ) ) + wave1.append( CreateDroppodGruntEvent( < 1226.410034, 1391.130005, 1334.689941 >, "hillRouteClose", index++ ) ) + wave1.append( CreateWaitForTimeEvent( 0.8840027, index++ ) ) + wave1.append( CreateDroppodStalkerEvent( < 1258.060059, 921.593994, 1330.750000 >, "hillRouteClose", index++ ) ) + wave1.append( CreateWaitForTimeEvent( 0.5999985, index++ ) ) + wave1.append( CreateDroppodStalkerEvent( < 1116.630005, 329.750000, 1372.280029 >, "hillRouteClose", index++ ) ) + wave1.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave1.append( CreateWaitUntilAliveWeightedEvent( 8, index++ ) ) + wave1.append( CreateDroppodGruntEvent( < 864.625000, 693.750000, 1379.910034 >, "hillRouteClose", index++ ) ) + wave1.append( CreateWaitForTimeEvent( 1.3829956, index++ ) ) + wave1.append( CreateDroppodGruntEvent( < 884.625000, 1721.750000, 1377.410034 >, "hillRouteClose", index++ ) ) + wave1.append( CreateWaitForTimeEvent( 0.6340027, index++ ) ) + wave1.append( CreateDroppodGruntEvent( < 1226.410034, 1391.130005, 1334.689941 >, "hillRouteClose", index++ ) ) + wave1.append( CreateWaitForTimeEvent( 1.3829956, index++ ) ) + wave1.append( CreateDroppodGruntEvent( < 1258.060059, 921.593994, 1330.750000 >, "hillRouteClose", index++ ) ) + wave1.append( CreateWaitForTimeEvent( 1.5, index++ ) ) + wave1.append( CreateDroppodGruntEvent( < 1116.630005, 329.750000, 1372.280029 >, "hillRouteClose", index++ ) ) + wave1.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave1.append( CreateWaitUntilAliveWeightedEvent( 8, index++ ) ) + wave1.append( CreateDroppodGruntEvent( < 864.625000, 693.750000, 1379.910034 >, "hillRouteClose", index++ ) ) + wave1.append( CreateWaitForTimeEvent( 1.5, index++ ) ) + wave1.append( CreateDroppodGruntEvent( < 884.625000, 1721.750000, 1377.410034 >, "hillRouteClose", index++ ) ) + wave1.append( CreateWaitForTimeEvent( 0.9840088, index++ ) ) + wave1.append( CreateDroppodGruntEvent( < 1226.410034, 1391.130005, 1334.689941 >, "hillRouteClose", index++ ) ) + wave1.append( CreateWaitForTimeEvent( 1.5, index++ ) ) + wave1.append( CreateDroppodStalkerEvent( < 1258.060059, 921.593994, 1330.750000 >, "hillRouteClose", index++ ) ) + wave1.append( CreateWaitForTimeEvent( 1.2829895, index++ ) ) + wave1.append( CreateDroppodStalkerEvent( < 1116.630005, 329.750000, 1372.280029 >, "hillRouteClose", index++ ) ) + wave1.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave1.append( CreateWaitUntilAliveWeightedEvent( 8, index++ ) ) + wave1.append( CreateDroppodGruntEvent( < 864.625000, 693.750000, 1379.910034 >, "hillRouteClose", index++ ) ) + wave1.append( CreateWaitForTimeEvent( 1.5, index++ ) ) + wave1.append( CreateDroppodGruntEvent( < 884.625000, 1721.750000, 1377.410034 >, "hillRouteClose", index++ ) ) + wave1.append( CreateWaitForTimeEvent( 1.1829987, index++ ) ) + wave1.append( CreateDroppodGruntEvent( < 1226.410034, 1391.130005, 1334.689941 >, "hillRouteClose", index++ ) ) + wave1.append( CreateWaitForTimeEvent( 1.449997, index++ ) ) + wave1.append( CreateDroppodGruntEvent( < 1258.060059, 921.593994, 1330.750000 >, "hillRouteClose", index++ ) ) + wave1.append( CreateWaitForTimeEvent( 0.66700745, index++ ) ) + wave1.append( CreateDroppodGruntEvent( < 1116.630005, 329.750000, 1372.280029 >, "hillRouteClose", index++ ) ) + wave1.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave1.append( CreateWaitUntilAliveWeightedEvent( 8, index++ ) ) + wave1.append( CreateDroppodGruntEvent( < 864.625000, 693.750000, 1379.910034 >, "hillRouteClose", index++ ) ) + wave1.append( CreateWaitForTimeEvent( 1.2169952, index++ ) ) + wave1.append( CreateDroppodGruntEvent( < 884.625000, 1721.750000, 1377.410034 >, "hillRouteClose", index++ ) ) + wave1.append( CreateWaitForTimeEvent( 0.6159973, index++ ) ) + wave1.append( CreateDroppodGruntEvent( < 1226.410034, 1391.130005, 1334.689941 >, "hillRouteClose", index++ ) ) + wave1.append( CreateWaitForTimeEvent( 1.4840088, index++ ) ) + wave1.append( CreateToneSniperTitanEvent( < 1373.469971, 1219.410034, 1314.339966 >, < 0.000000, 169.541000, 0.000000 >, 0 ) ) + waveEvents.append( wave1 ) + index = 1 + array< WaveEvent > wave2 + wave2.append( CreateDroppodTickEvent( < 864.625000, 693.750000, 1379.910034 >, 4, "hillRouteClose", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 0.1, index++ ) ) + wave2.append( CreateSmokeEvent( < -12, 1720, 1540 >, 120, index++ ) ) + wave2.append( CreateWaitForTimeEvent( 0.2, index++ ) ) + wave2.append( CreateSmokeEvent( < -64, 964, 1540 >, 120, index++ ) ) + wave2.append( CreateWaitForTimeEvent( 0.7169983, index++ ) ) + wave2.append( CreateDroppodTickEvent( < 884.625000, 1721.750000, 1377.410034 >, 4, "hillRouteClose", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 1.6500244, index++ ) ) + wave2.append( CreateDroppodTickEvent( < 1226.410034, 1391.130005, 1334.689941 >, 4, "hillRouteClose", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 1.0329895, index++ ) ) + wave2.append( CreateDroppodTickEvent( < 1258.060059, 921.593994, 1330.750000 >, 4, "hillRouteClose", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave2.append( CreateWaitUntilAliveWeightedEvent( 12, index++ ) ) + wave2.append( CreateToneSniperTitanEvent( < 1373.469971, 1219.410034, 1314.339966 >, < 0.000000, 169.541000, 0.000000 >, index++ ) ) + wave2.append( CreateWaitForTimeEvent( 1.0159912, index++ ) ) + wave2.append( CreateToneSniperTitanEvent( < 1209.469971, 579.406006, 1332.310059 >, < 0.000000, 169.541000, 0.000000 >, index++ ) ) + wave2.append( CreateWaitForTimeEvent( 0.8999939, index++ ) ) + wave2.append( CreateToneTitanEvent( < 2475.810059, -3544.189941, 810.218994 >, < 0.000000, 90.000000, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 1.3000183, index++ ) ) + wave2.append( CreateToneTitanEvent( < 2665.060059, 4456.129883, 960.687988 >, < 0.000000, -141.108002, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 1.1499939, index++ ) ) + wave2.append( CreateDroppodSpectreMortarEvent( < 864.625000, 693.750000, 1379.910034 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave2.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave2.append( CreateDroppodSpectreMortarEvent( < 884.625000, 1721.750000, 1377.410034 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 0.6000061, index++ ) ) + wave2.append( CreateDroppodGruntEvent( < 1226.410034, 1391.130005, 1334.689941 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 1.6999817, index++ ) ) + wave2.append( CreateDroppodGruntEvent( < 864.625000, 693.750000, 1379.910034 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 2.9160156, index++ ) ) + wave2.append( CreateDroppodGruntEvent( < 1258.060059, 921.593994, 1330.750000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave2.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave2.append( CreateDroppodGruntEvent( < 864.625000, 693.750000, 1379.910034 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 0.8659973, index++ ) ) + wave2.append( CreateDroppodGruntEvent( < 884.625000, 1721.750000, 1377.410034 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 0.6839905, index++ ) ) + wave2.append( CreateDroppodGruntEvent( < 1226.410034, 1391.130005, 1334.689941 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 1.4160156, index++ ) ) + wave2.append( CreateToneTitanEvent( < 2475.810059, -3544.189941, 810.218994 >, < 0.000000, 90.000000, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 0.6000061, index++ ) ) + wave2.append( CreateToneTitanEvent( < 2665.060059, 4456.129883, 960.687988 >, < 0.000000, -141.108002, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave2.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave2.append( CreateWarningEvent( FD_IncomingWarnings.Reaper, index++ ) ) + wave2.append( CreateSuperSpectreEvent( < 1856.959961, -3177.639893, 812.718018 >, < -0.000000, -162.389999, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 1.03302, index++ ) ) + wave2.append( CreateSuperSpectreEvent( < 3123.000000, 4201.589844, 950.937988 >, < 0.000000, -117.246002, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 3.6169739, index++ ) ) + wave2.append( CreateSuperSpectreEvent( < 681.140991, -3538.780029, 813.127014 >, < 0.000000, -169.145996, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 0.78302, index++ ) ) + wave2.append( CreateSuperSpectreEvent( < 2614.629883, 4771.560059, 947.968994 >, < 0.000000, -141.108002, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 3.1829834, index++ ) ) + wave2.append( CreateSuperSpectreEvent( < 2184.969971, -3550.040039, 819.479980 >, < 0.000000, 177.582993, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave2.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave2.append( CreateSuperSpectreEvent( < 1764.410034, 4424.220215, 953.375000 >, < -0.000000, -170.024002, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave2.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave2.append( CreateDroppodTickEvent( < 3248.840088, 161.156006, 951.781006 >, 4, "hillRouteClose", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 1.1499939, index++ ) ) + wave2.append( CreateDroppodTickEvent( < 3156.560059, 2266.939941, 951.781006 >, 4, "hillRouteClose", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave2.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave2.append( CreateDroppodTickEvent( < 3248.840088, 161.156006, 951.781006 >, 4, "hillRouteClose", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 1.1170044, index++ ) ) + wave2.append( CreateDroppodTickEvent( < 3156.560059, 2266.939941, 951.781006 >, 4, "hillRouteClose", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 0.8829956, index++ ) ) + wave2.append( CreateToneTitanEvent( < 4466.220215, 1469.410034, 947.281006 >, < 0.000000, 169.541000, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 3.5169983, index++ ) ) + wave2.append( CreateDroppodGruntEvent( < 2336.000000, 1968.000000, 953.531006 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave2.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave2.append( CreateDroppodGruntEvent( < 3248.840088, 161.156006, 951.781006 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 2.6660156, index++ ) ) + wave2.append( CreateDroppodGruntEvent( < 3156.560059, 2266.939941, 951.781006 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 1.1999817, index++ ) ) + wave2.append( CreateDroppodGruntEvent( < 2336.000000, 1968.000000, 953.531006 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave2.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave2.append( CreateSuperSpectreEvent( < 4163.069824, 1471.650024, 944.281006 >, < -0.000000, -179.416000, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 1.5159912, index++ ) ) + wave2.append( CreateSuperSpectreEvent( < 4210.669922, 895.575989, 944.281006 >, < -0.000000, -164.787003, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 2.75, index++ ) ) + wave2.append( CreateSuperSpectreEvent( < 3577.010010, 1491.959961, 944.281006 >, < -0.000000, 169.908005, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 1.1340027, index++ ) ) + wave2.append( CreateSuperSpectreEvent( < 3982.860107, 1778.540039, 944.281006 >, < -0.000000, 179.488007, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave2.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave2.append( CreateDroppodGruntEvent( < 2457.310059, -2563.659912, 789.250000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 1.3840027, index++ ) ) + wave2.append( CreateDroppodGruntEvent( < 1935.839966, 3727.840088, 931.656006 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave2.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave2.append( CreateSuperSpectreEvent( < 2182.939941, -3549.810059, 819.468994 >, < 0.000000, 177.582993, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 0.1159668, index++ ) ) + wave2.append( CreateDroppodGruntEvent( < 1045.339966, -2843.340088, 804.812988 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 0.5670166, index++ ) ) + wave2.append( CreateSuperSpectreEvent( < 2357.739990, 4476.339844, 962.960022 >, < -0.000000, 177.669998, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 0.7000122, index++ ) ) + wave2.append( CreateDroppodGruntEvent( < 2111.840088, 3295.840088, 939.031006 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave2.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave2.append( CreateSmokeEvent( < 2684, 1252, 1092 >, 120, index++ ) ) + wave2.append( CreateWaitForTimeEvent( 0.2, index++ ) ) + wave2.append( CreateSmokeEvent( < 2452, 1812, 1092 >, 120, index++ ) ) + wave2.append( CreateWaitForTimeEvent( 0.2, index++ ) ) + wave2.append( CreateSmokeEvent( < 2336, 636, 1092 >, 120, index++ ) ) + wave2.append( CreateWaitForTimeEvent( 0.6, index++ ) ) + wave2.append( CreateSuperSpectreEvent( < 2343.590088, -3185.840088, 788.312988 >, < -0.000000, 174.550995, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 0.8500366, index++ ) ) + wave2.append( CreateSuperSpectreEvent( < 2338.270020, 4684.279785, 952.682007 >, < -0.000000, -167.669006, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave2.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave2.append( CreateSuperSpectreEvent( < 2177.209961, -3539.600098, 817.719971 >, < 0.000000, 178.065994, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 1.0, index++ ) ) + wave2.append( CreateSuperSpectreEvent( < 2401.719971, 4475.089844, 962.406006 >, < 0.000000, 177.626999, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 0.0, index++ ) ) + wave2.append( CreateIonTitanEvent( < 1817.380005, -3585.909912, 813.937988 >, < 0.000000, 90.000000, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 1.032959, index++ ) ) + wave2.append( CreateSuperSpectreEvent( < 2576.909912, -3007.250000, 796.093994 >, < 0.000000, -165.850006, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 0.28302002, index++ ) ) + wave2.append( CreateIonTitanEvent( < 2614.879883, 4771.560059, 951.000000 >, < 0.000000, -141.108002, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 0.7839966, index++ ) ) + wave2.append( CreateSuperSpectreEvent( < 2828.399902, 4138.450195, 938.893982 >, < 0.000000, -171.078995, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave2.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave2.append( CreateLegionTitanEvent( < 4466.689941, 1469.410034, 947.281006 >, < 0.000000, 169.541000, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave2.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave2.append( CreateSuperSpectreEvent( < 4182.189941, 917.906006, 944.281006 >, < 0.000000, -124.805000, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 1.3170166, index++ ) ) + wave2.append( CreateSuperSpectreEvent( < 2747.790039, 1574.170044, 944.281006 >, < -0.000000, -164.485001, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave2.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave2.append( CreateScorchTitanEvent( < 2821.659912, -2937.090088, 827.937988 >, < 0.000000, 117.202003, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 1.0, index++ ) ) + wave2.append( CreateScorchTitanEvent( < 3123.560059, 4202.060059, 954.343994 >, < 0.000000, -141.108002, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 0.1159668, index++ ) ) + wave2.append( CreateSuperSpectreEvent( < 2169.590088, -3540.250000, 817.875000 >, < -0.000000, 178.065002, 0.000000 >, "", index++ ) ) + wave2.append( CreateWaitForTimeEvent( 1.3840332, index++ ) ) + wave2.append( CreateSuperSpectreEvent( < 2354.810059, 4476.589844, 962.968994 >, < -0.000000, 177.759003, 0.000000 >, "", 0 ) ) + waveEvents.append( wave2 ) + index = 1 + array< WaveEvent > wave3 + wave3.append( CreateRoninTitanEvent( < 1763.839966, -1608.750000, 810.281006 >, < 0.000000, 90.000000, 0.000000 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 0.1670288, index++ ) ) + wave3.append( CreateSmokeEvent( < -2264, -2096, 928 >, 120, index++ ) ) + wave3.append( CreateWaitForTimeEvent( 0.333, index++ ) ) + wave3.append( CreateSmokeEvent( < -3132, -1904, 928 >, 120, index++ ) ) + wave3.append( CreateWaitForTimeEvent( 0.2, index++ ) ) + wave3.append( CreateSmokeEvent( < -1548, -2240, 928 >, 120, index++ ) ) + wave3.append( CreateWaitForTimeEvent( 0.067, index++ ) ) + wave3.append( CreateCloakDroneEvent( < 1883.910034, -1569.939941, 1108.000000 >, < 0.000000, 0.000000, 0.000000 >, index++ ) ) + wave3.append( CreateWaitForTimeEvent( 1.1499634, index++ ) ) + wave3.append( CreateDroppodGruntEvent( < 2457.310059, -2563.659912, 789.250000 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 1.3829956, index++ ) ) + wave3.append( CreateDroppodGruntEvent( < 1045.339966, -2843.340088, 804.812988 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 3.4000244, index++ ) ) + wave3.append( CreateDroppodGruntEvent( < 346.312988, -2838.659912, 803.968994 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 1.1170044, index++ ) ) + wave3.append( CreateDroppodGruntEvent( < 1418.310059, -2254.659912, 810.031006 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave3.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave3.append( CreateWarningEvent( FD_IncomingWarnings.Reaper, index++ ) ) + wave3.append( CreateSuperSpectreEvent( < 2170.020020, -3549.570068, 819.468994 >, < -0.000000, 177.626007, 0.000000 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 1.0669556, index++ ) ) + wave3.append( CreateSuperSpectreEvent( < 2577.060059, -3007.379883, 796.093994 >, < -0.000000, -165.850006, 0.000000 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 1.1329956, index++ ) ) + wave3.append( CreateSuperSpectreEvent( < 1512.939941, -3294.090088, 798.000000 >, < -0.000000, 89.077103, 0.000000 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 1.4000244, index++ ) ) + wave3.append( CreateSuperSpectreEvent( < 1531.000000, -1779.880005, 800.031006 >, < 0.000000, 133.110001, 0.000000 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave3.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave3.append( CreateScorchTitanEvent( < 2475.909912, -3544.659912, 810.281006 >, < 0.000000, 90.000000, 0.000000 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 0.6829834, index++ ) ) + wave3.append( CreateIonTitanEvent( < 2821.340088, -2936.719971, 827.937988 >, < 0.000000, 117.202003, 0.000000 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 0.7839966, index++ ) ) + wave3.append( CreateIonTitanEvent( < 1503.810059, -3600.189941, 813.687988 >, < 0.000000, 90.000000, 0.000000 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 1.0, index++ ) ) + wave3.append( CreateScorchTitanEvent( < 1559.910034, -2024.660034, 803.031006 >, < 0.000000, 90.000000, 0.000000 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave3.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave3.append( CreateSpawnDroneEvent( < 2487.310059, -2561.379883, 5744.229980 >, < 0.004999, 90.003700, 0.000004 >, "", index++, false ) ) + wave3.append( CreateWaitForTimeEvent( 0.0, index++ ) ) + wave3.append( CreateSpawnDroneEvent( < 2457.310059, -2591.379883, 5744.189941 >, < 0.004999, 90.003700, 0.000004 >, "", index++, false ) ) + wave3.append( CreateWaitForTimeEvent( 0.0, index++ ) ) + wave3.append( CreateSpawnDroneEvent( < 2457.310059, -2531.379883, 5744.319824 >, < 0.004999, 90.003700, 0.000004 >, "", index++, false ) ) + wave3.append( CreateWaitForTimeEvent( 0.0, index++ ) ) + wave3.append( CreateSpawnDroneEvent( < 2427.310059, -2561.379883, 5744.549805 >, < 0.004999, 90.003700, 0.000004 >, "", index++, false ) ) + wave3.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave3.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave3.append( CreateDroppodGruntEvent( < 2457.310059, -2563.659912, 789.250000 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 1.282959, index++ ) ) + wave3.append( CreateDroppodGruntEvent( < 1045.339966, -2843.340088, 804.812988 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 2.6170044, index++ ) ) + wave3.append( CreateDroppodGruntEvent( < 346.312988, -2838.659912, 803.968994 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 0.9660034, index++ ) ) + wave3.append( CreateDroppodGruntEvent( < 1418.310059, -2254.659912, 810.031006 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 1.0999756, index++ ) ) + wave3.append( CreateToneSniperTitanEvent( < 4466.220215, 1469.410034, 947.281006 >, < 0.000000, 169.541000, 0.000000 >, index++ ) ) + wave3.append( CreateWaitForTimeEvent( 0.6170044, index++ ) ) + wave3.append( CreateMonarchTitanEvent( < 4453.129883, 964.750000, 947.281006 >, < 0.000000, -172.529007, 0.000000 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave3.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave3.append( CreateRoninTitanEvent( < 1763.839966, -1608.750000, 810.281006 >, < 0.000000, 90.000000, 0.000000 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 0.61602783, index++ ) ) + wave3.append( CreateRoninTitanEvent( < 2359.840088, -1596.750000, 802.718994 >, < 0.000000, 90.000000, 0.000000 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 1.9840088, index++ ) ) + wave3.append( CreateToneTitanEvent( < 2475.810059, -3544.189941, 810.218994 >, < 0.000000, 90.000000, 0.000000 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 1.0999756, index++ ) ) + wave3.append( CreateToneTitanEvent( < 2821.340088, -2936.719971, 827.937988 >, < 0.000000, 117.202003, 0.000000 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave3.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave3.append( CreateSuperSpectreEvent( < 2180.080078, -3539.689941, 817.739014 >, < 0.000000, 178.065994, 0.000000 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 0.6329956, index++ ) ) + wave3.append( CreateLegionTitanEvent( < 2680.219971, -1724.630005, 809.718994 >, < 0.000000, 169.320999, 0.000000 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 0.06695557, index++ ) ) + wave3.append( CreateSuperSpectreEvent( < 2533.800049, -3018.310059, 795.421021 >, < 0.000000, -165.806000, 0.000000 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 1.0170288, index++ ) ) + wave3.append( CreateLegionTitanEvent( < 1763.910034, -1608.660034, 810.218994 >, < 0.000000, 90.000000, 0.000000 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 0.16601562, index++ ) ) + wave3.append( CreateSuperSpectreEvent( < 1512.839966, -3298.719971, 797.968994 >, < -0.000000, 89.120796, 0.000000 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 1.0, index++ ) ) + wave3.append( CreateSuperSpectreEvent( < 1499.910034, -1748.660034, 801.656006 >, < -0.000000, 132.934998, 0.000000 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 2.2340088, index++ ) ) + wave3.append( CreateDroppodGruntEvent( < 2457.310059, -2563.659912, 789.250000 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 1.4829712, index++ ) ) + wave3.append( CreateDroppodGruntEvent( < 1045.339966, -2843.340088, 804.812988 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 2.9000244, index++ ) ) + wave3.append( CreateDroppodGruntEvent( < 346.312988, -2838.659912, 803.968994 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 0.5999756, index++ ) ) + wave3.append( CreateDroppodGruntEvent( < 1418.310059, -2254.659912, 810.031006 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 0.6829834, index++ ) ) + wave3.append( CreateScorchTitanEvent( < 1503.910034, -3600.659912, 813.781006 >, < 0.000000, 90.000000, 0.000000 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 1.3170166, index++ ) ) + wave3.append( CreateScorchTitanEvent( < 2475.909912, -3544.659912, 810.281006 >, < 0.000000, 90.000000, 0.000000 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave3.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave3.append( CreateToneTitanEvent( < 1763.810059, -1608.189941, 810.000000 >, < 0.000000, 90.000000, 0.000000 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 0.9000244, index++ ) ) + wave3.append( CreateToneTitanEvent( < 2359.810059, -1596.189941, 802.718994 >, < 0.000000, 90.000000, 0.000000 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 0.5839844, index++ ) ) + wave3.append( CreateWarningEvent( FD_IncomingWarnings.CloakDrone, index++ ) ) + wave3.append( CreateCloakDroneEvent( < 1923.000000, -1544.000000, 1108.000000 >, < 0.000000, 0.000000, 0.000000 >, index++ ) ) + wave3.append( CreateWaitForTimeEvent( 1.3330078, index++ ) ) + wave3.append( CreateCloakDroneEvent( < 1982.020020, -1598.000000, 1236.040039 >, < 0.000000, 0.000000, 0.000000 >, index++ ) ) + wave3.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave3.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave3.append( CreateLegionTitanEvent( < 4466.689941, 1469.410034, 947.281006 >, < 0.000000, 169.541000, 0.000000 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 0.7999878, index++ ) ) + wave3.append( CreateLegionTitanEvent( < 4453.589844, 964.906006, 947.281006 >, < 0.000000, -172.529007, 0.000000 >, "", index++ ) ) + wave3.append( CreateWaitForTimeEvent( 1.4000244, index++ ) ) + wave3.append( CreateMonarchTitanEvent( < 3866.659912, 1445.630005, 947.281006 >, < 0.000000, 180.000000, 0.000000 >, "", 0 ) ) + waveEvents.append( wave3 ) + index = 1 + array< WaveEvent > wave4 + wave4.append( CreateDroppodStalkerEvent( < 1935.839966, 3727.840088, 931.656006 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.6000366, index++ ) ) + wave4.append( CreateSmokeEvent( < -2596, 3224, 1104 >, 120, index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.1, index++ ) ) + wave4.append( CreateSmokeEvent( < -3252, 3052, 1104 >, 120, index++ ) ) + wave4.append( CreateDroppodStalkerEvent( < 2111.840088, 3295.840088, 939.031006 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.1, index++ ) ) + wave4.append( CreateSmokeEvent( < -1728, 3136, 1104 >, 120, index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.8, index++ ) ) + wave4.append( CreateScorchTitanEvent( < 2665.340088, 4456.500000, 960.656006 >, < 0.000000, -141.108002, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.8829956, index++ ) ) + wave4.append( CreateToneTitanEvent( < 3123.250000, 4201.689941, 954.281006 >, < 0.000000, -141.108002, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.6000366, index++ ) ) + wave4.append( CreateToneTitanEvent( < 1324.160034, 4820.189941, 937.531006 >, < 0.000000, -90.000000, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 1.0, index++ ) ) + wave4.append( CreateNukeTitanEvent( < 3144.659912, 2935.629883, 917.218994 >, < 0.000000, 179.341003, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 1.2000122, index++ ) ) + wave4.append( CreateNukeTitanEvent( < 3739.129883, 1985.719971, 947.281006 >, < 0.000000, 180.000000, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 1.5, index++ ) ) + wave4.append( CreateDroppodStalkerEvent( < 1087.839966, 3863.840088, 931.750000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 1.3499756, index++ ) ) + wave4.append( CreateDroppodStalkerEvent( < 908.750000, 3093.629883, 967.500000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 1.2999878, index++ ) ) + wave4.append( CreateDroppodStalkerEvent( < 3156.560059, 2266.939941, 951.781006 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave4.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave4.append( CreateDroppodStalkerEvent( < 1935.839966, 3727.840088, 931.656006 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.7000122, index++ ) ) + wave4.append( CreateDroppodStalkerEvent( < 2111.840088, 3295.840088, 939.031006 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.9830322, index++ ) ) + wave4.append( CreateDroppodStalkerEvent( < 1087.839966, 3863.840088, 931.750000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 3.5999756, index++ ) ) + wave4.append( CreateWarningEvent( FD_IncomingWarnings.MortarTitan, index++ ) ) + wave4.append( CreateMortarTitanEvent( < 2475.810059, -3544.189941, 810.218994 >, < 0.000000, 90.000000, 0.000000 >, index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.5830078, index++ ) ) + wave4.append( CreateMortarTitanEvent( < 2821.340088, -2936.719971, 827.937988 >, < 0.000000, 117.202003, 0.000000 >, index++ ) ) + wave4.append( CreateWaitForTimeEvent( 1.3499756, index++ ) ) + wave4.append( CreateScorchTitanEvent( < 2665.340088, 4456.500000, 960.656006 >, < 0.000000, -141.108002, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 1.0670166, index++ ) ) + wave4.append( CreateScorchTitanEvent( < 3123.560059, 4202.060059, 954.343994 >, < 0.000000, -141.108002, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 1.21698, index++ ) ) + wave4.append( CreateIonTitanEvent( < 1324.160034, 4820.189941, 937.531006 >, < 0.000000, -90.000000, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.9160156, index++ ) ) + wave4.append( CreateIonTitanEvent( < 3144.159912, 2935.530029, 917.187988 >, < 0.000000, 179.341003, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.684021, index++ ) ) + wave4.append( CreateNukeTitanEvent( < 3739.129883, 1985.719971, 947.281006 >, < 0.000000, 180.000000, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.5999756, index++ ) ) + wave4.append( CreateNukeTitanEvent( < -31.906300, 4688.660156, 1027.660034 >, < 0.000000, -90.000000, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 1.2659912, index++ ) ) + wave4.append( CreateNukeTitanEvent( < 1293.939941, 1827.410034, 1321.750000 >, < 0.000000, 169.541000, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 1.5339966, index++ ) ) + wave4.append( CreateDroppodStalkerEvent( < 908.750000, 3093.629883, 967.500000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 1.3000488, index++ ) ) + wave4.append( CreateDroppodStalkerEvent( < 3156.560059, 2266.939941, 951.781006 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave4.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave4.append( CreateWarningEvent( FD_IncomingWarnings.Reaper, index++ ) ) + wave4.append( CreateSuperSpectreEvent( < 2355.209961, 4472.799805, 963.218994 >, < -0.000000, 175.473007, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.5999756, index++ ) ) + wave4.append( CreateSuperSpectreEvent( < 2835.689941, 4139.939941, 939.281006 >, < 0.000000, -171.078995, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 1.0170288, index++ ) ) + wave4.append( CreateSuperSpectreEvent( < 1014.690002, 4844.540039, 941.236023 >, < -0.000000, 173.994995, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.6170044, index++ ) ) + wave4.append( CreateSuperSpectreEvent( < 2833.949951, 2953.350098, 910.458008 >, < -0.000000, 178.046997, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.5830078, index++ ) ) + wave4.append( CreateSuperSpectreEvent( < 4164.439941, 1471.750000, 944.281006 >, < -0.000000, -179.429001, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.117004395, index++ ) ) + wave4.append( CreateDroppodStalkerEvent( < 1935.839966, 3727.840088, 931.656006 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 1.0999756, index++ ) ) + wave4.append( CreateSuperSpectreEvent( < 4207.680176, 894.888977, 944.281006 >, < -0.000000, -167.283005, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.21600342, index++ ) ) + wave4.append( CreateDroppodStalkerEvent( < 2111.840088, 3295.840088, 939.031006 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.9840088, index++ ) ) + wave4.append( CreateSuperSpectreEvent( < 3570.689941, 1491.780029, 944.281006 >, < 0.000000, 169.761002, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.23297119, index++ ) ) + wave4.append( CreateDroppodStalkerEvent( < 1087.839966, 3863.840088, 931.750000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.3670044, index++ ) ) + wave4.append( CreateSuperSpectreEvent( < 3604.739990, 835.104004, 944.281006 >, < -0.000000, -159.296997, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave4.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave4.append( CreateWarningEvent( FD_IncomingWarnings.ArcTitan, index++ ) ) + wave4.append( CreateArcTitanEvent( < 2665.469971, 4456.529785, 960.656006 >, < 0.000000, -141.108002, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.1, index++ ) ) + wave4.append( CreateSmokeEvent( < -2596, 3224, 1104 >, 120, index++ ) ) + wave4.append( CreateSmokeEvent( < -3252, 3052, 1104 >, 120, index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.2, index++ ) ) + wave4.append( CreateSmokeEvent( < -1728, 3136, 1104 >, 120, index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.9199829, index++ ) ) + wave4.append( CreateArcTitanEvent( < 3123.659912, 4202.089844, 954.343994 >, < 0.000000, -141.108002, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.6799927, index++ ) ) + wave4.append( CreateScorchTitanEvent( < 1324.060059, 4820.660156, 937.562988 >, < 0.000000, -90.000000, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 1.2200317, index++ ) ) + wave4.append( CreateScorchTitanEvent( < 3144.659912, 2935.629883, 917.218994 >, < 0.000000, 179.341003, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.90997314, index++ ) ) + wave4.append( CreateToneTitanEvent( < 3738.659912, 1985.630005, 947.281006 >, < 0.000000, 180.000000, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.5700073, index++ ) ) + wave4.append( CreateToneTitanEvent( < -31.812500, 4688.189941, 1027.560059 >, < 0.000000, -90.000000, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 1.4000244, index++ ) ) + wave4.append( CreateRoninTitanEvent( < 1294.030029, 1827.339966, 1321.719971 >, < 0.000000, 169.541000, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.9299927, index++ ) ) + wave4.append( CreateRoninTitanEvent( < 4278.029785, 1771.339966, 947.281006 >, < 0.000000, 169.541000, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.8899536, index++ ) ) + wave4.append( CreateToneSniperTitanEvent( < 4453.129883, 964.750000, 947.281006 >, < 0.000000, -172.529007, 0.000000 >, index++ ) ) + wave4.append( CreateWaitForTimeEvent( 1.210083, index++ ) ) + wave4.append( CreateToneSniperTitanEvent( < 3866.659912, 1445.630005, 947.281006 >, < 0.000000, 180.000000, 0.000000 >, index++ ) ) + wave4.append( CreateWaitForTimeEvent( 1.0, index++ ) ) + wave4.append( CreateCloakDroneEvent( < 4432.939941, 1262.939941, 1244.000000 >, < 0.000000, 0.000000, 0.000000 >, index++ ) ) + wave4.append( CreateWaitForTimeEvent( 4.3898926, index++ ) ) + wave4.append( CreateSuperSpectreEvent( < 3878.439941, 933.812988, 944.281006 >, < -0.000000, -79.509102, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 1.2000732, index++ ) ) + wave4.append( CreateSuperSpectreEvent( < 4008.780029, 378.406006, 944.281006 >, < 0.000000, -120.498001, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.92993164, index++ ) ) + wave4.append( CreateSuperSpectreEvent( < 2916.810059, 2679.780029, 939.000000 >, < -0.000000, -44.335999, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.5800781, index++ ) ) + wave4.append( CreateSuperSpectreEvent( < 545.906006, 1309.910034, 1438.750000 >, < 0.000000, -166.860001, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave4.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave4.append( CreateWarningEvent( FD_IncomingWarnings.NukeTitan, index++ ) ) + wave4.append( CreateNukeTitanEvent( < 2665.340088, 4456.500000, 960.656006 >, < 0.000000, -141.108002, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 1.0198975, index++ ) ) + wave4.append( CreateNukeTitanEvent( < 3123.560059, 4202.060059, 954.343994 >, < 0.000000, -141.108002, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.9000244, index++ ) ) + wave4.append( CreateNukeTitanEvent( < 3144.659912, 2935.629883, 917.218994 >, < 0.000000, 179.341003, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 1.5, index++ ) ) + wave4.append( CreateNukeTitanEvent( < 1324.060059, 4820.660156, 937.562988 >, < 0.000000, -90.000000, 0.000000 >, "", index++ ) ) + wave4.append( CreateWaitForTimeEvent( 0.60998535, index++ ) ) + wave4.append( CreateNukeTitanEvent( < 3739.129883, 1985.719971, 947.281006 >, < 0.000000, 180.000000, 0.000000 >, "", 0 ) ) + waveEvents.append( wave4 ) + index = 1 + array< WaveEvent > wave5 + wave5.append( CreateSmokeEvent( < -12, 1720, 1540 >, 120, index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.1, index++ ) ) + wave5.append( CreateSmokeEvent( < -64, 964, 1540 >, 120, index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.3, index++ ) ) + wave5.append( CreateSmokeEvent( < -2264, -2096, 928 >, 120, index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.3, index++ ) ) + wave5.append( CreateSmokeEvent( < -3132, -1904, 928 >, 120, index++ ) ) + wave5.append( CreateDroppodTickEvent( < 864.625000, 693.750000, 1379.910034 >, 4, "hillRouteClose", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.1, index++ ) ) + wave5.append( CreateSmokeEvent( < -1548, -2240, 928 >, 120, index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.1, index++ ) ) + wave5.append( CreateSmokeEvent( < -2596, 3224, 1104 >, 120, index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.2, index++ ) ) + wave5.append( CreateSmokeEvent( < -3252, 3052, 1104 >, 120, index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.3, index++ ) ) + wave5.append( CreateSmokeEvent( < -1728, 3136, 1104 >, 120, index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.4, index++ ) ) + wave5.append( CreateDroppodTickEvent( < 884.625000, 1721.750000, 1377.410034 >, 4, "hillRouteClose", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.79992676, index++ ) ) + wave5.append( CreateDroppodStalkerEvent( < 1226.410034, 1391.130005, 1334.689941 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.9400635, index++ ) ) + wave5.append( CreateDroppodStalkerEvent( < 1258.060059, 921.593994, 1330.750000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave5.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave5.append( CreateSuperSpectreEvent( < 1094.089966, 1330.660034, 1354.969971 >, < -0.000000, 157.544006, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.7800293, index++ ) ) + wave5.append( CreateSuperSpectreEvent( < 857.406006, 739.843994, 1373.030029 >, < -0.000000, 151.962997, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 2.0700684, index++ ) ) + wave5.append( CreateSuperSpectreEvent( < 1048.969971, 1660.810059, 1349.089966 >, < 0.000000, -100.986000, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 1.2099609, index++ ) ) + wave5.append( CreateSuperSpectreEvent( < 2724.129883, 2458.629883, 946.155029 >, < -0.000000, -127.245003, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave5.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave5.append( CreateSuperSpectreEvent( < 1092.119995, 1331.380005, 1355.650024 >, < 0.000000, 157.500000, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 1.1699219, index++ ) ) + wave5.append( CreateSuperSpectreEvent( < 938.187988, 707.406006, 1362.939941 >, < -0.000000, 153.720993, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 2.710083, index++ ) ) + wave5.append( CreateDroppodStalkerEvent( < 1528.660034, -1443.339966, 816.031006 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 1.1199951, index++ ) ) + wave5.append( CreateDroppodStalkerEvent( < 1418.310059, -2254.659912, 810.031006 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 2.2999268, index++ ) ) + wave5.append( CreateToneTitanEvent( < 2475.810059, -3544.189941, 810.218994 >, < 0.000000, 90.000000, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 1.3000488, index++ ) ) + wave5.append( CreateToneTitanEvent( < 2821.340088, -2936.719971, 827.937988 >, < 0.000000, 117.202003, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.8000488, index++ ) ) + wave5.append( CreateSuperSpectreEvent( < 1511.339966, -1445.229980, 825.757996 >, < -0.000000, 141.589996, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.099975586, index++ ) ) + wave5.append( CreateScorchTitanEvent( < 1559.910034, -2024.660034, 803.031006 >, < 0.000000, 90.000000, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.57995605, index++ ) ) + wave5.append( CreateSuperSpectreEvent( < 2086.750000, -1459.000000, 810.750000 >, < -0.000000, 143.964996, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.6199951, index++ ) ) + wave5.append( CreateIonTitanEvent( < 2665.060059, 4456.129883, 960.687988 >, < 0.000000, -141.108002, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.8800049, index++ ) ) + wave5.append( CreateToneTitanEvent( < 3123.250000, 4201.689941, 954.281006 >, < 0.000000, -141.108002, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 1.3399658, index++ ) ) + wave5.append( CreateLegionTitanEvent( < 3144.659912, 2935.629883, 917.218994 >, < 0.000000, 179.341003, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave5.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave5.append( CreateDroppodStalkerEvent( < 2457.310059, -2563.659912, 789.250000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.92004395, index++ ) ) + wave5.append( CreateDroppodStalkerEvent( < 1045.339966, -2843.340088, 804.812988 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave5.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave5.append( CreateIonTitanEvent( < 4466.220215, 1469.410034, 947.281006 >, < 0.000000, 169.541000, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.9499512, index++ ) ) + wave5.append( CreateIonTitanEvent( < 4453.129883, 964.750000, 947.281006 >, < 0.000000, -172.529007, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.17004395, index++ ) ) + wave5.append( CreateSuperSpectreEvent( < 1548.780029, -1475.209961, 805.556030 >, < -0.000000, 141.876999, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 1.5, index++ ) ) + wave5.append( CreateSuperSpectreEvent( < 2087.750000, -1461.540039, 810.366028 >, < -0.000000, 143.395004, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 3.9799805, index++ ) ) + wave5.append( CreateScorchTitanEvent( < 2475.909912, -3544.659912, 810.281006 >, < 0.000000, 90.000000, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 1.3399658, index++ ) ) + wave5.append( CreateToneTitanEvent( < 2821.340088, -2936.719971, 827.937988 >, < 0.000000, 117.202003, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.85998535, index++ ) ) + wave5.append( CreateIonTitanEvent( < 1817.380005, -3585.909912, 813.937988 >, < 0.000000, 90.000000, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.9400635, index++ ) ) + wave5.append( CreateDroppodStalkerEvent( < 1528.660034, -1443.339966, 816.031006 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 1.1099854, index++ ) ) + wave5.append( CreateDroppodStalkerEvent( < 1418.310059, -2254.659912, 810.031006 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 1.9899902, index++ ) ) + wave5.append( CreateScorchTitanEvent( < 1559.910034, -2024.660034, 803.031006 >, < 0.000000, 90.000000, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.8100586, index++ ) ) + wave5.append( CreateScorchTitanEvent( < 2411.909912, -1108.660034, 803.375000 >, < 0.000000, 90.000000, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 1.289917, index++ ) ) + wave5.append( CreateSuperSpectreEvent( < 1511.310059, -1437.780029, 826.656006 >, < -0.000000, 142.382996, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.710083, index++ ) ) + wave5.append( CreateSuperSpectreEvent( < 2129.800049, -1492.459961, 806.202026 >, < 0.000000, 143.744995, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave5.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave5.append( CreateToneTitanEvent( < 2665.060059, 4456.129883, 960.687988 >, < 0.000000, -141.108002, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.5600586, index++ ) ) + wave5.append( CreateToneTitanEvent( < 3123.250000, 4201.689941, 954.281006 >, < 0.000000, -141.108002, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 1.3199463, index++ ) ) + wave5.append( CreateMonarchTitanEvent( < 1324.160034, 4820.189941, 937.531006 >, < 0.000000, -90.000000, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave5.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave5.append( CreateSuperSpectreEvent( < 1511.160034, -1437.079956, 809.958008 >, < -0.000000, 142.475998, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 1.1899414, index++ ) ) + wave5.append( CreateSuperSpectreEvent( < 2091.909912, -1464.430054, 809.992981 >, < -0.000000, 143.503998, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 1.8800049, index++ ) ) + wave5.append( CreateDroppodStalkerEvent( < 1528.660034, -1443.339966, 816.031006 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 1.1500244, index++ ) ) + wave5.append( CreateDroppodStalkerEvent( < 1418.310059, -2254.659912, 810.031006 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.3499756, index++ ) ) + wave5.append( CreateSuperSpectreEvent( < 1452.199951, -1794.530029, 804.614990 >, < -0.000000, 112.485001, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.22998047, index++ ) ) + wave5.append( CreateDroppodStalkerEvent( < 896.656006, -1227.339966, 964.437988 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.8699951, index++ ) ) + wave5.append( CreateSuperSpectreEvent( < 2162.209961, -1065.609985, 806.807007 >, < -0.000000, -174.283005, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.11999512, index++ ) ) + wave5.append( CreateDroppodStalkerEvent( < 2457.310059, -2563.659912, 789.250000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave5.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave5.append( CreateToneTitanEvent( < 2665.060059, 4456.129883, 960.687988 >, < 0.000000, -141.108002, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.5999756, index++ ) ) + wave5.append( CreateToneTitanEvent( < 3123.250000, 4201.689941, 954.281006 >, < 0.000000, -141.108002, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.60009766, index++ ) ) + wave5.append( CreateCloakDroneEvent( < 2674.979980, 4322.020020, 1283.979980 >, < 0.000000, 0.000000, 0.000000 >, index++ ) ) + wave5.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave5.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave5.append( CreateToneTitanEvent( < 2475.810059, -3544.189941, 810.218994 >, < 0.000000, 90.000000, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 1.2999268, index++ ) ) + wave5.append( CreateToneTitanEvent( < 2821.340088, -2936.719971, 827.937988 >, < 0.000000, 117.202003, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.70007324, index++ ) ) + wave5.append( CreateCloakDroneEvent( < 2363.000000, -3327.010010, 1235.989990 >, < 0.000000, 0.000000, 0.000000 >, index++ ) ) + wave5.append( CreateWaitForTimeEvent( 6.0, index++ ) ) + wave5.append( CreateScorchTitanEvent( < 1763.910034, -1608.660034, 810.218994 >, < 0.000000, 90.000000, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 1.2999268, index++ ) ) + wave5.append( CreateScorchTitanEvent( < 2359.909912, -1596.660034, 802.718994 >, < 0.000000, 90.000000, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 1.4000244, index++ ) ) + wave5.append( CreateIonTitanEvent( < 1559.810059, -2024.189941, 803.031006 >, < 0.000000, 90.000000, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.6999512, index++ ) ) + wave5.append( CreateIonTitanEvent( < 2411.810059, -1108.189941, 803.375000 >, < 0.000000, 90.000000, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave5.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave5.append( CreateToneSniperTitanEvent( < 4466.220215, 1469.410034, 947.281006 >, < 0.000000, 169.541000, 0.000000 >, index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.9000244, index++ ) ) + wave5.append( CreateToneSniperTitanEvent( < 4453.129883, 964.750000, 947.281006 >, < 0.000000, -172.529007, 0.000000 >, index++ ) ) + wave5.append( CreateWaitForTimeEvent( 1.0999756, index++ ) ) + wave5.append( CreateArcTitanEvent( < 3867.219971, 1445.689941, 947.281006 >, < 0.000000, 180.000000, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave5.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave5.append( CreateNukeTitanEvent( < 2475.909912, -3544.659912, 810.281006 >, < 0.000000, 90.000000, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 1.2000732, index++ ) ) + wave5.append( CreateNukeTitanEvent( < 2665.340088, 4456.500000, 960.656006 >, < 0.000000, -141.108002, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 1.2999268, index++ ) ) + wave5.append( CreateNukeTitanEvent( < 2821.659912, -2937.090088, 827.937988 >, < 0.000000, 117.202003, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.8000488, index++ ) ) + wave5.append( CreateNukeTitanEvent( < 3123.560059, 4202.060059, 954.343994 >, < 0.000000, -141.108002, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 1.0999756, index++ ) ) + wave5.append( CreateNukeTitanEvent( < 1817.469971, -3586.379883, 814.062988 >, < 0.000000, 90.000000, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 0.6999512, index++ ) ) + wave5.append( CreateNukeTitanEvent( < 1324.060059, 4820.660156, 937.562988 >, < 0.000000, -90.000000, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 5.0, index++ ) ) + wave5.append( CreateWaitUntilAliveWeightedEvent( 16, index++ ) ) + wave5.append( CreateToneTitanEvent( < 4466.220215, 1469.410034, 947.281006 >, < 0.000000, 169.541000, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 1.3000488, index++ ) ) + wave5.append( CreateToneTitanEvent( < 4453.129883, 964.750000, 947.281006 >, < 0.000000, -172.529007, 0.000000 >, "", index++ ) ) + wave5.append( CreateWaitForTimeEvent( 1.3000488, index++ ) ) + wave5.append( CreateScorchTitanEvent( < 3867.129883, 1445.719971, 947.281006 >, < 0.000000, 180.000000, 0.000000 >, "", 0 ) ) + waveEvents.append( wave5 ) +} diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_glitch.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_glitch.nut index 37b89169..e6eb493d 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_glitch.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_glitch.nut @@ -1 +1,8 @@ -//fuck
\ No newline at end of file +global function CodeCallback_MapInit + +void function CodeCallback_MapInit() +{ + // Load Frontier Defense Data + if( GameRules_GetGameMode() == "fd" ) + initFrontierDefenseData() +}
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_glitch_fd.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_glitch_fd.nut index 37b89169..cd3e2822 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_glitch_fd.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_glitch_fd.nut @@ -1 +1,23 @@ -//fuck
\ No newline at end of file +global function initFrontierDefenseData +void function initFrontierDefenseData() +{ + shopPosition = <0,0,0> + + + array<WaveEvent> wave0 + array<WaveEvent> wave1 + array<WaveEvent> wave2 + array<WaveEvent> wave3 + array<WaveEvent> wave4 + + + + + + + waveEvents.append(wave0) + waveEvents.append(wave1) + waveEvents.append(wave2) + waveEvents.append(wave3) + waveEvents.append(wave4) +}
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_grave.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_grave.nut index f4b48f6d..9b5d3080 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_grave.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_grave.nut @@ -4,6 +4,11 @@ void function CodeCallback_MapInit() { // there are some really busted titan startspawns that are on the fucking other side of the map from where they should be, so we remove them AddSpawnCallback( "info_spawnpoint_titan_start", TrimBadTitanStartSpawns ) + + // Load Frontier Defense Data + if( GameRules_GetGameMode() == "fd" ) + initFrontierDefenseData() + } void function TrimBadTitanStartSpawns( entity spawn ) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_grave_fd.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_grave_fd.nut index 37b89169..cd3e2822 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_grave_fd.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_grave_fd.nut @@ -1 +1,23 @@ -//fuck
\ No newline at end of file +global function initFrontierDefenseData +void function initFrontierDefenseData() +{ + shopPosition = <0,0,0> + + + array<WaveEvent> wave0 + array<WaveEvent> wave1 + array<WaveEvent> wave2 + array<WaveEvent> wave3 + array<WaveEvent> wave4 + + + + + + + waveEvents.append(wave0) + waveEvents.append(wave1) + waveEvents.append(wave2) + waveEvents.append(wave3) + waveEvents.append(wave4) +}
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_homestead.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_homestead.nut index 37b89169..e6eb493d 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_homestead.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_homestead.nut @@ -1 +1,8 @@ -//fuck
\ No newline at end of file +global function CodeCallback_MapInit + +void function CodeCallback_MapInit() +{ + // Load Frontier Defense Data + if( GameRules_GetGameMode() == "fd" ) + initFrontierDefenseData() +}
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_homestead_fd.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_homestead_fd.nut index 37b89169..dce818cb 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_homestead_fd.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_homestead_fd.nut @@ -1 +1,568 @@ -//fuck
\ No newline at end of file +global function initFrontierDefenseData +void function initFrontierDefenseData() +{ + shopPosition = < -800.156, -4250, -63 > + shopAngles = < 9, 60, 0 > + FD_spawnPosition = < 576.47, -3946.24, -174.07> + FD_spawnAngles = < 0, 60, 0 > + + int index = 1 + array<WaveEvent> wave1 + wave1.append(CreateSpawnDroneEvent(< 6050.669922 , 132.485001 , 4918.959961 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave1.append(CreateWaitForTimeEvent(1.5,index++)) + wave1.append(CreateSpawnDroneEvent(< 3341.850098 , 2237.580078 , 4965.220215 >,< 0.004999 , -115.792000 , 0.000004 >,"centerLeftDrones_Loop3",index++)) + wave1.append(CreateWaitForTimeEvent(1.5,index++)) + wave1.append(CreateDroppodGruntEvent(< 68.781303 , -516.468994 , -97.937500 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(0.5999985,index++)) + wave1.append(CreateDroppodGruntEvent(< -770.500000 , 1070.060059 , -159.781006 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(0.9000015,index++)) + wave1.append(CreateDroppodGruntEvent(< 2696.000000 , -1068.719971 , -92.687500 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(1.0,index++)) + wave1.append(CreateDroppodGruntEvent(< 2420.310059 , -1135.250000 , -159.218994 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + // replaced this with the one below because it seemed off? + //wave1.append(CreateSpawnDroneEvent(< -697.750000 , 940.593994 , 153.656006 >,< -0.000000 , 0.000000 , 0.000000 >,"",index++)) + wave1.append(CreateSpawnDroneEvent(< 6050.669922 , 132.485001 , 4918.959961 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave1.append(CreateWaitForTimeEvent(0.5999985,index++)) + // replaced this with the one below because it seemed off? + //wave1.append(CreateSpawnDroneEvent(< 2696.909912 , -388.062988 , 349.250000 >,< -0.000000 , 0.000000 , 0.000000 >,"",index++)) + wave1.append(CreateSpawnDroneEvent(< 3341.850098 , 2237.580078 , 4965.220215 >,< 0.004999 , -115.792000 , 0.000004 >,"centerLeftDrones_Loop3",index++)) + wave1.append(CreateWaitForTimeEvent(1.199997,index++)) + wave1.append(CreateDroppodGruntEvent(< 3917.000000 , -2654.719971 , -81.468803 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(1.1000061,index++)) + wave1.append(CreateDroppodGruntEvent(< 3754.719971 , -2589.250000 , -63.906300 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(1.2999954,index++)) + wave1.append(CreateDroppodGruntEvent(< 2870.810059 , -2727.629883 , 77.968803 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(1.25,index++)) + wave1.append(CreateDroppodGruntEvent(< 4230.189941 , -366.312988 , 22.968800 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(1.5830078,index++)) + wave1.append(CreateDroppodGruntEvent(< 4731.839844 , -2077.219971 , -35.625000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave1.append(CreateDroppodGruntEvent(< 3917.000000 , -2654.719971 , -81.468803 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(2.7829895,index++)) + wave1.append(CreateDroppodGruntEvent(< -1197.939941 , 1928.560059 , 80.031303 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(1.3340149,index++)) + wave1.append(CreateDroppodGruntEvent(< -610.500000 , 1743.060059 , 93.156303 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(0.2659912,index++)) + wave1.append(CreateSuperSpectreEvent(< 779.500000 , -365.375000 , -166.093994 >,< 0.000000 , -52.734402 , 0.000000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(0.6170044,index++)) + wave1.append(CreateDroppodGruntEvent(< -3570.879883 , -1498.500000 , -49.625000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave1.append(CreateDroppodGruntEvent(< -3570.879883 , -1498.500000 , -49.625000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(1.2999878,index++)) + wave1.append(CreateSpawnDroneEvent(< 6050.669922 , 132.485001 , 4877.899902 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave1.append(CreateWaitForTimeEvent(2.0170135,index++)) + wave1.append(CreateSpawnDroneEvent(< 5994.600098 , 1378.760010 , 4810.569824 >,< 0.004999 , -73.121300 , 0.000004 >,"centerLeftDrones_Loop3",index++)) + wave1.append(CreateWaitForTimeEvent(0.6659851,index++)) + wave1.append(CreateSpawnDroneEvent(< 3381.919922 , 2251.550049 , 4955.319824 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave1.append(CreateWaitForTimeEvent(2.0,index++)) + wave1.append(CreateSuperSpectreEvent(< 2918.379883 , -3060.629883 , -25.187500 >,< -0.000000 , -170.770996 , 0.000000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave1.append(CreateDroppodGruntEvent(< 3917.000000 , -2654.719971 , -81.468803 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(1.300003,index++)) + wave1.append(CreateDroppodGruntEvent(< 3754.719971 , -2589.250000 , -63.906300 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(1.0829926,index++)) + wave1.append(CreateDroppodGruntEvent(< 2870.810059 , -2727.629883 , 77.968803 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(0.93400574,index++)) + wave1.append(CreateDroppodGruntEvent(< 4230.189941 , -366.312988 , 22.968800 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(2.9000092,index++)) + wave1.append(CreateDroppodGruntEvent(< 4009.219971 , 3091.500000 , -2.406250 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave1.append(CreateDroppodGruntEvent(< 4009.219971 , 3091.500000 , -2.406250 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(1.4669952,index++)) + wave1.append(CreateDroppodGruntEvent(< 5542.589844 , 2078.189941 , -31.531300 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(1.0330048,index++)) + wave1.append(CreateDroppodGruntEvent(< 5204.000000 , 1308.000000 , 7.593750 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave1.append(CreateSuperSpectreEvent(< -523.031006 , 807.125000 , -167.218994 >,< 0.000000 , -91.450203 , 0.000000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(1.2169952,index++)) + wave1.append(CreateSuperSpectreEvent(< 3316.060059 , -2935.530029 , -67.218803 >,< -0.000000 , -156.182007 , 0.000000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave1.append(CreateDroppodSpectreMortarEvent(< 3754.719971 , -2589.250000 , -63.906300 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(1.1000061,index++)) + wave1.append(CreateDroppodSpectreMortarEvent(< -1881.280029 , 1307.310059 , -159.781006 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(1.0,index++)) + wave1.append(CreateDroppodSpectreMortarEvent(< 3917.000000 , -2654.719971 , -81.468803 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(1.5,index++)) + wave1.append(CreateDroppodSpectreMortarEvent(< -1008.880005 , 1265.500000 , -159.781006 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(1.0,index++)) + wave1.append(CreateDroppodSpectreMortarEvent(< 2870.810059 , -2727.629883 , 77.968803 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave1.append(CreateDroppodGruntEvent(< 4230.189941 , -366.312988 , 22.968800 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave1.append(CreateDroppodGruntEvent(< -1881.280029 , 1307.310059 , -159.781006 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave1.append(CreateDroppodGruntEvent(< 2812.340088 , -1307.750000 , -156.563004 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave1.append(CreateDroppodGruntEvent(< 2696.000000 , -1068.719971 , -92.687500 >,"",0)) + waveEvents.append(wave1) + index = 1 + array<WaveEvent> wave2 + wave2.append(CreateSpawnDroneEvent(< 6090.759766 , 146.453995 , 4888.700195 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave2.append(CreateWaitForTimeEvent(1.1170044,index++)) + wave2.append(CreateDroppodGruntEvent(< 3917.000000 , -2654.719971 , -81.468803 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.78302,index++)) + wave2.append(CreateDroppodGruntEvent(< 3754.719971 , -2589.250000 , -63.906300 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(3.21698,index++)) + wave2.append(CreateDroppodGruntEvent(< 68.781303 , -516.468994 , -97.937500 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.7669983,index++)) + wave2.append(CreateDroppodGruntEvent(< -770.500000 , 1070.060059 , -159.781006 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(5.0,index++)) + wave2.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave2.append(CreateDroppodGruntEvent(< 4230.189941 , -366.312988 , 22.968800 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(1.0,index++)) + wave2.append(CreateDroppodGruntEvent(< 3754.719971 , -2589.250000 , -63.906300 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(5.0,index++)) + wave2.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave2.append(CreateSpawnDroneEvent(< 6036.729980 , 172.546997 , 4870.890137 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave2.append(CreateWaitForTimeEvent(2.7000122,index++)) + wave2.append(CreateSpawnDroneEvent(< 6012.029785 , 1321.359985 , 4831.279785 >,< 0.004999 , -73.121300 , 0.000004 >,"centerLeftDrones_Loop3",index++)) + wave2.append(CreateWaitForTimeEvent(5.0,index++)) + wave2.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave2.append(CreateSpawnDroneEvent(< 6076.790039 , 186.516006 , 4886.330078 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave2.append(CreateWaitForTimeEvent(5.0,index++)) + wave2.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave2.append(CreateSpawnDroneEvent(< 3367.949951 , 2291.610107 , 4918.220215 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave2.append(CreateWaitForTimeEvent(1.4830322,index++)) + wave2.append(CreateDroppodSpectreMortarEvent(< 3754.719971 , -2589.250000 , -63.906300 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.6170044,index++)) + wave2.append(CreateDroppodSpectreMortarEvent(< -1881.280029 , 1307.310059 , -159.781006 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(5.0,index++)) + wave2.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave2.append(CreateDroppodGruntEvent(< 2812.340088 , -1307.750000 , -156.563004 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(1.3500366,index++)) + wave2.append(CreateDroppodGruntEvent(< -3570.879883 , -1498.500000 , -49.625000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(5.0,index++)) + wave2.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave2.append(CreateDroppodGruntEvent(< 4230.189941 , -366.312988 , 22.968800 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(3.0,index++)) + wave2.append(CreateToneSniperTitanEvent(< 1484.189941 , 968.218994 , 97.968803 >,< -0.922852 , -141.942993 , -1.582030 >,index++)) + wave2.append(CreateWaitForTimeEvent(5.0,index++)) + wave2.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave2.append(CreateDroppodGruntEvent(< 2812.340088 , -1307.750000 , -156.563004 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(1.1670532,index++)) + wave2.append(CreateDroppodGruntEvent(< 2696.000000 , -1068.719971 , -92.687500 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(1.4829712,index++)) + wave2.append(CreateMortarTitanEvent(< -515.187988 , 1099.160034 , -162.281006 >,< 0.000000 , -90.000000 , 0.000000 >,index++)) + wave2.append(CreateWaitForTimeEvent(5.0,index++)) + wave2.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave2.append(CreateDroppodGruntEvent(< 68.781303 , -516.468994 , -97.937500 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(1.5170288,index++)) + wave2.append(CreateDroppodGruntEvent(< 4230.189941 , -366.312988 , 22.968800 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(3.0999756,index++)) + wave2.append(CreateDroppodGruntEvent(< -770.500000 , 1070.060059 , -159.781006 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(5.0,index++)) + wave2.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave2.append(CreateDroppodGruntEvent(< 3754.719971 , -2589.250000 , -63.906300 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.8829956,index++)) + wave2.append(CreateDroppodGruntEvent(< 3917.000000 , -2654.719971 , -81.468803 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.6170044,index++)) + wave2.append(CreateDroppodGruntEvent(< -3570.879883 , -1498.500000 , -49.625000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(1.3670044,index++)) + wave2.append(CreateDroppodGruntEvent(< 2870.810059 , -2727.629883 , 77.968803 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(2.8999634,index++)) + wave2.append(CreateDroppodGruntEvent(< 2812.340088 , -1307.750000 , -156.563004 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(5.0,index++)) + wave2.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave2.append(CreateDroppodGruntEvent(< -3570.879883 , -1498.500000 , -49.625000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(1.532959,index++)) + wave2.append(CreateDroppodGruntEvent(< 4230.189941 , -366.312988 , 22.968800 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.8670044,index++)) + wave2.append(CreateNukeTitanEvent(< 2758.840088 , -436.187988 , -75.156303 >,< -0.922852 , -141.942993 , -1.582030 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.61602783,index++)) + wave2.append(CreateNukeTitanEvent(< -515.281006 , 1099.630005 , -162.281006 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.8999634,index++)) + wave2.append(CreateNukeTitanEvent(< 4027.840088 , -2180.129883 , -61.937500 >,< -0.922852 , -143.613007 , -1.582030 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.8840332,index++)) + wave2.append(CreateNukeTitanEvent(< -918.125000 , 890.625000 , -155.250000 >,< 0.000000 , 90.000000 , 0.000000 >,"",0)) + waveEvents.append(wave2) + index = 1 + array<WaveEvent> wave3 + wave3.append(CreateSpawnDroneEvent(< 6050.669922 , 132.485001 , 4893.919922 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave3.append(CreateWaitForTimeEvent(1.0170288,index++)) + wave3.append(CreateSpawnDroneEvent(< 6032.029785 , 1358.760010 , 4813.379883 >,< 0.004999 , -73.121300 , 0.000004 >,"centerLeftDrones_Loop3",index++)) + wave3.append(CreateWaitForTimeEvent(0.8829956,index++)) + wave3.append(CreateSpawnDroneEvent(< 3327.889893 , 2277.639893 , 4935.830078 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave3.append(CreateWaitForTimeEvent(0.7839966,index++)) + wave3.append(CreateSpawnDroneEvent(< 4582.979980 , 2624.050049 , 4906.810059 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave3.append(CreateWaitForTimeEvent(0.9160156,index++)) + wave3.append(CreateSpawnDroneEvent(< 4024.330078 , 3117.510010 , 4947.189941 >,< 0.004999 , -25.792200 , 0.000004 >,"centerRightDrones_Loop4",index++)) + wave3.append(CreateWaitForTimeEvent(5.0,index++)) + wave3.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave3.append(CreateSpawnDroneEvent(< 3341.850098 , 2237.580078 , 4889.950195 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave3.append(CreateWaitForTimeEvent(5.0,index++)) + wave3.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave3.append(CreateSuperSpectreEvent(< -515.437988 , -263.281006 , 420.281006 >,< -0.000000 , 176.923996 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.2160034,index++)) + wave3.append(CreateSuperSpectreEvent(< 2567.189941 , -3095.969971 , 25.437500 >,< -0.000000 , -174.945999 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(0.10003662,index++)) + wave3.append(CreateSpawnDroneEvent(< 3341.850098 , 2237.580078 , 4936.169922 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave3.append(CreateWaitForTimeEvent(5.0,index++)) + wave3.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave3.append(CreateSpawnDroneEvent(< 3381.919922 , 2251.550049 , 4946.819824 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave3.append(CreateWaitForTimeEvent(0.717041,index++)) + wave3.append(CreateSpawnDroneEvent(< 2880.760010 , 3060.300049 , 4874.819824 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave3.append(CreateWaitForTimeEvent(0.782959,index++)) + wave3.append(CreateSpawnDroneEvent(< 4569.009766 , 2664.110107 , 4897.569824 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave3.append(CreateWaitForTimeEvent(1.4169922,index++)) + wave3.append(CreateSpawnDroneEvent(< 3984.270020 , 3103.570068 , 4931.939941 >,< 0.004999 , -25.792200 , 0.000004 >,"centerRightDrones_Loop4",index++)) + wave3.append(CreateWaitForTimeEvent(1.4830322,index++)) + wave3.append(CreateSpawnDroneEvent(< 3381.919922 , 2251.550049 , 4931.640137 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave3.append(CreateWaitForTimeEvent(4.0999756,index++)) + wave3.append(CreateIonTitanEvent(< -515.187988 , 1099.160034 , -162.281006 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.0170288,index++)) + wave3.append(CreateIonTitanEvent(< 3574.409912 , -2788.219971 , -68.312500 >,< 0.000000 , 0.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(5.0,index++)) + wave3.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave3.append(CreateDroppodGruntEvent(< 25.437500 , -2.062500 , -159.781006 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(0.96698,index++)) + wave3.append(CreateDroppodGruntEvent(< 3754.719971 , -2589.250000 , -63.906300 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(5.950012,index++)) + wave3.append(CreateSpawnDroneEvent(< 3367.949951 , 2291.610107 , 4920.089844 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave3.append(CreateWaitForTimeEvent(1.4829712,index++)) + wave3.append(CreateMortarTitanEvent(< -515.187988 , 1099.160034 , -162.281006 >,< 0.000000 , -90.000000 , 0.000000 >,index++)) + wave3.append(CreateWaitForTimeEvent(0.717041,index++)) + wave3.append(CreateMortarTitanEvent(< 3574.409912 , -2788.219971 , -68.312500 >,< 0.000000 , 0.000000 , 0.000000 >,index++)) + wave3.append(CreateWaitForTimeEvent(5.0,index++)) + wave3.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave3.append(CreateDroppodGruntEvent(< -1197.939941 , 1928.560059 , 80.031303 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.5,index++)) + wave3.append(CreateDroppodGruntEvent(< -610.500000 , 1743.060059 , 93.156303 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(0.9000244,index++)) + wave3.append(CreateDroppodGruntEvent(< 3917.000000 , -2654.719971 , -81.468803 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.3829956,index++)) + wave3.append(CreateDroppodGruntEvent(< 4230.189941 , -366.312988 , 22.968800 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.21698,index++)) + wave3.append(CreateToneSniperTitanEvent(< 1484.189941 , 968.218994 , 97.968803 >,< -0.922852 , -141.942993 , -1.582030 >,index++)) + wave3.append(CreateWaitForTimeEvent(0.6000366,index++)) + wave3.append(CreateMortarTitanEvent(< 1984.030029 , 138.125000 , -75.031303 >,< -0.922852 , -97.602501 , -1.582030 >,index++)) + wave3.append(CreateWaitForTimeEvent(5.0,index++)) + wave3.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave3.append(CreateDroppodGruntEvent(< -1197.939941 , 1928.560059 , 80.031303 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.5,index++)) + wave3.append(CreateDroppodGruntEvent(< 3917.000000 , -2654.719971 , -81.468803 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(0.5999756,index++)) + wave3.append(CreateSuperSpectreEvent(< 512.492004 , -288.734985 , -167.218994 >,< 0.000000 , 148.755005 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(0.41705322,index++)) + wave3.append(CreateDroppodGruntEvent(< -610.500000 , 1743.060059 , 93.156303 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(5.0,index++)) + wave3.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave3.append(CreateDroppodGruntEvent(< 3917.000000 , -2654.719971 , -81.468803 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(5.017029,index++)) + wave3.append(CreateSuperSpectreEvent(< 3324.590088 , -2931.780029 , -67.531303 >,< 0.000000 , -156.138000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(2.6829834,index++)) + wave3.append(CreateSpawnDroneEvent(< 6090.759766 , 146.453995 , 4907.120117 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave3.append(CreateWaitForTimeEvent(1.217041,index++)) + wave3.append(CreateSpawnDroneEvent(< 3367.949951 , 2291.610107 , 4934.399902 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave3.append(CreateWaitForTimeEvent(5.0,index++)) + wave3.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave3.append(CreateDroppodGruntEvent(< -1197.939941 , 1928.560059 , 80.031303 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.1329956,index++)) + wave3.append(CreateDroppodGruntEvent(< 3917.000000 , -2654.719971 , -81.468803 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(4.049988,index++)) + wave3.append(CreateSpawnDroneEvent(< 6076.790039 , 186.516006 , 4905.089844 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave3.append(CreateWaitForTimeEvent(1.2330322,index++)) + wave3.append(CreateSpawnDroneEvent(< 6012.029785 , 1321.359985 , 4808.120117 >,< 0.004999 , -73.121300 , 0.000004 >,"centerLeftDrones_Loop3",index++)) + wave3.append(CreateWaitForTimeEvent(1.0999756,index++)) + wave3.append(CreateSpawnDroneEvent(< 5204.000000 , 1275.729980 , 4938.310059 >,< 0.004999 , -89.996300 , 0.000004 >,"centerRightDrones_Loop2",index++)) + wave3.append(CreateWaitForTimeEvent(5.0,index++)) + wave3.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave3.append(CreateSpawnDroneEvent(< 3367.949951 , 2291.610107 , 4898.049805 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave3.append(CreateWaitForTimeEvent(1.1669922,index++)) + wave3.append(CreateSpawnDroneEvent(< 4542.890137 , 2610.110107 , 4888.470215 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave3.append(CreateWaitForTimeEvent(1.3330078,index++)) + wave3.append(CreateSpawnDroneEvent(< 2826.729980 , 3086.419922 , 4851.450195 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave3.append(CreateWaitForTimeEvent(0.9500122,index++)) + wave3.append(CreateNukeTitanEvent(< 3573.939941 , -2788.310059 , -68.281303 >,< 0.000000 , 0.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.532959,index++)) + wave3.append(CreateNukeTitanEvent(< -1799.530029 , 1310.839966 , -164.218994 >,< -0.922852 , -151.830994 , -1.582030 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(0.7839966,index++)) + wave3.append(CreateNukeTitanEvent(< 4027.840088 , -2180.129883 , -61.937500 >,< -0.922852 , -143.613007 , -1.582030 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.5,index++)) + wave3.append(CreateNukeTitanEvent(< -2077.379883 , 950.062988 , -143.813004 >,< 0.000000 , 90.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(4.31604,index++)) + wave3.append(CreateSuperSpectreEvent(< -522.593994 , -251.406006 , 416.437988 >,< -0.000000 , 169.408997 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(5.0,index++)) + wave3.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave3.append(CreateSpawnDroneEvent(< 6076.790039 , 186.516006 , 4864.759766 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave3.append(CreateWaitForTimeEvent(0.8840332,index++)) + wave3.append(CreateSpawnDroneEvent(< 3367.949951 , 2291.610107 , 4941.009766 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave3.append(CreateWaitForTimeEvent(0.8999634,index++)) + wave3.append(CreateScorchTitanEvent(< 5251.529785 , 2049.280029 , 13.125000 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.5159912,index++)) + wave3.append(CreateScorchTitanEvent(< 4249.879883 , 2937.159912 , -44.156300 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.467041,index++)) + wave3.append(CreateNukeTitanEvent(< 3573.939941 , -2788.310059 , -68.281303 >,< 0.000000 , 0.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(0.9329834,index++)) + wave3.append(CreateNukeTitanEvent(< -1799.530029 , 1310.839966 , -164.218994 >,< -0.922852 , -151.830994 , -1.582030 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(5.0,index++)) + wave3.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave3.append(CreateDroppodGruntEvent(< 3917.000000 , -2654.719971 , -81.468803 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.3999634,index++)) + wave3.append(CreateDroppodGruntEvent(< -1197.939941 , 1928.560059 , 80.031303 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.2000122,index++)) + wave3.append(CreateDroppodGruntEvent(< -3570.879883 , -1498.500000 , -49.625000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(5.0,index++)) + wave3.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave3.append(CreateDroppodGruntEvent(< 4230.189941 , -366.312988 , 22.968800 >,"",0)) + waveEvents.append(wave3) + index = 1 + array<WaveEvent> wave4 + wave4.append(CreateIonTitanEvent(< -1799.910034 , 1310.530029 , -164.218994 >,< -0.922852 , -151.830994 , -1.582030 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(5.0,index++)) + wave4.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave4.append(CreateSuperSpectreEvent(< -2619.399902 , 511.446014 , -141.567993 >,< -0.000000 , -139.373001 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.5,index++)) + wave4.append(CreateSuperSpectreEvent(< -1172.420044 , 1221.010010 , -167.218994 >,< 0.000000 , -175.912994 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(0.11999512,index++)) + wave4.append(CreateSpawnDroneEvent(< 6090.759766 , 146.453995 , 4879.229980 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave4.append(CreateWaitForTimeEvent(1.0999756,index++)) + wave4.append(CreateSpawnDroneEvent(< 3381.919922 , 2251.550049 , 4925.459961 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave4.append(CreateWaitForTimeEvent(1.0599365,index++)) + wave4.append(CreateDroppodGruntEvent(< 3754.719971 , -2589.250000 , -63.906300 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.1400146,index++)) + wave4.append(CreateDroppodSpectreMortarEvent(< 5542.589844 , 2078.189941 , -31.531300 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(5.0,index++)) + wave4.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave4.append(CreateDroppodGruntEvent(< -3570.879883 , -1498.500000 , -49.625000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.1199951,index++)) + wave4.append(CreateDroppodSpectreMortarEvent(< -3375.090088 , -1307.969971 , -90.593803 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.1999512,index++)) + wave4.append(CreateDroppodGruntEvent(< 3917.000000 , -2654.719971 , -81.468803 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.1600342,index++)) + wave4.append(CreateDroppodSpectreMortarEvent(< 3754.719971 , -2589.250000 , -63.906300 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(5.0,index++)) + wave4.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave4.append(CreateScorchTitanEvent(< 5251.529785 , 2049.280029 , 13.125000 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(0.7800293,index++)) + wave4.append(CreateScorchTitanEvent(< 4249.879883 , 2937.159912 , -44.156300 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.920044,index++)) + wave4.append(CreateSuperSpectreEvent(< 275.593994 , -144.656006 , -156.968994 >,< 0.000000 , -168.091003 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(5.0,index++)) + wave4.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave4.append(CreateRoninTitanEvent(< -1799.439941 , 1310.839966 , -164.218994 >,< -0.922852 , -151.830994 , -1.582030 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(5.0,index++)) + wave4.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave4.append(CreateSuperSpectreEvent(< -2191.379883 , 875.562988 , -139.968994 >,< -0.000000 , -142.382996 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(0.11999512,index++)) + wave4.append(CreateRoninTitanEvent(< 3573.840088 , -2788.250000 , -68.250000 >,< 0.000000 , 0.000000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(0.57995605,index++)) + wave4.append(CreateSuperSpectreEvent(< -1868.939941 , 1052.229980 , -153.057007 >,< -0.000000 , -156.475006 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(5.0,index++)) + wave4.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave4.append(CreateSuperSpectreEvent(< 3465.909912 , -2830.469971 , -68.375000 >,< -0.922858 , -149.106003 , -1.582030 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(0.9699707,index++)) + wave4.append(CreateIonTitanEvent(< 5136.720215 , -2059.379883 , -105.125000 >,< 0.000000 , 0.000000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(0.5,index++)) + wave4.append(CreateSuperSpectreEvent(< 3640.330078 , -2726.229980 , -72.381897 >,< -0.922858 , -146.380997 , -1.582030 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(5.0,index++)) + wave4.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave4.append(CreateSuperSpectreEvent(< 3683.840088 , -2703.780029 , -69.718803 >,< -0.922858 , -149.766006 , -1.582030 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(0.6800537,index++)) + wave4.append(CreateSuperSpectreEvent(< 2472.750000 , -733.406006 , -117.594002 >,< -0.922852 , -132.231003 , -1.582030 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(5.0,index++)) + wave4.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave4.append(CreateDroppodGruntEvent(< 4230.189941 , -366.312988 , 22.968800 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(0.79003906,index++)) + wave4.append(CreateDroppodGruntEvent(< -1197.939941 , 1928.560059 , 80.031303 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.0100098,index++)) + wave4.append(CreateDroppodGruntEvent(< 3917.000000 , -2654.719971 , -81.468803 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(5.0,index++)) + wave4.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave4.append(CreateSuperSpectreEvent(< 2614.300049 , -3101.199951 , 14.673600 >,< 0.000000 , -172.837006 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(0.8199463,index++)) + wave4.append(CreateSuperSpectreEvent(< -2551.510010 , 644.447998 , -123.125000 >,< -0.922858 , -132.886993 , -1.582030 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.4100342,index++)) + wave4.append(CreateSuperSpectreEvent(< 3910.250000 , -2404.560059 , -89.156303 >,< -0.922852 , -121.376999 , -1.582030 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(5.0,index++)) + wave4.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave4.append(CreateSpawnDroneEvent(< 6050.669922 , 132.485001 , 4890.120117 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave4.append(CreateWaitForTimeEvent(0.8099365,index++)) + wave4.append(CreateSpawnDroneEvent(< 5994.600098 , 1378.760010 , 4814.129883 >,< 0.004999 , -73.121300 , 0.000004 >,"centerLeftDrones_Loop3",index++)) + wave4.append(CreateWaitForTimeEvent(1.5,index++)) + wave4.append(CreateSpawnDroneEvent(< 5234.000000 , 1305.729980 , 4936.160156 >,< 0.004999 , -89.996300 , 0.000004 >,"centerRightDrones_Loop2",index++)) + wave4.append(CreateWaitForTimeEvent(1.2000732,index++)) + wave4.append(CreateSpawnDroneEvent(< 3341.850098 , 2237.580078 , 4911.430176 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave4.append(CreateWaitForTimeEvent(5.0,index++)) + wave4.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave4.append(CreateSpawnDroneEvent(< 3327.889893 , 2277.639893 , 4940.600098 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave4.append(CreateWaitForTimeEvent(0.8300781,index++)) + wave4.append(CreateSpawnDroneEvent(< 2866.790039 , 3100.360107 , 4857.200195 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave4.append(CreateWaitForTimeEvent(1.2799072,index++)) + wave4.append(CreateToneSniperTitanEvent(< 1484.189941 , 968.218994 , 97.968803 >,< -0.922852 , -141.942993 , -1.582030 >,index++)) + wave4.append(CreateWaitForTimeEvent(1.2900391,index++)) + wave4.append(CreateToneTitanEvent(< -515.187988 , 1099.160034 , -162.281006 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(0.60998535,index++)) + wave4.append(CreateToneTitanEvent(< 3574.409912 , -2788.219971 , -68.312500 >,< 0.000000 , 0.000000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(2.9899902,index++)) + wave4.append(CreateDroppodGruntEvent(< 68.781303 , -516.468994 , -97.937500 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.4100342,index++)) + wave4.append(CreateDroppodGruntEvent(< 3917.000000 , -2654.719971 , -81.468803 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(5.0,index++)) + wave4.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave4.append(CreateSpawnDroneEvent(< 6036.729980 , 172.546997 , 4861.959961 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave4.append(CreateWaitForTimeEvent(0.98999023,index++)) + wave4.append(CreateSpawnDroneEvent(< 6032.029785 , 1358.760010 , 4831.629883 >,< 0.004999 , -73.121300 , 0.000004 >,"centerLeftDrones_Loop3",index++)) + wave4.append(CreateWaitForTimeEvent(1.1099854,index++)) + wave4.append(CreateSpawnDroneEvent(< 5204.000000 , 1335.729980 , 4926.459961 >,< 0.004999 , -89.996300 , 0.000004 >,"centerRightDrones_Loop2",index++)) + wave4.append(CreateWaitForTimeEvent(5.0,index++)) + wave4.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave4.append(CreateToneSniperTitanEvent(< 1484.189941 , 968.218994 , 97.968803 >,< -0.922852 , -141.942993 , -1.582030 >,index++)) + wave4.append(CreateWaitForTimeEvent(5.0,index++)) + wave4.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave4.append(CreateDroppodGruntEvent(< -1197.939941 , 1928.560059 , 80.031303 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.1099854,index++)) + wave4.append(CreateDroppodGruntEvent(< 3917.000000 , -2654.719971 , -81.468803 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.0400391,index++)) + wave4.append(CreateSuperSpectreEvent(< 496.070007 , -280.742004 , -167.218994 >,< 0.000000 , 148.403000 , 0.000000 >,"",0)) + waveEvents.append(wave4) + index = 1 + array<WaveEvent> wave5 + wave5.append(CreateDroppodSpectreMortarEvent(< 3754.719971 , -2589.250000 , -63.906300 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.7800293,index++)) + wave5.append(CreateDroppodSpectreMortarEvent(< -1881.280029 , 1307.310059 , -159.781006 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.1300049,index++)) + wave5.append(CreateDroppodSpectreMortarEvent(< 5204.000000 , 1308.000000 , 7.593750 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.1899414,index++)) + wave5.append(CreateMortarTitanEvent(< 1484.189941 , 968.218994 , 97.968803 >,< -0.922852 , -141.942993 , -1.582030 >,index++)) + wave5.append(CreateWaitForTimeEvent(5.0,index++)) + wave5.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave5.append(CreateNukeTitanEvent(< 5251.529785 , 2049.280029 , 13.125000 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.0999756,index++)) + wave5.append(CreateNukeTitanEvent(< 4249.879883 , 2937.159912 , -44.156300 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(4.580078,index++)) + wave5.append(CreateSuperSpectreEvent(< 4956.689941 , 1462.579956 , 55.508598 >,< -0.000000 , -158.052002 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.92993164,index++)) + wave5.append(CreateSuperSpectreEvent(< 3183.560059 , 2090.909912 , -48.263699 >,< -0.000000 , -105.017998 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(5.0,index++)) + wave5.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave5.append(CreateNorthstarSniperTitanEvent(< 5251.560059 , 2049.379883 , 13.093800 >,< 0.000000 , -90.000000 , 0.000000 >,index++)) + wave5.append(CreateWaitForTimeEvent(0.8000488,index++)) + wave5.append(CreateToneSniperTitanEvent(< 4249.970215 , 2936.689941 , -44.187500 >,< 0.000000 , -90.000000 , 0.000000 >,index++)) + wave5.append(CreateWaitForTimeEvent(6.910034,index++)) + wave5.append(CreateNukeTitanEvent(< 5748.529785 , 1979.339966 , -71.062500 >,< 0.000000 , -142.690002 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.3898926,index++)) + wave5.append(CreateNukeTitanEvent(< 3610.939941 , 2928.689941 , 22.218800 >,< 0.000000 , -113.642998 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(3.9000244,index++)) + wave5.append(CreateArcTitanEvent(< 2758.969971 , -436.187988 , -75.125000 >,< -0.922852 , -141.942993 , -1.582030 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.0100098,index++)) + wave5.append(CreateSuperSpectreEvent(< 4416.339844 , 1310.920044 , 4.697280 >,< 0.000000 , -124.364998 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.98999023,index++)) + wave5.append(CreateSuperSpectreEvent(< 5161.879883 , 804.687988 , -41.937500 >,< 0.000000 , -134.824005 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(5.0,index++)) + wave5.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave5.append(CreateNukeTitanEvent(< 5251.529785 , 2049.280029 , 13.125000 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.0,index++)) + wave5.append(CreateNukeTitanEvent(< 4249.879883 , 2937.159912 , -44.156300 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.23999023,index++)) + wave5.append(CreateSpawnDroneEvent(< 3027.270020 , 1470.109985 , 196.347000 >,< 13.667000 , -114.433998 , 0.000000 >,"centerRightDrones_Loop6",index++)) + wave5.append(CreateWaitForTimeEvent(0.10998535,index++)) + wave5.append(CreateSpawnDroneEvent(< 2938.060059 , 1411.089966 , 100.563004 >,< 13.667000 , -110.039001 , 0.000000 >,"centerRightDrones_Loop6",index++)) + wave5.append(CreateWaitForTimeEvent(0.11999512,index++)) + wave5.append(CreateSpawnDroneEvent(< 3031.810059 , 1541.949951 , 103.435997 >,< 12.767300 , -112.807999 , -0.000001 >,"centerRightDrones_Loop6",index++)) + wave5.append(CreateWaitForTimeEvent(3.5999756,index++)) + wave5.append(CreateSuperSpectreEvent(< 5122.479980 , 1549.989990 , 38.913399 >,< -0.000000 , -147.757004 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.82006836,index++)) + wave5.append(CreateSuperSpectreEvent(< 3277.000000 , 2468.239990 , -11.818300 >,< -0.000000 , -106.505997 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(5.709961,index++)) + wave5.append(CreateSuperSpectreEvent(< 3270.409912 , 2209.939941 , -29.437500 >,< -0.000000 , -109.906998 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.1999512,index++)) + wave5.append(CreateSuperSpectreEvent(< 5253.410156 , 1635.689941 , 16.718800 >,< 0.000000 , -146.908997 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(5.0,index++)) + wave5.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave5.append(CreateNukeTitanEvent(< 5605.439941 , 1266.410034 , -54.562500 >,< 0.000000 , -162.641998 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.2199707,index++)) + wave5.append(CreateNukeTitanEvent(< 4249.879883 , 2937.159912 , -44.156300 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.6800537,index++)) + wave5.append(CreateSuperSpectreEvent(< 5153.359863 , 1756.530029 , 39.026600 >,< 0.000000 , -111.313004 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.2199707,index++)) + wave5.append(CreateArcTitanEvent(< 5748.660156 , 1979.380005 , -71.062500 >,< 0.000000 , -142.690002 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.70007324,index++)) + wave5.append(CreateNukeTitanEvent(< 5375.560059 , 2948.280029 , -33.250000 >,< 0.000000 , -142.690002 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.5999756,index++)) + wave5.append(CreateSuperSpectreEvent(< 5297.750000 , 59.281300 , -167.063004 >,< 0.000000 , -54.975601 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.16992188,index++)) + wave5.append(CreateNukeTitanEvent(< 3897.439941 , 3308.530029 , -20.593800 >,< 0.000000 , -113.642998 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.5300293,index++)) + wave5.append(CreateSuperSpectreEvent(< 3347.310059 , 2737.810059 , 18.812500 >,< -0.000000 , -102.084999 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.47998047,index++)) + wave5.append(CreateArcTitanEvent(< 2758.969971 , -436.187988 , -75.125000 >,< -0.922852 , -141.942993 , -1.582030 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.4000244,index++)) + wave5.append(CreateNukeTitanEvent(< 5251.529785 , 2049.280029 , 13.125000 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.2900391,index++)) + wave5.append(CreateNukeTitanEvent(< 3610.939941 , 2928.689941 , 22.218800 >,< 0.000000 , -113.642998 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.60998535,index++)) + wave5.append(CreateSpawnDroneEvent(< 3341.850098 , 2237.580078 , 4942.560059 >,< 0.004999 , -115.792000 , 0.000004 >,"centerRightDrones_Loop1",index++)) + wave5.append(CreateWaitForTimeEvent(0.73999023,index++)) + wave5.append(CreateNukeTitanEvent(< 5797.589844 , 1407.689941 , -93.906303 >,< 0.000000 , -161.498993 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.7800293,index++)) + wave5.append(CreateNukeTitanEvent(< 4320.029785 , 2913.030029 , -56.593800 >,< 0.000000 , -113.642998 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(5.0200195,index++)) + wave5.append(CreateSuperSpectreEvent(< 3990.439941 , 419.718994 , -130.875000 >,< -0.000000 , -171.210999 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.3599854,index++)) + wave5.append(CreateSuperSpectreEvent(< 2692.169922 , 2159.280029 , -142.787003 >,< -0.000000 , -84.377403 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(5.0,index++)) + wave5.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave5.append(CreateArcTitanEvent(< 5251.560059 , 2049.379883 , 13.093800 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.4399414,index++)) + wave5.append(CreateNukeTitanEvent(< 5748.529785 , 1979.339966 , -71.062500 >,< 0.000000 , -142.690002 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.8800049,index++)) + wave5.append(CreateNukeTitanEvent(< 4249.879883 , 2937.159912 , -44.156300 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.9000244,index++)) + wave5.append(CreateMortarTitanEvent(< 1484.189941 , 968.218994 , 97.968803 >,< -0.922852 , -141.942993 , -1.582030 >,index++)) + wave5.append(CreateWaitForTimeEvent(0.7199707,index++)) + wave5.append(CreateNukeTitanEvent(< 5797.589844 , 1407.689941 , -93.906303 >,< 0.000000 , -161.498993 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.5999756,index++)) + wave5.append(CreateNukeTitanEvent(< 3610.939941 , 2928.689941 , 22.218800 >,< 0.000000 , -113.642998 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(2.9100342,index++)) + wave5.append(CreateNukeTitanEvent(< 5375.560059 , 2948.280029 , -33.250000 >,< 0.000000 , -142.690002 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.77001953,index++)) + wave5.append(CreateNukeTitanEvent(< 3897.439941 , 3308.530029 , -20.593800 >,< 0.000000 , -113.642998 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.3199463,index++)) + wave5.append(CreateNukeTitanEvent(< 5251.529785 , 2049.280029 , 13.125000 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.3601074,index++)) + wave5.append(CreateNukeTitanEvent(< 4699.589844 , 2906.159912 , -72.843803 >,< 0.000000 , -115.795998 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(5.0,index++)) + wave5.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave5.append(CreateSuperSpectreEvent(< -524.656006 , -249.875000 , 416.437988 >,< -0.000000 , 161.938004 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(5.0,index++)) + wave5.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave5.append(CreateScorchTitanEvent(< 5251.529785 , 2049.280029 , 13.125000 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.9199219,index++)) + wave5.append(CreateScorchTitanEvent(< 4249.879883 , 2937.159912 , -44.156300 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(5.0,index++)) + wave5.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave5.append(CreateNukeTitanEvent(< 5605.439941 , 1266.410034 , -54.562500 >,< 0.000000 , -162.641998 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.3800049,index++)) + wave5.append(CreateNukeTitanEvent(< 1484.500000 , 968.593994 , 98.031303 >,< -0.922852 , -141.942993 , -1.582030 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(5.0,index++)) + wave5.append(CreateWaitUntilAliveWeightedEvent(12,index++)) + wave5.append(CreateScorchTitanEvent(< 5251.529785 , 2049.280029 , 13.125000 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.8300781,index++)) + wave5.append(CreateScorchTitanEvent(< 4249.879883 , 2937.159912 , -44.156300 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.4899902,index++)) + wave5.append(CreateNukeTitanEvent(< 5748.529785 , 1979.339966 , -71.062500 >,< 0.000000 , -142.690002 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.0,index++)) + wave5.append(CreateNukeTitanEvent(< 3610.939941 , 2928.689941 , 22.218800 >,< 0.000000 , -113.642998 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.8800049,index++)) + wave5.append(CreateNukeTitanEvent(< 5797.589844 , 1407.689941 , -93.906303 >,< 0.000000 , -161.498993 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.7199707,index++)) + wave5.append(CreateNukeTitanEvent(< 3897.439941 , 3308.530029 , -20.593800 >,< 0.000000 , -113.642998 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.60998535,index++)) + wave5.append(CreateNukeTitanEvent(< 5375.560059 , 2948.280029 , -33.250000 >,< 0.000000 , -142.690002 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.9499512,index++)) + wave5.append(CreateNukeTitanEvent(< 4699.589844 , 2906.159912 , -72.843803 >,< 0.000000 , -115.795998 , 0.000000 >,"",0)) + waveEvents.append(wave5) + +}
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_relic02.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_relic02.nut index 37b89169..3441fc60 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_relic02.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_relic02.nut @@ -1 +1,6 @@ -//fuck
\ No newline at end of file +void function CodeCallback_MapInit() +{ + // Load Frontier Defense Data + if( GameRules_GetGameMode() == "fd" ) + initFrontierDefenseData() +}
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_relic02_fd.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_relic02_fd.nut index 37b89169..cd3e2822 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_relic02_fd.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_relic02_fd.nut @@ -1 +1,23 @@ -//fuck
\ No newline at end of file +global function initFrontierDefenseData +void function initFrontierDefenseData() +{ + shopPosition = <0,0,0> + + + array<WaveEvent> wave0 + array<WaveEvent> wave1 + array<WaveEvent> wave2 + array<WaveEvent> wave3 + array<WaveEvent> wave4 + + + + + + + waveEvents.append(wave0) + waveEvents.append(wave1) + waveEvents.append(wave2) + waveEvents.append(wave3) + waveEvents.append(wave4) +}
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_rise.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_rise.nut index 37b89169..e6eb493d 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_rise.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_rise.nut @@ -1 +1,8 @@ -//fuck
\ No newline at end of file +global function CodeCallback_MapInit + +void function CodeCallback_MapInit() +{ + // Load Frontier Defense Data + if( GameRules_GetGameMode() == "fd" ) + initFrontierDefenseData() +}
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_rise_fd.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_rise_fd.nut index 37b89169..fb0452db 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_rise_fd.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_rise_fd.nut @@ -1 +1,617 @@ -//fuck
\ No newline at end of file +global function initFrontierDefenseData + + +void function initFrontierDefenseData() +{ + shopPosition = < -5165.42, -679.285, 384.031 > //only aproximate position + FD_spawnPosition = < -5325.66, -1363.046, 384.031 > + + FD_spawnAngles = < 0, 0, 0 > + + int index = 1 + array<WaveEvent> wave1 + wave1.append(CreateNukeTitanEvent(< 3562.689941 , 597.062988 , 147.031006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveEvent(0,index++)) + wave1.append(CreateNukeTitanEvent(< 2007.030029 , -57.000000 , 243.468994 >,< -0.000000 , -157.455994 , 0.000000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveEvent(0,index++)) + wave1.append(CreateNukeTitanEvent(< 3562.689941 , 597.062988 , 147.031006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(1.2999954,index++)) + wave1.append(CreateDroppodStalkerEvent(< -3328.030029 , 1423.030029 , 327.500000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(1.0999985,index++)) + wave1.append(CreateDroppodGruntEvent(< -3224.000000 , 1101.719971 , 327.562988 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(1.5,index++)) + wave1.append(CreateDroppodGruntEvent(< 3637.560059 , 571.968994 , 151.500000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveEvent(0,index++)) + wave1.append(CreateDroppodStalkerEvent(< -3218.719971 , -1766.530029 , 391.500000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveEvent(0,index++)) + wave1.append(CreateNukeTitanEvent(< 1989.280029 , -64.187500 , 243.438004 >,< -0.000000 , -158.511002 , 0.000000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveEvent(0,index++)) + wave1.append(CreateSuperSpectreEvent(< 2611.629883 , 78.937500 , 197.813004 >,< 0.000000 , -168.794006 , 0.000000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveEvent(0,index++)) + wave1.append(CreateDroppodGruntEvent(< -3218.719971 , -1766.530029 , 391.500000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveEvent(0,index++)) + wave1.append(CreateDroppodGruntEvent(< 3637.560059 , 571.968994 , 151.500000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveEvent(0,index++)) + wave1.append(CreateDroppodGruntEvent(< -991.843994 , 411.093994 , 254.656006 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(1.0,index++)) + wave1.append(CreateDroppodStalkerEvent(< -3328.030029 , 1423.030029 , 327.500000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(1.0999908,index++)) + wave1.append(CreateDroppodStalkerEvent(< -3218.719971 , -1766.530029 , 391.500000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(2.800003,index++)) + wave1.append(CreateDroppodStalkerEvent(< 2117.560059 , 1491.969971 , 21.625000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(1.3999939,index++)) + wave1.append(CreateDroppodGruntEvent(< -2995.780029 , -1754.030029 , 391.500000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveEvent(0,index++)) + wave1.append(CreateDroppodGruntEvent(< -2442.189941 , -522.093994 , 391.562988 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveEvent(0,index++)) + wave1.append(CreateDroppodGruntEvent(< 3349.560059 , -12.031300 , 161.313004 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveEvent(0,index++)) + wave1.append(CreateDroppodGruntEvent(< -2240.590088 , -572.375000 , 357.218994 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveEvent(0,index++)) + wave1.append(CreateDroppodGruntEvent(< -2442.189941 , -522.093994 , 391.562988 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveEvent(0,index++)) + wave1.append(CreateDroppodGruntEvent(< 3637.560059 , 571.968994 , 151.500000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(1.5,index++)) + wave1.append(CreateDroppodGruntEvent(< -2240.590088 , -572.375000 , 357.218994 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(1.2000122,index++)) + wave1.append(CreateDroppodGruntEvent(< -2228.689941 , 278.750000 , 324.625000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(0.5999756,index++)) + wave1.append(CreateDroppodGruntEvent(< 2117.560059 , 1491.969971 , 21.625000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveEvent(0,index++)) + wave1.append(CreateDroppodStalkerEvent(< -3328.030029 , 1423.030029 , 327.500000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(0.5999756,index++)) + wave1.append(CreateDroppodStalkerEvent(< -3218.719971 , -1766.530029 , 391.500000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(0.9000244,index++)) + wave1.append(CreateDroppodStalkerEvent(< -2442.189941 , -522.093994 , 391.562988 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(2.8339844,index++)) + wave1.append(CreateDroppodGruntEvent(< 3349.560059 , -12.031300 , 161.313004 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(1.0830078,index++)) + wave1.append(CreateDroppodGruntEvent(< -2240.590088 , -572.375000 , 357.218994 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveEvent(0,index++)) + wave1.append(CreateDroppodGruntEvent(< -2442.189941 , -522.093994 , 391.562988 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(0.7669983,index++)) + wave1.append(CreateNukeTitanEvent(< 3562.689941 , 597.062988 , 147.031006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(1.1999817,index++)) + wave1.append(CreateNukeTitanEvent(< 3599.909912 , 21.781300 , 193.906006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(1.3170166,index++)) + wave1.append(CreateDroppodGruntEvent(< -3328.030029 , 1423.030029 , 327.500000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(0.7999878,index++)) + wave1.append(CreateDroppodGruntEvent(< -3218.719971 , -1766.530029 , 391.500000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveEvent(0,index++)) + wave1.append(CreateDroppodGruntEvent(< 2117.560059 , 1491.969971 , 21.625000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(2.0,index++)) + wave1.append(CreateDroppodGruntEvent(< -1274.589966 , 1488.410034 , 271.593994 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(2.5,index++)) + wave1.append(CreateDroppodGruntEvent(< -996.187988 , -1501.560059 , 255.500000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(1.3999939,index++)) + wave1.append(CreateDroppodGruntEvent(< -1252.689941 , -1680.530029 , 255.500000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(1.7669983,index++)) + wave1.append(CreateDroppodGruntEvent(< -1589.910034 , 1445.589966 , 271.500000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveEvent(0,index++)) + wave1.append(CreateDroppodGruntEvent(< -996.187988 , -1501.560059 , 255.500000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveEvent(0,index++)) + wave1.append(CreateNukeTitanEvent(< 3599.909912 , 21.781300 , 193.906006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveEvent(0,index++)) + wave1.append(CreateSuperSpectreEvent(< 1823.390015 , -62.063999 , 229.139999 >,< -0.000000 , -178.341995 , 0.000000 >,"",index++)) + wave1.append(CreateWaitForTimeEvent(5.0,index++)) + wave1.append(CreateWaitUntilAliveEvent(0,index++)) + wave1.append(CreateNukeTitanEvent(< 2072.510010 , -114.669998 , 240.608994 >,< 0.000000 , -2.153320 , 0.000000 >,"",0)) + waveEvents.append(wave1) + index = 1 + array<WaveEvent> wave2 + wave2.append(CreateDroppodGruntEvent(< -3328.030029 , 1423.030029 , 327.500000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(2.0,index++)) + wave2.append(CreateDroppodGruntEvent(< -3224.000000 , 1101.719971 , 327.562988 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.9000244,index++)) + wave2.append(CreateDroppodStalkerEvent(< -3104.379883 , 1348.000000 , 327.500000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.9169922,index++)) + wave2.append(CreateDroppodStalkerEvent(< -3218.719971 , -1766.530029 , 391.500000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(5.0,index++)) + wave2.append(CreateWaitUntilAliveEvent(0,index++)) + wave2.append(CreateScorchTitanEvent(< 3599.909912 , 21.781300 , 193.906006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(5.0,index++)) + wave2.append(CreateWaitUntilAliveEvent(0,index++)) + wave2.append(CreateSuperSpectreEvent(< 2337.030029 , -69.686699 , 226.059998 >,< -0.000000 , -179.475006 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(1.3170166,index++)) + wave2.append(CreateSuperSpectreEvent(< 41.778801 , 1492.930054 , 207.095001 >,< -0.000000 , -107.139999 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(1.3330078,index++)) + wave2.append(CreateSuperSpectreEvent(< 1897.969971 , 3546.590088 , 11.343800 >,< -0.000000 , -97.514702 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.5830078,index++)) + wave2.append(CreateSuperSpectreEvent(< 2715.909912 , 2444.469971 , 287.549011 >,< -0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.8170166,index++)) + wave2.append(CreateSuperSpectreEvent(< 1463.780029 , 1324.219971 , 131.906006 >,< -0.000000 , -139.350998 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.75,index++)) + wave2.append(CreateSuperSpectreEvent(< 1463.060059 , 797.065979 , 169.285995 >,< -0.000000 , 167.210999 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.8329468,index++)) + wave2.append(CreateSuperSpectreEvent(< 936.437988 , 2916.439941 , 45.218800 >,< 0.000000 , -98.833000 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.6340332,index++)) + wave2.append(CreateSuperSpectreEvent(< 1320.030029 , 3197.560059 , 20.562500 >,< 0.000000 , -170.464005 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.9500122,index++)) + wave2.append(CreateScorchTitanEvent(< 1403.640015 , 6.090660 , 248.841995 >,< -0.000000 , 154.104996 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(2.3330078,index++)) + wave2.append(CreateSuperSpectreEvent(< 1887.949951 , 2189.469971 , 8.031250 >,< -0.000000 , -178.822998 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(5.0,index++)) + wave2.append(CreateWaitUntilAliveEvent(0,index++)) + wave2.append(CreateArcTitanEvent(< 3562.780029 , 597.000000 , 147.031006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(1.53302,index++)) + wave2.append(CreateSuperSpectreEvent(< 158.718994 , 1828.060059 , 205.938004 >,< 0.000000 , -112.807999 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.56695557,index++)) + wave2.append(CreateSuperSpectreEvent(< 1455.800049 , 791.848999 , 172.475998 >,< -0.000000 , 166.639999 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.8170166,index++)) + wave2.append(CreateSuperSpectreEvent(< 2348.000000 , -132.188004 , 234.906006 >,< -0.000000 , 166.641006 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(2.1000366,index++)) + wave2.append(CreateSuperSpectreEvent(< 1475.770020 , 1334.510010 , 127.028000 >,< 0.000000 , -139.307007 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.6159668,index++)) + wave2.append(CreateSuperSpectreEvent(< 2163.419922 , 1372.069946 , 38.044701 >,< -0.000000 , -165.878006 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.7000122,index++)) + wave2.append(CreateArcTitanEvent(< 3600.000000 , 21.718800 , 194.000000 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.5839844,index++)) + wave2.append(CreateSuperSpectreEvent(< 889.906006 , 2926.129883 , 50.593800 >,< -0.000000 , -93.427696 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.8829956,index++)) + wave2.append(CreateScorchTitanEvent(< 3146.129883 , 42.906300 , 172.250000 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.5170288,index++)) + wave2.append(CreateSuperSpectreEvent(< 2071.060059 , 2108.060059 , 8.031250 >,< 0.000000 , -160.093002 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(3.065979,index++)) + wave2.append(CreateArcTitanEvent(< 1324.250000 , 43.000000 , 256.625000 >,< -0.000000 , 154.600006 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(1.21698,index++)) + wave2.append(CreateSuperSpectreEvent(< 1455.780029 , 792.064026 , 172.410004 >,< -0.000000 , 166.639008 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.9000244,index++)) + wave2.append(CreateSuperSpectreEvent(< 153.862000 , 1829.819946 , 206.039993 >,< -0.000000 , -112.330002 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.23297119,index++)) + wave2.append(CreateScorchTitanEvent(< 2474.560059 , 1404.660034 , 63.562500 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.5170288,index++)) + wave2.append(CreateSuperSpectreEvent(< 1576.560059 , -228.938004 , 236.343994 >,< -0.000000 , -173.188004 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.75,index++)) + wave2.append(CreateSuperSpectreEvent(< 1478.390015 , 1336.760010 , 125.976997 >,< 0.000000 , -139.307007 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(2.7000122,index++)) + wave2.append(CreateArcTitanEvent(< 1272.239990 , 68.484001 , 256.885986 >,< -0.000000 , 154.994003 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.8999634,index++)) + wave2.append(CreateSuperSpectreEvent(< 889.038025 , 2913.489990 , 50.996201 >,< -0.000000 , -93.384903 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.5830078,index++)) + wave2.append(CreateScorchTitanEvent(< 1209.160034 , 96.343803 , 256.281006 >,< -0.000000 , 154.688004 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.4500122,index++)) + wave2.append(CreateSuperSpectreEvent(< 2054.219971 , 2189.840088 , 8.031250 >,< 0.000000 , -178.550003 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.8170166,index++)) + wave2.append(CreateSuperSpectreEvent(< 1611.719971 , -210.145996 , 235.520004 >,< 0.000000 , -141.108002 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(1.2999878,index++)) + wave2.append(CreateSuperSpectreEvent(< 150.729996 , 1828.010010 , 206.033005 >,< 0.000000 , -112.105003 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(3.3170166,index++)) + wave2.append(CreateSuperSpectreEvent(< 2517.409912 , 274.963013 , 213.567001 >,< 0.000000 , -150.468994 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(5.0,index++)) + wave2.append(CreateWaitUntilAliveEvent(0,index++)) + wave2.append(CreateArcTitanEvent(< 3562.780029 , 597.000000 , 147.031006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(1.0999756,index++)) + wave2.append(CreateSuperSpectreEvent(< 2351.110107 , -69.093002 , 225.748001 >,< -0.000000 , -179.738007 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(1.3000488,index++)) + wave2.append(CreateSuperSpectreEvent(< 153.097000 , 1827.900024 , 206.031998 >,< 0.000000 , -112.323997 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(3.1170044,index++)) + wave2.append(CreateSuperSpectreEvent(< 3145.469971 , 43.000000 , 169.281006 >,< -0.000000 , -180.000000 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.56695557,index++)) + wave2.append(CreateSuperSpectreEvent(< 2774.689941 , 1398.219971 , 69.062500 >,< -0.000000 , 17.050800 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(1.03302,index++)) + wave2.append(CreateSuperSpectreEvent(< 1480.160034 , 1338.219971 , 125.280998 >,< 0.000000 , -139.350998 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.08300781,index++)) + wave2.append(CreateScorchTitanEvent(< 3599.909912 , 21.781300 , 193.906006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.9840088,index++)) + wave2.append(CreateNukeTitanEvent(< 2775.560059 , 220.063004 , 174.468994 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.39996338,index++)) + wave2.append(CreateSuperSpectreEvent(< 1897.969971 , 3546.590088 , 11.343800 >,< 0.000000 , -97.514603 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.81604004,index++)) + wave2.append(CreateSuperSpectreEvent(< 2715.909912 , 2444.469971 , 264.968994 >,< -0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(1.93396,index++)) + wave2.append(CreateArcTitanEvent(< 1344.760010 , 33.344200 , 256.279999 >,< -0.000000 , 154.438995 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.46600342,index++)) + wave2.append(CreateSuperSpectreEvent(< 938.549988 , -22.322100 , 250.496002 >,< -0.000000 , 135.744995 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.4500122,index++)) + wave2.append(CreateSuperSpectreEvent(< 1322.630005 , 3196.280029 , 19.882500 >,< 0.000000 , -173.231995 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(0.6500244,index++)) + wave2.append(CreateSuperSpectreEvent(< 2501.810059 , -40.656300 , 215.906006 >,< -0.000000 , 179.735992 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(2.8169556,index++)) + wave2.append(CreateSuperSpectreEvent(< 1895.780029 , 2189.280029 , 8.031250 >,< -0.000000 , -179.473007 , 0.000000 >,"",index++)) + wave2.append(CreateWaitForTimeEvent(3.4170532,index++)) + wave2.append(CreateScorchTitanEvent(< 1701.880005 , -121.780998 , 227.375000 >,< -0.000000 , -13.095700 , 0.000000 >,"",0)) + waveEvents.append(wave2) + index = 1 + array<WaveEvent> wave3 + wave3.append(CreateArcTitanEvent(< 3562.780029 , 597.000000 , 147.031006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(0.8170166,index++)) + wave3.append(CreateArcTitanEvent(< 1904.310059 , 3554.219971 , 13.718800 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.3829956,index++)) + wave3.append(CreateArcTitanEvent(< 2474.689941 , 1404.589966 , 63.562500 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.0,index++)) + wave3.append(CreateDroppodGruntEvent(< 3637.560059 , 571.968994 , 151.500000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.0830078,index++)) + wave3.append(CreateDroppodGruntEvent(< 3349.560059 , -12.031300 , 161.313004 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(0.8170166,index++)) + wave3.append(CreateDroppodStalkerEvent(< 2117.560059 , 1491.969971 , 21.625000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(0.5999756,index++)) + wave3.append(CreateDroppodStalkerEvent(< 2221.560059 , -196.031006 , 250.625000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(3.1170044,index++)) + wave3.append(CreateDroppodGruntEvent(< 2677.560059 , 1907.969971 , 53.250000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(2.5499878,index++)) + wave3.append(CreateArcTitanEvent(< 1323.239990 , 43.979000 , 256.675995 >,< -0.000000 , 174.664993 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(5.0,index++)) + wave3.append(CreateWaitUntilAliveEvent(0,index++)) + wave3.append(CreateDroppodGruntEvent(< 3637.560059 , 571.968994 , 151.500000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(0.6170044,index++)) + wave3.append(CreateDroppodGruntEvent(< 3349.560059 , -12.031300 , 161.313004 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.1329956,index++)) + wave3.append(CreateDroppodStalkerEvent(< 2117.560059 , 1491.969971 , 21.625000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(0.6669922,index++)) + wave3.append(CreateArcTitanEvent(< 3562.780029 , 597.000000 , 147.031006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.2000122,index++)) + wave3.append(CreateToneSniperTitanEvent(< 3599.439941 , 21.687500 , 193.781006 >,< 0.000000 , 180.000000 , 0.000000 >,index++)) + wave3.append(CreateWaitForTimeEvent(5.017029,index++)) + wave3.append(CreateSuperSpectreEvent(< 3145.469971 , 43.000000 , 419.500000 >,< -0.000000 , -180.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(0.3659668,index++)) + wave3.append(CreateToneTitanEvent(< 2474.090088 , 1404.560059 , 63.500000 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(0.23400879,index++)) + wave3.append(CreateSuperSpectreEvent(< 1904.189941 , 3540.340088 , 11.500000 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(0.5,index++)) + wave3.append(CreateToneTitanEvent(< 2695.500000 , 3543.280029 , 30.843800 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(0.9000244,index++)) + wave3.append(CreateSuperSpectreEvent(< 2276.209961 , -301.247009 , 255.914001 >,< -0.000000 , 123.747002 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.2000122,index++)) + wave3.append(CreateSuperSpectreEvent(< 1281.839966 , 3074.530029 , 14.156300 >,< -0.000000 , -166.376999 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(0.6999512,index++)) + wave3.append(CreateSuperSpectreEvent(< 1002.700012 , -84.696800 , 254.085007 >,< 0.000000 , 135.615005 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.3330078,index++)) + wave3.append(CreateArcTitanEvent(< 1407.380005 , 4.218750 , 249.938004 >,< 0.000000 , 154.072006 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(0.117004395,index++)) + wave3.append(CreateSuperSpectreEvent(< 422.968994 , 2117.439941 , 153.593994 >,< -0.000000 , -152.798004 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.6160278,index++)) + wave3.append(CreateToneSniperTitanEvent(< 1608.089966 , -689.601013 , 258.437988 >,< -0.000000 , -164.445999 , 0.000000 >,index++)) + wave3.append(CreateWaitForTimeEvent(5.0,index++)) + wave3.append(CreateWaitUntilAliveEvent(0,index++)) + wave3.append(CreateToneTitanEvent(< 3599.439941 , 21.687500 , 193.781006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(0.8999634,index++)) + wave3.append(CreateNukeTitanEvent(< 3562.689941 , 597.062988 , 147.031006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.3829956,index++)) + wave3.append(CreateNukeTitanEvent(< 1904.250000 , 3554.129883 , 13.718800 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.184021,index++)) + wave3.append(CreateNukeTitanEvent(< 3146.129883 , 42.906300 , 172.250000 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(0.5999756,index++)) + wave3.append(CreateToneSniperTitanEvent(< 2645.750000 , -114.375000 , 234.563004 >,< 0.000000 , 180.000000 , 0.000000 >,index++)) + wave3.append(CreateWaitForTimeEvent(1.4330444,index++)) + wave3.append(CreateSpawnDroneEvent(< 3503.659912 , 11.184200 , 463.877014 >,< 0.000000 , 0.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(0.6669922,index++)) + wave3.append(CreateDroppodStalkerEvent(< -991.843994 , 411.093994 , 254.656006 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(5.0,index++)) + wave3.append(CreateWaitUntilAliveEvent(0,index++)) + wave3.append(CreateSuperSpectreEvent(< 3325.479980 , 201.667007 , 179.955002 >,< -0.000000 , -158.610992 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(0.8670044,index++)) + wave3.append(CreateSuperSpectreEvent(< 1677.130005 , 3349.620117 , 18.890200 >,< 0.000000 , -153.281006 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(5.217041,index++)) + wave3.append(CreateSpawnDroneEvent(< 191.919998 , -1930.219971 , 6534.589844 >,< 0.004999 , -175.953003 , 0.000004 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.315979,index++)) + wave3.append(CreateSpawnDroneEvent(< 478.014008 , -2108.659912 , 6535.350098 >,< 0.004999 , -175.953003 , 0.000004 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(0.9000244,index++)) + wave3.append(CreateArcTitanEvent(< 2474.689941 , 1404.589966 , 63.562500 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.2669678,index++)) + wave3.append(CreateToneTitanEvent(< 3562.219971 , 596.968994 , 147.031006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(0.8330078,index++)) + wave3.append(CreateToneTitanEvent(< 1904.339966 , 3553.659912 , 13.750000 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.1669922,index++)) + wave3.append(CreateToneTitanEvent(< 3599.439941 , 21.687500 , 193.781006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.1329956,index++)) + wave3.append(CreateScorchTitanEvent(< 1580.530029 , 3133.030029 , 12.375000 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.0840454,index++)) + wave3.append(CreateScorchTitanEvent(< 3146.129883 , 42.906300 , 172.250000 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(0.782959,index++)) + wave3.append(CreateScorchTitanEvent(< 2646.219971 , -114.280998 , 234.438004 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.1500244,index++)) + wave3.append(CreateNukeTitanEvent(< 2368.409912 , 2199.159912 , 11.031300 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.2669678,index++)) + wave3.append(CreateNukeTitanEvent(< 3321.590088 , 3089.659912 , 53.437500 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.0,index++)) + wave3.append(CreateNukeTitanEvent(< 2474.560059 , 1404.660034 , 63.562500 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(5.0,index++)) + wave3.append(CreateWaitUntilAliveEvent(0,index++)) + wave3.append(CreateArcTitanEvent(< 1904.310059 , 3554.219971 , 13.718800 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(0.79992676,index++)) + wave3.append(CreateArcTitanEvent(< 3562.780029 , 597.000000 , 147.031006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.0999756,index++)) + wave3.append(CreateArcTitanEvent(< 1580.630005 , 3133.000000 , 12.375000 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.3000488,index++)) + wave3.append(CreateArcTitanEvent(< 2695.469971 , 3543.840088 , 31.062500 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.4000244,index++)) + wave3.append(CreateArcTitanEvent(< 2730.000000 , 2866.090088 , 13.093800 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(1.2999268,index++)) + wave3.append(CreateArcTitanEvent(< 991.500000 , 3212.439941 , 79.531303 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave3.append(CreateWaitForTimeEvent(5.0,index++)) + wave3.append(CreateWaitUntilAliveEvent(0,index++)) + wave3.append(CreateArcTitanEvent(< 2716.030029 , 2445.219971 , 17.687500 >,< 0.000000 , -90.000000 , 0.000000 >,"",0)) + waveEvents.append(wave3) + index = 1 + array<WaveEvent> wave4 + wave4.append(CreateSpawnDroneEvent(< 102.452003 , -2172.350098 , 6554.939941 >,< 0.004999 , -175.953003 , 0.000004 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.2000732,index++)) + wave4.append(CreateSpawnDroneEvent(< -445.360992 , 2927.620117 , 6683.160156 >,< 0.004999 , -175.953003 , 0.000004 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(5.0,index++)) + wave4.append(CreateWaitUntilAliveEvent(0,index++)) + wave4.append(CreateSpawnDroneEvent(< 70.420502 , -2144.540039 , 6547.779785 >,< 0.004999 , -175.953003 , 0.000004 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.4000244,index++)) + wave4.append(CreateSpawnDroneEvent(< 191.919998 , -1930.219971 , 6563.669922 >,< 0.004999 , -175.953003 , 0.000004 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.5,index++)) + wave4.append(CreateSpawnDroneEvent(< -417.548004 , 2959.649902 , 6676.850098 >,< 0.004999 , -175.953003 , 0.000004 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(5.0,index++)) + wave4.append(CreateWaitUntilAliveEvent(0,index++)) + wave4.append(CreateSpawnDroneEvent(< 74.639198 , -2204.379883 , 6556.439941 >,< 0.004999 , -175.953003 , 0.000004 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(0.8000488,index++)) + wave4.append(CreateScorchTitanEvent(< 3562.689941 , 597.062988 , 147.031006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.1999512,index++)) + wave4.append(CreateSpawnDroneEvent(< 3523.969971 , 589.687988 , 463.968994 >,< 0.000000 , 0.000000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.5,index++)) + wave4.append(CreateScorchTitanEvent(< 3599.909912 , 21.781300 , 193.906006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(0.9000244,index++)) + wave4.append(CreateScorchTitanEvent(< 3146.129883 , 42.906300 , 172.250000 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(0.9000244,index++)) + wave4.append(CreateArcTitanEvent(< 2474.689941 , 1404.589966 , 63.562500 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(0.89990234,index++)) + wave4.append(CreateDroppodStalkerEvent(< -3218.719971 , -1766.530029 , 391.500000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.2000732,index++)) + wave4.append(CreateDroppodStalkerEvent(< -3328.030029 , 1423.030029 , 327.500000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(2.9000244,index++)) + wave4.append(CreateScorchTitanEvent(< 2695.409912 , 3543.750000 , 31.031300 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(0.5999756,index++)) + wave4.append(CreateScorchTitanEvent(< 1930.030029 , 3156.879883 , 11.156300 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(0.79992676,index++)) + wave4.append(CreateSuperSpectreEvent(< 2485.379883 , 2253.969971 , 8.031250 >,< 0.000000 , -151.039993 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(0.20007324,index++)) + wave4.append(CreateScorchTitanEvent(< 1585.530029 , 3552.379883 , 53.968800 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(0.5999756,index++)) + wave4.append(CreateSuperSpectreEvent(< 3107.750000 , 2873.530029 , 11.531300 >,< -0.000000 , -114.477997 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(0.5,index++)) + wave4.append(CreateArcTitanEvent(< 3171.560059 , 608.468994 , 150.375000 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(0.5999756,index++)) + wave4.append(CreateArcTitanEvent(< 1700.560059 , 1538.380005 , 21.031300 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(5.0,index++)) + wave4.append(CreateWaitUntilAliveEvent(0,index++)) + wave4.append(CreateArcTitanEvent(< 2474.689941 , 1404.589966 , 63.562500 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(5.0,index++)) + wave4.append(CreateWaitUntilAliveEvent(0,index++)) + wave4.append(CreateSuperSpectreEvent(< 3266.909912 , 586.875000 , 161.000000 >,< 0.000000 , -169.102005 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.2999268,index++)) + wave4.append(CreateSuperSpectreEvent(< 3319.340088 , 120.438004 , 158.375000 >,< -0.000000 , 179.209000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(5.0,index++)) + wave4.append(CreateWaitUntilAliveEvent(0,index++)) + wave4.append(CreateSuperSpectreEvent(< 2479.770020 , 2250.840088 , 8.031250 >,< 0.000000 , -151.039993 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(0.9000244,index++)) + wave4.append(CreateSuperSpectreEvent(< 1670.160034 , 3346.110107 , 18.495300 >,< 0.000000 , -153.237000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(0.5,index++)) + wave4.append(CreateNukeTitanEvent(< 3599.909912 , 21.781300 , 193.906006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(0.6999512,index++)) + wave4.append(CreateSuperSpectreEvent(< 3104.560059 , 2874.250000 , 11.468800 >,< -0.000000 , -119.355003 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(0.70007324,index++)) + wave4.append(CreateSuperSpectreEvent(< 1285.500000 , 3074.939941 , 13.343800 >,< -0.000000 , -166.641006 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.2999268,index++)) + wave4.append(CreateSuperSpectreEvent(< 2612.909912 , 3263.360107 , 8.372550 >,< 0.000000 , -93.867203 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.5,index++)) + wave4.append(CreateSpawnDroneEvent(< 3436.909912 , 101.063004 , 463.968994 >,< 0.000000 , 0.000000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.4000244,index++)) + wave4.append(CreateScorchTitanEvent(< 1904.250000 , 3554.129883 , 13.718800 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.5,index++)) + wave4.append(CreateScorchTitanEvent(< 2715.969971 , 2445.129883 , 17.687500 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(0.6999512,index++)) + wave4.append(CreateScorchTitanEvent(< 1580.530029 , 3133.030029 , 12.375000 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(0.60009766,index++)) + wave4.append(CreateToneSniperTitanEvent(< 2695.500000 , 3543.280029 , 30.843800 >,< 0.000000 , -90.000000 , 0.000000 >,index++)) + wave4.append(CreateWaitForTimeEvent(5.0,index++)) + wave4.append(CreateWaitUntilAliveEvent(0,index++)) + wave4.append(CreateArcTitanEvent(< 991.500000 , 3212.439941 , 79.531303 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.1000977,index++)) + wave4.append(CreateSpawnDroneEvent(< 74.639198 , -2204.379883 , 6556.759766 >,< 0.004999 , -175.953003 , 0.000004 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.1999512,index++)) + wave4.append(CreateSpawnDroneEvent(< -417.548004 , 2959.649902 , 6681.479980 >,< 0.004999 , -175.953003 , 0.000004 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(5.0,index++)) + wave4.append(CreateWaitUntilAliveEvent(0,index++)) + wave4.append(CreateSpawnDroneEvent(< 74.639198 , -2204.379883 , 6554.790039 >,< 0.004999 , -175.953003 , 0.000004 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.2000732,index++)) + wave4.append(CreateSpawnDroneEvent(< 164.108002 , -1962.290039 , 6565.899902 >,< 0.004999 , -175.953003 , 0.000004 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.2999268,index++)) + wave4.append(CreateSpawnDroneEvent(< -417.548004 , 2959.649902 , 6676.520020 >,< 0.004999 , -175.953003 , 0.000004 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(5.0,index++)) + wave4.append(CreateWaitUntilAliveEvent(0,index++)) + wave4.append(CreateSpawnDroneEvent(< 74.639198 , -2204.379883 , 6552.459961 >,< 0.004999 , -175.953003 , 0.000004 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(0.9000244,index++)) + wave4.append(CreateArcTitanEvent(< 2716.030029 , 2445.219971 , 17.687500 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.5,index++)) + wave4.append(CreateArcTitanEvent(< 3321.659912 , 3089.750000 , 53.437500 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.0,index++)) + wave4.append(CreateArcTitanEvent(< 3562.780029 , 597.000000 , 147.031006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(0.6999512,index++)) + wave4.append(CreateArcTitanEvent(< 3600.000000 , 21.718800 , 194.000000 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(0.9000244,index++)) + wave4.append(CreateArcTitanEvent(< 1904.310059 , 3554.219971 , 13.718800 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.1999512,index++)) + wave4.append(CreateArcTitanEvent(< 2695.469971 , 3543.840088 , 31.062500 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave4.append(CreateWaitForTimeEvent(1.0999756,index++)) + wave4.append(CreateArcTitanEvent(< 1580.630005 , 3133.000000 , 12.375000 >,< 0.000000 , 180.000000 , 0.000000 >,"",0)) + waveEvents.append(wave4) + index = 1 + array<WaveEvent> wave5 + wave5.append(CreateToneSniperTitanEvent(< 3599.439941 , 21.687500 , 193.781006 >,< 0.000000 , 180.000000 , 0.000000 >,index++)) + wave5.append(CreateWaitForTimeEvent(0.5800781,index++)) + wave5.append(CreateArcTitanEvent(< 3562.780029 , 597.000000 , 147.031006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.4000244,index++)) + wave5.append(CreateArcTitanEvent(< 3146.219971 , 42.875000 , 172.218994 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.82995605,index++)) + wave5.append(CreateArcTitanEvent(< 1904.310059 , 3554.219971 , 13.718800 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.0,index++)) + wave5.append(CreateToneTitanEvent(< 2645.750000 , -114.375000 , 234.563004 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.5699463,index++)) + wave5.append(CreateToneTitanEvent(< 1580.060059 , 3132.939941 , 12.375000 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.95007324,index++)) + wave5.append(CreateNukeTitanEvent(< 2474.560059 , 1404.660034 , 63.562500 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.3699951,index++)) + wave5.append(CreateNukeTitanEvent(< 2368.409912 , 2199.159912 , 11.031300 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.9000244,index++)) + wave5.append(CreateNukeTitanEvent(< 3321.590088 , 3089.659912 , 53.437500 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.0,index++)) + wave5.append(CreateNukeTitanEvent(< 2695.409912 , 3543.750000 , 31.031300 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.079956,index++)) + wave5.append(CreateNukeTitanEvent(< 3608.689941 , 324.875000 , 147.031006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.1500244,index++)) + wave5.append(CreateNukeTitanEvent(< 991.468994 , 3212.340088 , 79.500000 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.2700195,index++)) + wave5.append(CreateSpawnDroneEvent(< 102.452003 , -2172.350098 , 6532.419922 >,< 0.004999 , -175.953003 , 0.000004 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.60998535,index++)) + wave5.append(CreateSpawnDroneEvent(< 196.169998 , -1990.069946 , 6516.410156 >,< 0.004999 , -175.953003 , 0.000004 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.2999268,index++)) + wave5.append(CreateSpawnDroneEvent(< -417.548004 , 2959.649902 , 6638.049805 >,< 0.004999 , -175.953003 , 0.000004 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.1000977,index++)) + wave5.append(CreateSpawnDroneEvent(< -355.891998 , 3169.709961 , 6646.209961 >,< 0.004999 , -175.953003 , 0.000004 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(3.8999023,index++)) + wave5.append(CreateSpawnDroneEvent(< 102.452003 , -2172.350098 , 6502.850098 >,< 0.004999 , -175.953003 , 0.000004 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(5.0,index++)) + wave5.append(CreateWaitUntilAliveEvent(0,index++)) + wave5.append(CreateSpawnDroneEvent(< 74.639198 , -2204.379883 , 6526.680176 >,< 0.004999 , -175.953003 , 0.000004 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.72998047,index++)) + wave5.append(CreateNukeTitanEvent(< 3562.689941 , 597.062988 , 147.031006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.97998047,index++)) + wave5.append(CreateNukeTitanEvent(< 3599.909912 , 21.781300 , 193.906006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.420044,index++)) + wave5.append(CreateNukeTitanEvent(< 3146.129883 , 42.906300 , 172.250000 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(5.880005,index++)) + wave5.append(CreateToneTitanEvent(< 2645.750000 , -114.375000 , 234.563004 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.5999756,index++)) + wave5.append(CreateSpawnDroneEvent(< 3496.929932 , 95.000397 , 463.927002 >,< 0.000000 , 0.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.8000488,index++)) + wave5.append(CreateNukeTitanEvent(< 3171.469971 , 608.500000 , 150.375000 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.9000244,index++)) + wave5.append(CreateNukeTitanEvent(< 3608.689941 , 324.875000 , 147.031006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.1199951,index++)) + wave5.append(CreateNukeTitanEvent(< 2474.560059 , 1404.660034 , 63.562500 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.79992676,index++)) + wave5.append(CreateToneTitanEvent(< 2367.909912 , 2199.060059 , 11.031300 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.5,index++)) + wave5.append(CreateSpawnDroneEvent(< 191.919998 , -1930.219971 , 6518.930176 >,< 0.004999 , -175.953003 , 0.000004 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.0999756,index++)) + wave5.append(CreateSpawnDroneEvent(< 478.014008 , -2108.659912 , 6532.169922 >,< 0.004999 , -175.953003 , 0.000004 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.2800293,index++)) + wave5.append(CreateSpawnDroneEvent(< 70.420502 , -2144.540039 , 6517.500000 >,< 0.004999 , -175.953003 , 0.000004 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.4899902,index++)) + wave5.append(CreateSpawnDroneEvent(< 3466.889893 , 69.121399 , 591.948975 >,< 0.000000 , 0.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.5999756,index++)) + wave5.append(CreateSpawnDroneEvent(< -323.829987 , 3141.929932 , 6701.140137 >,< 0.004999 , -175.953003 , 0.000004 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(5.0,index++)) + wave5.append(CreateWaitUntilAliveEvent(0,index++)) + wave5.append(CreateSpawnDroneEvent(< 196.169998 , -1990.069946 , 6509.910156 >,< 0.004999 , -175.953003 , 0.000004 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.1600342,index++)) + wave5.append(CreateSpawnDroneEvent(< 445.983002 , -2080.850098 , 6576.009766 >,< 0.004999 , -175.953003 , 0.000004 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.4499512,index++)) + wave5.append(CreateNukeTitanEvent(< 2474.560059 , 1404.660034 , 63.562500 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.3699951,index++)) + wave5.append(CreateNukeTitanEvent(< 3171.469971 , 608.500000 , 150.375000 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.3200684,index++)) + wave5.append(CreateNukeTitanEvent(< 3599.909912 , 21.781300 , 193.906006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.1799316,index++)) + wave5.append(CreateNukeTitanEvent(< 3146.129883 , 42.906300 , 172.250000 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.3300781,index++)) + wave5.append(CreateNukeTitanEvent(< 2646.219971 , -114.280998 , 234.438004 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.4499512,index++)) + wave5.append(CreateNukeTitanEvent(< 2368.409912 , 2199.159912 , 11.031300 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.8399658,index++)) + wave5.append(CreateSpawnDroneEvent(< 2550.909912 , 1338.000000 , 392.437988 >,< 0.000000 , 0.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.1600342,index++)) + wave5.append(CreateSpawnDroneEvent(< 2652.000000 , 1237.910034 , 520.499023 >,< 0.000000 , 0.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.0200195,index++)) + wave5.append(CreateArcTitanEvent(< 3321.659912 , 3089.750000 , 53.437500 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.1999512,index++)) + wave5.append(CreateArcTitanEvent(< 3562.780029 , 597.000000 , 147.031006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.4000244,index++)) + wave5.append(CreateArcTitanEvent(< 2474.689941 , 1404.589966 , 63.562500 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.8000488,index++)) + wave5.append(CreateNukeTitanEvent(< 1904.250000 , 3554.129883 , 13.718800 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.3800049,index++)) + wave5.append(CreateNukeTitanEvent(< 1580.530029 , 3133.030029 , 12.375000 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.73999023,index++)) + wave5.append(CreateNukeTitanEvent(< 2729.939941 , 2866.000000 , 13.093800 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.89990234,index++)) + wave5.append(CreateSpawnDroneEvent(< 102.452003 , -2172.350098 , 6507.430176 >,< 0.004999 , -175.953003 , 0.000004 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.5600586,index++)) + wave5.append(CreateSpawnDroneEvent(< 164.108002 , -1962.290039 , 6557.959961 >,< 0.004999 , -175.953003 , 0.000004 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(5.0,index++)) + wave5.append(CreateWaitUntilAliveEvent(0,index++)) + wave5.append(CreateNukeTitanEvent(< 3599.909912 , 21.781300 , 193.906006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.8000488,index++)) + wave5.append(CreateNukeTitanEvent(< 3146.129883 , 42.906300 , 172.250000 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.1199951,index++)) + wave5.append(CreateNukeTitanEvent(< 3562.689941 , 597.062988 , 147.031006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.1600342,index++)) + wave5.append(CreateNukeTitanEvent(< 2646.219971 , -114.280998 , 234.438004 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.1999512,index++)) + wave5.append(CreateNukeTitanEvent(< 1904.250000 , 3554.129883 , 13.718800 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.2199707,index++)) + wave5.append(CreateNukeTitanEvent(< 2715.969971 , 2445.129883 , 17.687500 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.60009766,index++)) + wave5.append(CreateToneTitanEvent(< 2474.090088 , 1404.560059 , 63.500000 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.5,index++)) + wave5.append(CreateNukeTitanEvent(< 1580.530029 , 3133.030029 , 12.375000 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.57995605,index++)) + wave5.append(CreateNukeTitanEvent(< 2695.409912 , 3543.750000 , 31.031300 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.420044,index++)) + wave5.append(CreateNukeTitanEvent(< 3321.590088 , 3089.659912 , 53.437500 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.1199951,index++)) + wave5.append(CreateNukeTitanEvent(< 3599.909912 , 21.781300 , 193.906006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.95996094,index++)) + wave5.append(CreateNukeTitanEvent(< 1700.469971 , 1538.439941 , 21.031300 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(5.0,index++)) + wave5.append(CreateWaitUntilAliveEvent(0,index++)) + wave5.append(CreateNukeTitanEvent(< 2474.560059 , 1404.660034 , 63.562500 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.0300293,index++)) + wave5.append(CreateArcTitanEvent(< 3562.780029 , 597.000000 , 147.031006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.1699219,index++)) + wave5.append(CreateArcTitanEvent(< 3600.000000 , 21.718800 , 194.000000 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.0200195,index++)) + wave5.append(CreateArcTitanEvent(< 1904.310059 , 3554.219971 , 13.718800 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.0,index++)) + wave5.append(CreateNukeTitanEvent(< 3146.129883 , 42.906300 , 172.250000 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.8100586,index++)) + wave5.append(CreateNukeTitanEvent(< 2646.219971 , -114.280998 , 234.438004 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.4899902,index++)) + wave5.append(CreateNukeTitanEvent(< 2368.409912 , 2199.159912 , 11.031300 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(5.0,index++)) + wave5.append(CreateWaitUntilAliveEvent(0,index++)) + wave5.append(CreateArcTitanEvent(< 3562.780029 , 597.000000 , 147.031006 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.7800293,index++)) + wave5.append(CreateArcTitanEvent(< 3600.000000 , 21.718800 , 194.000000 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.0200195,index++)) + wave5.append(CreateArcTitanEvent(< 3146.219971 , 42.875000 , 172.218994 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.0,index++)) + wave5.append(CreateArcTitanEvent(< 1904.310059 , 3554.219971 , 13.718800 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.67993164,index++)) + wave5.append(CreateScorchTitanEvent(< 255.968994 , 2110.750000 , 184.938004 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.0300293,index++)) + wave5.append(CreateScorchTitanEvent(< 1700.469971 , 1538.439941 , 21.031300 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(5.0,index++)) + wave5.append(CreateWaitUntilAliveEvent(0,index++)) + wave5.append(CreateScorchTitanEvent(< 255.968994 , 2110.750000 , 184.938004 >,< 0.000000 , -90.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(0.70007324,index++)) + wave5.append(CreateNukeTitanEvent(< 1762.500000 , 758.437988 , 143.593994 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.0,index++)) + wave5.append(CreateNukeTitanEvent(< 2646.219971 , -114.280998 , 234.438004 >,< 0.000000 , 180.000000 , 0.000000 >,"",index++)) + wave5.append(CreateWaitForTimeEvent(1.4000244,index++)) + wave5.append(CreateNukeTitanEvent(< 1700.469971 , 1538.439941 , 21.031300 >,< 0.000000 , 180.000000 , 0.000000 >,"",0)) + waveEvents.append(wave5) + +}
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_thaw.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_thaw.nut index 37b89169..e6eb493d 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_thaw.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_thaw.nut @@ -1 +1,8 @@ -//fuck
\ No newline at end of file +global function CodeCallback_MapInit + +void function CodeCallback_MapInit() +{ + // Load Frontier Defense Data + if( GameRules_GetGameMode() == "fd" ) + initFrontierDefenseData() +}
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_thaw_fd.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_thaw_fd.nut index 37b89169..cd3e2822 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_thaw_fd.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_thaw_fd.nut @@ -1 +1,23 @@ -//fuck
\ No newline at end of file +global function initFrontierDefenseData +void function initFrontierDefenseData() +{ + shopPosition = <0,0,0> + + + array<WaveEvent> wave0 + array<WaveEvent> wave1 + array<WaveEvent> wave2 + array<WaveEvent> wave3 + array<WaveEvent> wave4 + + + + + + + waveEvents.append(wave0) + waveEvents.append(wave1) + waveEvents.append(wave2) + waveEvents.append(wave3) + waveEvents.append(wave4) +}
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_wargames.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_wargames.nut index 8d859ba6..d0ce4f79 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_wargames.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_wargames.nut @@ -29,8 +29,13 @@ void function CodeCallback_MapInit() // currently disabled until finished: intro if ( !IsFFAGame() ) ClassicMP_SetLevelIntro( WargamesIntroSetup, 20.0 ) + + // Load Frontier Defense Data + if( GameRules_GetGameMode() == "fd" ) + initFrontierDefenseData() } + void function AddEvacNodes() { AddEvacNode( GetEnt( "evac_location1" ) ) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_wargames_fd.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_wargames_fd.nut index 37b89169..cd3e2822 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_wargames_fd.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_wargames_fd.nut @@ -1 +1,23 @@ -//fuck
\ No newline at end of file +global function initFrontierDefenseData +void function initFrontierDefenseData() +{ + shopPosition = <0,0,0> + + + array<WaveEvent> wave0 + array<WaveEvent> wave1 + array<WaveEvent> wave2 + array<WaveEvent> wave3 + array<WaveEvent> wave4 + + + + + + + waveEvents.append(wave0) + waveEvents.append(wave1) + waveEvents.append(wave2) + waveEvents.append(wave3) + waveEvents.append(wave4) +}
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/rodeo/_rodeo_titan.gnut b/Northstar.CustomServers/mod/scripts/vscripts/rodeo/_rodeo_titan.gnut index 78cfdb27..153be7cd 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/rodeo/_rodeo_titan.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/rodeo/_rodeo_titan.gnut @@ -27,6 +27,7 @@ global function Rodeo_PilotPicksUpBattery_Silent global function AddOnRodeoStartedCallback global function AddOnRodeoEndedCallback +global function AddBatteryHealCallback global function PilotBattery_SetMaxCount global function ThrowRiderOff @@ -92,6 +93,7 @@ struct { array<void functionref(entity,entity)> onRodeoEndedCallbacks array<void functionref(entity,entity)> onRodeoStartedCallbacks + array<void functionref(entity,entity,int,int)> batteryHealCallbacks table<entity, AntiRodeoPlayerData> antiRodeoPlayerData @@ -535,6 +537,12 @@ void function AddOnRodeoEndedCallback( void functionref(entity,entity) callbackF file.onRodeoEndedCallbacks.append( callbackFunc ) } +void function AddBatteryHealCallback( void functionref(entity,entity,int,int) callbackFunc ) +{ + Assert (!( file.batteryHealCallbacks.contains( callbackFunc ) )) + file.batteryHealCallbacks.append( callbackFunc ) +} + function PlayerBeginsTitanRodeo( entity player, RodeoPackageStruct rodeoPackage, entity rodeoTitan ) { entity soul = rodeoTitan.GetTitanSoul() @@ -1769,6 +1777,8 @@ void function Rodeo_ApplyBatteryToTitan( entity battery, entity titan ) int addHealth = int( healingAmount * frac ) int totalHealth = minint( titan.GetMaxHealth(), titan.GetHealth() + addHealth ) + if( titan.GetHealth() + addHealth > titan.GetMaxHealth() ) + addHealth = titan.GetMaxHealth() - titan.GetHealth() if ( soul.IsDoomed() && batteryIsAmped ) { UndoomTitan( titan, 1 ) @@ -1779,6 +1789,11 @@ void function Rodeo_ApplyBatteryToTitan( entity battery, entity titan ) titan.SetHealth( totalHealth ) soul.SetShieldHealth( soul.GetShieldHealthMax() ) } + + foreach ( callbackFunc in file.batteryHealCallbacks ) + { + callbackFunc( battery, titan, shieldDifference, addHealth ) + } } if ( battery != null ) @@ -2456,4 +2471,4 @@ bool function ClientCommand_TryNukeGrenade( entity player, array<string> args ) return true } -#endif
\ No newline at end of file +#endif diff --git a/Northstar.CustomServers/mod/scripts/vscripts/weapons/_cloaker.gnut b/Northstar.CustomServers/mod/scripts/vscripts/weapons/_cloaker.gnut index 6ec0bc0a..b4045f3e 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/weapons/_cloaker.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/weapons/_cloaker.gnut @@ -97,6 +97,8 @@ function CloakerThink( entity cloaker, float radius, array<string> ents = [ "any void function CloakerCloaksGuy( guy ) { + if( guy.IsNPC() ) + guy.SetCanCloak(true) // if you don't want to cloak specific targets, it should be handled by shouldCloakGuyFunc in CloakerThink guy.SetCloakDuration( 2.0, -1, 0 ) EmitSoundOnEntity( guy, CLOAKED_DRONE_CLOAK_START_SFX ) EmitSoundOnEntity( guy, CLOAKED_DRONE_CLOAK_LOOP_SFX ) @@ -110,6 +112,8 @@ void function CloakerDeCloaksGuy( guy ) StopSoundOnEntity( guy, CLOAKED_DRONE_CLOAK_LOOP_SFX ) guy.Minimap_AlwaysShow( TEAM_IMC, null ) guy.Minimap_AlwaysShow( TEAM_MILITIA, null ) + if( guy.IsNPC() ) + guy.SetCanCloak(false) } bool function CloakerShouldCloakGuy( entity cloaker, entity guy ) @@ -118,4 +122,4 @@ bool function CloakerShouldCloakGuy( entity cloaker, entity guy ) return false return true -}
\ No newline at end of file +} diff --git a/Northstar.CustomServers/mod/scripts/vscripts/weapons/sh_phase_shift.gnut b/Northstar.CustomServers/mod/scripts/vscripts/weapons/sh_phase_shift.gnut new file mode 100644 index 00000000..52d07f00 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/vscripts/weapons/sh_phase_shift.gnut @@ -0,0 +1,774 @@ +untyped
+#if CLIENT
+#endif
+
+global function MpAbilityShifter_Init
+global function PhaseShift
+global function CodeCallback_EnterPhaseShift
+global function CodeCallback_ExitPhaseShift
+global function CancelPhaseShift
+
+#if SERVER
+global function PlayPhaseShiftDisappearFX
+global function UntrackAllToneMarks
+#endif
+
+const SHIFTER_OUTRO_TIME_BEFORE_END = 1.5
+
+const SHIFTER_PRE_FX = $"P_warpjump_FP"
+
+const SHIFTER_APPEAR_FX = $"P_phase_shift_main"
+const SHIFTER_APPEAR_FX_TITAN = $"P_phase_shift_main_XO"
+const SHIFTER_DISAPPEAR_FX = $"P_phase_shift_main"
+const SHIFTER_DISAPPEAR_FX_TITAN = $"P_phase_shift_main_XO"
+
+const SHIFTER_SCREEN_FX = $"P_phase_shift_screen"
+const SHIFTER_PERSONAL_FX = $"P_phase_shift_player"
+const SHIFTER_SCREEN_FX_START = $"P_phase_shift_screen_start"
+const SHIFTER_COLORCORRECTION = "materials/correction/mp_ability_shifter.raw"
+
+const SHIFTER_PRE_SOUND_1P = "Pilot_PhaseShift_PreActivate_1P"
+const SHIFTER_PRE_SOUND_3P = "Pilot_PhaseShift_PreActivate_3P"
+global const SHIFTER_START_SOUND_1P = "Pilot_PhaseShift_Activate_1P"
+global const SHIFTER_START_SOUND_3P = "Pilot_PhaseShift_Activate_3P"
+const SHIFTER_LOOP_SOUND_1P = "Pilot_PhaseShift_Loop_1P"
+const SHIFTER_LOOP_SOUND_3P = "Pilot_PhaseShift_Loop_3P"
+const SHIFTER_PRE_END_SOUND_1P = "Pilot_PhaseShift_WarningToEnd_1P"
+const SHIFTER_PRE_END_SOUND_3P = "Pilot_PhaseShift_WarningToEnd_3P"
+global const SHIFTER_END_SOUND_1P = "Pilot_PhaseShift_End_1P"
+global const SHIFTER_END_SOUND_3P = "Pilot_PhaseShift_End_3P"
+
+const SHIFTER_PRE_SOUND_1P_TITAN = "Pilot_PhaseShift_PreActivate_1P"
+const SHIFTER_PRE_SOUND_3P_TITAN = "Pilot_PhaseShift_PreActivate_3P"
+global const SHIFTER_START_SOUND_1P_TITAN = "titan_phasedash_activate_1p"
+global const SHIFTER_START_SOUND_3P_TITAN = "titan_phasedash_activate_3p"
+const SHIFTER_LOOP_SOUND_1P_TITAN = "titan_phasedash_loop_1p"
+const SHIFTER_LOOP_SOUND_3P_TITAN = "titan_phasedash_loop_3p"
+const SHIFTER_PRE_END_SOUND_1P_TITAN = "titan_phasedash_warningtoend_1p"
+const SHIFTER_PRE_END_SOUND_3P_TITAN = "titan_phasedash_warningtoend_3p"
+global const SHIFTER_END_SOUND_1P_TITAN = "titan_phasedash_end_1p"
+global const SHIFTER_END_SOUND_3P_TITAN = "titan_phasedash_end_3p"
+
+const int TELEFRAG_DAMAGE = 5000;
+
+struct
+{
+} file;
+
+void function CodeCallback_EnterPhaseShift( entity ent )
+{
+ PhaseShift( ent, 0.0, 999.0 )
+}
+
+void function CodeCallback_ExitPhaseShift( entity ent )
+{
+#if SERVER
+ CancelPhaseShift( ent )
+#endif
+}
+
+void function CancelPhaseShift( entity ent )
+{
+ ent.PhaseShiftCancel()
+
+#if SERVER
+ ent.Signal( "ForceStopPhaseShift" )
+ PlayPhaseShiftAppearFX( ent )
+#endif //
+}
+
+
+void function MpAbilityShifter_Init()
+{
+#if CLIENT
+ //ColorCorrection_RegisterRemoteTurret( "materials/correction/remote_turret.raw" )
+
+ ColorCorrection_RegisterPhaseShift( SHIFTER_COLORCORRECTION )
+ thread ClientPhaseShiftFirstPersonFXThread()
+
+ thread ClientRemoteTurretFirstPersonFXThread()
+#endif // #if CLIENT
+
+ PrecacheParticleSystem( SHIFTER_PRE_FX )
+ PrecacheParticleSystem( SHIFTER_APPEAR_FX )
+ PrecacheParticleSystem( SHIFTER_APPEAR_FX_TITAN )
+ PrecacheParticleSystem( SHIFTER_DISAPPEAR_FX )
+ PrecacheParticleSystem( SHIFTER_DISAPPEAR_FX_TITAN )
+ PrecacheParticleSystem( SHIFTER_PERSONAL_FX )
+ PrecacheParticleSystem( SHIFTER_SCREEN_FX )
+ PrecacheParticleSystem( SHIFTER_SCREEN_FX_START )
+
+ MpAbilityShifterWeapon_Init()
+
+ RegisterSignal( "StartPhaseShift" )
+ RegisterSignal( "StopPhaseShift" )
+ RegisterSignal( "ForceStopPhaseShift" )
+}
+
+int function PhaseShift( entity ent, float warmupTime, float duration )
+{
+ if ( !IsAlive( ent ) )
+ return 0
+
+ if ( ent.IsPhaseShifted() )
+ return 0
+
+ // PROTO: this should be better eventually
+ // this is to prevent weirdness if you're already in a context action
+ if ( ent.IsPlayer() )
+ {
+ entity proxy = ent.GetFirstPersonProxy()
+ if ( ( ent.ContextAction_IsActive() || (proxy != null && proxy.Anim_IsActive()) )
+ && !ent.IsZiplining()
+ && !ent.ContextAction_IsLeeching()
+ && ent.GetTitanSoulBeingRodeoed() == null )
+ {
+ return 0
+ }
+
+ ent.PhaseShiftBegin( warmupTime, duration )
+
+ #if SERVER
+ thread ServerPhaseShiftPlayerThread( ent, warmupTime, duration )
+ #else
+ thread ClientPhaseShiftWarmupThread( ent, warmupTime )
+ #endif // #if SERVER
+
+ return 1
+ }
+ else
+ {
+ ent.PhaseShiftBegin( warmupTime, duration )
+
+ #if SERVER
+ thread ServerPhaseShiftPlayerThread( ent, warmupTime, duration )
+ #endif // #if SERVER
+
+ return 1
+ }
+
+ unreachable
+}
+
+#if SERVER
+void function ServerPhaseShiftPlayerThread( entity ent, float warmupTime, float shiftTime )
+{
+ ent.EndSignal( "OnDeath" )
+ ent.EndSignal( "ForceStopPhaseShift" )
+
+ // initialise the two ent.s variables if needed
+ if ( !( "oldPhaseStateLock" in ent.s ) || !( "oldPhaseState" in ent.s ) )
+ {
+ ent.s.oldPhaseStateLock <- false
+ ent.s.oldPhaseState <- false
+ }
+
+ bool keepAnimActive = false
+
+ if ( ent.IsPlayer() )
+ {
+ ent.EndSignal( "player_embarks_titan" )
+
+ Leech_Disallow( ent )
+ // EmitSoundOnEntityExceptToPlayer( ent, ent, SHIFTER_PRE_SOUND_3P )
+
+ entity proxy = ent.GetFirstPersonProxy()
+ if ( proxy != null )
+ proxy.SetForceVisibleInPhaseShift( true )
+
+ if ( Rodeo_IsAttached( ent ) )
+ {
+ if ( ent.GetParent() != null && ent.GetParent().IsPhaseShifted() )
+ keepAnimActive = true
+ else
+ ent.Signal( "RodeoOver" )
+ }
+
+ if ( ent.IsTitan() )
+ {
+ UntrackAllToneMarks( ent )
+ entity titanSoul = ent.GetTitanSoul()
+ if ( titanSoul != null )
+ {
+ if ( titanSoul.soul.batteryContainer != null )
+ {
+ titanSoul.soul.batteryContainer.SetForceVisibleInPhaseShift( true )
+ }
+ }
+ }
+
+ Battery_StopFXAndHideIconForPlayer( ent )
+ }
+ else
+ {
+ if ( ent.IsTitan() )
+ UntrackAllToneMarks( ent )
+ ent.EnableNPCFlag( NPC_IGNORE_ALL )
+ EmitSoundOnEntity( ent, SHIFTER_PRE_SOUND_3P )
+ }
+
+ // only change the oldPhaseState if it's not locked
+ if ( !ent.s.oldPhaseStateLock || !GetConVarBool("ns_use_phase_fix") )
+ {
+ ent.s.oldPhaseStateLock <- true
+ ent.s.oldPhaseState <- ent.GetNoTarget()
+ }
+
+ OnThreadEnd(
+ function() : ( ent )
+ {
+ if ( IsValid( ent ) )
+ {
+ ent.Signal( "StopPhaseShift" )
+ ent.Solid()
+ ent.SetNoTarget( ent.s.oldPhaseState )
+ // unlock the oldPhaseState
+ ent.s.oldPhaseStateLock <- false
+
+ StopSoundOnEntity( ent, SHIFTER_PRE_SOUND_3P )
+ StopSoundOnEntity( ent, SHIFTER_LOOP_SOUND_3P )
+ StopSoundOnEntity( ent, SHIFTER_PRE_SOUND_3P_TITAN )
+ StopSoundOnEntity( ent, SHIFTER_LOOP_SOUND_3P_TITAN )
+
+ ent.DisablePhaseShiftFlags()
+
+ if ( ent.IsPlayer() )
+ {
+ Leech_Allow( ent )
+ UpdatePlayerHighlightsSettings( ent )
+
+ if ( GetSoulFromPlayer( ent ) != null )
+ {
+ entity soul = GetSoulFromPlayer( ent )
+ if ( soul.soul.batteryContainer != null )
+ {
+ soul.soul.batteryContainer.SetForceVisibleInPhaseShift( false )
+ }
+ }
+
+ entity proxy = ent.GetFirstPersonProxy()
+ if ( proxy != null )
+ proxy.SetForceVisibleInPhaseShift( false )
+
+ if ( PlayerHasBattery( ent ) )
+ Battery_StartFX( GetBatteryOnBack( ent ) )
+ }
+ else
+ {
+ ent.DisableNPCFlag( NPC_IGNORE_ALL )
+ Highlight_ClearEnemyHighlight( ent )
+ }
+
+ entity teleFragTarget = ent.GetEntityAtPhaseShiftExitPosition();
+ if ( IsValid( teleFragTarget ) )
+ {
+ if ( !IsHumanSized( teleFragTarget ) )
+ {
+ if ( ShouldEntitySelfKill( ent, teleFragTarget ) )
+ {
+ ent.TakeDamage( ent.GetHealth() + 1, teleFragTarget, teleFragTarget, { damageSourceId = eDamageSourceId.phase_shift, scriptType = DF_GIB | DF_BYPASS_SHIELD | DF_SKIPS_DOOMED_STATE } );
+ }
+ else
+ {
+ printt( "Pushed players apart" )
+ PushPlayersApart( teleFragTarget, ent, 600.0 ) // this will work for NPCs too
+ }
+ }
+ else
+ {
+ teleFragTarget.TakeDamage( teleFragTarget.GetHealth() + 1, ent, ent, { damageSourceId = eDamageSourceId.phase_shift, scriptType = DF_GIB | DF_BYPASS_SHIELD | DF_SKIPS_DOOMED_STATE } );
+ }
+ }
+ }
+ }
+ )
+
+ wait warmupTime
+
+ //thread PROTO_CapVelocity( ent )
+
+ entity soul
+ if ( ent.IsTitan() )
+ {
+ soul = ent.GetTitanSoul()
+ string titanType = GetSoulTitanSubClass( soul )
+ entity rider = GetRodeoPilot( ent )
+ if ( rider != null && Rodeo_IsAttached( rider ) )
+ {
+ if ( !rider.IsPlayer() )
+ rider.Signal( "RodeoOver" )
+ else
+ PhaseShift( rider, 0, shiftTime )
+ }
+ }
+
+ entity fx = PlayPhaseShiftDisappearFX( ent )
+ thread PhaseShiftDisappearEffectCleanup( ent, fx, shiftTime )
+
+ ent.Signal( "StartPhaseShift" )
+ if ( !keepAnimActive )
+ ent.Signal( "ScriptAnimStop" )
+ ent.NotSolid()
+ ent.SetNoTarget( true )
+ ent.EnablePhaseShiftFlags()
+ ent.Highlight_SetCurrentContext( -1 )
+
+ if ( ent.IsPlayer() )
+ {
+ PlayerDropsScriptedItems( ent )
+ if ( ent.IsTitan() )
+ {
+ EmitSoundOnEntityExceptToPlayer( ent, ent, SHIFTER_START_SOUND_3P_TITAN )
+ EmitSoundOnEntityExceptToPlayerNotPredicted( ent, ent, SHIFTER_LOOP_SOUND_3P_TITAN )
+ }
+ else
+ {
+ EmitSoundOnEntityExceptToPlayer( ent, ent, SHIFTER_START_SOUND_3P )
+ EmitSoundOnEntityExceptToPlayerNotPredicted( ent, ent, SHIFTER_LOOP_SOUND_3P )
+ }
+
+ foreach( statusEffect in ent.p.empStatusEffectsToClearForPhaseShift ) //Not great, done to avoid needing code work to get a separate empSlow/empSTurnEffects
+ {
+ StatusEffect_Stop( ent, statusEffect )
+ }
+
+ ent.p.empStatusEffectsToClearForPhaseShift.clear()
+ }
+ else
+ {
+ if ( ent.IsTitan() )
+ {
+ EmitSoundOnEntity( ent, SHIFTER_START_SOUND_3P_TITAN )
+ EmitSoundOnEntity( ent, SHIFTER_LOOP_SOUND_3P_TITAN )
+ }
+ else
+ {
+ EmitSoundOnEntity( ent, SHIFTER_START_SOUND_3P )
+ EmitSoundOnEntity( ent, SHIFTER_LOOP_SOUND_3P )
+ }
+ }
+
+ float FX_WARMUP_TIME = 0.3
+ bool timeAdjusted = false
+
+ if ( shiftTime > FX_WARMUP_TIME )
+ {
+ shiftTime -= FX_WARMUP_TIME // need to play the fx a little earlier so the timing lines up
+ timeAdjusted = true
+ }
+
+ if ( shiftTime >= SHIFTER_OUTRO_TIME_BEFORE_END )
+ {
+ wait ( shiftTime - SHIFTER_OUTRO_TIME_BEFORE_END )
+
+ if ( ent.IsPlayer() )
+ {
+ if ( ent.IsTitan() )
+ {
+ EmitSoundOnEntityOnlyToPlayer( ent, ent, SHIFTER_PRE_END_SOUND_1P_TITAN )
+ EmitSoundOnEntityExceptToPlayer( ent, ent, SHIFTER_PRE_END_SOUND_3P_TITAN )
+ }
+ else
+ {
+ EmitSoundOnEntityOnlyToPlayer( ent, ent, SHIFTER_PRE_END_SOUND_1P )
+ EmitSoundOnEntityExceptToPlayer( ent, ent, SHIFTER_PRE_END_SOUND_3P )
+ }
+
+ }
+ else
+ {
+ if ( ent.IsTitan() )
+ EmitSoundOnEntity( ent, SHIFTER_PRE_END_SOUND_3P_TITAN )
+ else
+ EmitSoundOnEntity( ent, SHIFTER_PRE_END_SOUND_3P )
+ }
+
+ wait SHIFTER_OUTRO_TIME_BEFORE_END
+ }
+ else
+ {
+ wait shiftTime
+ }
+
+ PlayPhaseShiftAppearFX( ent )
+
+ if ( timeAdjusted )
+ wait FX_WARMUP_TIME
+}
+
+// ASSUMES THAT SECOND ENTITY IS NOT HUMAN SIZED
+bool function ShouldEntitySelfKill( entity ent, entity largeTelefragTarget )
+{
+ if ( IsHumanSized( ent ) )
+ return true
+
+ if ( IsSingleplayer() )
+ return false
+
+ return ( DistanceSqr( largeTelefragTarget.GetOrigin(), ent.GetOrigin() ) < 4096.0 )
+}
+
+void function PhaseShiftDisappearEffectCleanup( entity ent, entity fx, float duration )
+{
+ fx.EndSignal( "OnDestroy" )
+ ent.EndSignal( "ForceStopPhaseShift" )
+
+ OnThreadEnd(
+ function() : ( fx )
+ {
+ if ( IsValid( fx ) )
+ {
+ EffectStop( fx )
+ }
+ }
+ )
+
+ float bufferTime = 1.4
+ if ( ent.IsTitan() )
+ bufferTime = 0.0
+
+ wait max( duration - bufferTime, 0.0 )
+}
+
+entity function PlayPhaseShiftAppearFX( entity ent )
+{
+ asset effect = SHIFTER_APPEAR_FX
+ if ( !IsHumanSized( ent ) )
+ effect = SHIFTER_APPEAR_FX_TITAN
+
+ if ( ent.IsPlayer() )
+ {
+ if ( ent.IsTitan() )
+ EmitSoundOnEntityExceptToPlayer( ent, ent, SHIFTER_END_SOUND_3P_TITAN )
+ else
+ EmitSoundOnEntityExceptToPlayer( ent, ent, SHIFTER_END_SOUND_3P )
+
+ return PlayFXOnEntityForEveryoneExceptPlayer( effect, ent, ent )
+ }
+ else
+ {
+ if ( ent.IsTitan() )
+ EmitSoundOnEntity( ent, SHIFTER_END_SOUND_3P_TITAN )
+ else
+ EmitSoundOnEntity( ent, SHIFTER_END_SOUND_3P )
+ return PlayFXOnEntity( effect, ent )
+ }
+}
+
+entity function PlayPhaseShiftDisappearFX( entity ent )
+{
+ asset effect = SHIFTER_DISAPPEAR_FX
+ if ( !IsHumanSized( ent ) )
+ effect = SHIFTER_DISAPPEAR_FX_TITAN
+
+ int fxid = GetParticleSystemIndex( effect )
+ int attachId = ent.LookupAttachment( "ORIGIN" )
+
+ return StartParticleEffectOnEntity_ReturnEntity( ent, fxid, FX_PATTACH_POINT_FOLLOW, attachId )
+}
+
+array<entity> function GetAttachedEnts( entity ent )
+{
+ array<entity> ents = [ ent ]
+
+ if ( HasSoul( ent ) )
+ {
+ entity soul = ent.GetTitanSoul()
+ if ( IsValid( soul.soul.batteryContainer ) )
+ ents.append( soul.soul.batteryContainer )
+ }
+
+ entity weapon = ent.GetActiveWeapon()
+ if ( IsValid( weapon ) )
+ ents.append( weapon )
+
+ return ents
+}
+
+/*
+void function PROTO_CapVelocity( player )
+{
+ player.EndSignal( "OnDeath" )
+ player.EndSignal( "StopPhaseShift" )
+
+ while( 1 )
+ {
+ local newVel = player.GetVelocity()
+ local zVel = newVel.z
+ newVel = Vector( newVel.x, newVel.y, 0 )
+ local speed = Length( newVel )
+ newVel = Normalize( newVel )
+ speed = min( speed, 400 )
+ newVel = newVel * speed
+ player.SetVelocity( Vector(newVel.x,newVel.y,zVel) )
+ WaitFrame()
+ }
+}
+*/
+
+void function UntrackAllToneMarks( entity ent )
+{
+ if ( IsSingleplayer() ) //JFS::Probably want to remove this for R3
+ return
+
+ array<entity> enemyTitans = GetTitanArrayOfEnemies( ent.GetTeam() )
+ foreach( titan in enemyTitans )
+ {
+ entity offhand = titan.GetOffhandWeapon( OFFHAND_RIGHT )
+ if ( !IsValid( offhand ) )
+ return
+
+ if ( offhand.GetWeaponClassName() != "mp_titanweapon_tracker_rockets" )
+ continue
+
+ offhand.SmartAmmo_UntrackEntity( ent )
+ }
+}
+#endif // #if SERVER
+
+
+#if CLIENT
+void function ClientPhaseShiftWarmupThread( entity player, float warmupTime )
+{
+ player.EndSignal( "OnDeath" )
+
+ if ( player != GetLocalViewPlayer() )
+ return
+ if ( InPrediction() && !IsFirstTimePredicted() )
+ return
+
+ if ( warmupTime <= 0 )
+ return
+
+ int index = GetParticleSystemIndex( SHIFTER_PRE_FX )
+ int fxID = StartParticleEffectInWorldWithHandle( index, ZERO_VECTOR, ZERO_VECTOR )
+
+ OnThreadEnd(
+ function() : ( fxID )
+ {
+ EffectStop( fxID, true, true );
+ }
+ )
+
+ if ( player.IsTitan() )
+ EmitSoundOnEntity( player, SHIFTER_PRE_SOUND_1P_TITAN )
+ else
+ EmitSoundOnEntity( player, SHIFTER_PRE_SOUND_1P )
+
+ wait warmupTime
+}
+
+void function ClientPhaseShiftFirstPersonFXThread()
+{
+ int effectSparkles;
+ int effectScreen;
+ bool effectsAreActive = false;
+ bool endSoundPlayed = false;
+ entity ourPlayer = null;
+
+ while( true )
+ {
+ if ( effectsAreActive )
+ {
+ entity localViewPlayer = GetLocalViewPlayer();
+
+ bool needShutdown = false;
+ if ( !IsValid( ourPlayer ) || !IsAlive( ourPlayer ) )
+ needShutdown = true;
+ else if ( ourPlayer != localViewPlayer )
+ needShutdown = true;
+ else if ( !ourPlayer.IsPhaseShifted() )
+ needShutdown = true;
+
+ if ( needShutdown )
+ {
+ if ( IsValid( ourPlayer ) && (ourPlayer == localViewPlayer) )
+ {
+ // FX
+ {
+ int fxIndex = GetParticleSystemIndex( SHIFTER_SCREEN_FX_START )
+ StartParticleEffectInWorldWithHandle( fxIndex, ZERO_VECTOR, ZERO_VECTOR )
+ }
+
+ // FX
+ {
+ int fxIndex = GetParticleSystemIndex( SHIFTER_APPEAR_FX )
+ vector viewAngles = ourPlayer.EyeAngles()
+ vector viewForward = AnglesToForward( viewAngles )
+ vector viewForward2d = Normalize( Vector( viewForward.x, viewForward.y, 0.0 ) )
+ StartParticleEffectOnEntityWithPos( ourPlayer, fxIndex, FX_PATTACH_ABSORIGIN, -1, (viewForward2d * 30), ZERO_VECTOR )
+ }
+
+ if ( ourPlayer.IsTitan() )
+ {
+ EmitSoundOnEntity( ourPlayer, SHIFTER_END_SOUND_1P_TITAN )
+ }
+ else
+ {
+ EmitSoundOnEntity( ourPlayer, SHIFTER_END_SOUND_1P )
+ }
+ StopSoundOnEntity( ourPlayer, SHIFTER_LOOP_SOUND_1P )
+ StopSoundOnEntity( ourPlayer, SHIFTER_LOOP_SOUND_1P_TITAN )
+ }
+
+ ClientPhaseShift_SCRIPT_HACKS_OFF()
+
+ EffectStop( effectSparkles, true, true )
+ EffectStop( effectScreen, true, true )
+ effectsAreActive = false;
+ ourPlayer = null;
+ endSoundPlayed = false;
+ }
+ else if ( IsValid( localViewPlayer ) && localViewPlayer.IsPhaseShifted() )
+ {
+ if ( !endSoundPlayed && (localViewPlayer.PhaseShiftTimeRemaining() <= SHIFTER_OUTRO_TIME_BEFORE_END) )
+ {
+ endSoundPlayed = true;
+ if ( localViewPlayer.IsTitan() )
+ EmitSoundOnEntity( localViewPlayer, SHIFTER_PRE_END_SOUND_1P_TITAN )
+ else
+ EmitSoundOnEntity( localViewPlayer, SHIFTER_PRE_END_SOUND_1P )
+ }
+ }
+
+ }
+
+ if ( !effectsAreActive )
+ {
+ entity localViewPlayer = GetLocalViewPlayer();
+
+ if ( IsValid( localViewPlayer ) && localViewPlayer.IsPhaseShifted() )
+ {
+ // FX
+ {
+ int fxIndex = GetParticleSystemIndex( SHIFTER_PERSONAL_FX )
+ int attachIdx = localViewPlayer.LookupAttachment( "CHESTFOCUS" )
+ effectSparkles = StartParticleEffectOnEntity( localViewPlayer, fxIndex, FX_PATTACH_POINT_FOLLOW, attachIdx )
+ }
+
+ // FX
+ {
+ int fxIndex = GetParticleSystemIndex( SHIFTER_SCREEN_FX )
+ effectScreen = StartParticleEffectInWorldWithHandle( fxIndex, ZERO_VECTOR, ZERO_VECTOR )
+ }
+
+ // FX
+ {
+ int fxIndex = GetParticleSystemIndex( SHIFTER_SCREEN_FX_START )
+ StartParticleEffectInWorldWithHandle( fxIndex, ZERO_VECTOR, ZERO_VECTOR )
+ }
+
+ // FX
+ {
+ entity viewModelEntity = localViewPlayer.GetViewModelEntity()
+ entity firstPersonProxy = localViewPlayer.GetPredictedFirstPersonProxy()
+
+ if ( IsValid( viewModelEntity ) )
+ {
+ viewModelEntity.Highlight_HideInside( 0.0 )
+ viewModelEntity.Highlight_HideOutline( 0.0 )
+ }
+
+ if ( IsValid( firstPersonProxy ) )
+ {
+ firstPersonProxy.Highlight_HideInside( 0.0 )
+ firstPersonProxy.Highlight_HideOutline( 0.0 )
+ }
+ }
+
+ ClientPhaseShift_SCRIPT_HACKS_ON()
+
+ if ( localViewPlayer.IsTitan() )
+ EmitSoundOnEntity( localViewPlayer, SHIFTER_START_SOUND_1P_TITAN )
+ else
+ EmitSoundOnEntity( localViewPlayer, SHIFTER_START_SOUND_1P )
+
+ if ( localViewPlayer.IsTitan() )
+ EmitSoundOnEntity( localViewPlayer, SHIFTER_LOOP_SOUND_1P_TITAN )
+ else
+ EmitSoundOnEntity( localViewPlayer, SHIFTER_LOOP_SOUND_1P )
+
+ effectsAreActive = true;
+ ourPlayer = localViewPlayer;
+ }
+ }
+
+ WaitFrame()
+ }
+}
+
+void function ClientRemoteTurretFirstPersonFXThread()
+{
+ int effectSparkles;
+ int effectScreen;
+ bool effectsAreActive = false;
+ entity ourPlayer = null;
+
+ const string TURRET_LOOP_SOUND = "Pilot_RemoteTurret_Loop_1P"
+
+ while( true )
+ {
+ if ( effectsAreActive )
+ {
+ entity localViewPlayer = GetLocalViewPlayer();
+
+ bool needShutdown = false;
+ if ( !IsValid( ourPlayer ) || !IsAlive( ourPlayer ) )
+ needShutdown = true;
+ else if ( ourPlayer != localViewPlayer )
+ needShutdown = true;
+ else if ( ourPlayer.GetRemoteTurret() == null )
+ needShutdown = true;
+
+ if ( needShutdown )
+ {
+ if ( IsValid( ourPlayer ) && (ourPlayer == localViewPlayer) )
+ StopSoundOnEntity( ourPlayer, TURRET_LOOP_SOUND )
+
+ effectsAreActive = false;
+ ourPlayer = null;
+ }
+ }
+
+ if ( !effectsAreActive )
+ {
+ entity localViewPlayer = GetLocalViewPlayer();
+ if ( IsValid( localViewPlayer ) && (localViewPlayer.GetRemoteTurret() != null) )
+ {
+ EmitSoundOnEntity( localViewPlayer, TURRET_LOOP_SOUND )
+ effectsAreActive = true;
+ ourPlayer = localViewPlayer;
+ }
+ }
+
+ WaitFrame()
+ }
+}
+
+void function ClientPhaseShift_SCRIPT_HACKS_ON()
+{
+ entity localViewPlayer = GetLocalViewPlayer();
+
+ localViewPlayer.Signal( "StartPhaseShift" )
+
+ if ( localViewPlayer == GetLocalClientPlayer() )
+ {
+ //localViewPlayer.cv.PlayerPetTitanIcon.Hide()
+ //localViewPlayer.cv.PlayerPetTitanArrow.Hide()
+ //localViewPlayer.cv.PlayerPetTitanLabel.Hide()
+ }
+}
+
+void function ClientPhaseShift_SCRIPT_HACKS_OFF()
+{
+ entity localViewPlayer = GetLocalViewPlayer();
+
+ if ( localViewPlayer == GetLocalClientPlayer() )
+ UpdatePetTitanIcon( localViewPlayer )
+
+ //It would be great if we could automatically hide icons using SetEntityOverhead if that entity is phased out.
+ // if ( GameRules_GetGameMode() == SURVIVOR )
+ // DisplayScrapCounter( GetLocalClientPlayer(), LIFE_ALIVE, LIFE_ALIVE )
+}
+
+#endif // #if CLIENT
|