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 ) }