146 lines
6.5 KiB
C#
146 lines
6.5 KiB
C#
/*
|
||
* @Author: 白哉
|
||
* @Description: 勇仪推技能
|
||
* @Date: 2026年03月06日
|
||
* @Modify:
|
||
*/
|
||
|
||
using RuntimeData;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using MemoryPack;
|
||
using TH1_Anim;
|
||
using TH1_Logic.Core;
|
||
using UnityEngine;
|
||
|
||
namespace Logic.Skill
|
||
{
|
||
public partial class YuugiPushSkill : SkillBase
|
||
{
|
||
public YuugiPushSkill()
|
||
{
|
||
IsPermanent = true;
|
||
TurnsLimit = 0;
|
||
Score = 4;
|
||
}
|
||
|
||
public override SkillType GetSkillType()
|
||
{
|
||
return SkillType.YuugiPush;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 推击攻击逻辑(纯数据),动画由UnitAttackAction.Execute负责
|
||
/// </summary>
|
||
/// <returns>true表示推击已执行,false表示不满足推击条件应走普通攻击</returns>
|
||
public bool YuugiPushAttack(UnitData self, UnitData target, MapData map,
|
||
out int outAttackDmg, out int outCounterDmg, out FragmentType outFragmentType, out bool outPushed)
|
||
{
|
||
outAttackDmg = 0;
|
||
outCounterDmg = 0;
|
||
outFragmentType = FragmentType.Attack;
|
||
outPushed = false;
|
||
|
||
if (self == null || target == null) return false;
|
||
var fullType = new UnitFullType();
|
||
fullType.UnitType = UnitType.BonePile;
|
||
|
||
if (self.GetAttackRange(map) > 1) return false;
|
||
if (self.GetAllAttackValue(map, target) <= target.GetAllDefenseValue(map, self)) return false;
|
||
var player = self.Player(map);
|
||
if (player == null) return false;
|
||
map.GetCapitalCityDataByPlayerId(player.Id, out var city);
|
||
var targetCity = target.City(map);
|
||
if (city == null || targetCity == null) return false;
|
||
var selfGrid = self.Grid(map);
|
||
var targetGrid = target.Grid(map);
|
||
if (selfGrid == null || targetGrid == null) return false;
|
||
var nextGrid = map.GridMap.GetNextGrid(selfGrid, targetGrid);
|
||
var dmg = Table.Instance.CalcDamage(map, self, target);
|
||
// 判断能否推动
|
||
bool canPush = nextGrid != null && !nextGrid.RealUnit(map, out _)
|
||
&& map.CheckLandTypeForGrid(target.UnitFullType, nextGrid)
|
||
&& map.CheckLandTypeForGrid(self.UnitFullType, targetGrid)
|
||
&& map.CheckLandTypeForGrid(self.UnitFullType, nextGrid);
|
||
// 能推→无额外伤害;不能推→+2伤害
|
||
int actualDmg = canPush ? dmg : dmg + 2;
|
||
|
||
// 只有能推动且实际伤害不会击杀,才走推人
|
||
if (canPush && actualDmg < target.Health)
|
||
{
|
||
// 推击:先移动数据,再攻击,可能有反击
|
||
outPushed = true;
|
||
Main.UnitLogic.MoveToLogic(map, target, nextGrid, MoveType.PushMove);
|
||
Main.UnitLogic.MoveToLogic(map, self, targetGrid, MoveType.AttackMove);
|
||
|
||
var cDmg = Table.Instance.CalcCounterDamage(map, self, target);
|
||
bool canCounter = Main.UnitLogic.CanCounter(map, self, target);
|
||
outAttackDmg = dmg;
|
||
|
||
Main.UnitLogic.DamageSettlement(map, self, target, dmg, DamageType.PushAttack);
|
||
if (canCounter && target.IsAlive() && self.IsAlive())
|
||
{
|
||
outCounterDmg = cDmg;
|
||
Main.UnitLogic.DamageSettlement(map, target, self, cDmg, DamageType.CounterAttack);
|
||
outFragmentType = !self.IsAlive() ? FragmentType.AttackAndCounterDie : FragmentType.AttackAndCounter;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 不能推动、或伤害足以击杀:直接攻击(含可能的+2)
|
||
outPushed = false;
|
||
outAttackDmg = actualDmg;
|
||
var cDmg = Table.Instance.CalcCounterDamage(map, self, target);
|
||
bool canCounter = Main.UnitLogic.CanCounter(map, self, target);
|
||
Main.UnitLogic.DamageSettlement(map, self, target, actualDmg, DamageType.PushAttack);
|
||
if (target.IsAlive() && self.IsAlive() && canCounter)
|
||
{
|
||
// 未击杀:对方反击
|
||
outCounterDmg = cDmg;
|
||
Main.UnitLogic.DamageSettlement(map, target, self, cDmg, DamageType.CounterAttack);
|
||
outFragmentType = !self.IsAlive() ? FragmentType.AttackAndCounterDie : FragmentType.AttackAndCounter;
|
||
}
|
||
else if (!target.IsAlive() && Main.UnitLogic.CheckUnitAbleForGrid_OfflineStatus(map, player, self, targetGrid))
|
||
{
|
||
outFragmentType = FragmentType.MoveKill;
|
||
Main.UnitLogic.MoveToLogic(map, self, targetGrid, MoveType.AttackMove);
|
||
// 击杀英雄不生成骨堆
|
||
if (target.UnitFullType.UnitType != UnitType.Giant)
|
||
{
|
||
var aroundBuf = RentAroundBuf();
|
||
map.GridMap.GetAroundGridData(1, 1, targetGrid, aroundBuf);
|
||
var randomList = new List<GridData>();
|
||
foreach (var grid in aroundBuf)
|
||
{
|
||
if (grid == targetGrid) continue;
|
||
if (grid.RealUnit(map,out _)) continue;
|
||
if(!map.CheckLandTypeForGrid(fullType, grid))continue;
|
||
randomList.Add(grid);
|
||
}
|
||
ReturnAroundBuf();
|
||
if (randomList.Count > 0)
|
||
{
|
||
var index = map.Net.GetRandom(map).Next(0, randomList.Count - 1);
|
||
if (map.AddUnitData(randomList[index].Id, city.Id, fullType, out var bone))
|
||
{
|
||
bone.GetSkill(SkillType.BonePile, out var skill);
|
||
var bonePile = skill as BonePileSkill;
|
||
if (bonePile != null)
|
||
{
|
||
bonePile.TargetType = target.UnitFullType;
|
||
bonePile.TargetCityId = targetCity.Id;
|
||
}
|
||
bone.Health = bone.GetMaxHealth() / 4;
|
||
if (bone.Health < 1) bone.Health = 1;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
|