Add tower Sell action with refund + coin VFX/SFX

Owner-validated sell RPC refunds SellRefundPercent of invested gold (Wall refunds 100% while un-upgraded), despawns the tower, and broadcasts a coin-burst VFX + rustle SFX. Refunds do not count as per-wave income. Investment/upgrade tracking added as the seam for the future upgrade system.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Matt F 2026-07-14 20:05:06 -07:00
parent 2429efbf6a
commit 9be31b1645
7 changed files with 361 additions and 12 deletions

View file

@ -143,11 +143,17 @@ namespace TD.Gameplay
/// <summary>
/// Server-side entry point for awarding gold (wave clear, enemy kill).
/// Direct call — not Rpc-wrapped — because awards always originate
/// from server-authoritative game events. Also increments
/// <see cref="GoldEarnedThisWave"/> so the HUD's per-wave counter reflects
/// it; spending does not decrement that counter (it tracks earnings, not balance).
/// from server-authoritative game events. When <paramref name="countAsEarned"/>
/// is true (the default) it also increments <see cref="GoldEarnedThisWave"/> so the
/// HUD's per-wave counter reflects it; spending does not decrement that counter (it
/// tracks earnings, not balance).
/// </summary>
public void AwardGold(int amount)
/// <param name="countAsEarned">
/// Pass false for gold returned to the player that isn't income — e.g. a tower-sell
/// refund. The player's balance still rises, but the per-wave "earned" counter does not,
/// so refunds don't inflate round-income stats.
/// </param>
public void AwardGold(int amount, bool countAsEarned = true)
{
if (!IsServer)
{
@ -158,7 +164,7 @@ namespace TD.Gameplay
if (amount <= 0) return;
currentGold.Value += amount;
goldEarnedThisWave.Value += amount;
if (countAsEarned) goldEarnedThisWave.Value += amount;
}
/// <summary>