diff options
16 files changed, 845 insertions, 101 deletions
diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..dc73e011 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +/Northstar.Client/mod/resource/* -text
\ No newline at end of file diff --git a/Northstar.Client/mod/resource/northstar_client_localisation_english.txt b/Northstar.Client/mod/resource/northstar_client_localisation_english.txt Binary files differindex 4cb79354..c277964b 100644 --- a/Northstar.Client/mod/resource/northstar_client_localisation_english.txt +++ b/Northstar.Client/mod/resource/northstar_client_localisation_english.txt diff --git a/Northstar.Client/mod/resource/northstar_client_localisation_french.txt b/Northstar.Client/mod/resource/northstar_client_localisation_french.txt Binary files differindex 6d902e61..2a7a82f4 100644 --- a/Northstar.Client/mod/resource/northstar_client_localisation_french.txt +++ b/Northstar.Client/mod/resource/northstar_client_localisation_french.txt diff --git a/Northstar.Client/mod/resource/northstar_client_localisation_russian.txt b/Northstar.Client/mod/resource/northstar_client_localisation_russian.txt Binary files differindex 76b61591..2a30c6ec 100644 --- a/Northstar.Client/mod/resource/northstar_client_localisation_russian.txt +++ b/Northstar.Client/mod/resource/northstar_client_localisation_russian.txt diff --git a/Northstar.Client/mod/resource/northstar_client_localisation_tchinese.txt b/Northstar.Client/mod/resource/northstar_client_localisation_tchinese.txt Binary files differindex cd8cf977..e61f9deb 100644 --- a/Northstar.Client/mod/resource/northstar_client_localisation_tchinese.txt +++ b/Northstar.Client/mod/resource/northstar_client_localisation_tchinese.txt diff --git a/Northstar.Custom/mod.json b/Northstar.Custom/mod.json index e687264c..d6c54033 100644 --- a/Northstar.Custom/mod.json +++ b/Northstar.Custom/mod.json @@ -1,7 +1,7 @@ { "Name" : "Northstar.Custom", "Description": "(ideally) Polished custom content for Northstar", - "Version": "1.0.0", + "Version": "1.1.0", "LoadPriority": 1, "RequiredOnClient": true, diff --git a/Northstar.Custom/mod/resource/northstar_custom_russian.txt b/Northstar.Custom/mod/resource/northstar_custom_russian.txt Binary files differnew file mode 100644 index 00000000..efb49f8c --- /dev/null +++ b/Northstar.Custom/mod/resource/northstar_custom_russian.txt diff --git a/Northstar.Custom/mod/scripts/vscripts/burnmeter/sh_burnmeter.gnut b/Northstar.Custom/mod/scripts/vscripts/burnmeter/sh_burnmeter.gnut index 3f914745..4705ef64 100644 --- a/Northstar.Custom/mod/scripts/vscripts/burnmeter/sh_burnmeter.gnut +++ b/Northstar.Custom/mod/scripts/vscripts/burnmeter/sh_burnmeter.gnut @@ -1,4 +1,6 @@ global function ShBurnMeter_Init +global function BurnMeter_SetNoTitansReplacement +global function BurnMeter_GetNoTitansReplacement global function BurnReward_GetById global function BurnReward_GetByRef global function BurnReward_GetRandom @@ -67,9 +69,8 @@ global table< string, bool functionref( entity ) > burnMeterCanUseFuncTable struct { - bool shouldCycleOnRelease = false - + table<string, string> noTitansReplacements } file array<string> turretBurnCards = [ @@ -131,6 +132,24 @@ void function ShBurnMeter_Init() RegisterConCommandTriggeredCallback( "-offhand4", CycleOnRelease ) #endif + + BurnMeter_SetNoTitansReplacement( "burnmeter_emergency_battery", "burnmeter_amped_weapons" ) + BurnMeter_SetNoTitansReplacement( "burnmeter_at_turret_weapon", "burnmeter_amped_weapons" ) + BurnMeter_SetNoTitansReplacement( "burnmeter_rodeo_grenade", "burnmeter_amped_weapons" ) + BurnMeter_SetNoTitansReplacement( "burnmeter_nuke_titan", "burnmeter_amped_weapons" ) +} + +void function BurnMeter_SetNoTitansReplacement( string original, string noTitansReplacement ) +{ + file.noTitansReplacements[original] <- noTitansReplacement +} + +string function BurnMeter_GetNoTitansReplacement( string burnRef ) +{ + if ( burnRef in file.noTitansReplacements ) + return file.noTitansReplacements[burnRef] + + return burnRef } #if SERVER || CLIENT @@ -164,10 +183,20 @@ int function GetBoostSkin( string ref ) return reward.skinIndex } - BurnReward function BurnReward_GetRandom() { - return burn.allowedCards.getrandom() + string ref = burn.allowedCards.getrandom().ref + + #if SERVER || CLIENT + if ( !EarnMeterMP_IsTitanEarnGametype() ) + ref = BurnMeter_GetNoTitansReplacement( ref ) + + if ( GetCurrentPlaylistVarInt( "featured_mode_all_ticks", 0 ) >= 1 ) + if ( ref == "burnmeter_ticks" || ref == "burnmeter_random_foil" ) + ref = "burnmeter_amped_weapons" + #endif + + return BurnReward_GetByRef( ref ) } string function GetSelectedBurnCardRef( entity player ) @@ -182,19 +211,12 @@ string function GetSelectedBurnCardRef( entity player ) #endif #if SERVER || CLIENT - - if ( Riff_TitanAvailability() == eTitanAvailability.Never ) - { - //JFS: Batteries and Titan turrets are useless in PvP, turn them into amped weapons instead. Not an elegant solution at all. Fix next game. (Make boosts editable mid-match? ) - if ( ref == "burnmeter_emergency_battery" || ref == "burnmeter_at_turret_weapon" ) - ref = "burnmeter_amped_weapons" - } + if ( !EarnMeterMP_IsTitanEarnGametype() ) + ref = BurnMeter_GetNoTitansReplacement( ref ) if ( GetCurrentPlaylistVarInt( "featured_mode_all_ticks", 0 ) >= 1 ) - { if ( ref == "burnmeter_ticks" || ref == "burnmeter_random_foil" ) ref = "burnmeter_amped_weapons" - } #endif return ref diff --git a/Northstar.Custom/mod/scripts/vscripts/earn_meter/cl_earn_meter.gnut b/Northstar.Custom/mod/scripts/vscripts/earn_meter/cl_earn_meter.gnut new file mode 100644 index 00000000..5de6d956 --- /dev/null +++ b/Northstar.Custom/mod/scripts/vscripts/earn_meter/cl_earn_meter.gnut @@ -0,0 +1,573 @@ +global function Cl_EarnMeter_Init +global function Cl_EarnMeter_RegisterNetworkFunctions + +global function Cl_EarnMeter_ShowRewardHint +global function Cl_EarnMeter_SetLastHintTime + +global function Cl_EarnMeter_UpdateHint + +global function ServerCallback_EarnMeterAwarded + +#if SP +global function Cl_SP_UpdateCoreIcon +#endif + +global function EarnMeter_Update + +const float FILL_ANIM_DURATION = 0.7 + +struct EarnChangeData +{ + float startValue = 0.0 + float endValue = 0.0 + float updateTime = 0.0 +} + +struct +{ + EarnChangeData lastEarnedData + EarnChangeData lastOwnedData + + var earnMeterRui + var rewardRui + + var meterHintRui + + float lastHintTime +} file + +void function Cl_EarnMeter_Init() +{ + if ( !EARNMETER_ENABLED ) + return + + AddCallback_OnClientScriptInit( Cl_EarnMeter_AddClient ) + AddCallback_KillReplayStarted( KillReplayStarted ) + AddCallback_KillReplayEnded( KillReplayEnded ) + AddFirstPersonSpectateStartedCallback( FirstPersonSpectate_UpdateEarnMeter ) + AddFirstPersonSpectateEndedCallback( FirstPersonSpectate_UpdateEarnMeter ) + AddCallback_OnPlayerLifeStateChanged( Callback_PlayerLifestateChanged ) + AddCallback_OnPetTitanModeChanged( Callback_PetTitanModeChanged ) + AddCallback_OnPetTitanChanged( Callback_PetTitanChanged ) + + RegisterSignal( "Callback_PetTitanChanged" ) + + var rui = CreateCockpitRui( $"ui/earn_meter.rpak" ) + RuiSetFloat( rui, "fillAnimDuration", FILL_ANIM_DURATION ) + RuiSetGameTime( rui, "lastEarnChangeTime", RUI_BADGAMETIME ) + RuiSetGameTime( rui, "lastOwnChangeTime", RUI_BADGAMETIME ) + RuiSetFloat( rui, "earnedStartFrac", 0.0 ) + RuiSetFloat( rui, "ownedStartFrac", 0.0 ) + + file.earnMeterRui = rui + + file.meterHintRui = CreateCockpitRui( $"ui/meter_hint.rpak" ) + + { + //var rui = CreateCockpitRui( $"ui/reward_hud.rpak" ) + //file.rewardRui = rui + } +} + + +void function Cl_EarnMeter_RegisterNetworkFunctions() +{ + RegisterNetworkedVariableChangeCallback_float( EARNMETER_EARNEDFRAC, EarnedFracUpdate ) + RegisterNetworkedVariableChangeCallback_float( EARNMETER_OWNEDFRAC, OwnedFracUpdate ) + + RegisterNetworkedVariableChangeCallback_float( "coreAvailableFrac", CoreFracUpdate ) + + RegisterNetworkedVariableChangeCallback_int( EARNMETER_GOALID, GoalIdUpdate ) + RegisterNetworkedVariableChangeCallback_int( EARNMETER_REWARDID, RewardIdUpdate ) + RegisterNetworkedVariableChangeCallback_int( EARNMETER_MODE, ModeUpdate ) + RegisterNetworkedVariableChangeCallback_int( "rewardState", RewardStateUpdate ) + RegisterNetworkedVariableChangeCallback_int( "goalState", GoalStateUpdate ) +} + + +void function Cl_EarnMeter_AddClient( entity player ) +{ + EarnMeter_Update() + thread EarnMeter_Ping() +} + + +void function EarnedFracUpdate( entity player, float oldValue, float newValue, bool actuallyChanged ) +{ + if ( !actuallyChanged ) + return + + float currentValue = Cl_EarnMeter_GetCurrentMeterValue( file.lastEarnedData ) + RuiSetGameTime( file.earnMeterRui, "lastEarnChangeTime", Time() ) + RuiSetFloat( file.earnMeterRui, "earnedStartFrac", currentValue ) + + file.lastEarnedData.startValue = oldValue + file.lastEarnedData.endValue = newValue + file.lastEarnedData.updateTime = Time() +} + + +void function OwnedFracUpdate( entity player, float oldValue, float newValue, bool actuallyChanged ) +{ + if ( !actuallyChanged ) + return + + float currentValue = Cl_EarnMeter_GetCurrentMeterValue( file.lastOwnedData ) + RuiSetGameTime( file.earnMeterRui, "lastOwnChangeTime", Time() ) + RuiSetFloat( file.earnMeterRui, "ownedStartFrac", currentValue ) + + file.lastOwnedData.startValue = oldValue + file.lastOwnedData.endValue = newValue + file.lastOwnedData.updateTime = Time() +} + + +void function CoreFracUpdate( entity player, float oldValue, float newValue, bool actuallyChanged ) +{ + // net var lives on soul, which is global to all players + if ( player != GetLocalViewPlayer() ) + return + + if ( !actuallyChanged ) + return + + float currentValue = Cl_EarnMeter_GetCurrentMeterValue( file.lastOwnedData ) + RuiSetGameTime( file.earnMeterRui, "lastOwnChangeTime", Time() ) + RuiSetFloat( file.earnMeterRui, "ownedStartFrac", currentValue ) + + file.lastOwnedData.startValue = oldValue + file.lastOwnedData.endValue = newValue + file.lastOwnedData.updateTime = Time() +} + + +float function Cl_EarnMeter_GetCurrentMeterValue( EarnChangeData earnData ) +{ + float elapsedTime = Time() - earnData.updateTime + float delta = earnData.endValue - earnData.startValue + return earnData.endValue - (delta * EaseIn( GraphCapped( elapsedTime, 0.0, FILL_ANIM_DURATION, 1.0, 0.0 ) ) ) +} + + +void function RewardStateUpdate( entity player, int oldValue, int newValue, bool actuallyChanged ) +{ + if ( player != GetLocalViewPlayer() ) + return + + //if ( newValue == eRewardState.AVAILABLE ) + // RuiSetBool( file.rewardRui, "isVisible", true ) + //else + // RuiSetBool( file.rewardRui, "isVisible", false ) + + file.lastHintTime = 0 + if ( newValue == eRewardState.AVAILABLE ) + Cl_EarnMeter_ShowRewardHint() + + RuiSetInt( file.earnMeterRui, "rewardState", newValue ) +} + + +void function GoalStateUpdate( entity player, int oldValue, int newValue, bool actuallyChanged ) +{ + if ( player != GetLocalViewPlayer() ) + return + + file.lastHintTime = 0 + if ( newValue == eRewardState.AVAILABLE ) + Cl_EarnMeter_ShowRewardHint() + + RuiSetInt( file.earnMeterRui, "goalState", newValue ) +} + + +void function ModeUpdate( entity player, int oldValue, int newValue, bool actuallyChanged ) +{ + file.lastOwnedData.startValue = 0.0 + file.lastOwnedData.endValue = 0.0 + file.lastOwnedData.updateTime = 0.0 + + EarnMeter_Update() +} + +void function GoalIdUpdate( entity player, int oldValue, int newValue, bool actuallyChanged ) +{ + EarnMeter_Update() +} + +void function RewardIdUpdate( entity player, int oldValue, int newValue, bool actuallyChanged ) +{ + EarnMeter_Update() +} + +void function KillReplayStarted() +{ + EarnMeter_Update() +} + + +void function KillReplayEnded() +{ + EarnMeter_Update() +} + +void function FirstPersonSpectate_UpdateEarnMeter( entity clientPlayer, entity observerTarget ) +{ + EarnMeter_Update() +} + +void function Cl_EarnMeter_ShowRewardHint() +{ + entity player = GetLocalViewPlayer() + + if ( player == null ) + return + + if ( PlayerEarnMeter_GetMode( player ) == eEarnMeterMode.DEFAULT || PlayerEarnMeter_GetMode( player ) == eEarnMeterMode.CORE ) + { + if ( Time() - file.lastHintTime > 30.0 ) + { + RuiSetGameTime( file.earnMeterRui, "lastHintTime", Time() ) + file.lastHintTime = Time() + #if MP + if ( PlayerEarnMeter_GetMode( player ) == eEarnMeterMode.DEFAULT ) + { + TitanReadyMessage( 0.0, true ) + } + #endif + } + } +} + + +void function EarnMeter_Update() +{ + entity player = GetLocalViewPlayer() + if ( player == null ) + return + + if ( file.earnMeterRui == null ) + return + + switch ( PlayerEarnMeter_GetMode( player ) ) + { + case eEarnMeterMode.DISABLED: + break + + case eEarnMeterMode.DEFAULT: + EarnObject earnReward = PlayerEarnMeter_GetReward( player ) + EarnObject earnGoal = PlayerEarnMeter_GetGoal( player ) + + //RuiTrackFloat( file.meterHintRui, "earnedFrac", player, RUI_TRACK_SCRIPT_NETWORK_VAR, GetNetworkedVariableIndex( EARNMETER_EARNEDFRAC ) ) + //RuiTrackFloat( file.meterHintRui, "ownedFrac", player, RUI_TRACK_SCRIPT_NETWORK_VAR, GetNetworkedVariableIndex( EARNMETER_OWNEDFRAC ) ) + + RuiTrackFloat( file.earnMeterRui, "earnedFrac", player, RUI_TRACK_SCRIPT_NETWORK_VAR, GetNetworkedVariableIndex( EARNMETER_EARNEDFRAC ) ) + RuiTrackFloat( file.earnMeterRui, "ownedFrac", player, RUI_TRACK_SCRIPT_NETWORK_VAR, GetNetworkedVariableIndex( EARNMETER_OWNEDFRAC ) ) + RuiTrackFloat( file.earnMeterRui, "rewardFrac", player, RUI_TRACK_SCRIPT_NETWORK_VAR, GetNetworkedVariableIndex( EARNMETER_REWARDFRAC ) ) + RuiSetImage( file.earnMeterRui, "goalBuildingIcon", earnGoal.buildingImage ) + RuiSetImage( file.earnMeterRui, "goalReadyIcon", earnGoal.readyImage ) + RuiSetInt( file.earnMeterRui, "goalState", player.GetPlayerNetInt( "goalState" ) ) + RuiSetInt( file.earnMeterRui, "goalSubState", 0 ) + + RuiSetImage( file.earnMeterRui, "rewardBuildingIcon", earnReward.buildingImage ) + RuiSetImage( file.earnMeterRui, "rewardReadyIcon", earnReward.readyImage ) + RuiSetString( file.earnMeterRui, "rewardString", earnReward.localizedName ) + RuiSetInt( file.earnMeterRui, "rewardState", player.GetPlayerNetInt( "rewardState" ) ) + break + + case eEarnMeterMode.CORE: + if ( !IsValid( player.GetTitanSoul() ) ) + break + + entity soul = player.GetTitanSoul() + entity core = player.GetOffhandWeapons()[3] + string coreName = core.GetWeaponClassName() + array<string> coreMods = core.GetMods() + + #if SP + RuiTrackFloat( file.earnMeterRui, "earnedFrac", soul, RUI_TRACK_SCRIPT_NETWORK_VAR, GetNetworkedVariableIndex( "coreAvailableFrac" ) ) + RuiTrackFloat( file.earnMeterRui, "ownedFrac", soul, RUI_TRACK_SCRIPT_NETWORK_VAR, GetNetworkedVariableIndex( "coreAvailableFrac" ) ) + RuiSetFloat( file.earnMeterRui, "rewardFrac", 0.0 ) + RuiSetString( file.earnMeterRui, "rewardString", "" ) + + Cl_SP_UpdateCoreIcon( -1 ) + + RuiSetInt( file.earnMeterRui, "rewardState", eRewardState.DISABLED ) + RuiSetInt( file.earnMeterRui, "goalSubState", 0 ) + #endif + + #if MP + RuiTrackFloat( file.earnMeterRui, "earnedFrac", soul, RUI_TRACK_SCRIPT_NETWORK_VAR, GetNetworkedVariableIndex( "coreAvailableFrac" ) ) + RuiTrackFloat( file.earnMeterRui, "ownedFrac", soul, RUI_TRACK_SCRIPT_NETWORK_VAR, GetNetworkedVariableIndex( "coreAvailableFrac" ) ) + RuiTrackFloat( file.earnMeterRui, "rewardFrac", player, RUI_TRACK_SCRIPT_NETWORK_VAR, GetNetworkedVariableIndex( EARNMETER_REWARDFRAC ) ) + + if ( coreName == "mp_titancore_upgrade" ) + { + RuiSetImage( file.earnMeterRui, "goalBuildingIcon", GetVanguardCoreIcon( player ) ) + RuiSetImage( file.earnMeterRui, "goalReadyIcon", GetVanguardCoreIcon( player ) ) + } + else + { + RuiSetImage( file.earnMeterRui, "goalBuildingIcon", GetWeaponInfoFileKeyFieldAsset_WithMods_Global( coreName, coreMods, "hud_icon" ) ) + RuiSetImage( file.earnMeterRui, "goalReadyIcon", GetWeaponInfoFileKeyFieldAsset_WithMods_Global( coreName, coreMods, "hud_icon" ) ) + } + + EarnObject earnReward = PlayerEarnMeter_GetReward( player ) + RuiSetImage( file.earnMeterRui, "rewardBuildingIcon", earnReward.buildingImage ) + RuiSetImage( file.earnMeterRui, "rewardReadyIcon", earnReward.readyImage ) + RuiSetString( file.earnMeterRui, "rewardString", earnReward.localizedName ) + RuiSetInt( file.earnMeterRui, "rewardState", player.GetPlayerNetInt( "rewardState" ) ) + + RuiSetInt( file.earnMeterRui, "goalSubState", 0 ) + #endif + break + + case eEarnMeterMode.CORE_ACTIVE: + if ( !IsValid( player.GetTitanSoul() ) ) + break + + entity soul = player.GetTitanSoul() + entity core = player.GetOffhandWeapons()[3] + string coreName = core.GetWeaponClassName() + array<string> coreMods = core.GetMods() + + #if SP + Cl_SP_UpdateCoreIcon( -1 ) + #endif + + #if MP + if ( coreName == "mp_titancore_upgrade" ) + { + RuiSetImage( file.earnMeterRui, "goalBuildingIcon", GetVanguardCoreIcon( player, 1 ) ) + RuiSetImage( file.earnMeterRui, "goalReadyIcon", GetVanguardCoreIcon( player, 1 ) ) + } + else + { + RuiSetImage( file.earnMeterRui, "goalBuildingIcon", GetWeaponInfoFileKeyFieldAsset_WithMods_Global( coreName, coreMods, "hud_icon" ) ) + RuiSetImage( file.earnMeterRui, "goalReadyIcon", GetWeaponInfoFileKeyFieldAsset_WithMods_Global( coreName, coreMods, "hud_icon" ) ) + } + #endif + + RuiTrackFloat( file.earnMeterRui, "earnedFrac", soul, RUI_TRACK_SCRIPT_NETWORK_VAR, GetNetworkedVariableIndex( "coreExpireFrac" ) ) + RuiTrackFloat( file.earnMeterRui, "ownedFrac", soul, RUI_TRACK_SCRIPT_NETWORK_VAR, GetNetworkedVariableIndex( "coreExpireFrac" ) ) + RuiSetFloat( file.earnMeterRui, "rewardFrac", 0.0 ) + RuiSetString( file.earnMeterRui, "rewardString", "" ) + RuiSetInt( file.earnMeterRui, "rewardState", eRewardState.DISABLED ) + RuiSetInt( file.earnMeterRui, "goalSubState", 0 ) + + break + + case eEarnMeterMode.PET: + if ( !IsValid( player.GetPetTitan() ) ) + break + + entity titan = player.GetPetTitan() + string settingsName = PlayerSettingsIndexToName( titan.GetTitanSoul().GetPlayerSettingsNum() ) + + RuiSetBool( file.earnMeterRui, "isPetDoomed", titan.GetTitanSoul().IsDoomed() ) + RuiTrackFloat( file.earnMeterRui, "earnedFrac", titan, RUI_TRACK_HEALTH ) + RuiTrackFloat( file.earnMeterRui, "ownedFrac", titan, RUI_TRACK_HEALTH ) + RuiSetFloat( file.earnMeterRui, "rewardFrac", 0.0 ) + RuiSetString( file.earnMeterRui, "rewardString", "" ) + RuiSetImage( file.earnMeterRui, "goalBuildingIcon", Dev_GetPlayerSettingAssetByKeyField_Global( settingsName, "hud_follow_icon" ) ) + RuiSetImage( file.earnMeterRui, "goalReadyIcon", Dev_GetPlayerSettingAssetByKeyField_Global( settingsName, "hud_guard_icon" ) ) + RuiSetInt( file.earnMeterRui, "rewardState", eRewardState.DISABLED ) + RuiSetInt( file.earnMeterRui, "goalSubState", player.GetPetTitanMode() ) + break + } + + RuiSetInt( file.earnMeterRui, "meterMode", PlayerEarnMeter_GetMode( player ) ) + + Cl_EarnMeter_UpdateHint( player ) +} + +asset function GetVanguardCoreIcon( entity player, int countOffset = 0 ) +{ + Assert( player.IsTitan() ) + + if ( !IsConnected() ) //Persistence isn't available when we disconnect + return $"" + + if ( player != GetLocalClientPlayer() ) //Client Persistence doesn't know about other players. + return Dev_GetPlayerSettingAssetByKeyField_Global( "titan_atlas_vanguard", "core_building_icon" ) + + #if MP + TitanLoadoutDef loadout = GetActiveTitanLoadout( player ) + + entity soul = player.GetTitanSoul() + if ( !IsValid( soul ) ) + return $"" + + int upgradeCount = soul.GetTitanSoulNetInt( "upgradeCount" ) - countOffset + if ( upgradeCount == 0 && loadout.passive4 != "" ) + { + return GetItemImage( loadout.passive4 ) + } + else if ( upgradeCount == 1 && loadout.passive5 != "" ) + { + return GetItemImage( loadout.passive5 ) + } + else if ( upgradeCount == 2 && loadout.passive6 != "" ) + { + return GetItemImage( loadout.passive6 ) + } + else + { + return Dev_GetPlayerSettingAssetByKeyField_Global( "titan_atlas_vanguard", "core_building_icon" ) + } + #endif + + return $"" +} + +void function Cl_EarnMeter_UpdateHint( entity player ) +{ + if ( GetConVarInt( "hud_setting_showButtonHints" ) == 0 ) + RuiSetString( file.earnMeterRui, "buttonHintText", "" ) + else + RuiSetString( file.earnMeterRui, "buttonHintText", "%ability 1%" ) +} + + +void function Callback_PetTitanModeChanged( entity player ) +{ + EarnMeter_Update() +} + +void function Callback_PetTitanChanged( entity player ) +{ + if ( IsValid( player.GetPetTitan() ) ) + thread PetTitan_MeterUpdateThink( player, player.GetPetTitan() ) + + EarnMeter_Update() +} + + +void function PetTitan_MeterUpdateThink( entity player, entity titan ) +{ + titan.EndSignal( "OnDeath" ) + titan.EndSignal( "OnDestroy" ) + + player.Signal( "Callback_PetTitanChanged" ) + player.EndSignal( "Callback_PetTitanChanged" ) + + titan.EnableHealthChangedCallback() + + while ( true ) + { + WaitSignal( titan, "Doomed", "HealthChanged" ) + EarnMeter_Update() + } +} + + +void function Callback_PlayerLifestateChanged( entity player, int oldLifeState, int newLifeState ) +{ + if ( player != GetLocalViewPlayer() ) + return + + if ( newLifeState == LIFE_ALIVE ) + { + EarnMeter_Update() + Cl_EarnMeter_ShowRewardHint() + } +} + +void function EarnMeter_Ping() +{ + while ( true ) + { + entity player = GetLocalClientPlayer() + + switch ( PlayerEarnMeter_GetMode( player ) ) + { + case eEarnMeterMode.DEFAULT: + if ( player.GetPlayerNetInt( "rewardState" ) == eRewardState.AVAILABLE || player.GetPlayerNetInt( "goalState" ) == eRewardState.AVAILABLE ) + Cl_EarnMeter_ShowRewardHint() + break + + case eEarnMeterMode.CORE: + if ( !IsValid( player.GetTitanSoul() ) ) + break + + entity soul = player.GetTitanSoul() + if ( soul.GetTitanSoulNetFloat( "coreAvailableFrac" ) == 1.0 ) + Cl_EarnMeter_ShowRewardHint() + break + + } + + + wait 5.0 + } +} + +void function Cl_EarnMeter_SetLastHintTime( float time ) +{ + file.lastHintTime = time +} + + +#if SP +void function Cl_SP_UpdateCoreIcon( int loadoutIndex ) +{ + #if SP + string primaryWeaponName + + entity player = GetLocalViewPlayer() + if ( player == null ) + return + + if ( !player.IsTitan() ) + return + + if ( loadoutIndex == -1 ) + { + array<entity> weapons = player.GetMainWeapons() + + if ( weapons.len() <= 0 ) // JFS + return + + entity primaryWeapon = weapons[0] + primaryWeaponName = primaryWeapon.GetWeaponClassName() + } + else + { + primaryWeaponName = GetSPTitanLoadoutForIndex_PrimaryWeapon( loadoutIndex ) + } + + asset coreBuildingIcon = SP_GetIconForTitanWeapon( primaryWeaponName, "coreBuildingIcon" ) + asset coreReadyIcon = SP_GetIconForTitanWeapon( primaryWeaponName, "coreReadyIcon" ) + + RuiSetImage( file.earnMeterRui, "goalBuildingIcon", coreBuildingIcon ) + RuiSetImage( file.earnMeterRui, "goalReadyIcon", coreReadyIcon ) + #endif +} + + +asset function SP_GetIconForTitanWeapon( string weaponName, string iconName ) +{ + var dataTable = GetDataTable( $"datatable/titan_properties.rpak" ) + int row = GetDataTableRowMatchingStringValue( dataTable, GetDataTableColumnByName( dataTable, "primary" ), weaponName ) + + #if DEV + // Art uses a weapon_cubemap that breaks the Assert below, so just make it a warning in dev + if ( row == -1 ) + { + CodeWarning( "No loadout for weapon " + weaponName ) + return $"" + } + #endif + + Assert( row != -1, "No loadout for weapon " + weaponName ) + + asset icon = GetDataTableAsset( dataTable, row, GetDataTableColumnByName( dataTable, iconName ) ) + return icon +} + +#endif + + +void function ServerCallback_EarnMeterAwarded( float addedEarnedFrac, float addedOwnedFrac ) +{ + printt( "ServerCallback_EarnMeterAwarded", addedEarnedFrac, addedOwnedFrac ) +}
\ No newline at end of file diff --git a/Northstar.Custom/mod/scripts/vscripts/rodeo/_rodeo_titan.gnut b/Northstar.Custom/mod/scripts/vscripts/rodeo/_rodeo_titan.gnut index 499ca0b7..788b6dbe 100644 --- a/Northstar.Custom/mod/scripts/vscripts/rodeo/_rodeo_titan.gnut +++ b/Northstar.Custom/mod/scripts/vscripts/rodeo/_rodeo_titan.gnut @@ -2288,7 +2288,7 @@ void function PostRodeoAirControl( entity player ) { float elapsedTime = Time() - startTime player.kv.airSpeed = player.GetPlayerSettingsField( "airSpeed" ) * POST_RODEO_AIR_CONTROL_SCALE * (1 - (elapsedTime / POST_RODEO_AIR_CONTROL_DURATION)) - player.kv.airAcceleration = player.GetPlayerSettingsField( "airAcceleration" ) * POST_RODEO_AIR_CONTROL_SCALE * (1 - (elapsedTime / POST_RODEO_AIR_CONTROL_DURATION)) + player.kv.airAcceleration = GetCurrentPlaylistVarInt( "custom_air_accel_pilot", int( player.GetPlayerSettingsField( "airAcceleration" ) ) ) * POST_RODEO_AIR_CONTROL_SCALE * (1 - (elapsedTime / POST_RODEO_AIR_CONTROL_DURATION)) //printt( "scale", POST_RODEO_AIR_CONTROL_SCALE * (1 - (elapsedTime / POST_RODEO_AIR_CONTROL_DURATION)) ) WaitFrame() @@ -2345,7 +2345,7 @@ void function RestorePlayerAirControl( entity player ) //This function should re { Assert( player.IsPlayer() ) player.kv.airSpeed = player.GetPlayerSettingsField( "airSpeed" ) - player.kv.airAcceleration = player.GetPlayerSettingsField( "airAcceleration" ) + player.kv.airAcceleration = GetCurrentPlaylistVarInt( "custom_air_accel_pilot", int( player.GetPlayerSettingsField( "airAcceleration" ) ) ) } bool function ShouldThrowGrenadeInHatch( entity rodeoPilot ) @@ -2490,4 +2490,4 @@ bool function ClientCommand_TryNukeGrenade( entity player, array<string> args ) return true } -#endif
\ No newline at end of file +#endif diff --git a/Northstar.CustomServers/mod/scripts/vscripts/burnmeter/_burnmeter.gnut b/Northstar.CustomServers/mod/scripts/vscripts/burnmeter/_burnmeter.gnut index 6d13c75b..73277371 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/burnmeter/_burnmeter.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/burnmeter/_burnmeter.gnut @@ -1,6 +1,9 @@ untyped
global function BurnMeter_Init
+global function BurnMeter_SetBoostLimit
+global function BurnMeter_SetBoostRewardCount
+global function BurnMeter_GetLimitedRewardCount
global function ForceSetGlobalBurncardOverride
global function GetSelectedBurncardRefFromWeaponOrPlayer
global function RunBurnCardUseFunc
@@ -20,8 +23,11 @@ const float AMPED_WEAPONS_LENGTH = 30.0 const int MAPHACK_PULSE_COUNT = 4
const float MAPHACK_PULSE_DELAY = 2.0
-struct {
+struct
+{
string forcedGlobalBurncardOverride = ""
+ table<string, int> boostRewardCount
+ table<string, int> boostLimits
} file
void function BurnMeter_Init()
@@ -46,6 +52,13 @@ void function BurnMeter_Init() BurnReward_GetByRef( "burnmeter_rodeo_grenade" ).rewardAvailableCallback = PlayerUsesRodeoGrenadeBurncard
BurnReward_GetByRef( "burnmeter_nuke_titan" ).rewardAvailableCallback = PlayerUsesNukeTitanBurncard // unused in vanilla, fun though
+ BurnMeter_SetBoostRewardCount( "burnmeter_ticks", 2 )
+
+ BurnMeter_SetBoostLimit( "burnmeter_ticks", 6 )
+ BurnMeter_SetBoostLimit( "burnmeter_ap_turret_weapon", 3 )
+ BurnMeter_SetBoostLimit( "burnmeter_at_turret_weapon", 3 )
+ BurnMeter_SetBoostLimit( "burnmeter_holopilot_nova", 3 )
+
// setup player callbacks
AddCallback_GameStateEnter( eGameState.Playing, InitBurncardsForIntroPlayers )
AddCallback_OnClientConnected( InitBurncardsForLateJoiner )
@@ -57,6 +70,42 @@ void function BurnMeter_Init() RegisterSignal( "StopAmpedWeapons" )
}
+void function BurnMeter_SetBoostLimit( string burnRef, int limit )
+{
+ file.boostLimits[burnRef] <- limit
+}
+
+
+void function BurnMeter_SetBoostRewardCount( string burnRef, int rewardCount )
+{
+ file.boostRewardCount[burnRef] <- rewardCount
+}
+
+int function BurnMeter_GetLimitedRewardCount( entity player )
+{
+ EarnObject earnObject = PlayerEarnMeter_GetReward( player )
+ string burnRef = earnObject.ref
+ int limit = -1
+ int rewardCount = 1
+
+ if ( burnRef in file.boostLimits )
+ limit = file.boostLimits[burnRef]
+
+ if ( burnRef in file.boostRewardCount )
+ rewardCount = file.boostRewardCount[burnRef]
+
+ if ( limit < 0 )
+ return rewardCount
+
+ int current = PlayerInventory_CountBurnRef( player, burnRef )
+ int delta = limit - current
+
+ if ( delta <= 0 )
+ return 0
+
+ return int( min( delta, rewardCount ) )
+}
+
void function ForceSetGlobalBurncardOverride( string ref )
{
file.forcedGlobalBurncardOverride = ref
@@ -203,13 +252,10 @@ void function UseBurnCardWeapon( entity weapon, entity player ) Remote_CallFunction_Replay( player, "ServerCallback_RewardUsed", BurnReward_GetByRef( ref ).id )
RunBurnCardUseFunc( player, ref )
- // dont remove in RunBurnCardUseFunc because it can be called in non-burn_card_weapon_mod contexts
- // TODO: currently not sure how burncards can be stacked ( max clipcount for all burncards is 1, so can't just set that )
- // if this gets figured out, add a conditional check here to prevent removes if they've got burncards left
if ( PlayerEarnMeter_IsRewardAvailable( player ) )
PlayerEarnMeter_SetRewardUsed( player )
- player.TakeWeapon( BurnReward_GetByRef( ref ).weaponName )
+ PlayerInventory_PopInventoryItem( player )
}
void function UseBurnCardWeaponInCriticalSection( entity weapon, entity ownerPlayer )
@@ -220,20 +266,8 @@ void function UseBurnCardWeaponInCriticalSection( entity weapon, entity ownerPla void function BurnMeter_GiveRewardDirect( entity player, string itemRef )
{
- BurnReward burncard = BurnReward_GetByRef( itemRef )
-
- array<string> mods = [ "burn_card_weapon_mod" ]
- if ( burncard.extraWeaponMod != "" )
- mods.append( burncard.extraWeaponMod )
-
- // ensure inventory slot isn't full to avoid crash
- entity preexistingWeapon = player.GetOffhandWeapon( OFFHAND_INVENTORY )
- if ( IsValid( preexistingWeapon ) )
- player.TakeWeaponNow( preexistingWeapon.GetWeaponClassName() )
-
- player.GiveOffhandWeapon( burncard.weaponName, OFFHAND_INVENTORY, mods )
+ PlayerInventory_PushInventoryItemByBurnRef( player, itemRef )
Remote_CallFunction_Replay( player, "ServerCallback_RewardReadyMessage", player.s.respawnTime )
-
}
int function GetBurnCardWeaponSkin( entity weapon )
@@ -408,35 +442,27 @@ void function PlayerUsesNukeTitanBurncard( entity player ) void function PlayerUsesNukeBurncardThreaded( entity player )
{
- // if this is given manually ( i.e. not the equipped burnreward in inventory ), this will run at bad times
- // so do this check here, yes, this will cause people to lose their cards and get nothing, but better than free titan regens
- if ( !BurnMeterPlayer_CanUseReward( player, BurnReward_GetByRef( "burnmeter_nuke_titan" ) ) )
- return
-
- float ownedFrac = PlayerEarnMeter_GetOwnedFrac( player )
+ Point spawnpoint = GetTitanReplacementPoint( player, false )
+ entity titan = CreateOgre( TEAM_UNASSIGNED, spawnpoint.origin, spawnpoint.angles )
+ DispatchSpawn( titan )
- // use player's titan loadout, but with warpfall so faster and no dome
- TitanLoadoutDef titanLoadout = GetTitanLoadoutForPlayer( player )
- titanLoadout.passive3 = "pas_warpfall"
+ titan.kv.script_hotdrop = "4"
+ thread NPCTitanHotdrops( titan, false, "at_hotdrop_drop_2knee_turbo" )
- thread CreateTitanForPlayerAndHotdrop( player, GetTitanReplacementPoint( player, false ) )
+ Remote_CallFunction_Replay( player, "ServerCallback_ReplacementTitanSpawnpoint", spawnpoint.origin.x, spawnpoint.origin.y, spawnpoint.origin.z, Time() + GetHotDropImpactTime( titan, "at_hotdrop_drop_2knee_turbo" ) + 1.6 )
- entity titan = player.GetPetTitan()
- SetTeam( titan, TEAM_UNASSIGNED ) // make it so you can kill yourself lol
DoomTitan( titan )
- NPC_SetNuclearPayload( titan )
- // this should get run after the vanilla set_usable's event, so titan is never embarkable
- // embarking a titan in this state WILL kill the server so uhh, pretty bad
- AddAnimEvent( titan, "set_usable", void function( entity titan ) { titan.UnsetUsable() } )
+ titan.SetBossPlayer(player) // Do this so that if we crush something we get awarded the kill.
+
+ entity soul = titan.GetTitanSoul()
+ soul.soul.nukeAttacker = player // Use this to get credit for the explosion kills.
- titan.WaitSignal( "TitanHotDropComplete" )
- AutoTitan_SelfDestruct( titan )
+ NPC_SetNuclearPayload( titan )
- while ( PlayerEarnMeter_GetMode( player ) == eEarnMeterMode.PET )
- WaitFrame()
+ titan.WaitSignal( "ClearDisableTitanfall" )
+ titan.ClearBossPlayer() // Stop being the boss so we don't get an award for this titan blowing up.
- // restore original earnmeter values, no way to set earned that's exposed unfortunately
- PlayerEarnMeter_SetOwnedFrac( player, ownedFrac )
+ thread TitanEjectPlayer( titan, true )
}
void function PlayerUsesPermanentAmpedWeaponsBurncard( entity player )
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/earn_meter/sv_earn_meter.gnut b/Northstar.CustomServers/mod/scripts/vscripts/earn_meter/sv_earn_meter.gnut index dda84976..691f07fb 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/earn_meter/sv_earn_meter.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/earn_meter/sv_earn_meter.gnut @@ -39,6 +39,8 @@ global function SharedEarnMeter_AddEarnedAndOwned global function PlayerEarnMeter_SetEnabled global function PlayerEarnMeter_Enabled +global function PlayerEarnMeter_SetBoostByRef + global struct EarnMeterThresholdEarnedStruct { float threshold @@ -505,4 +507,24 @@ void function PlayerEarnMeter_SetEnabled( bool enabled ) bool function PlayerEarnMeter_Enabled() { return file.earnMeterEnabled +} + +void function PlayerEarnMeter_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 ) }
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/earn_meter/sv_earn_meter_mp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/earn_meter/sv_earn_meter_mp.gnut index 4c42a825..1aa0f042 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/earn_meter/sv_earn_meter_mp.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/earn_meter/sv_earn_meter_mp.gnut @@ -23,7 +23,7 @@ void function EarnMeterMP_SetTitanLoadout( entity player ) if ( EarnMeterMP_IsTitanEarnGametype() ) PlayerEarnMeter_SetGoal( player, EarnObject_GetByRef( GetTitanLoadoutForPlayer( player ).titanClass ) ) else - PlayerEarnMeter_SetGoal( player, EarnObject_GetByRef( GetSelectedBurncardRefFromWeaponOrPlayer( null, player ) ) ) + PlayerEarnMeter_SetGoal( player, PlayerEarnMeter_GetReward( player ) ) } void function EarnMeterMP_SetPassiveMeterGainEnabled( bool enabled ) @@ -34,23 +34,10 @@ void function EarnMeterMP_SetPassiveMeterGainEnabled( bool enabled ) void function SetupPlayerEarnMeter( entity player ) { PlayerEarnMeter_Reset( player ) - - if ( Riff_BoostAvailability() != eBoostAvailability.Disabled ) - { - string burncardRef = GetSelectedBurncardRefFromWeaponOrPlayer( null, player ) - PlayerEarnMeter_SetReward( player, EarnObject_GetByRef( burncardRef ) ) // pretty sure this works? - PlayerEarnMeter_SetRewardFrac( player, BurnReward_GetByRef( burncardRef ).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_GetByRef( GetSelectedBurncardRefFromWeaponOrPlayer( null, player ) ) ) - + + string burncardRef = GetSelectedBurnCardRef( player ) + PlayerEarnMeter_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 ) @@ -61,24 +48,24 @@ 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 ) } @@ -116,14 +103,12 @@ void function EarnMeterMP_PlayerLifeThink( entity player ) { if ( !IsTitanAvailable( player ) && PlayerEarnMeter_GetOwnedFrac( player ) == 1.0 ) // this should only be the case after player has dropped their titan { + float oldRewardFrac = PlayerEarnMeter_GetRewardFrac( player ) PlayerEarnMeter_Reset( player ) - // reset rewards - string burncardRef = GetSelectedBurncardRefFromWeaponOrPlayer( null, player ) - PlayerEarnMeter_SetReward( player, EarnObject_GetByRef( burncardRef ) ) - PlayerEarnMeter_SetRewardFrac( player, BurnReward_GetByRef( burncardRef ).cost ) + PlayerEarnMeter_SetRewardFrac( player, oldRewardFrac ) PlayerEarnMeter_EnableReward( player ) } - + if ( PlayerEarnMeter_GetRewardFrac( player ) != 0 ) PlayerEarnMeter_EnableReward( player ) } @@ -135,7 +120,7 @@ void function EarnMeterMP_PlayerLifeThink( entity player ) lastEarnMeterMode = desiredEarnMeterMode } - + if ( lastEarnMeterMode == eEarnMeterMode.DEFAULT ) { if ( PlayerEarnMeter_GetOwnedFrac( player ) < 1.0 ) @@ -148,26 +133,30 @@ void function EarnMeterMP_PlayerLifeThink( entity player ) player.SetPlayerNetInt( "goalState", eRewardState.AVAILABLE ) PlayerEarnMeter_RefreshGoal( player ) } - + 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 ) { - BurnReward burncard = BurnReward_GetByRef( GetSelectedBurnCardRef( player ) ) - + EarnObject earnobject = PlayerEarnMeter_GetReward( player ) + BurnReward burncard = BurnReward_GetByRef( earnobject.ref ) + while ( burncard.ref == "burnmeter_random_foil" ) burncard = BurnReward_GetRandom() - BurnMeter_GiveRewardDirect( player, burncard.ref ) + for ( int i = 0; i < BurnMeter_GetLimitedRewardCount( player ); i++ ) + BurnMeter_GiveRewardDirect( player, burncard.ref ) + + PlayerEarnMeter_DisableReward( player ) } void function EarnMeterMP_TitanEarned( entity player ) @@ -179,13 +168,11 @@ void function EarnMeterMP_TitanEarned( entity player ) } else { + float oldRewardFrac = PlayerEarnMeter_GetRewardFrac( player ) PlayerEarnMeter_Reset( player ) - // reset rewards - string burncardRef = GetSelectedBurncardRefFromWeaponOrPlayer( null, player ) - PlayerEarnMeter_SetReward( player, EarnObject_GetByRef( burncardRef ) ) - PlayerEarnMeter_SetRewardFrac( player, BurnReward_GetByRef( burncardRef ).cost ) + PlayerEarnMeter_SetRewardFrac( player, oldRewardFrac ) PlayerEarnMeter_EnableReward( player ) - + if ( PlayerEarnMeter_GetRewardFrac( player ) != 0 ) PlayerEarnMeter_EnableReward( player ) } diff --git a/Northstar.CustomServers/mod/scripts/vscripts/item_inventory/sv_item_inventory.gnut b/Northstar.CustomServers/mod/scripts/vscripts/item_inventory/sv_item_inventory.gnut index 6d8cf55c..a768b3f3 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/item_inventory/sv_item_inventory.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/item_inventory/sv_item_inventory.gnut @@ -5,19 +5,126 @@ global function PlayerInventory_RefreshEquippedState global function PlayerInventory_StartCriticalSection global function PlayerInventory_EndCriticalSectionForWeaponOnEndFrame +global function PlayerInventory_PushInventoryItem +global function PlayerInventory_PushInventoryItemByBurnRef +global function PlayerInventory_PopInventoryItem +global function PlayerInventory_CountBurnRef + +struct +{ + table<entity, array<InventoryItem> > playerInventoryStacks +} file + void function Sv_ItemInventory_Init() { + AddCallback_OnClientConnected( Sv_ItemInventory_OnClientConnected ) + AddCallback_OnPlayerRespawned( Sv_ItemInventory_OnPlayerRespawned ) +} +void function Sv_ItemInventory_OnClientConnected( entity player ) +{ + file.playerInventoryStacks[ player ] <- [] } +void function Sv_ItemInventory_OnPlayerRespawned( entity player ) +{ + array<InventoryItem> playerInventoryStack = file.playerInventoryStacks[ player ] + + if (playerInventoryStack.len() > 0) { + InventoryItem topInventoryItem = playerInventoryStack[playerInventoryStack.len() - 1] + PlayerInventory_GiveInventoryItem(player, topInventoryItem) + } + + return +} + + int function SvPlayerInventory_ItemCount( entity player ) { - return 0 + return file.playerInventoryStacks[ player ].len() } int function PlayerInventory_CountTurrets( entity player ) { - return 0 + int turretCount = 0 + + foreach ( inventoryItem in file.playerInventoryStacks[ player ] ) + if ( inventoryItem.weaponRef == "mp_ability_turretweapon" ) + turretCount += 1 + + return turretCount +} + +int function PlayerInventory_CountBurnRef( entity player, string burnRef ) +{ + int count = 0 + + foreach ( inventoryItem in file.playerInventoryStacks[ player ] ) + if ( inventoryItem.itemType == eInventoryItemType.burnmeter ) + if ( inventoryItem.burnReward.ref == burnRef ) + count += 1 + + return count +} + +void function PlayerInventory_TakeInventoryItem( entity player ) +{ + entity preexistingWeapon = player.GetOffhandWeapon( OFFHAND_INVENTORY ) + if ( IsValid( preexistingWeapon ) ) + player.TakeWeaponNow( preexistingWeapon.GetWeaponClassName() ) +} + +void function PlayerInventory_GiveInventoryItem( entity player, InventoryItem inventoryItem ) +{ + array<string> mods = [] + + if ( inventoryItem.itemType == eInventoryItemType.burnmeter ) { + mods.append( "burn_card_weapon_mod" ) + if ( inventoryItem.burnReward.extraWeaponMod != "" ) + mods.append( inventoryItem.burnReward.extraWeaponMod ) + } + + // ensure inventory slot isn't full to avoid crash + PlayerInventory_TakeInventoryItem( player ) + + player.GiveOffhandWeapon( inventoryItem.weaponRef, OFFHAND_INVENTORY, mods ) +} + +void function PlayerInventory_PushInventoryItem( entity player, InventoryItem inventoryItem ) +{ + file.playerInventoryStacks[ player ].append(inventoryItem) + player.SetPlayerNetInt( "itemInventoryCount", file.playerInventoryStacks[ player ].len() ) + + PlayerInventory_GiveInventoryItem(player, inventoryItem) +} + +void function PlayerInventory_PushInventoryItemByBurnRef( entity player, string burnRef ) +{ + InventoryItem inventoryItem + inventoryItem.itemType = eInventoryItemType.burnmeter + inventoryItem.burnReward = BurnReward_GetByRef( burnRef ) + inventoryItem.weaponRef = inventoryItem.burnReward.weaponName + + PlayerInventory_PushInventoryItem(player, inventoryItem) +} + +void function PlayerInventory_PopInventoryItem( entity player ) +{ + array<InventoryItem> playerInventoryStack = file.playerInventoryStacks[ player ] + + if (playerInventoryStack.len() > 0) { + InventoryItem topInventoryItem = playerInventoryStack.pop() + player.SetPlayerNetInt( "itemInventoryCount", playerInventoryStack.len() ) + + if (playerInventoryStack.len() > 0) { + InventoryItem nextInventoryItem = playerInventoryStack[playerInventoryStack.len() - 1] + PlayerInventory_GiveInventoryItem(player, nextInventoryItem) + } else { + PlayerInventory_TakeInventoryItem( player ) + } + } + + return } void function PlayerInventory_RefreshEquippedState( entity player ) @@ -30,7 +137,7 @@ void function PlayerInventory_StartCriticalSection( entity player ) } -void function PlayerInventory_EndCriticalSectionForWeaponOnEndFrame( entity player ) +void function PlayerInventory_EndCriticalSectionForWeaponOnEndFrame( entity weapon ) { }
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut index 62f7d459..b8cd67ad 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut @@ -335,6 +335,7 @@ void function PostDeathThread_MP( entity player, var damageInfo ) // based on ga } player.SetPlayerSettings( "spectator" ) // prevent a crash with going from titan => pilot on respawn + player.StopPhysics() // need to set this after SetPlayerSettings if ( RespawnsEnabled() ) { @@ -467,6 +468,7 @@ void function RespawnAsTitan( entity player, bool manualPosition = false ) void function PlayerBecomesSpectator( entity player ) { player.StartObserverMode( OBS_MODE_CHASE ) + player.StopPhysics() player.EndSignal( "OnRespawned" ) player.EndSignal( "OnDestroy" ) @@ -533,6 +535,7 @@ void function PlayerBecomesSpectator( entity player ) player.SetObserverModeStaticAngles( target.GetAngles() ) player.StartObserverMode( OBS_MODE_STATIC ) } + player.StopPhysics() } } diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut index 119b1712..002b1331 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut @@ -148,6 +148,11 @@ void function ScoreEvent_PlayerKilled( entity victim, entity attacker, var damag if ( attacker.p.playerKillStreaks[ victim ] == DOMINATING_KILL_REQUIREMENT ) AddPlayerScore( attacker, "Dominating" ) + if ( Time() - attacker.s.lastKillTime > CASCADINGKILL_REQUIREMENT_TIME ) + { + attacker.s.currentTimedKillstreak = 0 // reset first before kill + attacker.s.lastKillTime = Time() + } // timed killstreaks if ( Time() - attacker.s.lastKillTime <= CASCADINGKILL_REQUIREMENT_TIME ) @@ -161,8 +166,6 @@ void function ScoreEvent_PlayerKilled( entity victim, entity attacker, var damag else if ( attacker.s.currentTimedKillstreak == MEGAKILL_REQUIREMENT_KILLS ) AddPlayerScore( attacker, "MegaKill" ) } - else - attacker.s.currentTimedKillstreak = 0 // reset if a kill took too long attacker.s.lastKillTime = Time() } @@ -231,4 +234,4 @@ void function ScoreEvent_SetupEarnMeterValuesForMixedModes() // mixed modes in t void function ScoreEvent_SetupEarnMeterValuesForTitanModes() { // relatively sure we don't have to do anything here but leaving this function for consistency -}
\ No newline at end of file +} |