aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd.nut222
1 files changed, 183 insertions, 39 deletions
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd.nut
index bff0ebab..a89d5a30 100644
--- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd.nut
@@ -40,6 +40,7 @@ global struct SoundEvent{
global struct WaveEvent{
void functionref(SmokeEvent,SpawnEvent,WaitEvent,SoundEvent) eventFunction
+ bool shouldThread
SmokeEvent smokeEvent
SpawnEvent spawnEvent
WaitEvent waitEvent
@@ -56,8 +57,20 @@ global table<string,array<vector> > routes
struct player_struct_fd{
bool diedThisRound
- int scoreThisRound
-
+ float scoreThisRound
+ int totalMVPs
+ int mortarUnitsKilled
+ int moneySpend
+ int coresUsed
+ float longestTitanLife
+ int turretsRepaired
+ int moneyShared
+ float timeNearHarvester
+ float longestLife
+ int heals
+ int titanKills
+ float damageDealt
+ int harvesterHeals
}
@@ -65,7 +78,7 @@ struct {
array<entity> aiSpawnpoints
array<entity> smokePoints
array<entity> routeNodes
- table<string,float> harvesterDamageSource
+ array<float> harvesterDamageSource
bool havesterWasDamaged
array<entity> spawnedNPCs
table<entity,player_struct_fd> players
@@ -79,11 +92,13 @@ void function GamemodeFD_Init()
RegisterSignal("FD_ReachedHarvester")
RegisterSignal("OnFailedToPath")
+
SetRoundBased(true)
SetShouldUseRoundWinningKillReplay(false)
-
Riff_ForceBoostAvailability( eBoostAvailability.Disabled )
PlayerEarnMeter_SetEnabled(false)
+ SetShouldUsePickLoadoutScreen( true )
+
AddCallback_EntitiesDidLoad(LoadEntities)
AddDamageCallback("prop_script",OnDamagedPropScript)
@@ -91,7 +106,9 @@ void function GamemodeFD_Init()
AddCallback_GameStateEnter( eGameState.Playing,startMainGameLoop)
AddCallback_OnClientConnected(GamemodeFD_InitPlayer)
AddCallback_OnPlayerKilled(GamemodeFD_OnPlayerKilled)
-
+ AddCallback_OnRoundEndCleanup(FD_NPCCleanup)
+ AddDamageByCallback("player",FD_DamageByPlayerCallback)
+
AddDeathCallback("npc_titan",OnNpcDeath)
AddDeathCallback("npc_stalker",OnNpcDeath)
@@ -100,25 +117,39 @@ void function GamemodeFD_Init()
AddDeathCallback("npc_soldier",OnNpcDeath)
AddDeathCallback("npc_frag_drone",OnNpcDeath)
AddDeathCallback("npc_drone",OnNpcDeath)
+ SetUsedCoreCallback(FD_UsedCoreCallback)
AddClientCommandCallback("FD_ToggleReady",ClientCommandCallbackToggleReady)
AddClientCommandCallback("FD_UseHarvesterShieldBoost",useShieldBoost)
+
+
+
}
+
void function GamemodeFD_OnPlayerKilled(entity victim, entity attacker, var damageInfo)
{
file.players[victim].diedThisRound = true
}
+void function FD_UsedCoreCallback(entity titan,entity weapon)
+{
+ if(!(titan in file.players))
+ {
+ return
+ }
+ file.players[titan].coresUsed += 1
+}
+
void function GamemodeFD_InitPlayer(entity player)
{
player_struct_fd data
data.diedThisRound = false
data.scoreThisRound = 0
file.players[player] <- data
-}
-
+
+}
void function OnNpcDeath( entity ent, var damageInfo )
{
@@ -127,7 +158,7 @@ void function OnNpcDeath( entity ent, var damageInfo )
{
file.spawnedNPCs.remove( findIndex )
}
- printt("callback")
+
}
void function RateSpawnpoints_FD(int _0, array<entity> _1, int _2, entity _3){}
@@ -140,6 +171,7 @@ bool function useShieldBoost(entity player,array<string> args)
SetGlobalNetTime("FD_harvesterInvulTime",Time()+5)
MessageToTeam(TEAM_MILITIA,eEventNotifications.FD_PlayerHealedHarvester)
player.SetPlayerNetInt( "numHarvesterShieldBoost", player.GetPlayerNetInt( "numHarvesterShieldBoost" ) - 1 )
+ file.players[player].harvesterHeals += 1
}
return true
}
@@ -279,11 +311,12 @@ array<int> function getEnemyTypesForWave(int wave)
bool function runWave(int waveIndex,bool shouldDoBuyTime)
{
-
-
-
SetGlobalNetInt("FD_currentWave",waveIndex)
file.havesterWasDamaged = false
+ for(int i = 0; i<20;i++)//Number of npc type ids
+ {
+ file.harvesterDamageSource.append(0.0)
+ }
foreach(player_struct_fd player in file.players)
{
player.diedThisRound = false
@@ -327,18 +360,51 @@ bool function runWave(int waveIndex,bool shouldDoBuyTime)
foreach(WaveEvent event in waveEvents[waveIndex])
{
- event.eventFunction(event.smokeEvent,event.spawnEvent,event.waitEvent,event.soundEvent)
+ if(event.shouldThread)
+ thread event.eventFunction(event.smokeEvent,event.spawnEvent,event.waitEvent,event.soundEvent)
+ else
+ event.eventFunction(event.smokeEvent,event.spawnEvent,event.waitEvent,event.soundEvent)
if(!IsAlive(fd_harvester.harvester))
- return false
- waitUntilLessThanAmountAlive(0)
- }
- if(!IsAlive(fd_harvester.harvester))
- {
-
+ break
+
}
-
+ waitUntilLessThanAmountAlive_expensive(0)
if(!IsAlive(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
@@ -365,7 +431,7 @@ bool function runWave(int waveIndex,bool shouldDoBuyTime)
EmitSoundOnEntityOnlyToPlayer(player,player,"HUD_MP_BountyHunt_BankBonusPts_Deposit_Start_1P")
}
wait 1
- int highestScore = 0;
+ float highestScore = 0;
entity highestScore_player = GetPlayerArray()[0]
foreach(entity player in GetPlayerArray())
{
@@ -382,6 +448,7 @@ bool function runWave(int waveIndex,bool shouldDoBuyTime)
}
wait 1
+ file.players[highestScore_player].totalMVPs += 1
AddPlayerScore(highestScore_player,"FDWaveMVP")
AddMoneyToPlayer(highestScore_player,100)
EmitSoundOnEntityOnlyToPlayer(highestScore_player,highestScore_player,"HUD_MP_BountyHunt_BankBonusPts_Deposit_Start_1P")
@@ -447,13 +514,17 @@ void function OnDamagedPropScript(entity prop,var damageInfo)
fd_harvester.lastDamage = Time()
if(prop.GetShieldHealth()==0)
{
+ int attackerID = FD_GetAITypeID_ByString(attacker.GetTargetName())
+ file.harvesterDamageSource[attackerID] += damageAmount
+
+
float newHealth = prop.GetHealth()-damageAmount
if(newHealth<0)
{
EmitSoundAtPosition(TEAM_UNASSIGNED,fd_harvester.harvester.GetOrigin(),"coop_generator_destroyed")
newHealth=0
- fd_harvester.rings.Destroy()
+ fd_harvester.rings.Destroy()//TODO death animation
}
prop.SetHealth(newHealth)
@@ -466,7 +537,7 @@ void function OnDamagedPropScript(entity prop,var damageInfo)
void function FD_NPCCleanup()
{
- foreach(entity npc in file.spawnedNPCs){
+ foreach(entity npc in GetEntArrayByClass_Expensive("C_AI_BaseNPC")){
if(IsValid(npc))
npc.Destroy()
}
@@ -566,7 +637,7 @@ void function initNetVars()
{
bool showShop = false
SetGlobalNetInt("FD_currentWave",0)
- if(GetCurrentPlaylistVarInt("fd_difficulty",0)>=5)
+ if(FD_IsDifficultyLevelOrHigher(eFDDifficultyLevel.INSANE))
FD_SetNumAllowedRestarts(0)
else
FD_SetNumAllowedRestarts(2)
@@ -574,6 +645,17 @@ void function initNetVars()
}
+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.players[player].damageDealt += damage
+ file.players[player].scoreThisRound += damage //TODO NOT HOW SCORE WORKS
+
+}
+
void function FD_createHarvester()
{
HarvesterStruct ret = SpawnHarvester(file.harvester_info.GetOrigin(),file.harvester_info.GetAngles(),25000,6000,TEAM_MILITIA)
@@ -622,7 +704,7 @@ void function LoadEntities()
initNetVars()
}
-void function titanNav_thread(entity titan, string routeName)
+void function titanNav_thread(entity titan, string routeName,float nextDistance = 500.0)
{
titan.EndSignal( "OnDeath" )
titan.EndSignal( "OnDestroy" )
@@ -644,15 +726,16 @@ void function titanNav_thread(entity titan, string routeName)
foreach(entity node in routeArray)
{
-
+ if(!IsAlive(fd_harvester.harvester))
+ return
if(Distance(fd_harvester.harvester.GetOrigin(),titan.GetOrigin())<Distance(fd_harvester.harvester.GetOrigin(),node.GetOrigin()))
continue
titan.AssaultPoint(node.GetOrigin())
int i = 0
- while((Distance(titan.GetOrigin(),node.GetOrigin())>500))
+ while((Distance(titan.GetOrigin(),node.GetOrigin())>nextDistance))
{
WaitFrame()
- printt(Distance(titan.GetOrigin(),node.GetOrigin()))
+ //printt(Distance(titan.GetOrigin(),node.GetOrigin()))
// i++
// if(i>1200)
// {
@@ -678,11 +761,45 @@ bool function ClientCommandCallbackToggleReady( entity player, array<string> arg
{
if(args[0]=="true")
player.SetPlayerNetBool("FD_readyForNextWave",true)
- if(args[0]=="flase")
+ if(args[0]=="false")
player.SetPlayerNetBool("FD_readyForNextWave",false)
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
+}
+
/****************************************************************************************************************\
####### # # ####### # # ####### ##### ####### # # ####### ###### # ####### ####### ######
# # # # ## # # # # # ## # # # # # # # # # # #
@@ -697,6 +814,7 @@ WaveEvent function createSmokeEvent(vector position,float lifetime)
{
WaveEvent event
event.eventFunction = spawnSmoke
+ event.shouldThread = true
event.smokeEvent.position = position
event.smokeEvent.lifetime = lifetime
return event
@@ -706,6 +824,7 @@ WaveEvent function createArcTitanEvent(vector origin,vector angles,string route)
{
WaveEvent event
event.eventFunction = spawnArcTitan
+ event.shouldThread = true
event.spawnEvent.spawnType= eFD_AITypeIDs.TITAN_ARC
event.spawnEvent.spawnAmount = 1
event.spawnEvent.origin = origin
@@ -718,6 +837,7 @@ WaveEvent function createSuperSpectreEvent(vector origin,vector angles,string ro
{
WaveEvent event
event.eventFunction = spawnSuperSpectre
+ event.shouldThread = true
event.spawnEvent.spawnType= eFD_AITypeIDs.REAPER
event.spawnEvent.spawnAmount = 1
event.spawnEvent.origin = origin
@@ -730,6 +850,7 @@ WaveEvent function createDroppodGruntEvent(vector origin,string route)
{
WaveEvent event
event.eventFunction = spawnDroppodGrunts
+ event.shouldThread = true
event.spawnEvent.spawnType= eFD_AITypeIDs.GRUNT
event.spawnEvent.spawnAmount = 4
event.spawnEvent.origin = origin
@@ -741,6 +862,7 @@ WaveEvent function createDroppodStalkerEvent(vector origin,string route)
{
WaveEvent event
event.eventFunction = spawnDroppodStalker
+ event.shouldThread = true
event.spawnEvent.spawnType= eFD_AITypeIDs.STALKER
event.spawnEvent.spawnAmount = 4
event.spawnEvent.origin = origin
@@ -752,6 +874,7 @@ WaveEvent function createDroppodSpectreMortarEvent(vector origin,string route)
{
WaveEvent event
event.eventFunction = spawnDroppodSpectreMortar
+ event.shouldThread = true
event.spawnEvent.spawnType= eFD_AITypeIDs.SPECTRE_MORTAR
event.spawnEvent.spawnAmount = 4
event.spawnEvent.origin = origin
@@ -762,6 +885,7 @@ WaveEvent function createDroppodSpectreMortarEvent(vector origin,string route)
WaveEvent function createWaitForTimeEvent(float amount)
{
WaveEvent event
+ event.shouldThread = false
event.eventFunction = waitForTime
event.waitEvent.amount = amount
return event
@@ -771,6 +895,7 @@ WaveEvent function createWaitUntilAliveEvent(int amount)
{
WaveEvent event
event.eventFunction = waitUntilLessThanAmountAliveEvent
+ event.shouldThread = false
event.waitEvent.amount = amount.tofloat()
return event
}
@@ -779,6 +904,7 @@ WaveEvent function createGenericSpawnEvent(string npcClassName,vector origin,vec
{
WaveEvent event
event.eventFunction = spawnGenericNPC
+ event.shouldThread = true
event.spawnEvent.npcClassName = npcClassName
event.spawnEvent.origin = origin
event.spawnEvent.angles = angles
@@ -792,6 +918,7 @@ WaveEvent function createGenericTitanSpawnWithAiSettingsEvent(string npcClassNam
{
WaveEvent event
event.eventFunction = spawnGenericNPCTitanwithSettings
+ event.shouldThread = true
event.spawnEvent.npcClassName = npcClassName
event.spawnEvent.aiSettings = aiSettings
event.spawnEvent.origin = origin
@@ -806,6 +933,7 @@ WaveEvent function createNukeTitanEvent(vector origin,vector angles,string route
{
WaveEvent event
event.eventFunction = spawnNukeTitan
+ event.shouldThread = true
event.spawnEvent.spawnType= eFD_AITypeIDs.TITAN_NUKE
event.spawnEvent.spawnAmount = 1
event.spawnEvent.origin = origin
@@ -818,6 +946,7 @@ WaveEvent function createMortarTitanEvent(vector origin,vector angles)
{
WaveEvent event
event.eventFunction = spawnMortarTitan
+ event.shouldThread = true
event.spawnEvent.spawnType= eFD_AITypeIDs.TITAN_MORTAR
event.spawnEvent.spawnAmount = 1
event.spawnEvent.origin = origin
@@ -826,8 +955,9 @@ WaveEvent function createMortarTitanEvent(vector origin,vector angles)
}
WaveEvent function createCloakDroneEvent(vector origin,vector angles){
- WaveEvent event
+ WaveEvent event
event.eventFunction = fd_spawnCloakDrone
+ event.shouldThread = true
event.spawnEvent.spawnType= eFD_AITypeIDs.DRONE_CLOAK
event.spawnEvent.spawnAmount = 1
event.spawnEvent.origin = origin
@@ -865,11 +995,11 @@ void function spawnArcTitan(SmokeEvent smokeEvent,SpawnEvent spawnEvent,WaitEven
{
PingMinimap(spawnEvent.origin.x, spawnEvent.origin.y, 4, 600, 150, 0)
entity npc = CreateArcTitan(TEAM_IMC,spawnEvent.origin,spawnEvent.angles)
- thread titanNav_thread(npc,spawnEvent.route)
- SetSpawnOption_Titanfall(npc)
- npc.DisableNPCFlag(NPC_ALLOW_INVESTIGATE | NPC_USE_SHOOTING_COVER|NPC_ALLOW_PATROL)
+ file.spawnedNPCs.append(npc)
DispatchSpawn(npc)
- file.spawnedNPCs.append(npc)
+ npc.DisableNPCFlag(NPC_ALLOW_INVESTIGATE | NPC_USE_SHOOTING_COVER|NPC_ALLOW_PATROL)
+ SetSpawnOption_Titanfall(npc)
+ thread titanNav_thread(npc,spawnEvent.route)
thread EMPTitanThinkConstant(npc)
}
@@ -992,7 +1122,7 @@ void function spawnSuperSpectre_threaded(entity npc)
wait 4.7
DispatchSpawn(npc)
thread SuperSpectre_WarpFall(npc)
- thread Reaper_LaunchFragDrone_Think( npc, "npc_frag_drone_fd")
+ thread ReaperMinionLauncherThink(npc)
}
void function CreateTrackedDroppodSoldier( vector origin, int team)
@@ -1084,17 +1214,31 @@ void function PingMinimap(float x, float y, float duration, float spreadRadius,
}
void function waitUntilLessThanAmountAlive(int amount)
-{
+{
+ printt("start wait")
int aliveTitans = file.spawnedNPCs.len()
while(aliveTitans>amount)
{
- printt("Titans alive",aliveTitans,amount)
WaitFrame()
aliveTitans = file.spawnedNPCs.len()
if(!IsAlive(fd_harvester.harvester))
break
-
+ printt("titans alive ", aliveTitans)
+ }
+}
+
+void function waitUntilLessThanAmountAlive_expensive(int amount)
+{
+ printt("start wait")
+ int aliveTitans = GetEntArrayByClassWildCard_Expensive("*npc*").len()
+
+ while(aliveTitans>amount)
+ {
+ WaitFrame()
+ aliveTitans = GetEntArrayByClassWildCard_Expensive("*npc*").len()
+ if(!IsAlive(fd_harvester.harvester))
+ break
+ printt("titans alive ", aliveTitans)
}
- printt("Titans alive end",aliveTitans,amount)
} \ No newline at end of file