using UnityEngine;
///
/// Holds agent stats and provides utility methods
/// Each stat is 1-100, total pool is (number of stats * 100) / 10 = 40 for 4 stats
///
public class AgentStats
{
public int Strength { get; private set; }
public int Speed { get; private set; }
public int Magic { get; private set; }
public int Dexterity { get; private set; }
public int Intelligence { get; private set; }
public int Constitution { get; private set; }
///
/// Max health derived from Constitution: 10 + Constitution (range: 11–110)
///
public int MaxHealth => 10 + Constitution;
///
/// Current health – starts at MaxHealth and decreases when taking damage.
///
public int CurrentHealth { get; private set; }
/// True once CurrentHealth reaches 0.
public bool IsDead => CurrentHealth <= 0;
private const int STAT_TOTAL_POOL = 60; // (6 stats * 100) / 10
private const int NUM_STATS = 6;
private const int MAX_STAT_VALUE = 100;
private const int MIN_STAT_VALUE = 1;
public AgentStats()
{
GenerateRandomStats();
CurrentHealth = MaxHealth; // initialise after stats are generated
}
/// Apply damage; returns actual damage dealt.
public int ApplyDamage(int amount)
{
int actual = Mathf.Min(amount, CurrentHealth);
CurrentHealth -= actual;
return actual;
}
///
/// Generates random stats by creating 4 random values and shuffling them
/// This ensures all stats get a fair distribution
///
private void GenerateRandomStats()
{
int[] stats = new int[NUM_STATS];
// Generate 4 random values between 1 and 100
for (int i = 0; i < NUM_STATS; i++)
{
stats[i] = Random.Range(MIN_STAT_VALUE, MAX_STAT_VALUE + 1);
}
// Shuffle the stats array to randomly assign values
for (int i = NUM_STATS - 1; i > 0; i--)
{
int randomIndex = Random.Range(0, i + 1);
// Swap
int temp = stats[i];
stats[i] = stats[randomIndex];
stats[randomIndex] = temp;
}
Strength = stats[0];
Speed = stats[1];
Magic = stats[2];
Dexterity = stats[3];
Intelligence = stats[4];
Constitution = stats[5];
// Normalize to fit within pool
NormalizeStats();
}
///
/// Normalizes stats to roughly fit within the STAT_TOTAL_POOL
///
private void NormalizeStats()
{
int total = Strength + Speed + Magic + Dexterity + Intelligence;
if (total > STAT_TOTAL_POOL)
{
float scale = (float)STAT_TOTAL_POOL / total;
Strength = Mathf.Max(MIN_STAT_VALUE, (int)(Strength * scale));
Speed = Mathf.Max(MIN_STAT_VALUE, (int)(Speed * scale));
Magic = Mathf.Max(MIN_STAT_VALUE, (int)(Magic * scale));
Dexterity = Mathf.Max(MIN_STAT_VALUE, (int)(Dexterity * scale));
Intelligence = Mathf.Max(MIN_STAT_VALUE, (int)(Intelligence * scale));
Constitution = Mathf.Max(MIN_STAT_VALUE, (int)(Constitution * scale));
}
}
public int GetTotalStats()
{
return Strength + Speed + Magic + Dexterity + Intelligence + Constitution;
}
///
/// 0-1 chance to consider joining a group instead of going solo.
/// Higher intelligence = more willing to team up strategically.
///
public float GroupUpAffinity => Intelligence / 100f;
///
/// 0-1 risk tolerance when evaluating fights or dangerous rooms.
/// High intelligence = lower tolerance (more cautious).
///
public float RiskTolerance => 1f - (Intelligence / 100f);
public override string ToString()
{
return $"STR: {Strength} | SPD: {Speed} | MAG: {Magic} | DEX: {Dexterity} | INT: {Intelligence} | CON: {Constitution} | HP: {CurrentHealth}/{MaxHealth} | Total: {GetTotalStats()}";
}
}