55 lines
2.6 KiB
C#
55 lines
2.6 KiB
C#
// Assets/_Project/Scripts/Gameplay/EnemyAbilities/EnemyAbilityDefinition.cs
|
|
using UnityEngine;
|
|
using TD.Core;
|
|
|
|
namespace TD.Gameplay.EnemyAbilities
|
|
{
|
|
/// <summary>
|
|
/// Base class for one enemy ability (e.g. "split into smaller enemies on death"). Rolled
|
|
/// at random for each spawned enemy by <see cref="EnemyAbilityPool.RollRandom"/> and applied
|
|
/// via <see cref="EnemyAbility.InitializeServer"/>.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// <para><b>One asset per kind.</b> <see cref="Kind"/> is fixed per subclass, same as
|
|
/// <see cref="BuilderSpells.BuilderSpellDefinition"/>. <see cref="EnemyAbilityPool"/> uses
|
|
/// it to build a fixed-size, enum-indexed lookup table.</para>
|
|
///
|
|
/// <para><b>Server-only hooks.</b> All three hooks below only ever run on the server —
|
|
/// <see cref="EnemyAbility"/> only calls them when <c>IsServer</c> is true. <see
|
|
/// cref="ServerOnSpawn"/> and <see cref="ServerTick"/> are no-ops for abilities that don't
|
|
/// need spawn-time setup or a per-frame timer (e.g. Split on Death uses neither); they exist
|
|
/// so a future cooldown-driven ability (disable towers, teleport) doesn't need a base-class
|
|
/// change.</para>
|
|
/// </remarks>
|
|
public abstract class EnemyAbilityDefinition : ScriptableObject
|
|
{
|
|
/// <summary>Which enemy ability this asset's data belongs to.</summary>
|
|
public abstract EnemyAbilityKind Kind { get; }
|
|
|
|
[Header("Presentation")]
|
|
[Tooltip("Name shown in debug logs and future enemy-info UI.")]
|
|
public string DisplayName;
|
|
|
|
[Tooltip("Short description shown in future enemy-info UI.")]
|
|
[TextArea(2, 4)]
|
|
public string Description;
|
|
|
|
[Header("Selection")]
|
|
[Tooltip("Relative weight of this ability being rolled, vs. the pool's other abilities " +
|
|
"and its no-ability chance. Same semantics as DraftOption.Weight.")]
|
|
[Min(0f)]
|
|
public float Weight = 1f;
|
|
|
|
/// <summary>Server-only: called once, right after this ability is assigned (before the
|
|
/// enemy's NetworkObject is spawned to clients). Default no-op.</summary>
|
|
public virtual void ServerOnSpawn(EnemyAbility instance) { }
|
|
|
|
/// <summary>Server-only: called every frame this ability is active on a live enemy.
|
|
/// Default no-op.</summary>
|
|
public virtual void ServerTick(EnemyAbility instance, float dt) { }
|
|
|
|
/// <summary>Server-only: called the instant the enemy's HP reaches zero, before the
|
|
/// death animation/despawn sequence plays. Default no-op.</summary>
|
|
public virtual void ServerOnDeath(EnemyAbility instance, EnemyHealth health) { }
|
|
}
|
|
}
|