using System.Collections.Generic;
using Core.Health;
using KTGMGemClient;
using TowerDefense.Affectors;
using TowerDefense.UI.HUD;
using UnityEngine;
using TMPro;
namespace TowerDefense.Towers
{
///
/// An individual level of a tower
///
[DisallowMultipleComponent]
public class TowerLevel : MonoBehaviour, ISerializationCallbackReceiver
{
///
/// The prefab for communicating placement in the scene
///
public TowerPlacementGhost towerGhostPrefab;
///
/// 升级特效
///
public GameObject UpgradeEffectPrefab;
///
/// The parent tower controller of this tower
///
public Tower ParentTower { get; protected set; }
///
/// The list of effects attached to the tower
///
Affector[] m_Affectors;
///
/// 未上阵的形象
///
public GameObject Body;
///
/// 上阵形象
///
public GameObject AttackBody;
///
/// 可以放置的材质
///
public MeshRenderer canPlaceMesh;
///
/// 精灵塔动作状态
///
public TowerActionState ActionState { get; protected set; }
private string paramName = "ActionState";
///
/// 动作动画器
///
public Animator ActionAnimator;
public TextMeshPro LevelText;
///
/// 精灵初始配置数据
///
public elf_info ElfInfo { get; protected set; }
///
/// 发射子弹速率
///
protected float fireRate;
///
/// 初始攻击速率
///
private float attackSpeed = 1f;
///
/// 多倍速攻击速度,基准速度的 N 倍速
///
private float fireSpeed = 1f;
[SerializeField]
private SpriteRenderer levelBorder;
///
/// 发射倍速,如果设置多倍速攻击,直接修改此属性,恢复之前的攻速直接设置为 1
///
///
public float FireSpeed
{
get { return fireSpeed; }
set
{
if (value < 0) value = 0;
fireSpeed = value;
if (ActionState == TowerActionState.Attack)
ActionAnimator.speed = attackSpeed * fireSpeed;
}
}
///
/// 各个动作的基准播放时长(播放一遍用的时间)
///
protected float[] actionTimeArr;
///
/// Gets the list of effects attached to the tower
///
protected Affector[] Affectors
{
get
{
if (m_Affectors == null)
{
m_Affectors = GetComponentsInChildren();
}
return m_Affectors;
}
}
///
/// The physics layer mask that the tower searches on
///
public LayerMask mask { get; protected set; }
///
/// Initialises the Effects attached to this object
///
public virtual void Initialize(Tower tower, LayerMask enemyMask, IAlignmentProvider alignment)
{
mask = enemyMask;
foreach (Affector effect in Affectors)
{
effect.Initialize(alignment, mask);
effect.towerPtr = tower;
AttackAffector attackAffector = effect.GetComponent();
}
ParentTower = tower;
ElfInfo = ElfInfoData.GetDataById(tower.ElfId);
}
///
/// 设置显示等级
///
/// 从1开始
public void SetShowLevel(int level)
{
elf_upgrade info = ElfUpgradeData.GetDataById(level);
LevelText.text = $"{level}";
levelBorder.sprite = Resources.Load($"UI/TowerLevel/{info.rank_img}");
Vector3 pos = levelBorder.transform.localPosition;
if (info.rank_img < 3)
pos.z = ParentTower.ElfId == 201 ? 0.542f : 0.645f;
else
pos.z = ParentTower.ElfId == 201 ? 0.497f : 0.594f;
levelBorder.transform.localPosition = pos;
}
///
/// 设置缩放
///
/// 从1开始
public void SetScale(int level)
{
elf_upgrade info = ElfUpgradeData.GetDataById(level);
//Debug.Log($"level:{level} 设置了缩放:{info.zoom}");
transform.localScale = Vector3.one * info.zoom;
}
private void Awake()
{
canPlaceMesh.enabled = false;
}
private void Start()
{
if (ActionAnimator != null)
{
AnimationClip[] clips = ActionAnimator.runtimeAnimatorController.animationClips;
actionTimeArr = new float[clips.Length];
for (int i = 0; i < clips.Length; ++i)
{
if (clips[i].name == "Standing")
actionTimeArr[0] = clips[i].length;
else if (clips[i].name == "Attack")
actionTimeArr[1] = clips[i].length;
}
fireRate = GetFireRate();
if (actionTimeArr[1] > 1 / fireRate)
{
// 动画时间比攻击长
attackSpeed = actionTimeArr[1] * fireRate;
}
SetAttackState(false);
}
}
///
/// 获取发射速率
///
///
public float GetFireRate()
{
DecreaseTowerAttackCD endlessBuff = (DecreaseTowerAttackCD)EndlessBuffManager.instance.GetBuffInstanceByType(EndlessBuffEffectType.DecreaseTowerAttackCD);
float fireRate = endlessBuff != null ? endlessBuff.GetDecreaseCD(ParentTower.ElfId, 1 / ElfInfo.b_atkf) : 1 / ElfInfo.b_atkf;
// 限制最大速度为 每0.1s发射一次
return Mathf.Max(fireRate, 0.1f);
}
public void LateUpdate()
{
if (ActionAnimator == null || !ActionAnimator.isActiveAndEnabled) return;
AnimatorStateInfo stateInfo = ActionAnimator.GetCurrentAnimatorStateInfo(0);
if (ActionState == TowerActionState.Attack && stateInfo.normalizedTime >= 1f)
ChangeState(TowerActionState.Standing);
}
///
/// 设置可以放置
///
///
public void SetCanPlace(bool isOn)
{
if (canPlaceMesh.enabled != isOn)
canPlaceMesh.enabled = isOn;
}
public void ChangeState(TowerActionState state)
{
if (ActionAnimator == null || !ActionAnimator.isActiveAndEnabled) return;
ActionState = state;
if (ActionState == TowerActionState.Attack && state == TowerActionState.Attack)
{
ActionAnimator.Update(0);
ActionAnimator.Play("Attack", 0, 0);
}
ActionAnimator.SetInteger(paramName, (int)state);
if (state == TowerActionState.Attack)
ActionAnimator.speed = attackSpeed * FireSpeed;
else if (state == TowerActionState.Standing)
ActionAnimator.speed = 1f;
}
///
/// A method for activating or deactivating the attached
///
public void SetAffectorState(bool state, int waveline)
{
foreach (Affector affector in Affectors)
{
if (affector != null)
{
affector.enabled = state;
affector.waveLineID = waveline;
}
}
}
///
/// Returns a list of affectors that implement ITowerRadiusVisualizer
///
/// ITowerRadiusVisualizers of tower
public List GetRadiusVisualizers()
{
List visualizers = new List();
foreach (Affector affector in Affectors)
{
var visualizer = affector as ITowerRadiusProvider;
if (visualizer != null)
{
visualizers.Add(visualizer);
}
}
return visualizers;
}
public void Kill()
{
ParentTower.KillTower();
}
public void OnBeforeSerialize()
{
}
///
/// 获取当前TowerLevel对应的AttackRise.
/// ///
public float attackRise { get { return ParentTower.attackRise; } }
public void OnAfterDeserialize()
{
// Setting this member to null is required because we are setting this value on a prefab which will
// persists post run in editor, so we null this member to ensure it is repopulated every run
m_Affectors = null;
}
///
/// 设置上阵和非上阵状态下,塔的自身形象
///
///
public void SetAttackState(bool isAttackMode)
{
if (isAttackMode)
{
AttackBody.SetActive(isAttackMode);
Body.SetActive(!isAttackMode);
ChangeState(TowerActionState.Attack);
}
else
{
ChangeState(TowerActionState.Standing);
}
}
///
/// 播放升级特效
///
public void PlayUpGradeEffect()
{
if (UpgradeEffectPrefab != null)
{
GameObject obj = Instantiate(UpgradeEffectPrefab);
obj.transform.position = gameObject.transform.position;
ParticleSystem ps = obj.GetComponent();
if (ps == null)
ps = obj.transform.GetChild(0).GetComponent();
Vector3 pos = obj.transform.position;
pos.y = 5f;
obj.transform.position = pos;
ps.Play();
Destroy(obj, ps.main.duration);
}
}
}
}