Updating HUD, Gold Config, and finishing off Play flow for 9player map.

This commit is contained in:
Matt F 2026-05-22 12:18:23 -07:00
parent a7be12fa9b
commit 3dcc0e7edd
28 changed files with 2272 additions and 9601 deletions

View file

@ -0,0 +1,112 @@
// Assets/_Project/Scripts/Gameplay/GoldConfig.cs
using System;
using UnityEngine;
namespace TD.Gameplay
{
/// <summary>
/// Per-wave gold rules nested under <see cref="GoldConfig"/>. Each entry maps to one
/// wave by array index in <see cref="GoldConfig.Waves"/>.
/// </summary>
/// <remarks>
/// <b>Pairing with WaveDefinition.</b> The runtime pairing of gold entry to wave is by
/// array index — entry 0 applies to wave 1, etc. The <see cref="Wave"/> reference here
/// is OPTIONAL and exists purely so the inspector can compute and display the
/// <see cref="PreviewTotalGold"/> read-only value (which needs to know the wave's
/// total enemy count to multiply against <see cref="GoldPerEnemy"/>). Leaving it
/// unset just hides the kill-reward portion of the preview; runtime is unaffected.
/// </remarks>
[Serializable]
public class WaveGoldEntry
{
[Tooltip("Optional reference to the WaveDefinition this entry pairs with. " +
"Used ONLY for the inspector preview total — runtime pairing is by " +
"array index in GoldConfig.Waves. Drag the matching WaveDefinition " +
"here to see the live total computed under this entry.")]
public WaveDefinition Wave;
[Tooltip("Gold awarded to the killing player per enemy slain during this wave. " +
"Applies uniformly to every enemy type in the wave.")]
public int GoldPerEnemy = 10;
[Tooltip("Flat bonus gold awarded to every active player when this wave is fully " +
"cleared (all enemies dead or reached the goal).")]
public int CompletionBonus = 50;
[Tooltip("Extra bonus gold awarded to a player who cleared this wave without any " +
"enemy from their own zone escaping their leak volume. Stacks on top of " +
"CompletionBonus for the no-leak achievement.")]
public int NoLeaksBonus = 50;
/// <summary>
/// Read-only preview of the maximum gold a single player could earn in this wave:
/// <c>GoldPerEnemy × totalEnemyCount + CompletionBonus + NoLeaksBonus</c>.
/// </summary>
/// <remarks>
/// Returns just <c>CompletionBonus + NoLeaksBonus</c> if <see cref="Wave"/> is null
/// (no enemy count to multiply against). Pure computation — safe at edit time and
/// at runtime. The custom inspector under <see cref="GoldConfig"/> renders this as
/// a non-editable label under the entry's fields.
/// </remarks>
public int PreviewTotalGold
{
get
{
int total = CompletionBonus + NoLeaksBonus;
if (Wave != null && Wave.Entries != null)
{
int enemies = 0;
foreach (var e in Wave.Entries)
{
if (e.EnemyType != null && e.Count > 0)
enemies += e.Count;
}
total += GoldPerEnemy * enemies;
}
return total;
}
}
}
/// <summary>
/// Single source of truth for every gold-related tunable in the game.
/// </summary>
/// <remarks>
/// <b>Inspector layout.</b> StartingGold is at the top and applies to every player.
/// The Waves array follows, each element collapsible in the inspector with the
/// per-wave rules and a read-only preview total computed from the entry's data.
///
/// <b>Wiring.</b> Assign one GoldConfig asset to <c>WaveManager.goldConfig</c> in
/// the Match scene. WaveManager initializes per-player starting gold from
/// <see cref="StartingGold"/> at match start, uses <see cref="WaveGoldEntry.GoldPerEnemy"/>
/// to compute kill rewards, and awards <see cref="WaveGoldEntry.CompletionBonus"/> /
/// <see cref="WaveGoldEntry.NoLeaksBonus"/> when each wave clears.
///
/// <b>No per-enemy-type bounties.</b> Every enemy killed in wave N grants the same
/// <see cref="WaveGoldEntry.GoldPerEnemy"/> regardless of <see cref="EnemyDefinition"/>.
/// If per-type variation becomes a design need, extend WaveGoldEntry with a per-type
/// table; the current model intentionally favors simplicity.
/// </remarks>
[CreateAssetMenu(fileName = "GoldConfig", menuName = "TD/Gold Config", order = 2)]
public class GoldConfig : ScriptableObject
{
[Tooltip("Gold each player starts the match with. Same for every player.")]
public int StartingGold = 100;
[Tooltip("Per-wave gold rules. Element 0 = Wave 1. Match the order and length of " +
"WaveManager.waveDefinitions; extra entries are ignored, missing entries " +
"fall back to zero gold for that wave.")]
public WaveGoldEntry[] Waves;
/// <summary>
/// Returns the gold entry for the given 1-based wave number, or null if out of range.
/// </summary>
public WaveGoldEntry GetWaveEntry(int waveNumber)
{
if (Waves == null) return null;
int index = waveNumber - 1;
if (index < 0 || index >= Waves.Length) return null;
return Waves[index];
}
}
}