aboutsummaryrefslogtreecommitdiff
path: root/Northstar.CustomServers
diff options
context:
space:
mode:
authorConnie Price <contact@connieprice.co.uk>2022-01-04 19:13:56 +0000
committerConnie Price <contact@connieprice.co.uk>2022-01-04 19:13:56 +0000
commita352fbb877aabdaf9b124eee47fb78f2ac0007a6 (patch)
treea97dc0ed1c8673715e1fce1420560589aa312973 /Northstar.CustomServers
parente128e87bd23d5c7702e92c01e07684e3804f5a69 (diff)
downloadNorthstarMods-a352fbb877aabdaf9b124eee47fb78f2ac0007a6.tar.gz
NorthstarMods-a352fbb877aabdaf9b124eee47fb78f2ac0007a6.zip
Big Boost/Earn Meter Fixes!
* Only set the boost from persistence once, allowing for the boost to be changed mid game by other scripts. * Added `PlayerEarnMeter_SetBoostByRef(string boostRef)` to simplify setting boosts. * Boosts now correctly disappear after being reward to the player. * Client-side reward icon will now update when the boost is changed. * Titan cores will now pull the HUD icon from the core, instead of the titan chassis. Allowing this to be handled better by other scripts. * Player boost inventory implemented! Now players will be able to store multiple boosts like vanilla. * Boost inventory limits, all vanilla boost limits are respected, and `BurnMeter_SetBoostLimit( string burnRef, int limit )` was added to accommodate this. * Fixed the unused nuke titan boost code so that if anyone decides to use it it's not horribly error prone.
Diffstat (limited to 'Northstar.CustomServers')
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/burnmeter/_burnmeter.gnut88
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/earn_meter/sv_earn_meter.gnut22
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/earn_meter/sv_earn_meter_mp.gnut64
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/item_inventory/sv_item_inventory.gnut113
4 files changed, 207 insertions, 80 deletions
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/burnmeter/_burnmeter.gnut b/Northstar.CustomServers/mod/scripts/vscripts/burnmeter/_burnmeter.gnut
index 6d13c75b9..9bcfd308c 100644
--- a/Northstar.CustomServers/mod/scripts/vscripts/burnmeter/_burnmeter.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/burnmeter/_burnmeter.gnut
@@ -1,6 +1,8 @@
untyped
global function BurnMeter_Init
+global function BurnMeter_SetBoostLimit
+global function BurnMeter_CheckBoostLimit
global function ForceSetGlobalBurncardOverride
global function GetSelectedBurncardRefFromWeaponOrPlayer
global function RunBurnCardUseFunc
@@ -22,6 +24,7 @@ const float MAPHACK_PULSE_DELAY = 2.0
struct {
string forcedGlobalBurncardOverride = ""
+ table<string, int> boostLimits
} file
void function BurnMeter_Init()
@@ -46,6 +49,11 @@ void function BurnMeter_Init()
BurnReward_GetByRef( "burnmeter_rodeo_grenade" ).rewardAvailableCallback = PlayerUsesRodeoGrenadeBurncard
BurnReward_GetByRef( "burnmeter_nuke_titan" ).rewardAvailableCallback = PlayerUsesNukeTitanBurncard // unused in vanilla, fun though
+ 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 +65,31 @@ void function BurnMeter_Init()
RegisterSignal( "StopAmpedWeapons" )
}
+void function BurnMeter_SetBoostLimit( string burnRef, int limit )
+{
+ file.boostLimits[burnRef] <- limit
+}
+
+bool function BurnMeter_CheckBoostLimit( entity player )
+{
+ EarnObject earnObject = PlayerEarnMeter_GetReward( player )
+ string burnRef = earnObject.ref
+ int limit = -1
+
+ if ( burnRef in file.boostLimits )
+ limit = file.boostLimits[burnRef]
+
+ if ( limit < 0 )
+ return false
+
+ int current = PlayerInventory_CountBurnRef( player, burnRef )
+
+ if ( current < limit )
+ return false
+
+ return true
+}
+
void function ForceSetGlobalBurncardOverride( string ref )
{
file.forcedGlobalBurncardOverride = ref
@@ -203,13 +236,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 +250,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 +426,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.
- titan.WaitSignal( "TitanHotDropComplete" )
- AutoTitan_SelfDestruct( titan )
+ entity soul = titan.GetTitanSoul()
+ soul.soul.nukeAttacker = player // Use this to get credit for the explosion kills.
+
+ 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 dda84976c..691f07fb4 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 4c42a825b..193262f17 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,31 @@ 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 )
+ if ( !BurnMeter_CheckBoostLimit( player ) ) {
+ BurnMeter_GiveRewardDirect( player, burncard.ref )
+ }
+
+ PlayerEarnMeter_DisableReward( player )
}
void function EarnMeterMP_TitanEarned( entity player )
@@ -179,13 +169,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 6d8cf55cb..a768b3f35 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