using System; using System.Collections.Generic; using CoreGame.Render; using GAS.Runtime; using Sog; using UnityEngine; namespace CoreGame.Render { public sealed class GARotateHurt : GameplayAbility { public GARotateHurt(IAbilityData abilityAsset) : base(abilityAsset) { } public override AbilitySpec CreateSpec(AbilitySystemComponent owner, GameAbilityContext ctx) { var rotateHurtSpec = SptPool.Malloc(); rotateHurtSpec.Awake(this, ctx); return rotateHurtSpec; } public override void FreeSpec(ref AbilitySpec spec) { if (spec is not GARotateHurtSpec rotateHurtSpec) { BattleLogger.LogInfo("RotateHurtSpec.FreeSpec: spec is not RotateHurtSpec"); return; } SptPool.Free(ref rotateHurtSpec); } } public sealed class GARotateHurtSpec : AbilitySpec, ISptPool { private int m_RotateCount; private float m_TimeAcc; private Fixed64Vector2 m_RotateDir; private List m_VFXList; private List> m_TriggerTasks; private static readonly List s_CacheEntities = new(); private static readonly List s_CacheVFXList = new(); private GARotateHurtAsset RotateHurtAsset => Ability.DataReference as GARotateHurtAsset; public override void Awake(GameplayAbility ability, GameAbilityContext gaCtx) { base.Awake(ability, gaCtx); m_VFXList = ListPool.Pop(); m_TriggerTasks = ListPool>.Pop(); } public override void GrantAbility() { base.GrantAbility(); if (RotateHurtAsset.triggerIds != null) { for (var index = 0; index < RotateHurtAsset.triggerIds.Length; index++) { // TODO: 整改到Asset里面去 var trigger = new CommTriggerTask(); trigger.cfgId = RotateHurtAsset.triggerIds[index]; var taskSpec = new TaskSpec(this); trigger.AddListen(ref taskSpec); m_TriggerTasks.Add(new Tuple(trigger, taskSpec)); } } } public override void UnGrantAbility() { base.UnGrantAbility(); for (var index = 0; index < m_TriggerTasks.Count; index++) { var (triggerTask, taskSpec) = m_TriggerTasks[index]; triggerTask.RemoveListen(ref taskSpec); } m_TriggerTasks.Clear(); } public override void ActivateAbility() { m_RotateCount = 0; m_TimeAcc = 0f; TargetSelectSrv.SpellSelectEnts(ctx, RotateHurtAsset.geCastPointSelectCfgId, ctx.castPos, s_CacheEntities); m_RotateDir = (ctx.castPos[0] - ctx.ownerEnt.logicTransform.position); m_RotateDir.Normalize(); DoCost(); } protected override void AbilityTick(Fixed64 dt) { // if (m_TimeAcc >= RotateHurtAsset.maxDuration) // { // TryEndAbility(); // return; // } // // var castHurt = false; // // // if (m_TimeAcc > RotateHurtAsset.rotateInterval * m_RotateCount || m_RotateCount == 0) // { // if (m_RotateCount > 0) // { // var radians = -RotateHurtAsset.rotateAngleEachTime * Mathf.Deg2Rad; // var cos = Mathf.Cos(radians); // var sin = Mathf.Sin(radians); // var newX = m_RotateDir.x * cos - m_RotateDir.y * sin; // var newY = m_RotateDir.x * sin + m_RotateDir.y * cos; // m_RotateDir = new Vector2(newX, newY); // } // else if (!string.IsNullOrEmpty(RotateHurtAsset.animStateName)) // { // ctx.ownerEnt.animationProxy.Play(RotateHurtAsset.AnimStateName, 1f, true); // } // m_RotateCount++; // castHurt = true; // } // // if (castHurt) // { // ctx.castPos.Clear(); // ctx.castTarget.Clear(); // ctx.castPos.Add(ctx.ownerEnt.transformProxy.position + m_RotateDir); // if (RotateHurtAsset.castEffectId > 0) // { // TexiaoShowParam param = default; // param.effectId = RotateHurtAsset.castEffectId; // param.scale = Vector3.one; // param.rotation = Quaternion.identity; // param.offset = Vector2.zero; // ctx.ownerEnt.effectShowProxy.GA_ShowCastEffect(ref param, ctx, s_CacheVFXList); // m_VFXList.AddRange(s_CacheVFXList); // } // TargetSelectSrv.EffectSelectEnts(ctx, RotateHurtAsset.geCatchTargetCfgId); // for (int i = 0; i < ctx.geCatchTargets.Count; i++) // { // var targetEnt = ctx.geCatchTargets[i]; // if (targetEnt.IsValid() == false) // continue; // // var context = AbilitySrv.GrantTransferAbility(ctx.ownerEnt, RotateHurtAsset.castHurtSkillId, // ctx.abilitySpec.gaInitCfg, null, ctx.level); // if (context != null) // { // context.castPos.Add(targetEnt.transformProxy.position); // context.castTarget.Add(targetEnt.creationIndex); // 有可能追着目标 // context.dropAbilityWhenEnd = true; // context.asc.TryActivateAbility_WithSeqAndParam(context.gaSeq, // ctx.abilitySpec.gaParams); // } // } // } // // m_TimeAcc += dt; } public override void CancelAbility() { } public override void EndAbility() { if (RotateHurtAsset.castEffectId > 0) ctx.ownerEnt.effectShowProxy.DestroyEffect(m_VFXList); m_VFXList.Clear(); } public void Reset() { ListPool>.Push(ref m_TriggerTasks); ListPool.Push(ref m_VFXList); } } }