/* * @Author: 白哉 * @Description: * @Date: 2025年04月23日 星期三 21:04:18 * @Modify: */ using System.Collections.Generic; using RuntimeData; using System; using Logic.Pool; using TH1_Logic.Core; using TH1_Anim.Fragments; using TH1_Core.Managers; using TH1_Renderer; using TH1Renderer; using UnityEngine; using MemoryPack; namespace Logic.Skill { public partial class StompSkill : SkillBase { public StompSkill() { IsPermanent = true; TurnsLimit = 0; Score = 4; } public override SkillType GetSkillType() { return SkillType.STOMP; } public override void OnMove(UnitData self, GridData grid, MapData mapData, MoveType moveType, List path = null) { if (mapData == null || self == null || grid == null) return; if (moveType == MoveType.PassiveMove) return; if (!self.IsValidOnMap(mapData, grid)) return; if (!mapData.GetPlayerDataByUnitId(self.Id, out var selfPlayer)) return; using var pooledSelfUnitList = THCollectionPool.GetHashSetHandle(out var selfUnitList); mapData.GetUnitDataListByPlayerId(selfPlayer.Id, selfUnitList); // 收集需要视觉更新的数据。Renderer 必须在 DamageSettlement 前缓存。 using var pooledVisualUpdates = THCollectionPool.GetListHandle<(UnitData unit, GridData grid, UnitRenderer renderer, int damage, bool wasKilled, GridRenderer gridRenderer)>(out var visualUpdates); //遍历会溅射的所有格子 var aroundBuf = RentAroundBuf(); mapData.GridMap.GetAroundGridData(1, 1, grid, aroundBuf); foreach (var roundGrid in aroundBuf) { if (roundGrid == null) continue; if (!self.IsValidOnMap(mapData, grid)) break; GridRenderer ROgrid = null; if (mapData == Main.MapData) MapRenderer.Instance?.ROGridMap?.TryGetValue(roundGrid.Id, out ROgrid); //如果格子上没有单位,播放地震动画 if (!roundGrid.RealUnit(mapData,out var unit)) { //TODO 下面的是不规范做法,后面要迭代 if (ROgrid != null && roundGrid.InMainSight()) { ROgrid.SetBounceAnim(NeedRandomWait:true); } } //如果格子上有单位,播放地震动画,并且播放对方受伤动画 else { if (selfUnitList.Contains(unit)) continue; if (mapData.IsLeagueOrJustBreakByUnit(unit.Id, self.Id)) continue; // 计算攻击伤害,执行伤害逻辑 var damage = Table.Instance.CalcDamage(mapData, self, unit, damagePara:0.5f); var targetRenderer = unit.Renderer(mapData); var settlement = Main.UnitLogic.DamageSettlement(mapData, self, unit, damage, DamageType.Splash); if (settlement == null) continue; bool wasKilled = !unit.IsAlive(); if (roundGrid.InMainSight()) { visualUpdates.Add((unit, roundGrid, targetRenderer, damage, wasKilled, ROgrid)); } } } ReturnAroundBuf(); // 视觉更新:处理所有受影响单位的显示 if (mapData != Main.MapData) return; // OnMove 通常不在攻击流程中,但为了兼容检查 scope var scope = PresentationManager.CurrentScope; if (scope != null) { // 在攻击流程中:延迟注入到攻击 Fragment foreach (var (unit, roundGrid, renderer, damage, wasKilled, ROgrid) in visualUpdates) { int phase = AnimPhase.AttackImpact + 50; var g = roundGrid; var r = renderer; var d = damage; var ro = ROgrid; var killed = wasKilled; scope.Add(new FragmentStep { Phase = phase, Duration = 0.1f, Execute = () => { if (killed) { r?.Die(); g.Renderer(mapData)?.PlayVFXInSight(new GridVFXParams(GridVFXType.Hurt)); g.Renderer(mapData)?.PlayVFXInSight(new GridVFXParams(GridVFXType.Die)); g.Renderer(mapData)?.PlayVFXInSight(new GridVFXParams(GridVFXType.Damage, d)); g.Renderer(mapData)?.InstantUpdateGrid(); } else { r?.InstantUpdateUnit(false); g.Renderer(mapData)?.PlayVFXInSight(new GridVFXParams(GridVFXType.Hurt)); g.Renderer(mapData)?.PlayVFXInSight(new GridVFXParams(GridVFXType.Damage, d)); g.Renderer(mapData)?.InstantUpdateGrid(); ro?.SetBounceAnim(NeedRandomWait:true); } } }); } } else { // 不在攻击流程中:直接刷新 foreach (var (unit, roundGrid, renderer, damage, wasKilled, ROgrid) in visualUpdates) { if (wasKilled) { renderer?.Die(); roundGrid.Renderer(mapData)?.PlayVFXInSight(new GridVFXParams(GridVFXType.Hurt)); roundGrid.Renderer(mapData)?.PlayVFXInSight(new GridVFXParams(GridVFXType.Die)); roundGrid.Renderer(mapData)?.PlayVFXInSight(new GridVFXParams(GridVFXType.Damage, damage)); roundGrid.Renderer(mapData)?.InstantUpdateGrid(); } else { renderer?.InstantUpdateUnit(false); roundGrid.Renderer(mapData)?.PlayVFXInSight(new GridVFXParams(GridVFXType.Hurt)); roundGrid.Renderer(mapData)?.PlayVFXInSight(new GridVFXParams(GridVFXType.Damage, damage)); roundGrid.Renderer(mapData)?.InstantUpdateGrid(); ROgrid?.SetBounceAnim(NeedRandomWait:true); } } } } } }