Player partial class methods for managing player upgrades. Declares a networked NetList<string> Upgrades, checks ownership, grants upgrades on the host, and handles host-validated purchase RPCs with dependency, price, and achievement checks.
using System.Linq;
using Sandbox;
using BrickJam.Upgrading;
namespace BrickJam;
public sealed partial class Player
{
/// <summary>
/// Owned upgrade identifiers. Host-authoritative and replicated. Replaces the legacy
/// <c>[Net, Change] IList<string> Upgrades</c>.
/// </summary>
[Sync( SyncFlags.FromHost )] public NetList<string> Upgrades { get; set; } = new();
public bool HasUpgrade( string identifier ) => Upgrades.Contains( identifier );
/// <summary>Grant an upgrade unconditionally (host-side).</summary>
public void GiveUpgrade( string identifier )
{
if ( Networking.IsHost && Upgrade.Exists( identifier ) && !Upgrades.Contains( identifier ) )
Upgrades.Add( identifier );
}
/// <summary>
/// Purchase request from the owning client's shop UI; validated and applied on the host.
/// Replaces the legacy <c>[ConCmd.Server] BuyUpgrade</c>.
/// </summary>
[Rpc.Host]
public void BuyUpgrade( string identifier )
{
var upgrade = Upgrade.Find( identifier );
if ( upgrade is null )
{
Log.Warning( $"Tried to buy unknown upgrade {identifier}" );
return;
}
if ( upgrade.Dependencies.Any( dep => !HasUpgrade( dep ) ) )
{
Log.Warning( $"Missing dependency for upgrade {identifier}" );
return;
}
if ( upgrade.Price > Money || HasUpgrade( identifier ) )
return;
SetMoney( Money - upgrade.Price );
Upgrades.Add( identifier );
// Fully Loaded: this purchase completed the full shop catalogue.
if ( Upgrade.All.Any() && Upgrade.All.All( u => HasUpgrade( u.Identifier ) ) )
TrackAchievement( GameStats.AchFullyLoaded );
}
}