146 lines
6.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* @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;
}
}
}