Table of Contents

Class CharacterCurrency

Namespace
FishMMO.Shared
Assembly
FishMMO.Shared.dll

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

character ICharacter
template CharacterAttributeTemplate
amount long

Returns

bool

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

character ICharacter
template CharacterAttributeTemplate
amount long

Amount 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

character ICharacter

The character to read.

template CharacterAttributeTemplate

The currency attribute template.

balance long

The 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

character ICharacter

The character to charge.

template CharacterAttributeTemplate

The currency attribute template.

amount long

Amount to deduct. Non-positive amounts are rejected.

persist Func<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.