Merge pull request 'tower-sell' (#12) from tower-sell into main

Reviewed-on: #12
This commit is contained in:
matt 2026-07-14 23:54:08 -07:00
commit 52f7bfdf51
28 changed files with 5746 additions and 33 deletions

View file

@ -1327,19 +1327,30 @@ namespace TD.UI
return btn;
}
// Sell action for a completed tower. Refund is computed on the TowerInstance (single
// source of truth shared with the server) so the badge shows exactly what the player
// gets back. Hotkey is Key.None: the bottom-right slot's letter (B) is already the
// global buff-menu toggle — see CreateBuffMenuButton — so binding it here would fire
// both. The button stays click-only.
private VisualElement CreateSellButton(TowerInstance tower, Key hotkey)
{
int sellValue = tower.Definition != null
? Mathf.RoundToInt(tower.Definition.GoldCost * 0.7f)
: 0;
// Only the tower's owner can sell it (the server enforces this too). A non-owner
// may have this tower view-selected — show the slot disabled with no refund badge
// so the action reads as unavailable rather than misleading.
bool ownedByLocal = tower != null
&& PlayerMatchState.Local != null
&& tower.Owner == PlayerMatchState.Local.Slot;
int sellValue = ownedByLocal ? tower.ComputeSellRefund() : 0;
var btn = CreateActionButton(
costText: sellValue > 0 ? $"+{sellValue}g" : "",
hotkey: hotkey,
hotkey: Key.None,
onClick: () =>
{
/* TODO: sell flow */
if (tower != null)
tower.RequestSellServerRpc();
});
btn.SetEnabled(false);
btn.SetEnabled(ownedByLocal);
return btn;
}
@ -1586,7 +1597,11 @@ namespace TD.UI
ttStats.text = "(stats pending)";
}
int sellValue = Mathf.RoundToInt(def.GoldCost * 0.7f);
// Sell preview for a freshly placed (un-upgraded) tower: mirrors
// TowerInstance.ComputeSellRefund for invested == GoldCost, upgradeCount == 0.
int sellValue = def.FullRefundIfUnupgraded
? def.GoldCost
: Mathf.RoundToInt(def.GoldCost * def.SellRefundPercent);
ttCost.text = $"Cost: {def.GoldCost}g · Sell: {sellValue}g";
}