69 lines
3.2 KiB
C#
69 lines
3.2 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("OPTIONAL override for the draft card icon. Leave empty to inherit the icon of " +
|
|
"the item this option grants (its tower / spell); assign one only when you want " +
|
|
"to override that inherited icon.")]
|
|
public Sprite Icon;
|
|
|
|
/// <summary>
|
|
/// The icon actually shown on the draft card. Returns the explicit <see cref="Icon"/>
|
|
/// override when one is assigned; otherwise subclasses fall back to the icon of the item
|
|
/// they grant (tower, spell). The base class has no referenced item, so it just returns
|
|
/// <see cref="Icon"/> (which may be null).
|
|
/// </summary>
|
|
public virtual Sprite ResolveIcon() => 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);
|
|
}
|
|
}
|