Class CharacterCurrency
Reads and moves a character's currency.
public static class CharacterCurrency
- Inheritance
-
CharacterCurrency
- Inherited Members
Remarks
Currency is a CharacterAttribute rather than a field of its own, so every
system that touches it — looting, crafting, merchants, mail, and housing — has to resolve
the template, find the attribute, check sufficiency, write the balance and persist it. Done
by hand at each site that is five chances to get it wrong, and it has already gone wrong:
the crafting path tested FinalValue while writing Value, which let a
character wearing any currency-boosting buff spend money it did not have, and that was
fixed in the merchant and ability-learning paths before anyone noticed crafting had the
same defect.
This puts the sequence in one place so a new caller inherits the corrected behaviour instead of reimplementing it.
Methods
CanAfford(ICharacter, CharacterAttributeTemplate, long)
True when the character holds at least amount.
public static bool CanAfford(ICharacter character, CharacterAttributeTemplate template, long amount)
Parameters
characterICharactertemplateCharacterAttributeTemplateamountlong
Returns
Remarks
A non-positive amount is affordable by definition; callers that treat zero as a free transaction do not need to special-case it.
TryAdd(ICharacter, CharacterAttributeTemplate, long)
Grants currency to a character.
public static bool TryAdd(ICharacter character, CharacterAttributeTemplate template, long amount)
Parameters
characterICharactertemplateCharacterAttributeTemplateamountlongAmount to grant. Non-positive amounts are rejected rather than silently deducting, so a sign error cannot quietly take money.
Returns
- bool
True when the balance was changed.
TryGetBalance(ICharacter, CharacterAttributeTemplate, out long)
Reads a character's currency balance.
public static bool TryGetBalance(ICharacter character, CharacterAttributeTemplate template, out long balance)
Parameters
characterICharacterThe character to read.
templateCharacterAttributeTemplateThe currency attribute template.
balancelongThe balance, or zero when it could not be read.
Returns
- bool
True when the character has the attribute.
Remarks
Deliberately the BASE value, not FinalValue. AddValue(int, bool) writes the base, and FinalValue is the base plus every modifier in force — so testing one while writing the other lets a buff be spent as though it were money and drives the balance negative by exactly the size of the buff.
TrySpend(ICharacter, CharacterAttributeTemplate, long, Func<bool>)
Deducts currency, persists the change, and refunds it if persistence is refused.
public static bool TrySpend(ICharacter character, CharacterAttributeTemplate template, long amount, Func<bool> persist = null)
Parameters
characterICharacterThe character to charge.
templateCharacterAttributeTemplateThe currency attribute template.
amountlongAmount to deduct. Non-positive amounts are rejected.
persistFunc<bool>Persistence callback; return false to refuse and trigger a refund.
Returns
- bool
True when the character was charged and the change persisted.
Remarks
The ordering is deliberate and matches the merchant, ability-learning and crafting paths: deduct, then persist, then let the caller grant whatever was bought. Persisting snapshots the in-memory values as they stand, so it has to run after the deduction rather than before it — and if the write is refused the deduction has to be undone, otherwise the player is charged for something they never received.
Persistence is supplied by the caller because it differs by context: the scene server has its own attribute-write path, and shared code has no business knowing about it. Passing null skips persistence for callers that batch their own writes.