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.
 
 
 
 
 
 

246 lines
9.1 KiB

using System;
using System.Collections.Generic;
using CoreGame.Render;
using Framw.AudioFramework;
using GAS.Runtime;
using Sog;
using UnityEngine;
namespace CoreGame.Render
{
public sealed class GARush : GameplayAbility
{
public GARush(IAbilityData abilityAsset) : base(abilityAsset)
{
}
public override AbilitySpec CreateSpec(AbilitySystemComponent owner, GameAbilityContext ctx)
{
var rushAbilitySpec = SptPool<GARushSpec>.Malloc();
rushAbilitySpec.Awake(this, ctx);
return rushAbilitySpec;
}
public override void FreeSpec(ref AbilitySpec spec)
{
if (spec is not GARushSpec rushAbilitySpec)
{
BattleLogger.LogInfo("RushAbilitySpec.FreeSpec: spec is not RushAbilitySpec");
return;
}
SptPool<GARushSpec>.Free(ref rushAbilitySpec);
}
}
public sealed class GARushSpec : AbilitySpec, ISptPool
{
private Fixed64 m_TimeAcc;
private bool m_StartAnimPlayed;
private bool m_LoopAnimPlayed;
private bool m_EndAnimPlayed;
private Fixed64 m_StartAnimEndTime;
private Fixed64 m_LoopAnimEndTime;
private Fixed64 m_EndAnimEndTime;
private Fixed64 m_RushSpeed;
private Fixed64 m_Distance;
private Fixed64Vector2 m_RushDir;
private static Collider2D[] s_HitResults;
private LayerMask m_LayerMask;
private Fixed64 m_DirAngle;
private List<HitData> m_HitDataList;
private List<int> m_VFXList;
private int m_SoundIdx;
private static List<CombatEntity> s_CacheEnts = new();
private GARushAsset RushAsset => Ability.DataReference as GARushAsset;
public override void Awake(GameplayAbility ability, GameAbilityContext gaCtx)
{
base.Awake(ability, gaCtx);
m_HitDataList = ListPool<HitData>.Pop();
m_VFXList = ListPool<int>.Pop();
}
public override void ActivateAbility()
{
m_TimeAcc = 0f;
m_SoundIdx = -1;
s_HitResults = new Collider2D[20];
m_LayerMask = ColliderSrv.GetLayerMask(ctx.ownerEnt.faction.faction, 5);
TargetSelectSrv.SpellSelectEnts(ctx, RushAsset.castPointSelectCfgId, ctx.castPos, s_CacheEnts);
ctx.FillInCastEnt(s_CacheEnts);
var offset = ctx.castPos[0] - ctx.ownerEnt.logicTransform.position;
m_RushSpeed = RushAsset.speed;
switch (RushAsset.rushType)
{
case GARushAsset.RushType.GetTo:
m_Distance = offset.Magnitude;
m_RushDir = offset / m_Distance;
break;
case GARushAsset.RushType.Toward:
m_Distance = RushAsset.distance;
m_RushDir = offset;
m_RushDir.Normalize();
break;
default:
throw new ArgumentOutOfRangeException();
}
m_DirAngle = FixedMath.Angle(Fixed64Vector2.right, m_RushDir);
m_StartAnimEndTime = RushAsset.startAnimDuration;
m_LoopAnimEndTime = m_StartAnimEndTime + m_Distance / m_RushSpeed;
m_EndAnimEndTime = m_LoopAnimEndTime + RushAsset.endAnimDuration;
DoCost();
}
protected override void AbilityTick(Fixed64 dt)
{
// var animationProxy = ctx.ownerEnt.animationProxy;
// if (m_TimeAcc < m_StartAnimEndTime)
// {
// if (!m_StartAnimPlayed)
// {
// if (RushAsset.startAnimStateName != string.Empty)
// {
// animationProxy.Play(RushAsset.StartAnimStateNameFName, 1f, true);
// }
// m_StartAnimPlayed = true;
// }
// }
// else if (m_TimeAcc < m_LoopAnimEndTime)
// {
// if (!m_LoopAnimPlayed)
// {
// if (!string.IsNullOrEmpty(RushAsset.loopAnimStateName))
// {
// animationProxy.Play(RushAsset.LoopAnimStateNameFName, 1f, true);
// }
// if (RushAsset.castEffectId > 0)
// {
// TexiaoShowParam param = default;
// param.effectId = RushAsset.castEffectId;
// param.scale = Vector3.one;
// param.rotation = Quaternion.identity;
// param.offset = Vector2.zero;
// ctx.ownerEnt.effectShowProxy.GA_ShowCastEffect(ref param, null, m_VFXList);
// }
// if (!string.IsNullOrEmpty(RushAsset.rushSound))
// {
// var soundDesc = SoundDescMgr.Instance.GetConfig(RushAsset.rushSound);
// m_SoundIdx = SoundManager.Instance.PlayLoop(soundDesc.path);
// }
// m_LoopAnimPlayed = true;
// }
//
// // 移动
// var offset = m_RushSpeed * dt * m_RushDir;
// if (!ForceMoveSrv.ForceMoveEntity(ctx.ownerEnt, offset, true))
// {
// m_TimeAcc = m_LoopAnimEndTime;
// return;
// }
//
// // 碰撞检测
// var cnt = PhysicsHelper.OverlapBoxNonAlloc2D(ctx.ownerEnt.transformProxy.position, RushAsset.boxSize,
// m_DirAngle, ref s_HitResults, m_LayerMask);
//
// for (var i = 0; i < cnt; i++)
// {
// var hitEnt = ColliderSrv.GetEntityByCollider(s_HitResults[i]);
// if (hitEnt == null) continue;
//
// var canHit = true;
// for (var j = m_HitDataList.Count - 1; j >= 0; j--)
// {
// if (m_HitDataList[j].targetEid != hitEnt.creationIndex) continue;
// canHit = false;
// break;
// }
//
// if (!canHit) continue;
//
// var hitPos = hitEnt.transformProxy.position;
// var hitData = SptPool<HitData>.Malloc();
// hitData.Awake(hitEnt.creationIndex, m_TimeAcc, hitPos, m_RushDir);
// m_HitDataList.Add(hitData);
//
// // 造成伤害
// var context = AbilitySrv.GrantTransferAbility(ctx.ownerEnt, RushAsset.castHurtSkillId,
// ctx.abilitySpec.gaInitCfg, null, ctx.level);
// if (context != null)
// {
// context.castTarget.Add(hitEnt.creationIndex);
// context.castPos.Add(hitPos);
// context.AddHitDataByRefs(m_HitDataList);
// context.dropAbilityWhenEnd = true;
// context.asc.TryActivateAbility_WithSeqAndParam(context.gaSeq, ctx.abilitySpec.gaParams);
// }
// }
// }
// else if (RushAsset.endAnimStateName == string.Empty || RushAsset.endAnimDuration <= 0.01f)
// {
// TryEndAbility();
// return;
// }
// else if (m_TimeAcc < m_EndAnimEndTime)
// {
// if (!m_EndAnimPlayed)
// {
// animationProxy.Play(RushAsset.EndAnimStateNameFName, 1f, true);
// DestroyEffect();
// m_EndAnimPlayed = true;
// }
// }
// else
// {
// TryEndAbility();
// return;
// }
//
// m_TimeAcc += dt;
}
public override void CancelAbility()
{
}
public override void EndAbility()
{
ctx.ownerEnt.animationProxy.Play(FNameLookup.Idle, 1f, true);
m_StartAnimPlayed = false;
m_LoopAnimPlayed = false;
m_EndAnimPlayed = false;
for (var i = m_HitDataList.Count - 1; i >= 0; i--)
{
var hasHitEid = m_HitDataList[i];
SptPool<HitData>.Free(ref hasHitEid);
}
DestroyEffect();
m_HitDataList.Clear();
m_VFXList.Clear();
}
private void DestroyEffect()
{
if (RushAsset.castEffectId > 0)
{
ctx.ownerEnt.effectShowProxy.DestroyEffect(m_VFXList);
}
if (!string.IsNullOrEmpty(RushAsset.rushSound) && m_SoundIdx != -1)
{
SoundManager.Instance.StopLoop(m_SoundIdx);
}
}
public void Reset()
{
ListPool<HitData>.Push(ref m_HitDataList);
ListPool<int>.Push(ref m_VFXList);
}
}
}