Files
WarGame/Assets/Scripts/Data/UnitDataSO.cs

131 lines
4.4 KiB
C#
Raw Permalink Normal View History

2026-09-30 23:45:58 +01:00
using System;
using System.Collections.Generic;
using UnityEngine;
namespace WarGame.Data
{
public enum UnitTacticType
{
None,
Flanking, // Maneuvers around enemy flank/rear to deal bonus flank damage
FeintRetreat, // Feigns retreat at low HP to disrupt enemy positioning, then rallies
ShieldWall, // Temporarily braces to absorb incoming physical damage
PowerStrike // High damage burst attack with a chance to stun
}
[System.Serializable]
public class UnlockedTactic
{
[Tooltip("The tactic skill unlocked")]
public UnitTacticType tacticType;
[Tooltip("Unit level required to unlock this tactic")]
public int requiredLevel = 2;
[TextArea(2, 4)]
[Tooltip("Description of how this tactic works")]
public string description;
[Header("Tactic Tuning")]
[Tooltip("Cooldown in seconds between activations")]
public float cooldown = 10f;
[Tooltip("Trigger threshold (e.g. 0.35 for 35% HP in Feint Retreat)")]
public float triggerThreshold = 0.35f;
[Tooltip("Duration of effect (e.g. retreat duration in seconds)")]
public float duration = 3f;
[Tooltip("Damage multiplier (e.g. 1.5 for +50% flank damage)")]
public float valueMultiplier = 1.5f;
}
public enum UnitClassType
{
MeleeInfantry,
Archer,
Cavalry,
HeavyGuardian
}
[CreateAssetMenu(fileName = "NewUnitData", menuName = "WarGame/Unit Data")]
public class UnitDataSO : ScriptableObject
{
[Header("General Info")]
public string unitName = "Swordsman";
public UnitClassType unitClass = UnitClassType.MeleeInfantry;
[TextArea(2, 4)]
public string description = "A reliable melee warrior.";
public int goldCost = 50;
public Sprite unitPortrait;
public GameObject unitPrefab; // Visual model or full prefab
[Header("Base Stats (Level 1)")]
public float maxHealth = 100f;
public float attackDamage = 15f;
public float attackRange = 1.8f;
public float attackInterval = 1.2f; // Time between attacks in seconds
public float moveSpeed = 3.5f;
public float defenseArmor = 2f;
[Range(0f, 1f)] public float criticalChance = 0.1f;
[Header("Level Growth (Per Level)")]
public float healthGrowth = 20f;
public float damageGrowth = 3.5f;
public float defenseGrowth = 1.0f;
public float speedGrowth = 0.1f;
[Header("Progression / XP Curve")]
public int maxLevel = 10;
[Tooltip("XP required for Level 2")]
public int baseExpRequirement = 50;
[Tooltip("Multiplier for each subsequent level (e.g., 1.5x)")]
public float expCurveMultiplier = 1.4f;
[Header("Tactics & Skills")]
public List<UnlockedTactic> unlockedTactics = new List<UnlockedTactic>();
/// <summary>
/// Calculates the required XP to advance from currentLevel to currentLevel + 1.
/// </summary>
public int GetExpRequiredForLevel(int currentLevel)
{
if (currentLevel >= maxLevel) return int.MaxValue;
return Mathf.RoundToInt(baseExpRequirement * Mathf.Pow(expCurveMultiplier, currentLevel - 1));
}
/// <summary>
/// Returns whether a tactic is unlocked at the given level.
/// </summary>
public bool HasTacticUnlocked(UnitTacticType tacticType, int level, out UnlockedTactic tacticConfig)
{
for (int i = 0; i < unlockedTactics.Count; i++)
{
if (unlockedTactics[i].tacticType == tacticType && level >= unlockedTactics[i].requiredLevel)
{
tacticConfig = unlockedTactics[i];
return true;
}
}
tacticConfig = null;
return false;
}
/// <summary>
/// Gets all tactics currently unlocked at a specific level.
/// </summary>
public List<UnlockedTactic> GetTacticsAtLevel(int level)
{
var list = new List<UnlockedTactic>();
for (int i = 0; i < unlockedTactics.Count; i++)
{
if (level >= unlockedTactics[i].requiredLevel)
{
list.Add(unlockedTactics[i]);
}
}
return list;
}
}
}