Updates to spells, HUD, Gold, and Camera Controls. New sound effects!

This commit is contained in:
Matt F 2026-07-18 18:12:56 -07:00
parent 689fe7be88
commit a33d951abd
27 changed files with 578 additions and 68 deletions

View file

@ -56,6 +56,21 @@ namespace TD.Gameplay
// -1 when not aiming.
private int activeSlot = -1;
// Frame on which the confirming cast click was consumed. Lets the selection controller
// ignore that click order-independently — see ConsumedCastClickThisFrame.
private int lastCastClickFrame = -1;
/// <summary>True while a spell is being aimed (awaiting the confirming click). The
/// selection input controller treats this as a modal state, so the click that confirms
/// the cast doesn't also fall through to selection and deselect the builder.</summary>
public bool IsAiming => activeSlot >= 0;
/// <summary>True during the frame the confirming cast click was consumed. Aim mode exits
/// the same frame the cast is submitted, flipping <see cref="IsAiming"/> false; this stays
/// true for the rest of that frame so the selection controller ignores the click no matter
/// which controller's Update ran first.</summary>
public bool ConsumedCastClickThisFrame => lastCastClickFrame == Time.frameCount;
private BuilderSpellDefinition activeDefinition;
private bool lastHitValid;
@ -85,6 +100,14 @@ namespace TD.Gameplay
if (activeSlot < 0) return; // idle — nothing to aim
// Deselecting the builder mid-aim cancels the cast, so you can't start aiming while
// selected and then deselect to sneak a cast past the gate above.
if (!LocalBuilderSelected())
{
ExitAimMode();
return;
}
var keyboard = Keyboard.current;
if (keyboard != null && keyboard.escapeKey.wasPressedThisFrame)
{
@ -115,16 +138,32 @@ namespace TD.Gameplay
if (mouse.leftButton.wasPressedThisFrame && lastHitValid)
{
// Record the frame so the selection controller ignores this click even though
// TrySubmitCast exits aim mode this same frame (IsAiming flips false). Without
// this, whether the click also deselected the builder depended on Update order.
lastCastClickFrame = Time.frameCount;
TrySubmitCast();
}
}
// ----- Hotkey scan --------------------------------------------------
// True when the local player's own builder is the current selection. Casting is gated
// on this so it matches the spell HUD (shown only for the selected builder).
private static bool LocalBuilderSelected()
{
var selected = SelectionState.Instance?.SelectedObject;
return selected is Builder builder && builder.IsOwner;
}
private void ScanHotkeys()
{
if (activeSlot >= 0) return; // already aiming — hotkeys re-scanned only when idle
// Spells cast only while the local player's OWN builder is selected — keeps casting
// in sync with the spell HUD, which is shown only for the selected builder.
if (!LocalBuilderSelected()) return;
var loadout = PlayerSpellLoadout.Local;
if (loadout == null) return;