7 internal readonly
struct WalletChangedEvent
9 public readonly Option<Character> Owner;
10 public readonly Wallet Wallet;
11 public readonly WalletInfo Info;
12 public readonly WalletChangedData ChangedData;
14 public WalletChangedEvent(Wallet wallet, WalletChangedData changedData, WalletInfo info)
18 ChangedData = changedData;
24 internal struct WalletInfo : INetSerializableStruct
26 public int RewardDistribution;
33 internal struct NetWalletUpdate : INetSerializableStruct
35 [NetworkSerialize(ArrayMaxSize = 256)]
36 public NetWalletTransaction[] Transactions;
43 internal struct NetWalletTransfer : INetSerializableStruct
45 public Option<ushort> Sender;
46 public Option<ushort> Receiver;
53 internal struct NetWalletSetSalaryUpdate : INetSerializableStruct
56 public Option<ushort>
Target;
58 [NetworkSerialize(MinValueInt = 0, MaxValueInt = 100)]
59 public int NewRewardDistribution;
67 internal struct WalletChangedData : INetSerializableStruct
69 public Option<int> RewardDistributionChanged;
70 public Option<int> BalanceChanged;
72 public readonly WalletChangedData MergeInto(WalletChangedData other)
74 other.BalanceChanged = AddOptionalInt(other.BalanceChanged, BalanceChanged);
75 other.RewardDistributionChanged = AddOptionalInt(other.RewardDistributionChanged, RewardDistributionChanged);
77 other.BalanceChanged = TurnToNoneIfZero(other.BalanceChanged);
78 other.RewardDistributionChanged = TurnToNoneIfZero(other.RewardDistributionChanged);
81 static Option<int> AddOptionalInt(Option<int> a, Option<int> b)
83 bool hasValue1 = a.TryUnwrap(out var value1);
84 bool hasValue2 = b.TryUnwrap(out var value2);
87 ? Option.Some(value1 + value2)
94 static Option<int> TurnToNoneIfZero(Option<int> option)
96 return option.Bind(i => i == 0 ? Option.None : Option.Some(i));
105 internal struct NetWalletTransaction : INetSerializableStruct
107 public Option<ushort> CharacterID;
108 public WalletChangedData ChangedData;
109 public WalletInfo Info;
113 internal sealed
class InvalidWallet : Wallet
117 public override int Balance
120 set =>
throw new InvalidOperationException(
"Tried to set the balance on an invalid wallet");
123 public override int RewardDistribution
126 set =>
throw new InvalidOperationException(
"Tried to set the reward distribution on an invalid wallet");
130 internal partial class Wallet
132 public static readonly Wallet
Invalid =
new InvalidWallet();
134 public const string LowerCaseSaveElementName =
"wallet";
136 private const string AttributeNameBalance =
"balance",
137 AttributeNameRewardDistribution =
"rewarddistribution",
138 SaveElementName =
"Wallet";
140 public readonly Option<Character> Owner;
144 public virtual int Balance
147 set => balance = ClampBalance(value);
150 private int rewardDistribution;
152 public virtual int RewardDistribution
154 get => rewardDistribution;
157 rewardDistribution = ClampRewardDistribution(value);
159 if (Owner.TryUnwrap(out var character) && character.Info is { } info)
161 info.LastRewardDistribution = Option.Some(rewardDistribution);
166 public Wallet(Option<Character> owner)
171 public Wallet(Option<Character> owner, XElement element): this(owner)
173 balance = ClampBalance(element.GetAttributeInt(AttributeNameBalance, 0));
174 rewardDistribution = ClampBalance(element.GetAttributeInt(AttributeNameRewardDistribution, 0));
177 public XElement Save()
179 XElement element =
new XElement(SaveElementName,
180 new XAttribute(AttributeNameBalance, Balance),
181 new XAttribute(AttributeNameRewardDistribution, RewardDistribution));
185 public bool TryDeduct(
int price)
187 if (!CanAfford(price)) {
return false; }
193 public bool CanAfford(
int price) => Balance >= price;
194 public void Refund(
int price) => Give(price);
196 public void Give(
int amount)
199 SettingsChanged(balanceChanged: Option<int>.Some(amount), rewardChanged: Option<int>.
None());
202 public void Deduct(
int price)
205 SettingsChanged(balanceChanged: Option<int>.Some(-price), rewardChanged: Option<int>.
None());
213 public void SetRewardDistribution(
int value)
215 int oldValue = RewardDistribution;
216 RewardDistribution = value;
217 SettingsChanged(balanceChanged: Option<int>.
None(), rewardChanged: Option<int>.Some(RewardDistribution - oldValue));
220 public WalletInfo CreateWalletInfo()
222 return new WalletInfo
225 RewardDistribution = RewardDistribution
229 public string GetOwnerLogName()
230 => Owner.TryUnwrap(out var character) ? character.Name :
"the bank";
232 partial
void SettingsChanged(Option<int> balanceChanged, Option<int> rewardChanged);
234 private static int ClampBalance(
int value) => Math.Clamp(value, 0, CampaignMode.MaxMoney);
235 private static int ClampRewardDistribution(
int value) => Math.Clamp(value, 0, 100);