diff options
Diffstat (limited to 'Northstar.CustomServers/scripts/vscripts/earn_meter')
-rw-r--r-- | Northstar.CustomServers/scripts/vscripts/earn_meter/sv_earn_meter.gnut | 508 | ||||
-rw-r--r-- | Northstar.CustomServers/scripts/vscripts/earn_meter/sv_earn_meter_mp.gnut | 128 |
2 files changed, 636 insertions, 0 deletions
diff --git a/Northstar.CustomServers/scripts/vscripts/earn_meter/sv_earn_meter.gnut b/Northstar.CustomServers/scripts/vscripts/earn_meter/sv_earn_meter.gnut new file mode 100644 index 00000000..dda84976 --- /dev/null +++ b/Northstar.CustomServers/scripts/vscripts/earn_meter/sv_earn_meter.gnut @@ -0,0 +1,508 @@ +global function Sv_EarnMeter_Init +global function PlayerEarnMeter_SoftReset +global function PlayerEarnMeter_SetOwnedFrac +global function PlayerEarnMeter_Reset +global function PlayerEarnMeter_Empty +global function PlayerEarnMeter_AddEarnedFrac +global function PlayerEarnMeter_AddOwnedFrac +global function PlayerEarnMeter_AddEarnedAndOwned +global function PlayerEarnMeter_SetMode +global function PlayerEarnMeter_SetRewardFrac + +global function PlayerEarnMeter_GetPilotMultiplier +global function PlayerEarnMeter_GetPilotOverdriveEnum + +global function PlayerEarnMeter_RefreshGoal + +global function PlayerEarnMeter_SetReward +global function PlayerEarnMeter_SetGoal + +global function PlayerEarnMeter_SetGoalUsed +global function PlayerEarnMeter_EnableGoal +global function PlayerEarnMeter_DisableGoal + +global function PlayerEarnMeter_SetRewardUsed +global function PlayerEarnMeter_DisableReward +global function PlayerEarnMeter_EnableReward + +global function PlayerEarnMeter_CanEarn + +global function SetCallback_EarnMeterGoalEarned +global function SetCallback_EarnMeterRewardEarned + +global function AddEarnMeterThresholdEarnedCallback + +global function JFS_PlayerEarnMeter_CoreRewardUpdate +global function GiveOffhandElectricSmoke + +global function SharedEarnMeter_AddEarnedAndOwned +global function PlayerEarnMeter_SetEnabled +global function PlayerEarnMeter_Enabled + +global struct EarnMeterThresholdEarnedStruct +{ + float threshold + bool triggerFunctionOnFullEarnMeter = false + void functionref( entity player ) thresholdEarnedCallback +} + +struct +{ + void functionref( entity player ) goalEarnedCallback + void functionref( entity player ) rewardEarnedCallback + array<EarnMeterThresholdEarnedStruct> thresholdEarnedCallbacks + + float earn_meter_pilot_multiplier + int earn_meter_pilot_overdrive // ePilotOverdrive + bool earnMeterEnabled = true +} file + +void function Sv_EarnMeter_Init() +{ + if ( !EARNMETER_ENABLED ) + return + + RegisterSignal( "EarnMeterDecayThink" ) + + SetCallback_EarnMeterGoalEarned( DummyGoalEarnedCallback ) + SetCallback_EarnMeterRewardEarned( DummyRewardEarnedCallback ) + + file.earn_meter_pilot_multiplier = PlayerEarnMeter_GetPilotMultiplier() + file.earn_meter_pilot_overdrive = PlayerEarnMeter_GetPilotOverdriveEnum() +} + +float function PlayerEarnMeter_GetPilotMultiplier() +{ + return GetCurrentPlaylistVarFloat( "earn_meter_pilot_multiplier", 1.0 ) +} + +int function PlayerEarnMeter_GetPilotOverdriveEnum() +{ + return GetCurrentPlaylistVarInt( "earn_meter_pilot_overdrive", ePilotOverdrive.Enabled ) +} + +void function AddEarnMeterThresholdEarnedCallback( float thresholdForCallback, void functionref( entity player ) callbackFunc, bool triggerFunctionOnFullEarnMeter = false ) +{ + EarnMeterThresholdEarnedStruct thresholdStruct + thresholdStruct.threshold = thresholdForCallback + thresholdStruct.thresholdEarnedCallback = callbackFunc + thresholdStruct.triggerFunctionOnFullEarnMeter = triggerFunctionOnFullEarnMeter + + Assert( !AlreadyContainsThresholdCallback( thresholdStruct ), "Already added " + string( callbackFunc ) + " with threshold " + thresholdForCallback ) + file.thresholdEarnedCallbacks.append( thresholdStruct ) +} + +bool function AlreadyContainsThresholdCallback( EarnMeterThresholdEarnedStruct thresholdStruct ) +{ + foreach( existingThresholdStruct in file.thresholdEarnedCallbacks ) + { + if ( existingThresholdStruct.threshold != thresholdStruct.threshold ) + continue + + if ( existingThresholdStruct.thresholdEarnedCallback != thresholdStruct.thresholdEarnedCallback ) + continue + + if ( existingThresholdStruct.triggerFunctionOnFullEarnMeter != thresholdStruct.triggerFunctionOnFullEarnMeter ) + continue + + return true + } + + return false +} + +void function SetCallback_EarnMeterGoalEarned( void functionref( entity player ) callback ) +{ + if ( file.goalEarnedCallback == null || file.goalEarnedCallback == DummyGoalEarnedCallback ) + file.goalEarnedCallback = callback +} + +void function SetCallback_EarnMeterRewardEarned( void functionref( entity player ) callback ) +{ + if ( file.rewardEarnedCallback == null || file.rewardEarnedCallback == DummyRewardEarnedCallback ) + file.rewardEarnedCallback = callback +} + + +void function PlayerEarnMeter_SetMode( entity player, int mode ) +{ + player.SetPlayerNetInt( EARNMETER_MODE, mode ) +} + + +void function PlayerEarnMeter_AddEarnedFrac( entity player, float earnedFrac ) +{ + PlayerEarnMeter_AddEarnedAndOwned( player, earnedFrac, 0.0 ) +} + + +void function PlayerEarnMeter_AddOwnedFrac( entity player, float addValue ) +{ + PlayerEarnMeter_AddEarnedAndOwned( player, 0.0, addValue ) +} + + +bool function PlayerEarnMeter_CanEarn( entity player ) +{ + if ( PlayerEarnMeter_GetMode( player ) != eEarnMeterMode.DEFAULT || player.IsTitan() || IsValid( player.GetPetTitan() ) ) + return false + + return file.earnMeterEnabled +} + +void function SharedEarnMeter_AddEarnedAndOwned( entity player, float addOverdriveValue, float addOwnedValue ) +{ + int teamShareEarnMeter = Riff_TeamShareEarnMeter() + Assert( teamShareEarnMeter != eTeamShareEarnMeter.Disabled ) + + float sharedEarnMeterScale = GetCurrentPlaylistVarFloat( "riff_team_share_earn_meter_scale", 0.5 ) + + float overdriveValue = addOverdriveValue * sharedEarnMeterScale + float ownedValue = addOwnedValue * sharedEarnMeterScale + + array<entity> teamPlayers = GetPlayerArrayOfTeam_Alive( player.GetTeam() ) + foreach ( teamPlayer in teamPlayers ) + { + if ( teamPlayer == player ) + continue + + if ( !PlayerEarnMeter_CanEarn( teamPlayer ) ) + continue + + if ( teamShareEarnMeter == eTeamShareEarnMeter.Enabled ) + PlayerEarnMeter_AddEarnedAndOwned( teamPlayer, overdriveValue, ownedValue ) + else if ( teamShareEarnMeter == eTeamShareEarnMeter.OwnedOnly ) + PlayerEarnMeter_AddOwnedFrac( teamPlayer, ownedValue ) + else if ( teamShareEarnMeter == eTeamShareEarnMeter.OverdriveOnly ) + PlayerEarnMeter_AddEarnedFrac( teamPlayer, overdriveValue ) + } +} + +void function PlayerEarnMeter_AddEarnedAndOwned( entity player, float addOverdriveValue, float addOwnedValue ) +{ + // TODO: Core Meter should be unified with earn meter so this can go away and we keep the hot streak concept for Titan Cores. + if ( player.IsTitan() ) + { + AddCreditToTitanCoreBuilder( player, addOwnedValue ) + return + } + + if ( !PlayerEarnMeter_CanEarn( player ) ) + return + + if ( addOverdriveValue == 0 && addOwnedValue == 0 ) + return + + if ( file.earn_meter_pilot_overdrive == ePilotOverdrive.Only ) + addOwnedValue = 0.0 + + if ( file.earn_meter_pilot_overdrive == ePilotOverdrive.Disabled ) + addOverdriveValue = 0.0 + + float startingOverdriveValue = PlayerEarnMeter_GetEarnedFrac( player ) + float startingOwnedValue = PlayerEarnMeter_GetOwnedFrac( player ) + float startingOverdriveDiff = max( 0, startingOverdriveValue - startingOwnedValue ) + + float multipliedOwnedValue = addOwnedValue * file.earn_meter_pilot_multiplier + float newOwnedValue = min( startingOwnedValue + multipliedOwnedValue, 1.0 ) + PlayerEarnMeter_SetOwnedFrac( player, min( newOwnedValue, 1.0 ) ) + + float multipliedOverdriveValue = addOverdriveValue * file.earn_meter_pilot_multiplier + float newOverdriveValue = max( min( newOwnedValue + startingOverdriveDiff + multipliedOverdriveValue, 1.0 ), 0.0 ) + PlayerEarnMeter_SetEarnedFrac( player, newOverdriveValue ) + + if ( newOverdriveValue > startingOverdriveValue ) + thread EarnMeterDecayThink( player ) + + foreach( thresholdStruct in file.thresholdEarnedCallbacks ) + { + if ( newOverdriveValue < thresholdStruct.threshold ) //We're not past the threshold yet, don't run the function + continue + + if ( startingOverdriveValue >= thresholdStruct.threshold ) //This isn't the first time we're past the threshold, don't run the function + continue + + if ( newOwnedValue == 1.0 && thresholdStruct.triggerFunctionOnFullEarnMeter == false ) //We've earned enough earn meter to just fill out the bar, we should just run whatever functionality + continue + + thresholdStruct.thresholdEarnedCallback( player ) + } + + if ( PlayerEarnMeter_IsRewardEnabled( player ) ) + { + float rewardFrac = PlayerEarnMeter_GetRewardFrac( player ) + + // If we earned our reward + if ( (startingOverdriveValue < rewardFrac && newOverdriveValue >= rewardFrac) || (startingOwnedValue < rewardFrac && newOwnedValue >= rewardFrac) ) + { + //if ( newOwnedValue < rewardFrac ) // if the owned portion isn't already maxed out, do so + // PlayerEarnMeter_SetOwnedFrac( player, rewardFrac ) + + PlayerEarnMeter_TryMakeRewardAvailable( player ) + } + } + + // If we earned our goal + if ( (startingOverdriveValue < 1.0 && newOverdriveValue >= 1.0) || (startingOwnedValue < 1.0 && newOwnedValue >= 1.0) ) + { + if ( newOwnedValue < 1.0 ) // if the owned portion isn't already maxed out, do so + PlayerEarnMeter_SetOwnedFrac( player, 1.0 ) + + PlayerEarnMeter_TryMakeGoalAvailable( player ) + } + + //#if MP + // Remote_CallFunction_NonReplay( player, "ServerCallback_EarnMeterAwarded", addOverdriveValue, addOwnedValue ) + //#endif +} + + +void function PlayerEarnMeter_RefreshGoal( entity player ) +{ + if ( player.GetPlayerNetInt( "goalState" ) == eRewardState.AVAILABLE ) + { + file.goalEarnedCallback( player ) + } +} + + +void function PlayerEarnMeter_SetEarnedFrac( entity player, float value ) +{ + player.p.earnMeterOverdriveFrac = value + player.SetPlayerNetFloat( EARNMETER_EARNEDFRAC, value ) +} + + +void function PlayerEarnMeter_SetOwnedFrac( entity player, float value ) +{ + player.p.earnMeterOwnedFrac = value + player.SetPlayerNetFloat( EARNMETER_OWNEDFRAC, value ) +} + + +void function PlayerEarnMeter_SetRewardFrac( entity player, float value ) +{ + player.p.earnMeterRewardFrac = value + player.SetPlayerNetFloat( EARNMETER_REWARDFRAC, value ) +} + + +void function PlayerEarnMeter_SoftReset( entity player ) +{ + float ownedFrac = PlayerEarnMeter_GetOwnedFrac( player ) + PlayerEarnMeter_SetEarnedFrac( player, ownedFrac ) +} + + +void function PlayerEarnMeter_Reset( entity player ) +{ + player.Signal( "EarnMeterDecayThink" ) + + PlayerEarnMeter_SetEarnedFrac( player, 0.0 ) + PlayerEarnMeter_SetOwnedFrac( player, 0.0 ) + PlayerEarnMeter_SetRewardFrac( player, 0.0 ) + + player.SetPlayerNetInt( "goalState", eRewardState.DISABLED ) + player.SetPlayerNetInt( "rewardState", eRewardState.DISABLED ) +} + +void function PlayerEarnMeter_Empty( entity player ) +{ + player.Signal( "EarnMeterDecayThink" ) + + PlayerEarnMeter_SetEarnedFrac( player, 0.0 ) + PlayerEarnMeter_SetOwnedFrac( player, 0.0 ) + PlayerEarnMeter_SetRewardFrac( player, 0.0 ) +} + + +void function EarnMeterDecayThink( entity player ) +{ + player.EndSignal( "OnDeath" ) + player.Signal( "EarnMeterDecayThink" ) + player.EndSignal( "EarnMeterDecayThink" ) + + if ( EarnMeter_DecayHold() < 0 ) + return + + wait EarnMeter_DecayHold() + + float earnedValue = PlayerEarnMeter_GetEarnedFrac( player ) + float ownedValue = PlayerEarnMeter_GetOwnedFrac( player ) + + // 10% over 20 seconds + float decayRate = 1.0 / 135.0 + + //float startTime = Time() + while ( earnedValue > ownedValue ) + { + //float frameTime = Time() - startTime + //startTime = Time() + + PlayerEarnMeter_AddEarnedFrac( player, -(decayRate * 0.25) ) + + wait 0.25 + + earnedValue = PlayerEarnMeter_GetEarnedFrac( player ) + ownedValue = PlayerEarnMeter_GetOwnedFrac( player ) + } +} + + +bool function PlayerEarnMeter_TryMakeGoalAvailable( entity player ) +{ + if ( player.GetPlayerNetInt( "goalState" ) == eRewardState.USED ) + return false + + if ( player.GetPlayerNetInt( "goalState" ) == eRewardState.DISABLED ) + return false + + if ( player.GetPlayerNetInt( "goalState" ) == eRewardState.AVAILABLE ) + return false + + player.SetPlayerNetInt( "goalState", eRewardState.AVAILABLE ) + + file.goalEarnedCallback( player ) + + return true +} + + +void function PlayerEarnMeter_DisableReward( entity player ) +{ + player.SetPlayerNetInt( "rewardState", eRewardState.DISABLED ) +} + + +void function PlayerEarnMeter_EnableReward( entity player ) +{ + player.SetPlayerNetInt( "rewardState", eRewardState.UNAVAILABLE ) +} + + +void function PlayerEarnMeter_SetRewardUsed( entity player ) +{ + player.SetPlayerNetInt( "rewardState", eRewardState.USED ) +} + + +void function PlayerEarnMeter_DisableGoal( entity player ) +{ + player.SetPlayerNetInt( "goalState", eRewardState.DISABLED ) +} + + +void function PlayerEarnMeter_EnableGoal( entity player ) +{ + player.SetPlayerNetInt( "goalState", eRewardState.UNAVAILABLE ) +} + + +void function PlayerEarnMeter_SetGoalUsed( entity player ) +{ + player.SetPlayerNetInt( "goalState", eRewardState.USED ) +} + + +bool function PlayerEarnMeter_TryMakeRewardAvailable( entity player ) +{ + if ( player.GetPlayerNetInt( "rewardState" ) == eRewardState.USED ) + return false + + if ( player.GetPlayerNetInt( "rewardState" ) == eRewardState.DISABLED ) + return false + + if ( player.GetPlayerNetInt( "rewardState" ) == eRewardState.AVAILABLE ) + return false + + player.SetPlayerNetInt( "rewardState", eRewardState.AVAILABLE ) + + file.rewardEarnedCallback( player ) + return true +} + + +void function PlayerEarnMeter_SetReward( entity player, EarnObject earnObject ) +{ + Assert( earnObject.id > -1 ) + Assert( earnObject.earnType == "REWARD" ) + + player.SetPlayerNetInt( EARNMETER_REWARDID, earnObject.id ) +} + +void function PlayerEarnMeter_SetGoal( entity player, EarnObject earnObject ) +{ + Assert( earnObject.id > -1 ) + //Assert( earnObject.earnType == "GOAL" ) + + player.SetPlayerNetInt( EARNMETER_GOALID, earnObject.id ) +} + + +void function DummyRewardEarnedCallback( entity player ) +{ + Assert( false, "Must set a reward earned callback with SetCallback_EarnMeterRewardEarned() if rewards are in use" ) +} + + +void function DummyGoalEarnedCallback( entity player ) +{ + Assert( false, "Must set a goal earned callback with SetCallback_EarnMeterGoalEarned() if meter is in use" ) +} + +// Hook into the existing core system until it can be replaced. +void function JFS_PlayerEarnMeter_CoreRewardUpdate( entity titan, float startingCoreValue, float newCoreValue ) +{ + #if ANTI_RODEO_SMOKE_ENABLED + if ( startingCoreValue < CORE_SMOKE_FRAC && newCoreValue >= CORE_SMOKE_FRAC ) + { + GiveOffhandElectricSmoke( titan ) + + if ( titan.IsPlayer() ) + Remote_CallFunction_NonReplay( titan, "ServerCallback_RewardReadyMessage", (Time() - GetPlayerLastRespawnTime( titan )) ) + + if ( titan.IsPlayer() ) + PlayerEarnMeter_SetRewardUsed( titan ) + } + #endif +} + +void function GiveOffhandElectricSmoke( entity titan ) +{ + entity soul = titan.GetTitanSoul() + bool hasAntiRodeoKit = IsValid( soul ) && SoulHasPassive( soul, ePassives.PAS_ANTI_RODEO ) + if ( titan.GetOffhandWeapon( OFFHAND_INVENTORY ) != null ) + { + entity weapon = titan.GetOffhandWeapon( OFFHAND_INVENTORY ) + if ( hasAntiRodeoKit ) + weapon.SetWeaponPrimaryAmmoCount( weapon.GetWeaponPrimaryAmmoCount() + 2 ) + else + weapon.SetWeaponPrimaryAmmoCount( weapon.GetWeaponPrimaryAmmoCount() + 1 ) + } + else + { + titan.GiveOffhandWeapon( CORE_SMOKE_WEAPON, OFFHAND_INVENTORY ) + entity weapon = titan.GetOffhandWeapon( OFFHAND_INVENTORY ) + if ( hasAntiRodeoKit ) + { + weapon.SetWeaponPrimaryAmmoCount( weapon.GetWeaponPrimaryAmmoCount() + 1 ) + } + if ( soul.GetTitanSoulNetInt( "upgradeCount" ) >= 2 && SoulHasPassive( soul, ePassives.PAS_VANGUARD_CORE5 ) ) + { + entity weapon = titan.GetOffhandWeapon( OFFHAND_INVENTORY ) + array<string> mods = weapon.GetMods() + mods.append( "maelstrom" ) + weapon.SetMods( mods ) + } + } +} + +void function PlayerEarnMeter_SetEnabled( bool enabled ) +{ + file.earnMeterEnabled = enabled +} + +bool function PlayerEarnMeter_Enabled() +{ + return file.earnMeterEnabled +}
\ No newline at end of file diff --git a/Northstar.CustomServers/scripts/vscripts/earn_meter/sv_earn_meter_mp.gnut b/Northstar.CustomServers/scripts/vscripts/earn_meter/sv_earn_meter_mp.gnut new file mode 100644 index 00000000..b5ad4fb1 --- /dev/null +++ b/Northstar.CustomServers/scripts/vscripts/earn_meter/sv_earn_meter_mp.gnut @@ -0,0 +1,128 @@ +global function Sv_EarnMeterMP_Init +global function EarnMeterMP_SetTitanLoadout + +struct { + float playingStartTime +} 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 ) ) +} + +void function SetupPlayerEarnMeter( entity player ) +{ + PlayerEarnMeter_Reset( player ) + + // todo: need to do burnmeter stuff here ( e.g. rewards/boosts ) + if ( EarnMeterMP_IsTitanEarnGametype() ) + PlayerEarnMeter_SetGoal( player, EarnObject_GetByRef( GetTitanLoadoutForPlayer( player ).titanClass ) ) + + PlayerEarnMeter_EnableGoal( player ) // prevents goalstate from being set incorrectly + + // 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 ) + + // 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 + AddEarnMeterThresholdEarnedCallback( 1.0, void function( entity player ) { SetTitanAvailable( player ) }, true ) + } + else // if no titans from earnmeter in this mode, just reset when we finish meter + AddEarnMeterThresholdEarnedCallback( 1.0, PlayerEarnMeter_Reset, true ) +} + +void function OnPlayerRespawned( entity player ) +{ + thread EarnMeterMP_PlayerLifeThink( player ) +} + +void function EarnMeterMP_PlayerLifeThink( entity player ) +{ + player.EndSignal( "OnDeath" ) + + int lastEarnMeterMode = PlayerEarnMeter_GetMode( player ) + float lastPassiveGainTime = Time() + + 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 ( desiredEarnMeterMode == eEarnMeterMode.DEFAULT ) + { + if ( !IsTitanAvailable( player ) && PlayerEarnMeter_GetOwnedFrac( player ) == 1.0 ) // this should only be the case after player has dropped their titan + PlayerEarnMeter_Reset( player ) + + if ( PlayerEarnMeter_GetRewardFrac( player ) != 0 ) + PlayerEarnMeter_EnableReward( player ) + } + else + { + PlayerEarnMeter_DisableGoal( player ) + PlayerEarnMeter_DisableReward( player ) + } + + lastEarnMeterMode = desiredEarnMeterMode + } + + if ( lastEarnMeterMode == eEarnMeterMode.DEFAULT ) + { + if ( PlayerEarnMeter_GetOwnedFrac( player ) < 1.0 ) + PlayerEarnMeter_DisableGoal( player ) + 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 ( Time() - lastPassiveGainTime > 4.0 ) // this might be 5.0 + { + lastPassiveGainTime = Time() + PlayerEarnMeter_AddOwnedFrac( player, 0.01 ) + } + } + + WaitFrame() + } +}
\ No newline at end of file |