119 lines
4.3 KiB
C#
119 lines
4.3 KiB
C#
using BumpCombat.Constants;
|
|
using UnityEngine;
|
|
|
|
namespace BumpCombat.Defense
|
|
{
|
|
[DisallowMultipleComponent]
|
|
public sealed class DefenseTower : MonoBehaviour
|
|
{
|
|
private DefensePrototypeController owner;
|
|
private DefenseConstants tuning;
|
|
private float attackCooldown;
|
|
private TextMesh label;
|
|
|
|
public DefenseTowerKind Kind { get; private set; }
|
|
public int PadIndex { get; private set; }
|
|
public bool IsOperational => isActiveAndEnabled
|
|
&& owner != null
|
|
&& owner.CanOperateTowers;
|
|
|
|
public void Configure(
|
|
DefensePrototypeController controller,
|
|
DefenseTowerKind kind,
|
|
int padIndex,
|
|
DefenseConstants constants)
|
|
{
|
|
owner = controller;
|
|
Kind = kind;
|
|
PadIndex = padIndex;
|
|
tuning = constants;
|
|
CreateVisuals();
|
|
if (Kind == DefenseTowerKind.Summon)
|
|
{
|
|
for (int i = 0; i < tuning.SummonUnitCount; i++)
|
|
{
|
|
GameObject unitObject = new($"Summon Unit {i + 1}");
|
|
unitObject.transform.SetParent(transform, false);
|
|
unitObject.transform.localPosition = new Vector3(
|
|
(i - (tuning.SummonUnitCount - 1) * 0.5f) * 0.42f,
|
|
-0.5f,
|
|
0f);
|
|
DefenseSummonUnit unit = unitObject.AddComponent<DefenseSummonUnit>();
|
|
unit.Configure(this, controller, unitObject.transform.localPosition);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (!IsOperational || Kind != DefenseTowerKind.Direct)
|
|
{
|
|
return;
|
|
}
|
|
|
|
attackCooldown -= Time.deltaTime;
|
|
if (attackCooldown > 0f)
|
|
{
|
|
return;
|
|
}
|
|
|
|
float interval = Kind == DefenseTowerKind.Direct
|
|
? tuning.DirectTowerAttackInterval
|
|
: tuning.SummonAttackInterval;
|
|
if (owner.TryAttackFromTower(this))
|
|
{
|
|
attackCooldown = Mathf.Max(0.05f, interval);
|
|
}
|
|
}
|
|
|
|
private void CreateVisuals()
|
|
{
|
|
SpriteRenderer renderer = gameObject.GetComponent<SpriteRenderer>();
|
|
if (renderer == null)
|
|
{
|
|
renderer = gameObject.AddComponent<SpriteRenderer>();
|
|
}
|
|
renderer.sprite = DefensePrototypeController.WhiteSprite;
|
|
renderer.color = Kind == DefenseTowerKind.Direct
|
|
? new Color32(65, 211, 240, 255)
|
|
: new Color32(244, 154, 74, 255);
|
|
renderer.sortingOrder = 8;
|
|
transform.localScale = new Vector3(0.72f, 0.72f, 1f);
|
|
|
|
GameObject crown = new("Tower Crown");
|
|
crown.transform.SetParent(transform, false);
|
|
crown.transform.localPosition = new Vector3(0f, 0.42f, 0f);
|
|
crown.transform.localScale = new Vector3(0.42f, 0.22f, 1f);
|
|
SpriteRenderer crownRenderer = crown.AddComponent<SpriteRenderer>();
|
|
crownRenderer.sprite = DefensePrototypeController.WhiteSprite;
|
|
crownRenderer.color = Color.white;
|
|
crownRenderer.sortingOrder = 9;
|
|
|
|
GameObject labelObject = new("Tower Label");
|
|
labelObject.transform.SetParent(transform, false);
|
|
labelObject.transform.localPosition = new Vector3(0f, 0.85f, 0f);
|
|
label = labelObject.AddComponent<TextMesh>();
|
|
label.text = Kind == DefenseTowerKind.Direct ? "DIRECT" : "SUMMON";
|
|
label.anchor = TextAnchor.MiddleCenter;
|
|
label.alignment = TextAlignment.Center;
|
|
label.characterSize = 0.16f;
|
|
label.fontSize = 32;
|
|
label.color = Color.white;
|
|
label.GetComponent<MeshRenderer>().sortingOrder = 10;
|
|
}
|
|
|
|
public bool TryAttack(DefenseRouteAgent target)
|
|
{
|
|
if (target == null || owner == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
float damage = Kind == DefenseTowerKind.Direct
|
|
? tuning.DirectTowerDamage
|
|
: tuning.SummonDamage;
|
|
return owner.TryApplyTowerDamage(this, target, damage);
|
|
}
|
|
}
|
|
}
|