59 lines
2.6 KiB
C#
59 lines
2.6 KiB
C#
// Assets/_Project/Scripts/Gameplay/Draft/DraftOption.cs
|
|
using UnityEngine;
|
|
|
|
namespace TD.Gameplay.Draft
|
|
{
|
|
/// <summary>
|
|
/// Base class for one authored draft choice. The draft system offers a player a
|
|
/// weighted-random selection of these between waves; the player picks one and the
|
|
/// server applies its effect.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// <para><b>One asset per choice.</b> Concrete subclasses (e.g.
|
|
/// <see cref="NewTowerDraftOption"/>) carry the payload and implement
|
|
/// <see cref="ServerApply"/>. New choice types (systemic upgrade, builder ability,
|
|
/// relic quest, enemy debuff) are added as new subclasses — the draft spine
|
|
/// (<see cref="DraftService"/>, <see cref="PlayerDraft"/>, HUD) is type-agnostic.</para>
|
|
///
|
|
/// <para><b>Identity.</b> Options live in <see cref="DraftPool"/> and are referenced
|
|
/// over the network by their pool index (<c>DraftOptionId</c>) — the same
|
|
/// stable-within-a-match index pattern used by the tower catalog.</para>
|
|
///
|
|
/// <para><b>Server-only logic.</b> <see cref="IsValidFor"/> and
|
|
/// <see cref="ServerApply"/> run on the server and operate on the target player's
|
|
/// per-player components (deck, gold, etc.). The ScriptableObject holds no per-player
|
|
/// state, so a single asset is shared across all players and matches.</para>
|
|
/// </remarks>
|
|
public abstract class DraftOption : ScriptableObject
|
|
{
|
|
[Header("Presentation")]
|
|
[Tooltip("Name shown on the draft card.")]
|
|
public string DisplayName;
|
|
|
|
[Tooltip("Short description shown on the draft card.")]
|
|
[TextArea(2, 4)]
|
|
public string Description;
|
|
|
|
[Tooltip("Icon shown on the draft card. Optional for placeholder content.")]
|
|
public Sprite Icon;
|
|
|
|
[Header("Generation")]
|
|
[Tooltip("Relative draw weight. Higher = offered more often. Rarer rewards use " +
|
|
"lower weights. Must be > 0.")]
|
|
[Min(0.0001f)]
|
|
public float Weight = 1f;
|
|
|
|
/// <summary>
|
|
/// Server-only: can this option validly be OFFERED to the given player right now?
|
|
/// Lets the generator skip options that would be a no-op (e.g. a tower the player
|
|
/// already owns). Default true; override when an option has prerequisites.
|
|
/// </summary>
|
|
public virtual bool IsValidFor(ulong clientId) => true;
|
|
|
|
/// <summary>
|
|
/// Server-only: apply this option's effect to the given player. Returns false if
|
|
/// it could not be applied (caller treats as a no-op and logs).
|
|
/// </summary>
|
|
public abstract bool ServerApply(ulong clientId);
|
|
}
|
|
}
|