ThreeKingdomsSlingshot/Assets/Scripts/Runtime/Unit.cs

123 lines
3.8 KiB
C#

using UnityEngine;
namespace TKS
{
/// <summary>전장의 유닛 1기. 능력치·상태·콜라이더를 가진다. 시각은 UnitView 가 담당.</summary>
[RequireComponent(typeof(CircleCollider2D))]
public class Unit : MonoBehaviour
{
public string DisplayName;
public UnitType Type;
public Faction Faction;
public bool IsBoss;
public int MaxHp;
public int Hp;
public int Atk;
public int Def;
public float Radius;
public float SlingMaxDistance;
public float AttackRange;
/// <summary>이번 아군 턴에 행동을 마쳤는가.</summary>
public bool ActedThisTurn;
/// <summary>보병이 최종 목표점 명중으로 얻은 추가 이동(이동만 가능).</summary>
public bool BonusMoveAvailable;
/// <summary>창병 대기(견제) 상태 — 적군 턴에 반경 안에서 움직이는 적에게 피해.</summary>
public bool Overwatch;
public CircleCollider2D Collider { get; private set; }
public UnitView View { get; private set; }
public bool IsAlive
{
get { return Hp > 0; }
}
public Vector2 Position
{
get { return transform.position; }
set { transform.position = new Vector3(value.x, value.y, 0f); }
}
public void Init(BalanceConfig cfg, UnitType type, Faction faction, string displayName, float hpMult, float atkMult, bool boss)
{
var s = cfg.GetStats(type);
Type = type;
Faction = faction;
DisplayName = displayName;
IsBoss = boss;
MaxHp = Mathf.Max(1, Mathf.RoundToInt(s.maxHp * hpMult * (boss ? cfg.bossHpMult : 1f)));
Hp = MaxHp;
Atk = Mathf.Max(1, Mathf.RoundToInt(s.atk * atkMult));
Def = s.def;
Radius = s.radius * (boss ? cfg.bossRadiusMult : 1f);
SlingMaxDistance = s.slingMaxDistance;
AttackRange = s.attackRange;
gameObject.name = (faction == Faction.Player ? "P_" : "E_") + displayName;
Collider = GetComponent<CircleCollider2D>();
Collider.radius = Radius;
Collider.isTrigger = false;
Collider.enabled = true;
View = GetComponentInChildren<UnitView>();
if (View == null)
{
var vgo = new GameObject("View");
vgo.transform.SetParent(transform, false);
View = vgo.AddComponent<UnitView>();
}
View.Build(this);
}
public void TakeDamage(int dmg)
{
if (!IsAlive) return;
Hp = Mathf.Max(0, Hp - dmg);
if (View != null)
{
View.OnHit();
View.Refresh();
}
if (!IsAlive) Die();
}
void Die()
{
Overwatch = false;
BonusMoveAvailable = false;
Collider.enabled = false;
if (View != null) View.PlayDeath();
}
public void SetOverwatch(bool on)
{
Overwatch = on && IsAlive;
if (View != null) View.Refresh();
}
public void ResetForNewTurn()
{
ActedThisTurn = false;
BonusMoveAvailable = false;
Overwatch = false;
if (View != null) View.Refresh();
}
public void MarkActed()
{
ActedThisTurn = true;
BonusMoveAvailable = false;
if (View != null) View.Refresh();
}
public void GrantBonusMove()
{
ActedThisTurn = false;
BonusMoveAvailable = true;
if (View != null) View.Refresh();
}
}
}