aboutsummaryrefslogtreecommitdiff
path: root/Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_lts.nut
blob: 82c304b6926ae5701af64a124db4cd33c08481df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
untyped
global function GamemodeLts_Init

struct {
	entity lastDamageInfoVictim
	entity lastDamageInfoAttacker
	int lastDamageInfoMethodOfDeath
	float lastDamageInfoTime
	
	bool shouldDoHighlights
} file

void function GamemodeLts_Init()
{
	// gamemode settings
	SetShouldUsePickLoadoutScreen( true )
	SetSwitchSidesBased( true )
	SetRoundBased( true )
	SetRespawnsEnabled( false )
	Riff_ForceSetEliminationMode( eEliminationMode.PilotsTitans )
	SetShouldUseRoundWinningKillReplay( true )
	SetRoundWinningKillReplayKillClasses( true, true ) // both titan and pilot kills are tracked
	
	AddDamageCallback( "player", OnPlayerDamaged )
	AddDamageCallback( "npc_titan", OnTitanDamaged )
	
	AddCallback_OnPilotBecomesTitan( RefreshThirtySecondWallhackHighlight )
	AddCallback_OnTitanBecomesPilot( RefreshThirtySecondWallhackHighlight )
	
	SetTimeoutWinnerDecisionFunc( CheckTitanHealthForDraw )
	
	ClassicMP_SetCustomIntro( GamemodeLTS_Intro, 0.0 ) // dont any sorta timer
}

// this should also probably be moved into a generic intro rather than being lts-specific
void function GamemodeLTS_Intro()
{
	AddCallback_GameStateEnter( eGameState.Prematch, LTSIntroOnPrematchStart )
}

void function LTSIntroOnPrematchStart()
{
	ClassicMP_OnIntroStarted()

	foreach ( entity player in GetPlayerArray() )
		thread LTSIntroSpawnPlayer( player )
	
	wait 2.0 // literally a guess number for how long the drop might take
	
	ClassicMP_OnIntroFinished()
	
	thread GamemodeLTS_PlayingThink()
}

void function LTSIntroSpawnPlayer( entity player )
{
	if ( IsAlive( player ) )
	{
		player.Die()
		WaitFrame() // this doesn't work for some reason but the player will die in roundend anyway so not really an issue
	}

	thread RespawnAsTitan( player, false )

	while ( !player.IsTitan() )
		WaitFrame()
		
	TryGameModeAnnouncement( player )
}

void function GamemodeLTS_PlayingThink()
{
	svGlobal.levelEnt.EndSignal( "RoundEnd" ) // end this on round end
	
	float endTime = expect float ( GetServerVar( "roundEndTime" ) )
	
	// wait until 30sec left 
	wait ( endTime - 30 ) - Time()
	foreach ( entity player in GetPlayerArray() )
	{	
		// warn there's 30 seconds left
		Remote_CallFunction_NonReplay( player, "ServerCallback_LTSThirtySecondWarning" )
		
		// do initial highlight
		RefreshThirtySecondWallhackHighlight( player, null )
	}
}

void function RefreshThirtySecondWallhackHighlight( entity player, entity titan )
{
	if ( TimeSpentInCurrentState() < expect float ( GetServerVar( "roundEndTime" ) ) - 30.0 )
		return
		
	Highlight_SetEnemyHighlight( player, "enemy_sonar" ) // i think this needs a different effect, this works for now tho
		
	if ( player.GetPetTitan() != null )
		Highlight_SetEnemyHighlight( player.GetPetTitan(), "enemy_sonar" )
}

int function CheckTitanHealthForDraw()
{
	int militiaTitans
	int imcTitans
	
	float militiaHealth
	float imcHealth
	
	foreach ( entity titan in GetTitanArray() )
	{
		if ( titan.GetTeam() == TEAM_MILITIA )
		{
			// doomed is counted as 0 health
			militiaHealth += titan.GetTitanSoul().IsDoomed() ? 0.0 : GetHealthFrac( titan )
			militiaTitans++
		}
		else
		{
			// doomed is counted as 0 health in this
			imcHealth += titan.GetTitanSoul().IsDoomed() ? 0.0 : GetHealthFrac( titan )
			imcTitans++
		}
	}
	
	// note: due to how stuff is set up rn, there's actually no way to do win/loss reasons in timeout decision funcs
	// as soon as there is, strings in question are "#GAMEMODE_TITAN_TITAN_ADVANTAGE" and "#GAMEMODE_TITAN_TITAN_DISADVANTAGE"
	
	if ( militiaTitans != imcTitans )
		return militiaTitans > imcTitans ? TEAM_MILITIA : TEAM_IMC
	else if ( militiaHealth != imcHealth )
		return militiaHealth > imcHealth ? TEAM_MILITIA : TEAM_IMC
		
	return TEAM_UNASSIGNED
}

// this should be generic, not restricted to a specific gamemode
void function AddToTitanDamageStat( entity victim, var damageInfo )
{
	// todo: this needs to not count selfdamage
	entity attacker = DamageInfo_GetAttacker( damageInfo )
	float amount = DamageInfo_GetDamage( damageInfo )

	if ( attacker.IsPlayer() && attacker != victim )
		attacker.AddToPlayerGameStat( PGS_ASSAULT_SCORE, amount ) // titan damage on 
}

void function OnPlayerDamaged( entity player, var damageInfo )
{
	if ( player.IsTitan() )
		AddToTitanDamageStat( player, damageInfo )
}

void function OnTitanDamaged( entity titan, var damageInfo )
{
	AddToTitanDamageStat( titan, damageInfo ) 
}