aboutsummaryrefslogtreecommitdiff
path: root/Northstar.CustomServers/mod/scripts/vscripts/earn_meter/sv_earn_meter_mp.gnut
blob: 21723ab5d5ec766d23fd954115b3931ead0f3987 (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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
untyped
global function Sv_EarnMeterMP_Init
global function EarnMeterMP_SetTitanLoadout
global function EarnMeterMP_SetPassiveMeterGainEnabled
global function EarnMeterMP_SetBoostByRef

struct {
	float playingStartTime
	bool passiveMeterGainEnabled = true
} file

void function Sv_EarnMeterMP_Init()
{
	if ( !EARNMETER_ENABLED )
		return

	AddCallback_OnClientConnected( SetupPlayerEarnMeter )
	AddCallback_GameStateEnter( eGameState.Playing, OnPlaying ) // can't change boost after prematch
	AddCallback_OnPlayerRespawned( OnPlayerRespawned )
}

void function EarnMeterMP_SetTitanLoadout( entity player )
{
	if ( EarnMeterMP_IsTitanEarnGametype() )
		PlayerEarnMeter_SetGoal( player, EarnObject_GetByRef( GetTitanLoadoutForPlayer( player ).titanClass ) )
	else
		PlayerEarnMeter_SetGoal( player, PlayerEarnMeter_GetReward( player ) )
}

void function EarnMeterMP_SetPassiveMeterGainEnabled( bool enabled )
{
	file.passiveMeterGainEnabled = enabled
}

void function SetupPlayerEarnMeter( entity player )
{
	PlayerEarnMeter_Reset( player )

	string burncardRef = GetSelectedBurnCardRef( player )
	EarnMeterMP_SetBoostByRef( player, burncardRef )

	// catchup bonus for late joiners
	// todo: maths on this is fine but for some reason it won't set correctly, could be getting reset somewhere?
	PlayerEarnMeter_AddOwnedFrac( player, ( ( Time() - file.playingStartTime ) / 4.0 ) * 0.01 )
}

void function OnPlaying()
{
	file.playingStartTime = Time()
	foreach ( entity player in GetPlayerArray() )
		SetupPlayerEarnMeter( player )

	if ( Riff_BoostAvailability() != eBoostAvailability.Disabled )
		SetCallback_EarnMeterRewardEarned( EarnMeterMP_BoostEarned )

	// do this in playing so that gamemodes/maps can disable and this'll take affect
	if ( EarnMeterMP_IsTitanEarnGametype() ) // settitanavailable when earnmeter full
	{
		Riff_ForceTitanAvailability( eTitanAvailability.Custom ) // doesn't seem to affect anything aside from preventing some annoying client stuff
		svGlobal.titanAvailabilityCheck = IsTitanAvailable
	}

	SetCallback_EarnMeterGoalEarned( EarnMeterMP_TitanEarned )
}

void function OnPlayerRespawned( entity player )
{
	thread EarnMeterMP_PlayerLifeThink( player )

	if ( PlayerEarnMeter_IsRewardAvailable( player ) )
		EarnMeterMP_BoostEarned( player )
}

void function EarnMeterMP_ReplaceReward( entity player, EarnObject reward, float rewardFrac )
{
	PlayerEarnMeter_Reset( player )
	if ( reward.id < 0 )
		return
	PlayerEarnMeter_SetReward( player, reward )
	PlayerEarnMeter_SetRewardFrac( player, rewardFrac )

	if( PlayerEarnMeter_GetRewardFrac( player ) != 0 )
		PlayerEarnMeter_EnableReward( player )
}

void function EarnMeterMP_PlayerLifeThink( entity player )
{
	player.EndSignal( "OnDeath" )
	player.EndSignal( "OnDestroy" )

	EarnObject pilotReward = PlayerEarnMeter_GetReward( player ) 
	float pilotRewardFrac = PlayerEarnMeter_GetRewardFrac( player )
	int lastEarnMeterMode = PlayerEarnMeter_GetMode( player )
	bool saidTitanSoon = false
	bool titanReadyMsg = false
	float lastPassiveGainTime = Time()

	OnThreadEnd(
		function() : ( player, pilotReward, pilotRewardFrac )
		{
			if ( !IsValid( player ) )
				return

			// Resets the meter to the pilot version if the player dies in a titan or while their titan is alive (otherwise they can be stuck with e-smoke)
			int earnMode = PlayerEarnMeter_GetMode( player )
			if( earnMode != eEarnMeterMode.DEFAULT )
				EarnMeterMP_ReplaceReward( player, pilotReward, pilotRewardFrac )
		}
	)

	while ( true )
	{
		int desiredEarnMeterMode

		if ( player.IsTitan() )
		{
			entity soul = player.GetTitanSoul()
			if ( SoulTitanCore_GetExpireTime( soul ) > Time() )
				desiredEarnMeterMode = eEarnMeterMode.CORE_ACTIVE
			else
				desiredEarnMeterMode = eEarnMeterMode.CORE
		}
		else if ( IsValid( player.GetPetTitan() ) )
			desiredEarnMeterMode = eEarnMeterMode.PET
		else
			desiredEarnMeterMode = eEarnMeterMode.DEFAULT

		if ( desiredEarnMeterMode != lastEarnMeterMode )
		{
			PlayerEarnMeter_SetMode( player, desiredEarnMeterMode )
			if ( lastEarnMeterMode == eEarnMeterMode.DEFAULT ) // Set these here in case the player changed boost during the match (e.g. in dropship)
			{
				pilotReward = PlayerEarnMeter_GetReward( player ) 
				pilotRewardFrac = PlayerEarnMeter_GetRewardFrac( player )
			}

			if ( desiredEarnMeterMode == eEarnMeterMode.DEFAULT ) // Only occurs when auto titan dies. Resets reward progress and reverts it back to boost.
				EarnMeterMP_ReplaceReward( player, pilotReward, pilotRewardFrac )
			else if ( desiredEarnMeterMode == eEarnMeterMode.CORE ) // Replace the pilot's earn meter reward with smoke when they enter their titan.
			{
				EarnMeterMP_ReplaceReward( player, EarnObject_GetByRef( "core_electric_smoke" ), CORE_SMOKE_FRAC )
				if( SoulTitanCore_GetNextAvailableTime( player.GetTitanSoul() ) >= CORE_SMOKE_FRAC )
					PlayerEarnMeter_SetRewardUsed( player )
			}
			else if ( desiredEarnMeterMode == eEarnMeterMode.CORE_ACTIVE ) // Enables smoke after core use (doesn't show up during active, so looks fine)
				PlayerEarnMeter_EnableReward( player )

			lastEarnMeterMode = desiredEarnMeterMode
		}

		if ( lastEarnMeterMode == eEarnMeterMode.DEFAULT )
		{
			if ( Riff_TitanAvailability() != eTitanAvailability.Never )
			{
				if ( PlayerEarnMeter_GetOwnedFrac( player ) >= 0.75 && PlayerEarnMeter_GetOwnedFrac( player ) < 0.95 && !saidTitanSoon )
				{
					PlayFactionDialogueToPlayer( "mp_titanSoon", player )
					saidTitanSoon = true
				}
				else if( PlayerEarnMeter_GetOwnedFrac( player ) < 0.75 )
					saidTitanSoon = false
			}
			
			if ( PlayerEarnMeter_GetOwnedFrac( player ) < 1.0 )
			{
				PlayerEarnMeter_DisableGoal( player )
				titanReadyMsg = false
			}
			else if ( player.GetPlayerNetInt( "goalState" ) != eRewardState.UNAVAILABLE )
			{
				// if goal is enabled then the client will show "titan ready" alerts even if it isn't
				// the problem is that if the goal isn't available when we fill the earnmeter, then it won't make it available
				// so unfortunately we have to do this manually
				player.SetPlayerNetInt( "goalState", eRewardState.AVAILABLE )
				PlayerEarnMeter_RefreshGoal( player )
				if( !titanReadyMsg )
				{
					Remote_CallFunction_NonReplay( player, "ServerCallback_TitanReadyMessage" )
					titanReadyMsg = true
				}
			}

			if ( Time() - lastPassiveGainTime > 4.0 && file.passiveMeterGainEnabled ) // this might be 5.0
			{
				lastPassiveGainTime = Time()
				PlayerEarnMeter_AddOwnedFrac( player, 0.01 )
			}
		}

		WaitFrame()
	}
}

void function EarnMeterMP_BoostEarned( entity player )
{
	// Can't have smoke earned via meter. Otherwise, Auto Titan could hit reward frac and get nothing
	if( player.IsTitan() )
		return

	EarnObject earnobject = PlayerEarnMeter_GetReward( player )
	BurnReward burncard = BurnReward_GetByRef( earnobject.ref )

	while ( burncard.ref == "burnmeter_random_foil" )
		burncard = BurnReward_GetRandom()

	for ( int i = 0; i < BurnMeter_GetLimitedRewardCount( player, burncard.ref ); i++ )
		BurnMeter_GiveRewardDirect( player, burncard.ref )

	PlayerEarnMeter_DisableReward( player )
}

void function EarnMeterMP_TitanEarned( entity player )
{
	if ( EarnMeterMP_IsTitanEarnGametype() )
	{
		SetTitanAvailable( player )
		//Remote_CallFunction_Replay( player, "ServerCallback_TitanReadyMessage" ) // broken for some reason
	}
	else
	{
		float oldRewardFrac = PlayerEarnMeter_GetRewardFrac( player )
		PlayerEarnMeter_Reset( player )
		PlayerEarnMeter_SetRewardFrac( player, oldRewardFrac )
		PlayerEarnMeter_EnableReward( player )

		if ( PlayerEarnMeter_GetRewardFrac( player ) != 0 )
			PlayerEarnMeter_EnableReward( player )
	}
}

void function EarnMeterMP_SetBoostByRef( entity player, string boostRef ) 
{
	EarnObject earnobject = EarnObject_GetByRef( boostRef )
	BurnReward burncard = BurnReward_GetByRef( boostRef )

	if ( Riff_BoostAvailability() != eBoostAvailability.Disabled )
	{
		PlayerEarnMeter_SetReward( player, earnobject ) // pretty sure this works?
		PlayerEarnMeter_SetRewardFrac( player, burncard.cost )
		PlayerEarnMeter_EnableReward( player )
	}

	if ( EarnMeterMP_IsTitanEarnGametype() )
	{
		PlayerEarnMeter_SetGoal( player, EarnObject_GetByRef( GetTitanLoadoutForPlayer( player ).titanClass ) )
		PlayerEarnMeter_EnableGoal( player ) // prevents goalstate from being set incorrectly
	}
	else
		PlayerEarnMeter_SetGoal( player, earnobject )
}