UnityTowerDefense/Assets/_Project/Scripts/Towers/TowerDefinition.cs

146 lines
No EOL
6.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using UnityEngine;
using TD.Core;
namespace TD.Towers
{
/// <summary>
/// Data definition for a single tower type. One asset per tower type; shared across all
/// instances of that tower in a match. Consumed by tower placement, construction, and
/// (eventually) combat systems.
/// </summary>
/// <remarks>
/// TowerDefinitions are authored as ScriptableObject assets and referenced by
/// <see cref="RaceDefinition"/> (tower roster) and <see cref="TowerInstance"/> (which
/// definition this placed tower corresponds to). Clients load the full asset locally
/// from the project's ScriptableObject pool; only the asset reference (not the full data)
/// is replicated over the network.
///
/// Fields marked STUBBED are defined here to lock in the data shape but are not yet
/// consumed by any runtime system. They will be wired in during the sessions noted.
/// </remarks>
[CreateAssetMenu(fileName = "TowerDefinition", menuName = "TD/Tower Definition", order = 2)]
public class TowerDefinition : ScriptableObject
{
// -------------------------------------------------------------------
// Identity
// -------------------------------------------------------------------
[Header("Identity")]
[Tooltip("Human-readable name shown in the HUD tower grid and context panel.")]
public string DisplayName;
[Tooltip("Short description shown in the HUD context panel when this tower is selected.")]
[TextArea(2, 4)]
public string Description;
// -------------------------------------------------------------------
// Placement
// -------------------------------------------------------------------
[Header("Placement")]
[Tooltip("Footprint size in tiles. Default 2×2. The anchor tile is the south-west corner " +
"of the footprint (minimum x, minimum y). Every tile in the footprint must be " +
"Buildable and owned by the placing player for placement to succeed.")]
public Vector2Int FootprintSize = new Vector2Int(2, 2);
[Tooltip("Gold cost to place this tower. Deducted from the placing player's pool on " +
"successful server-side placement validation.")]
public int GoldCost;
// -------------------------------------------------------------------
// Construction
// -------------------------------------------------------------------
[Header("Construction")]
[Tooltip("STUBBED — not consumed until Path D (Builder system). " +
"Time in seconds from construction start to tower becoming active. " +
"A Builder must be within build range for construction to proceed. " +
"Set to 0 for instant construction (placeholder behaviour during Path B testing).")]
public float BuildTime = 0f;
// -------------------------------------------------------------------
// Visuals
// -------------------------------------------------------------------
[Header("Visuals")]
[Tooltip("Prefab instantiated in the world when this tower is placed. Must have a " +
"TowerInstance component at its root. During Path B this is a colored cube; " +
"replace with a real mesh when art is available.")]
public GameObject TowerPrefab;
// -------------------------------------------------------------------
// Combat
// -------------------------------------------------------------------
[Header("Combat — Targeting")]
[Tooltip("How the tower's damage is typed. Determines lingering effects and enemy " +
"resistance/weakness interactions.")]
public DamageType DamageType;
[Tooltip("Which enemy in range the tower prioritizes.")]
public TargetPriority TargetPriority;
[Tooltip("How damage is distributed: Single (one enemy), Splash (primary + radius), " +
"Chain (primary then N nearest neighbours).")]
public TargetType TargetType;
[Tooltip("When true, this tower can only target grounded enemies. " +
"Default false = targets both grounded and flying units.")]
public bool GroundedOnly;
[Header("Combat — Attack")]
[Tooltip("Damage dealt per hit to the primary target, before resistances.")]
public float Damage;
[Tooltip("Attack range in world units. Enemies within this radius are targetable. " +
"Displayed as a translucent decal circle when the tower is selected.")]
public float Range;
[Tooltip("Attacks per second.")]
public float FireRate;
[Header("Combat — Area")]
[Tooltip("Radius of splash damage around the primary impact point. " +
"Only used when TargetType = Splash.")]
public float SplashRadius;
[Tooltip("Number of additional enemies damage chains to after the primary target. " +
"Only used when TargetType = Chain.")]
public int ChainCount;
[Tooltip("Maximum world-unit distance each chain jump can travel. " +
"Only used when TargetType = Chain.")]
public float ChainRange;
[Header("Combat — Effects")]
[Tooltip("For Cold towers: fraction of movement speed retained on hit. " +
"1.0 = no slow, 0.5 = half speed. Ignored for other damage types.")]
[Range(0f, 1f)]
public float SlowFactor = 1f;
[Tooltip("For Fire / Poison towers: damage per second applied as a damage-over-time tick. " +
"Ignored for other damage types.")]
public float DotDamagePerSecond;
[Tooltip("Duration in seconds that any lingering effect (slow, burn, poison) persists " +
"after the hit. 0 = no lingering effect.")]
public float EffectDuration;
[Header("Combat — Projectile")]
[Tooltip("Prefab fired at targets. Must have a Projectile component, NetworkObject, " +
"and NetworkTransform at its root. Null = hitscan (instant hit, no travel).")]
public GameObject ProjectilePrefab;
[Tooltip("World-units per second the projectile travels. Ignored when ProjectilePrefab is null.")]
public float ProjectileSpeed = 10f;
// -------------------------------------------------------------------
// Upgrades
// -------------------------------------------------------------------
[Header("Upgrades")]
[Tooltip("Tower definitions this tower can upgrade into. Leave empty for no upgrades. " +
"Multiple entries create branching paths — the player chooses one.")]
public TowerDefinition[] UpgradePaths;
}
}