You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
148 lines
4.6 KiB
148 lines
4.6 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Numerics;
|
|
using UnityEngine;
|
|
|
|
namespace Skill_V2
|
|
{
|
|
public class Skill : Entity
|
|
{
|
|
[SerializeField] CircleCollider2D castDistanceIndicator;
|
|
|
|
StatData castDistance;
|
|
StatData coolTime;
|
|
int currentSequenceIndex = -1;
|
|
float elapsedCoolTime;
|
|
|
|
Bitset32.Mask targetTags;
|
|
BIValue damageCalculator = new BIValue();
|
|
|
|
ContactFilter2D layerFilter;
|
|
List<Collider2D> castSkillDistOverlaped = new();
|
|
|
|
public Entity Caster { get; private set; }
|
|
public Bitset32.Mask TargetTags => targetTags;
|
|
public SkillData Data { get; private set; }
|
|
public float CastDistance => castDistance != null ? castDistance.Value : 0f;
|
|
public SkillSequence CurrentSequence => currentSequenceIndex >= 0 ? Data.Sequences[currentSequenceIndex] : null;
|
|
public bool IsInCoolTime => coolTime != null ? elapsedCoolTime < (float)coolTime.Value : false;
|
|
public float CoolTimeRemainTime => coolTime != null ? Mathf.Clamp((float)coolTime.Value - elapsedCoolTime, 0, (float)coolTime.Value) : 0f;
|
|
public float ElapsedCoolTimeRate => coolTime != null ? Mathf.Clamp01(elapsedCoolTime / (float)coolTime.Value) : 1f;
|
|
|
|
private void Awake()
|
|
{
|
|
AddTags(EntityTag.Skill);
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
var currentState = CurrentSequence;
|
|
|
|
if (currentState != null)
|
|
{
|
|
if (currentState.IsDone)
|
|
{
|
|
currentSequenceIndex++;
|
|
if (currentSequenceIndex < Data.Sequences.Count)
|
|
{
|
|
currentState.Exit();
|
|
CurrentSequence.Enter();
|
|
}
|
|
else
|
|
{
|
|
currentSequenceIndex = -1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
currentState.Excute();
|
|
}
|
|
}
|
|
}
|
|
|
|
public void SetSkillData(SkillData skillData)
|
|
{
|
|
Debug.Assert(skillData != null, Logger.LogMessage(LogType.Assert, nameof(SetSkillData), "SkillData is null"));
|
|
Data = skillData;
|
|
|
|
for (int i = 0; i < skillData.Sequences.Count; i++)
|
|
{
|
|
skillData.Sequences[i].Initialize(this);
|
|
}
|
|
|
|
Data.TryGetStat(StatID.CastDistance, out castDistance);
|
|
Data.TryGetStat(StatID.CoolTime, out coolTime);
|
|
}
|
|
|
|
public void UpdateSkillCoolTime()
|
|
{
|
|
if (!IsInCoolTime) return;
|
|
elapsedCoolTime += Time.fixedUnscaledDeltaTime;
|
|
elapsedCoolTime = Mathf.Min(elapsedCoolTime, coolTime.Value);
|
|
}
|
|
|
|
public void SetTargetTags(LayerMask mask, params EntityTag[] tags)
|
|
{
|
|
layerFilter.SetLayerMask(mask);
|
|
targetTags = Bitset32.GetMask(Array.ConvertAll(tags, (t) => (Enum)t));
|
|
}
|
|
|
|
public void Cast(Entity caster, BigInteger atk)
|
|
{
|
|
Caster = caster;
|
|
|
|
damageCalculator.ClearModifiers();
|
|
damageCalculator.DefaultValue = atk;
|
|
if (Data.TryGetStat(StatID.SkillDamage, out var stat))
|
|
{
|
|
damageCalculator.AddModifiers(new ValueModifier(ValueModifier.Type.Percent, stat.Value));
|
|
}
|
|
|
|
Stop();
|
|
|
|
if(Data.Sequences.Count > 0)
|
|
{
|
|
currentSequenceIndex = 0;
|
|
|
|
transform.position = caster.CenterPivot;
|
|
ChangeLookDirection(caster.LookDirection);
|
|
CurrentSequence.Enter();
|
|
}
|
|
}
|
|
|
|
public BigInteger GetSkillDamage() => damageCalculator.ModifiedValue;
|
|
|
|
public void StartCoolTime()
|
|
{
|
|
elapsedCoolTime = 0f;
|
|
}
|
|
|
|
public void Stop()
|
|
{
|
|
CurrentSequence?.Stop();
|
|
currentSequenceIndex = -1;
|
|
}
|
|
|
|
public bool IsTargetExistInCastRange()
|
|
{
|
|
if (castDistanceIndicator is null) return false;
|
|
|
|
castDistanceIndicator.radius = CastDistance;
|
|
|
|
castSkillDistOverlaped.Clear();
|
|
castDistanceIndicator.OverlapCollider(layerFilter, castSkillDistOverlaped);
|
|
|
|
for (int i = 0; i < castSkillDistOverlaped.Count; i++)
|
|
{
|
|
var overlapped = castSkillDistOverlaped[i];
|
|
if(overlapped.TryGetComponent(out IBattleEntity entity) && (entity as Entity).HasTagsAny(TargetTags) && entity.IsBattleAvail())
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|