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
|
global function Sv_GGEarnMeter_Init
global function Sv_GGEarnMeter_SetPercentage
global function Sv_GGEarnMeter_AddPercentage
global function AddCallback_GGEarnMeterFull
enum RewardType
{
SET,
ADD
}
struct RewardStruct
{
float amount = 0.0
int type = RewardType.ADD
}
struct
{
array< bool functionref( entity ) > onGGEarnMeterFullCallbacks,
table< entity, array< RewardStruct > > rewardQueue, // Because we have delayed reward handling, let's queue things so that everything gets handled eventually.
table< entity, bool > checkingQueue
} file
void function Sv_GGEarnMeter_Init()
{
AddCallback_OnClientConnected( Sv_GGEarnMeter_OnClientConnected )
}
void function Sv_GGEarnMeter_OnClientConnected( entity player )
{
file.rewardQueue[ player ] <- []
file.checkingQueue[ player ] <- false
}
void function AddReward( entity player, float amount, int type )
{
RewardStruct reward
reward.amount = amount
reward.type = type
file.rewardQueue[player].append( reward )
TryCheckQueue( player )
}
void function TryCheckQueue( entity player )
{
if ( !file.checkingQueue[player] ) {
thread CheckQueue( player )
}
}
void function CheckQueue( entity player )
{
player.EndSignal( "OnDestroy" ) // If the player disconnects or stops existing for some reason, stop doing shit with it so the server doesn't break.
file.checkingQueue[player] = true
while ( file.rewardQueue[player].len() > 0 && IsValid(player) )
{
RewardStruct reward = file.rewardQueue[player].remove(0)
float newValue = reward.amount
if ( reward.type == RewardType.ADD )
newValue += player.GetPlayerNetFloat( "gunGameLevelPercentage")
newValue = clamp( newValue, 0.0, 1.0 )
player.SetPlayerNetFloat( "gunGameLevelPercentage", newValue )
wait 0.2
if ( (newValue * 100) < 99 ) // To try and catch fun rounding issues.
continue
bool keepFull = false
foreach ( callbackFunc in file.onGGEarnMeterFullCallbacks )
keepFull = callbackFunc( player )
if ( !keepFull )
player.SetPlayerNetFloat( "gunGameLevelPercentage", 0.0 )
wait 0.2
}
file.checkingQueue[player] = false
}
void function Sv_GGEarnMeter_SetPercentage( entity player, float percentage )
{
AddReward( player, percentage, RewardType.SET )
}
void function Sv_GGEarnMeter_AddPercentage( entity player, float percentage )
{
AddReward( player, percentage, RewardType.ADD )
}
void function AddCallback_GGEarnMeterFull( bool functionref( entity ) callbackFunc )
{
Assert( !file.onGGEarnMeterFullCallbacks.contains( callbackFunc ), "Already added " + FunctionToString( callbackFunc ) + " with AddCallback_GGEarnMeterFull" )
file.onGGEarnMeterFullCallbacks.append( callbackFunc )
}
|