TH1/Unity/Assets/Scripts/TH1_Logic/Action/UnitActionLogic.cs
2025-10-18 02:03:11 +08:00

1144 lines
52 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: 2025年04月10日 星期四 11:04:44
* @Modify:
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using Logic.AI;
using Logic.CrashSight;
using RuntimeData;
using TH1_Logic.Core;
using UnityEngine;
using TH1Renderer;
using TH1Resource;
using Unity.VisualScripting;
//这里是所有BuildAction派生子类的实现模块
namespace Logic.Action
{
public enum UnitActionType
{
None,Upgrade,Recover,HEAL,Examine,Gather,Capture,Disband,ROYALFLAMES,ROYALFLAMESPRO,HeroUpgrade,
TEWIFRENCHBUFF,
MOKOUFRENCHBOOM,
KAGUYAFRENCHAROUND,
ForceDisband
}
//UnitAction单位行动逻辑类
public class UnitActionAction : ActionLogicBase
{
public UnitActionAction(CommonActionId id) : base(id)
{
}
protected override bool Execute(CommonActionParams actionParams)
{
//鲁棒性判断
if (actionParams.UnitData == null) return false;
var unitData = actionParams.UnitData;
var playerData = actionParams.PlayerData;
if (playerData == null)
if (!actionParams.MapData.GetPlayerDataByUnitId(actionParams.UnitData.Id, out playerData))
return false;
if (!actionParams.MapData.GetGridDataByUnitId(actionParams.UnitData.Id, out var gridData))
return false;
if (_actionId.UnitActionType == UnitActionType.Capture)
{
//处理捕获city的情况
if (actionParams.MapData.GetCityDataByGid(gridData.Id, out var cityData))
{
//Step #1 先更新unit 状态
actionParams.UnitData.CP = 0;
actionParams.UnitData.MP = 0;
actionParams.UnitData.AP = 0;
actionParams.UnitData.Renderer(actionParams.MapData)?.InstantUpdateUnit(true);
//Step #2 再处理占领城市的所有logic & view
Main.PlayerLogic.OccupyCity(actionParams.MapData,actionParams.UnitData,cityData);
//Step #3 再更新heroTask
unitData.HeroTask(actionParams.MapData)?.OnCaptureCity(actionParams.MapData);
return true;
}
//处理占领村庄的情况
else
{
gridData.Renderer(actionParams.MapData)?.PlayVFX(new GridVFXParams(GridVFXType.Fog));
cityData = Main.PlayerLogic.OccupyVillage(actionParams.MapData,actionParams.UnitData,gridData);
//处理占领城市的特效(所有领土会升起一面旗帜
HashSet<uint> gridList = new HashSet<uint>();
cityData.Territory.GetAllTerritoryArea(gridList);
foreach (var gd in gridList)
{
if (actionParams.MapData.GridMap.GetGridDataByGid(gd, out var gdd))
{
//设置gdd格子的VFXrendermark
var t = new GridVFXParams(GridVFXType.Flag);
t.CivId = playerData.PlayerCivId;
gdd.Renderer(actionParams.MapData)?.PlayVFX(t);
}
}
actionParams.UnitData.CP = 0;
actionParams.UnitData.MP = 0;
actionParams.UnitData.AP = 0;
unitData.Renderer(actionParams.MapData)?.InstantUpdateUnit(true);
return true;
}
}
if (_actionId.UnitActionType == UnitActionType.Upgrade)
{
if (!Table.Instance.UnitTypeDataAssets.GetUnitTypeInfo(actionParams.UnitData.UnitType,
actionParams.UnitData.GiantType, actionParams.UnitData.UnitLevel,out var info))
return false;
//处理CARRY的情况
if (info.Skills.Contains(SkillType.CARRY))
{
if (actionParams.UnitData.CarryVeteran)
return false;
if (actionParams.UnitData.CarryExp < 3)
return false;
actionParams.UnitData.CarryVeteran = true;
}
//处理非CARRY是老兵
else
{
if (actionParams.UnitData.Veteran)
return false;
if (actionParams.UnitData.Exp < 3)
return false;
actionParams.UnitData.Veteran = true;
}
actionParams.UnitData.Health = actionParams.UnitData.GetMaxHealth();
actionParams.UnitData.Renderer(actionParams.MapData)?.InstantUpdateUnit(true);
return true;
}
//处理ship
if (_actionId.UnitType == UnitType.Ship || _actionId.UnitType == UnitType.RammerShip
|| _actionId.UnitType == UnitType.BomberShip)
{
if (!Table.Instance.UnitTypeDataAssets.GetUnitTypeInfo(_actionId.UnitType,GiantType.None,0, out var info ))
return false;
if (actionParams.PlayerData.PlayerWealth < info.Cost)
return false;
actionParams.PlayerData.PlayerWealth -= info.Cost;
Main.UnitLogic.UnitTypeTransform(actionParams.MapData,actionParams.UnitData,_actionId.UnitType);
Main.PlayerLogic.UpdateSight(actionParams.MapData,actionParams.PlayerData,actionParams.MapData.GridMap.GetAroundGridIdList(unitData.GetSightRange(actionParams.MapData),gridData));
actionParams.UnitData.Renderer(actionParams.MapData)?.InstantUpdateUnit(true);
actionParams.UnitData.Grid(actionParams.MapData)?.Renderer(actionParams.MapData)?.PlayVFX(new GridVFXParams(GridVFXType.Fog));
return true;
}
//剩下的都需要CP消耗CP
//用ret做记录
bool ret = false;
//处理disband
if (_actionId.UnitActionType == UnitActionType.Disband)
{
int earn = 0;
if (!Table.Instance.UnitTypeDataAssets.GetUnitTypeInfo(actionParams.UnitData.UnitType,GiantType.None,0, out var info ))
return false;
earn += info.Cost / 2;
if (actionParams.UnitData.CarryUnitType != UnitType.None
&& Table.Instance.UnitTypeDataAssets.GetUnitTypeInfo(actionParams.UnitData.CarryUnitType,
GiantType.None,0, out var carryInfo))
earn += carryInfo.Cost / 2;
actionParams.PlayerData.PlayerWealth += earn;
if (actionParams.MapData.IsCurrentShowMap())
{
var v1 = Table.Instance.GridToWorld(gridData);
var startPos = Table.Instance.GridToWorld(gridData);
var moneyPanel = GameObject.Find("UICanvas/TopBarPanel/MoneyPanel/Icon").transform;
var endPos = moneyPanel.position;
//播放雾效
gridData.Renderer(actionParams.MapData)?.PlayVFX(new GridVFXParams(GridVFXType.Fog));
var renderer = MapRenderer.Instance.ROUnitMap[actionParams.UnitData.Id];
renderer.Die();
//播放获得钱的动画
if(playerData.Id == actionParams.MapData.PlayerMap.SelfPlayerId)
MapRenderer.Instance.ProjectileManager.CreateProjectileMulti(startPos,endPos,ProjectileType.Coin,ProjectileMoveType.CoinParabola,earn,0.05f);
//更新原来所属的城市的cityinfo
}
var city = actionParams.UnitData.City(actionParams.MapData);
Main.UnitLogic.Die(actionParams.MapData,actionParams.UnitData);
if (city != null)
{
city.CityInfoRenderer(actionParams.MapData)?.InstantUpdateCityInfo();
ret = true;
}
}
//处理recover
if (_actionId.UnitActionType == UnitActionType.Recover)
{
int recoverV = 4;
if (!actionParams.MapData.GetPlayerDataByTerritoryGridId(gridData.Id, out var terrPlayerData))
recoverV = 2;
else if (!actionParams.MapData.SameUnion(terrPlayerData.Id , actionParams.PlayerData.Id))
recoverV = 2;
actionParams.UnitData.Health += recoverV;
if (actionParams.UnitData.Health > actionParams.UnitData.GetMaxHealth())
actionParams.UnitData.Health = actionParams.UnitData.GetMaxHealth();
ret = true;
if(actionParams.UnitData.Renderer(actionParams.MapData)?.InstantUpdateUnit(true) ?? false)
gridData.Renderer(actionParams.MapData)?.PlayVFX(new GridVFXParams(GridVFXType.Heal));
}
//处理gather
if (_actionId.UnitActionType == UnitActionType.Gather)
{
gridData.Resource = ResourceType.None;
actionParams.PlayerData.PlayerWealth += 10;
gridData.Renderer(actionParams.MapData)?.SetUpdateGrid(true);
ret = true;
if (actionParams.MapData == Main.MapData && actionParams.MapData.PlayerMap.SelfPlayerId == playerData.Id)
{
var v1 = Table.Instance.GridToWorld(gridData);
var startPos = Table.Instance.GridToWorld(gridData);
var moneyPanel = GameObject.Find("UICanvas/TopBarPanel/MoneyPanel/Icon").transform;
var endPos = moneyPanel.position;
//播放获得钱的动画
MapRenderer.Instance.ProjectileManager.CreateProjectileMulti(startPos,endPos,ProjectileType.Coin,ProjectileMoveType.CoinParabola,10,0.05f);
//MapRenderer.Instance.ProjectileManager.CreateProjectileMulti(main,actionParams.MapData,v1,v2,ProjectileType.CityExp,ProjectileMoveType.CityExpHighParabola,wonderInfo.Exp);
}
}
//处理examine
if (_actionId.UnitActionType == UnitActionType.Examine)
{
unitData.HeroTask(actionParams.MapData)?.OnTreasure(actionParams.MapData);
gridData.Resource = ResourceType.None;
gridData.Renderer(actionParams.MapData)?.SetUpdateGrid(true);
if (actionParams.MapData.Net.GetRandom().Next(0, 100) < 50)
{
actionParams.PlayerData.PlayerWealth += 10;
//播放获得钱的动画
if (actionParams.MapData == Main.MapData && actionParams.MapData.PlayerMap.SelfPlayerId == playerData.Id)
MapRenderer.Instance.ProjectileManager.CreateCoinProjectile(Table.Instance.GridToWorld(gridData),10);
}
//给一个随机科技
else if (UnityEngine.Random.Range(0, 100) < 0)
{
var tt = new List<TechType>();
foreach (TechType tech in System.Enum.GetValues(typeof(TechType)))
{
if (actionParams.PlayerData.TechTree.CheckIfHasTech(tech))
continue;
tt.Add(tech);
}
if(tt.Count <= 0)
actionParams.PlayerData.PlayerWealth += 10;
else
{
Main.PlayerLogic.ResearchTech(actionParams.MapData,actionParams.PlayerData,tt[UnityEngine.Random.Range(0, tt.Count)],0);
}
}
//给一个单位
else
{
Main.UnitLogic.PassiveMoveAway(actionParams.MapData, actionParams.UnitData);
if(!actionParams.MapData.GetCapitalCityDataByPlayerId(actionParams.PlayerData.Id, out var capital))
return false;
if (gridData.Terrain == TerrainType.Land)
{
if (actionParams.MapData.AddUnitData(gridData.Id, capital.Id,new UnitFullType(UnitType.Swordsman,GiantType.None,0) , out var unit))
{
unit.Exp = 3;
unit.Veteran = true;
unit.Health = unit.GetMaxHealth();
unit.Renderer(actionParams.MapData)?.InstantUpdateUnit(true);
};
}
else
{
if (actionParams.MapData.AddUnitData(gridData.Id, capital.Id,
new UnitFullType(UnitType.RammerShip, GiantType.None, 0), out var unit))
{
unit.CarryExp = 3;
unit.CarryVeteran = true;
unit.Health = unit.GetMaxHealth();
unit.Renderer(actionParams.MapData)?.InstantUpdateUnit(true);
}
}
if(gridData.Terrain == TerrainType.Land)
capital.SetCityRenderer(actionParams.MapData);
}
ret = true;
}
//处理ROYALFLAMES
if (_actionId.UnitActionType == UnitActionType.ROYALFLAMES)
{
var unitA = actionParams.UnitData;
var gridA = gridData;
var gridList = actionParams.MapData.GridMap.GetAroundGridData(2,2,gridA);
gridData.Renderer(actionParams.MapData)?.PlayVFX(new GridVFXParams(GridVFXType.ROYALFLAMES));
Timer.Instance.TimerRegister(this,()=>
{
if (!actionParams.MapData.GetPlayerIdByUnitId(unitA.Id, out var pidA)) return;
foreach (var gridB in gridList)
{
//如果有地方单位,造成伤害
if (actionParams.MapData.GetUnitDataByGid(gridB.Id, out var unitB))
{
if (!actionParams.MapData.GetPlayerIdByUnitId(unitB.Id, out var pidB)) continue;
//如果是友军,跳过
if (actionParams.MapData.SameUnion(pidB,pidA)) continue;
var dis = Table.Instance.CalcDistance(gridA,gridB );
//处理内圈伤害
if (dis == 1)
{
//var damage = Table.Instance.CalcDamage(actionParams.MapData, unitA, unitB);
Main.UnitLogic.DamageSettlement(actionParams.MapData,unitA, unitB,6, DamageType.Splash);
//播放伤害数字特效
var damageMark1 = new GridVFXParams(GridVFXType.Damage);
damageMark1.Damage = 6;
gridData.Renderer(actionParams.MapData)?.PlayVFX(damageMark1);
//更新unit的显示
unitB.Renderer(actionParams.MapData)?.InstantUpdateUnit(true);
gridB.Renderer(actionParams.MapData)?.PlayVFX(new GridVFXParams(GridVFXType.Hurt));
// 执行相关动画,包括伤害特效、伤害数字、以及可能得死亡特效
MapRenderer.Instance.ROGridMap[gridB.Id].SetBounceAnim(NeedRandomWait:true);
}
//处理外圈伤害
if (dis == 2)
{
//var damage = Table.Instance.CalcDamage(actionParams.MapData, unitA, unitB,damagePara:0.5f);
Main.UnitLogic.DamageSettlement(actionParams.MapData,unitA, unitB,3, DamageType.Splash);
//播放伤害数字特效
var damageMark2 = new GridVFXParams(GridVFXType.Damage);
damageMark2.Damage = 3;
gridB.Renderer(actionParams.MapData)?.PlayVFX(damageMark2);
//更新unit的显示
unitB.Renderer(actionParams.MapData)?.InstantUpdateUnit(true);
//TODO 下面的是不规范做法,后面要迭代
//播放受伤特效
gridB.Renderer(actionParams.MapData)?.PlayVFX(new GridVFXParams(GridVFXType.Hurt));
// 执行相关动画,包括伤害特效、伤害数字、以及可能得死亡特效
MapRenderer.Instance.ROGridMap[gridB.Id].SetBounceAnim(NeedRandomWait:true);
}
}
else
//如果没有单位,造成地块震荡的效果
{
//处理动画效果
MapRenderer.Instance.ROGridMap[gridB.Id].SetBounceAnim(NeedRandomWait:true);
}
}
},0.5f,"ActionLogic_UnitAction_Execute_Anim");
ret = true;
}
if (ret)
{
actionParams.UnitData.CP = 0;
actionParams.UnitData.AP = 0;
actionParams.UnitData.MP = 0;
actionParams.UnitData.Renderer(actionParams.MapData)?.InstantUpdateUnit(true);
}
return ret;
}
public override bool CheckCan(CommonActionParams actionParams)
{
//鲁棒性判断
if (actionParams.UnitData == null) return false;
if (actionParams.PlayerData == null) return false;
if (!actionParams.MapData.GetGridDataByUnitId(actionParams.UnitData.Id, out var gridData))
return false;
//如果unit不是player的退出
if(!actionParams.MapData.GetPlayerDataByUnitId(actionParams.UnitData.Id, out var playerData) ||
playerData != actionParams.PlayerData)
return false;
//判断钱够不够
if (GetCost() > actionParams.PlayerData.PlayerWealth)
return false;
//如果不具备科技
if (!actionParams.PlayerData.TechTree.CheckActionCan(_actionId))
return false;
if (_actionId.UnitActionType == UnitActionType.Upgrade)
{
//鲁棒性处理
if (!Table.Instance.UnitTypeDataAssets.GetUnitTypeInfo(actionParams.UnitData.UnitType,
actionParams.UnitData.GiantType, actionParams.UnitData.UnitLevel,out var info))
return false;
//处理CARRY的情况
if (info.Skills.Contains(SkillType.CARRY))
{
if (actionParams.UnitData.CarryVeteran)
return false;
if (actionParams.UnitData.CarryExp >= 3)
return true;
return false;
}
//处理非CARRY是老兵
if (actionParams.UnitData.Veteran)
return false;
if (actionParams.UnitData.Exp >= 3)
return true;
return false;
}
//先处理不需要CP的 Upgrade UnitShip UnitRammerShip UnitBattleShip 这4个
if (_actionId.UnitType == UnitType.Ship || _actionId.UnitType == UnitType.RammerShip
|| _actionId.UnitType == UnitType.BomberShip)
{
if(actionParams.UnitData.UnitType != UnitType.Boat)
return false;
if (!actionParams.MapData.GetPlayerDataByTerritoryGridId(gridData.Id, out var player1))
return false;
if(!actionParams.MapData.SameUnion(player1.Id,actionParams.PlayerData.Id))
return false;
return true;
}
//剩下的都需要CP如果Unit有没有CP了return false
if (actionParams.UnitData.CP <= 0)
return false;
//处理capture
if (_actionId.UnitActionType == UnitActionType.Capture)
{
//如果是占领别的城市
if (actionParams.MapData.GetCityDataByGid(gridData.Id, out var cityData))
{
actionParams.MapData.GetPlayerDataByCityId(cityData.Id,out var playerId1);
actionParams.MapData.GetPlayerDataByUnitId(actionParams.UnitData.Id,out var playerId2);
return playerId1 != playerId2;
}
//如果是占领村庄
else
{
return gridData.Resource == ResourceType.CityCenter;
}
}
//处理disband
if (_actionId.UnitActionType == UnitActionType.Disband)
{
if ((actionParams.UnitData.UnitType is UnitType.Giant or UnitType.GiantJuggernaut or UnitType.KaguyaFrenchReisenIllusion or UnitType.KaguyaFrenchMokouEgg) || actionParams.UnitData.CarryUnitType == UnitType.Giant)
return false;
return true;
}
//处理recover
if (_actionId.UnitActionType == UnitActionType.Recover)
{
if (actionParams.UnitData.Health < actionParams.UnitData.GetMaxHealth())
return true;
return false;
}
//处理gather
if (_actionId.UnitActionType == UnitActionType.Gather)
return gridData.Resource == ResourceType.Starfish;
//处理examine
if (_actionId.UnitActionType == UnitActionType.Examine)
return gridData.Resource == ResourceType.Treasure;
//处理战技ROYALFLAMES
if (_actionId.UnitActionType == UnitActionType.ROYALFLAMES)
{
if (!actionParams.UnitData.GetSkill(SkillType.ROYALFLAMES, out var skillInfo))
return false;
return true;
}
return false;
}
public override bool CheckShow(CommonActionParams actionParams)
{
//鲁棒性判断
if (actionParams.UnitData == null) return false;
if (actionParams.PlayerData == null) return false;
if (!actionParams.MapData.GetGridDataByUnitId(actionParams.UnitData.Id, out var gridData))
return false;
//如果unit不是player的退出
if(!actionParams.MapData.GetPlayerDataByUnitId(actionParams.UnitData.Id, out var playerData) ||
playerData.Id != actionParams.PlayerData.Id)
return false;
//判断钱够不够 checkshow中 即使钱不够,也可以显示的
//if (GetCost() > actionParams.PlayerData.PlayerWealth)
// return false;
//如果不具备科技
if (!actionParams.PlayerData.TechTree.CheckActionCan(_actionId))
return false;
//先处理不需要CP的 Upgrade UnitShip UnitRammerShip UnitBattleShip 这4个
if (_actionId.UnitActionType == UnitActionType.Upgrade)
{
//鲁棒性处理
if (!Table.Instance.UnitTypeDataAssets.GetUnitTypeInfo(actionParams.UnitData.UnitType,
actionParams.UnitData.GiantType, actionParams.UnitData.UnitLevel,out var info))
return false;
//处理CARRY的情况
if (info.Skills.Contains(SkillType.CARRY))
{
if (actionParams.UnitData.CarryVeteran)
return false;
if (actionParams.UnitData.CarryExp >= 3)
return true;
return false;
}
//处理非CARRY是老兵
if (actionParams.UnitData.Veteran)
return false;
if (actionParams.UnitData.Exp >= 3)
return true;
return false;
}
if (_actionId.UnitType == UnitType.Ship || _actionId.UnitType == UnitType.RammerShip
|| _actionId.UnitType == UnitType.BomberShip)
{
if(actionParams.UnitData.UnitType != UnitType.Boat)
return false;
if (!actionParams.MapData.GetPlayerDataByTerritoryGridId(gridData.Id, out var player1))
return false;
if(!actionParams.MapData.SameUnion(player1.Id,actionParams.PlayerData.Id))
return false;
return true;
}
//剩下的都需要CP如果Unit有没有CP了return false
if (actionParams.UnitData.CP <= 0)
return false;
//处理capture
if (_actionId.UnitActionType == UnitActionType.Capture)
{
//如果是占领别的城市
if (actionParams.MapData.GetCityDataByGid(gridData.Id, out var cityData))
{
actionParams.MapData.GetPlayerDataByCityId(cityData.Id,out var playerId1);
actionParams.MapData.GetPlayerDataByUnitId(actionParams.UnitData.Id,out var playerId2);
return playerId1 != playerId2;
}
//如果是占领村庄
else
{
return gridData.Resource == ResourceType.CityCenter;
}
}
//处理disband
if (_actionId.UnitActionType == UnitActionType.Disband)
{
if ((actionParams.UnitData.UnitType is UnitType.Giant or UnitType.GiantJuggernaut or UnitType.KaguyaFrenchReisenIllusion or UnitType.KaguyaFrenchMokouEgg) || actionParams.UnitData.CarryUnitType == UnitType.Giant)
return false;
return true;
}
//处理recover
if (_actionId.UnitActionType == UnitActionType.Recover)
{
if (actionParams.UnitData.Health < actionParams.UnitData.GetMaxHealth())
return true;
return false;
}
//处理gather
if (_actionId.UnitActionType == UnitActionType.Gather)
return gridData.Resource == ResourceType.Starfish;
//处理examine
if (_actionId.UnitActionType == UnitActionType.Examine)
return gridData.Resource == ResourceType.Treasure;
//处理战技ROYALFLAMES
if (_actionId.UnitActionType == UnitActionType.ROYALFLAMES)
{
if (!actionParams.UnitData.GetSkill(SkillType.ROYALFLAMES, out var skillInfo))
return false;
return true;
}
return false;
}
//付钱
protected bool UnitActionPayMoney(CommonActionParams actionParam)
{
if (actionParam.PlayerData.PlayerWealth - GetCost() < 0) return false;
actionParam.PlayerData.PlayerWealth -= GetCost();
return true;
}
//确认是否满足基本信息,并且补全actionParam(主要是补充unit所处的grid)
protected bool UnitActionCheckBaseInfo(CommonActionParams actionParam)
{
//鲁棒性判断必须包含unitData和playerData表明是哪个玩家正在操作哪个单位
if (actionParam.UnitData == null) return false;
if (actionParam.PlayerData == null) return false;
if (!actionParam.MapData.GetGridDataByUnitId(actionParam.UnitData.Id, out var grid)) return false;
actionParam.GridData = grid;
return true;
}
protected bool UnitActionCheckUnitBelongPlayer(CommonActionParams actionParam)
{
//如果unit不是player的退出
if(!actionParam.MapData.GetPlayerDataByUnitId(actionParam.UnitData.Id, out var playerData) ||
playerData != actionParam.PlayerData)
return false;
return true;
}
//确认是否有科技
protected bool UnitActionCheckHasTech(CommonActionParams actionParam)
{
//如果没有对应科技return false
if (!actionParam.PlayerData.TechTree.CheckActionCan(_actionId))
return false;
return true;
}
//确认是否有钱
protected bool UnitActionCheckHasMoney(CommonActionParams actionParam)
{
//判断钱够不够
if (GetCost() > actionParam.PlayerData.PlayerWealth)
return false;
return true;
}
//确认unit是否有CP
protected bool UnitActionCheckUnitHasCP(CommonActionParams actionParam)
{
if (actionParam.UnitData == null || actionParam.UnitData.CP <= 0)
return false;
return true;
}
//确认unit是否拥有这个skill
protected bool UnitActionCheckUnitHasSkill(CommonActionParams actionParam)
{
//将unitActionType转化为skillType
if (!Enum.TryParse(_actionId.UnitActionType.ToString(), out SkillType skillType)) return false;
if (actionParam.UnitData == null || !actionParam.UnitData.GetSkill(skillType, out var _)) return false;
return true;
}
}
public class UnitActionROYALFLAMESPRO : UnitActionAction
{
public UnitActionROYALFLAMESPRO(CommonActionId id) : base(id)
{
}
protected override bool Execute(CommonActionParams actionParams)
{
var unitA = actionParams.UnitData;
var gridA = actionParams.GridData;
if(gridA == null)
if(!actionParams.MapData.GetGridDataByUnitId(unitA.Id, out gridA)) return false;
var gridList = actionParams.MapData.GridMap.GetAroundGridData(3,3,gridA);
var t = new GridVFXParams(GridVFXType.ROYALFLAMES);
gridA.Renderer(actionParams.MapData)?.PlayVFX(t);
Timer.Instance.TimerRegister(this,()=>
{
if (!actionParams.MapData.GetPlayerIdByUnitId(unitA.Id, out var pidA)) return;
foreach (var gridB in gridList)
{
//如果有地方单位,造成伤害
if (actionParams.MapData.GetUnitDataByGid(gridB.Id, out var unitB))
{
if (!actionParams.MapData.GetPlayerIdByUnitId(unitB.Id, out var pidB)) continue;
//如果是友军,跳过
if (actionParams.MapData.SameUnion(pidB,pidA)) continue;
var dis = Table.Instance.CalcDistance(gridA,gridB );
//处理内圈伤害
if (dis == 1)
{
//var damage = Table.Instance.CalcDamage(actionParams.MapData, unitA, unitB);
Main.UnitLogic.DamageSettlement(actionParams.MapData,unitA, unitB,10, DamageType.Splash);
//播放伤害数字特效
var damageMark1 = new GridVFXParams(GridVFXType.Damage);
damageMark1.Damage = 10;
gridB.Renderer(actionParams.MapData)?.PlayVFX(damageMark1);
//更新unit的显示
unitB.Renderer(actionParams.MapData)?.InstantUpdateUnit(true);
//TODO 下面的是不规范做法,后面要迭代
//播放受伤特效
gridB.Renderer(actionParams.MapData)?.PlayVFX(new GridVFXParams(GridVFXType.Hurt));
// 执行相关动画,包括伤害特效、伤害数字、以及可能得死亡特效
MapRenderer.Instance.ROGridMap[gridB.Id].SetBounceAnim(NeedRandomWait:true);
}
//处理外圈伤害
if (dis == 2)
{
//var damage = Table.Instance.CalcDamage(actionParams.MapData, unitA, unitB,damagePara:0.5f);
Main.UnitLogic.DamageSettlement(actionParams.MapData,unitA, unitB,6, DamageType.Splash);
//播放伤害数字特效
gridB.Renderer(actionParams.MapData)?.PlayVFX(new GridVFXParams(GridVFXType.Damage,6));
//更新unit的显示
unitB.Renderer(actionParams.MapData)?.InstantUpdateUnit(true);
gridB.Renderer(actionParams.MapData)?.PlayVFX(new GridVFXParams(GridVFXType.Hurt));
// 执行相关动画,包括伤害特效、伤害数字、以及可能得死亡特效
MapRenderer.Instance.ROGridMap[gridB.Id].SetBounceAnim(NeedRandomWait:true);
}
//处理3圈伤害
if (dis == 3)
{
//var damage = Table.Instance.CalcDamage(actionParams.MapData, unitA, unitB,damagePara:0.5f);
Main.UnitLogic.DamageSettlement(actionParams.MapData,unitA, unitB,3, DamageType.Splash);
//播放伤害数字特效
gridB.Renderer(actionParams.MapData)?.PlayVFX(new GridVFXParams(GridVFXType.Damage,3));
//更新unit的显示
unitB.Renderer(actionParams.MapData)?.InstantUpdateUnit(true);
//TODO 下面的是不规范做法,后面要迭代
//播放受伤特效
gridB.Renderer(actionParams.MapData)?.PlayVFX(new GridVFXParams(GridVFXType.Hurt));
// 执行相关动画,包括伤害特效、伤害数字、以及可能得死亡特效
MapRenderer.Instance.ROGridMap[gridB.Id].SetBounceAnim(NeedRandomWait:true);
}
}
else
//如果没有单位,造成地块震荡的效果
{
//处理动画效果
MapRenderer.Instance.ROGridMap[gridB.Id].SetBounceAnim(NeedRandomWait:true);
}
}
},0.5f,"UnitActionLogic_Execute_ROYALFLAMESPRO");
actionParams.UnitData.ClearAPMPCP();
actionParams.UnitData.Renderer(actionParams.MapData)?.InstantUpdateUnit(true);
return true;
}
public override bool CheckCan(CommonActionParams actionParam)
{
//step #1 check基本信息
if (!UnitActionCheckBaseInfo(actionParam)) return false;
//#step #2 check unit属于player
if (!UnitActionCheckUnitBelongPlayer(actionParam)) return false;
//step #3 check是否有CP释放技能
if (!UnitActionCheckUnitHasCP(actionParam)) return false;
//step #4 check unit是否拥有skill技能
if (!UnitActionCheckUnitHasSkill(actionParam)) return false;
return true;
}
public override bool CheckShow(CommonActionParams actionParam)
{
return CheckCan(actionParam);
}
}
//英雄升级
public class UnitActionGiantUpgrade : UnitActionAction
{
private int _healthBeforeAnim;
private bool CheckUnitCanGiantUpgrade(CommonActionParams actionParams)
{
var unit = actionParams.UnitData;
var player = actionParams.PlayerData;
if (player == null) return false;
if(unit == null || unit.UnitType != UnitType.Giant || unit.GiantType == GiantType.None || unit.UnitLevel >= 3) return false;
if(!Table.Instance.UnitTypeDataAssets.GetUnitTypeInfo(unit.UnitType,unit.GiantType,unit.UnitLevel,out var info)) return false;
return unit.HeroTask(actionParams.MapData)?.CheckFinished() ?? false;
}
public UnitActionGiantUpgrade(CommonActionId id) : base(id)
{
}
protected override bool Execute(CommonActionParams actionParams)
{
_healthBeforeAnim = actionParams.UnitData.Health;
//if (!CheckCan(actionParams)) return false;
var unit = actionParams.UnitData;
if (!Table.Instance.UnitTypeDataAssets.GetUnitTypeInfo(unit.UnitType, unit.GiantType, unit.UnitLevel,
out var info)) return false;
//step #1 已经升到满级就return
if (unit.UnitLevel + 1 > 3) return false;
//step #2 英雄升级
if (!Main.UnitLogic.HeroUpgrade(actionParams.MapData, unit)) return false;
//step #3 回复10点血
unit.AddHealth(10);
//更新视觉自动排除非真map情况和不在视野情况
if(actionParams.UnitData.Renderer(actionParams.MapData)?.InstantUpdateUnit(true)??false)
actionParams.UnitData.Grid(actionParams.MapData)?.Renderer(actionParams.MapData)?.PlayVFX(new GridVFXParams(GridVFXType.Heal));
return true;
}
public override bool CheckCan(CommonActionParams actionParam)
{
//step #1 check基本信息
if (!UnitActionCheckBaseInfo(actionParam)) return false;
//#step #2 check unit属于player
if (!UnitActionCheckUnitBelongPlayer(actionParam)) return false;
//step #3 check unit是否是hero并满足升级条件
if (!CheckUnitCanGiantUpgrade(actionParam)) return false;
return true;
}
public override bool CheckShow(CommonActionParams actionParam)
{
return CheckCan(actionParam);
}
public bool ExecuteViewBefore(CommonActionParams actionParams)
{
return true;
}
public bool ExecuteViewAfter(CommonActionParams actionParams)
{
return true;
}
}
public class UnitActionHEAL : UnitActionAction
{
public UnitActionHEAL(CommonActionId id) : base(id)
{
}
protected override bool Execute(CommonActionParams actionParams)
{
var map = actionParams.MapData;
var unit = actionParams.UnitData;
if (map == null || unit == null) return false;
if (!map.GetGridDataByUnitId(actionParams.UnitData.Id, out var targetGrid)) return false;
var roundGrid = map.GridMap.GetAroundGridData(1, 1, targetGrid);
foreach (var grid in roundGrid)
{
if (!map.GetUnitDataByGid(grid.Id, out var tunit)) continue;
if(tunit.Id == unit.Id)continue;
if (!map.SameUnionByUnitId(unit.Id,tunit.Id)) continue;
tunit.AddHealth(4);
if(tunit.Renderer(actionParams.MapData)?.InstantUpdateUnit(true)??false)
grid.Renderer(actionParams.MapData)?.PlayVFX(new GridVFXParams(GridVFXType.Heal));
}
unit.ClearAPMPCP();
unit.Renderer(actionParams.MapData)?.InstantUpdateUnit(true);
return true;
}
public override bool CheckCan(CommonActionParams actionParam)
{
//step #1 check基本信息
if (!UnitActionCheckBaseInfo(actionParam)) return false;
//#step #2 check unit属于player
if (!UnitActionCheckUnitBelongPlayer(actionParam)) return false;
//step #3 check是否有CP释放技能
if (!UnitActionCheckUnitHasCP(actionParam)) return false;
//step #4 check unit是否拥有skill技能
if (!UnitActionCheckUnitHasSkill(actionParam)) return false;
return true;
}
public override bool CheckShow(CommonActionParams actionParam)
{
return CheckCan(actionParam);
}
}
public class UnitActionTEWIFRENCHBUFF : UnitActionAction
{
public UnitActionTEWIFRENCHBUFF(CommonActionId id) : base(id)
{
}
protected override bool Execute(CommonActionParams actionParams)
{
var selfUnit = actionParams.UnitData;
var selfGrid = actionParams.GridData;
if(selfGrid == null)
if(!actionParams.MapData.GetGridDataByUnitId(selfUnit.Id, out selfGrid)) return false;
if (!actionParams.MapData.GetPlayerDataByUnitId(selfUnit.Id, out var selfPlayer)) return false;
var gridList = actionParams.MapData.GridMap.GetAroundGridData(1,1,selfGrid);
foreach (var grid in gridList)
{
if (grid == selfGrid) continue;
if(!actionParams.MapData.GetUnitDataByGid(grid.Id,out var targetUnit))continue;
if(!actionParams.MapData.GetPlayerDataByUnitId(targetUnit.Id, out var targetPlayer)) continue;
if(!actionParams.MapData.SameUnion(targetPlayer.Id,selfPlayer.Id)) continue;
targetUnit.AddSkill(SkillType.MOVERANGEUP,1);
targetUnit.AddSkill(SkillType.KAGUYAFRENCHSYNERGY,1);
if(targetUnit.Renderer(actionParams.MapData)?.InstantUpdateUnit(true)??false)
grid.Renderer(actionParams.MapData)?.PlayVFX(new GridVFXParams(GridVFXType.TewiFrenchBuff));
}
actionParams.UnitData.ClearAPMPCP();
actionParams.UnitData.Renderer(actionParams.MapData)?.InstantUpdateUnit(true);
return true;
}
public override bool CheckCan(CommonActionParams actionParam)
{
//step #1 check基本信息
if (!UnitActionCheckBaseInfo(actionParam)) return false;
//#step #2 check unit属于player
if (!UnitActionCheckUnitBelongPlayer(actionParam)) return false;
//step #3 check是否有CP释放技能
if (!UnitActionCheckUnitHasCP(actionParam)) return false;
//step #4 check unit是否拥有skill技能
if (!UnitActionCheckUnitHasSkill(actionParam)) return false;
return true;
}
public override bool CheckShow(CommonActionParams actionParam)
{
return CheckCan(actionParam);
}
}
public class UnitActionMOKOUFRENCHBOOM : UnitActionAction
{
public UnitActionMOKOUFRENCHBOOM(CommonActionId id) : base(id)
{
}
protected override bool Execute(CommonActionParams actionParams)
{
var selfUnit = actionParams.UnitData;
var selfGrid = actionParams.GridData;
if(selfGrid == null)
if(!actionParams.MapData.GetGridDataByUnitId(selfUnit.Id, out selfGrid)) return false;
if (!actionParams.MapData.GetPlayerDataByUnitId(selfUnit.Id, out var selfPlayer)) return false;
var gridList = actionParams.MapData.GridMap.GetAroundGridData(1,1,selfGrid);
foreach (var grid in gridList)
{
if (grid == selfGrid) continue;
if(!actionParams.MapData.GetUnitDataByGid(grid.Id,out var targetUnit))continue;
var dmg = Table.Instance.CalcDamage(actionParams.MapData,selfUnit,targetUnit,10);
var dmgType = actionParams.MapData.SameUnionByUnitId(selfUnit.Id, targetUnit.Id) ? DamageType.KillSelf : DamageType.True;
var settle = Main.UnitLogic.DamageSettlement(actionParams.MapData, selfUnit, targetUnit, dmg, dmgType);
if (!settle.IsKill)
{
settle.DamageTargetGrid.Renderer(actionParams.MapData)?.PlayVFX(new GridVFXParams(GridVFXType.Hurt));
targetUnit.Renderer(actionParams.MapData)?.InstantUpdateUnit(true);
}
else
{
settle.DamageTargetGrid.Renderer(actionParams.MapData)?.PlayVFX(new GridVFXParams(GridVFXType.Die));
}
}
Main.UnitLogic.DamageSettlement(actionParams.MapData, selfUnit, selfUnit, selfUnit.Health, DamageType.KillSelf);
return true;
}
public override bool CheckCan(CommonActionParams actionParam)
{
//step #1 check基本信息
if (!UnitActionCheckBaseInfo(actionParam)) return false;
//#step #2 check unit属于player
if (!UnitActionCheckUnitBelongPlayer(actionParam)) return false;
//step #3 check是否有CP释放技能
if (!UnitActionCheckUnitHasCP(actionParam)) return false;
//step #4 check unit是否拥有skill技能
if (!UnitActionCheckUnitHasSkill(actionParam)) return false;
return true;
}
public override bool CheckShow(CommonActionParams actionParam)
{
return CheckCan(actionParam);
}
}
public class UnitActionKAGUYAFRENCHAROUND : UnitActionAction
{
public UnitActionKAGUYAFRENCHAROUND(CommonActionId id) : base(id)
{
}
protected override bool Execute(CommonActionParams actionParams)
{
var selfUnit = actionParams.UnitData;
var selfGrid = actionParams.GridData;
if(selfGrid == null)
if(!actionParams.MapData.GetGridDataByUnitId(selfUnit.Id, out selfGrid)) return false;
if (!actionParams.MapData.GetPlayerDataByUnitId(selfUnit.Id, out var selfPlayer)) return false;
var gridList = actionParams.MapData.GridMap.GetAroundGridData(1,1,selfGrid);
foreach (var grid in gridList)
{
if (grid == selfGrid) continue;
if(!actionParams.MapData.GetUnitDataByGid(grid.Id,out var targetUnit))continue;
if(!actionParams.MapData.GetPlayerDataByUnitId(targetUnit.Id, out var targetPlayer)) continue;
if(!actionParams.MapData.SameUnion(targetPlayer.Id,selfPlayer.Id)) continue;
targetUnit.AddSkill(SkillType.KAGUYAFRENCHFOREVERBUFF);
if (targetUnit.GetSkill(SkillType.KAGUYAFRENCHFOREVERBUFF, out var skill))
skill.AddLevel(actionParams.MapData,selfUnit,1);
targetUnit.Renderer(actionParams.MapData)?.InstantUpdateUnit(true);
grid.Renderer(actionParams.MapData)?.PlayVFX(new GridVFXParams(GridVFXType.KaguyaFrenchBuff));
}
actionParams.UnitData.ClearAPMPCP();
actionParams.UnitData.Renderer(actionParams.MapData)?.InstantUpdateUnit(true);
return true;
}
public override bool CheckCan(CommonActionParams actionParam)
{
//step #1 check基本信息
if (!UnitActionCheckBaseInfo(actionParam)) return false;
//#step #2 check unit属于player
if (!UnitActionCheckUnitBelongPlayer(actionParam)) return false;
//step #3 check是否有CP释放技能
if (!UnitActionCheckUnitHasCP(actionParam)) return false;
//step #4 check unit是否拥有skill技能
if (!UnitActionCheckUnitHasSkill(actionParam)) return false;
return true;
}
public override bool CheckShow(CommonActionParams actionParam)
{
return CheckCan(actionParam);
}
}
public class UnitActionForceDisband : UnitActionAction
{
public UnitActionForceDisband(CommonActionId id) : base(id)
{
}
protected override bool Execute(CommonActionParams actionParams)
{
//Step #1 鲁棒性判断
if (actionParams.UnitData == null) return false;
var unitData = actionParams.UnitData;
var playerData = actionParams.PlayerData;
if (playerData == null)
if (!actionParams.MapData.GetPlayerDataByUnitId(actionParams.UnitData.Id, out playerData))
return false;
if (!actionParams.MapData.GetGridDataByUnitId(actionParams.UnitData.Id, out var gridData))
return false;
//Step #2 计算花费的金币数,增加金币
int earn = 0;
//返还造价一半的金币
if (!Table.Instance.UnitTypeDataAssets.GetUnitTypeInfo(actionParams.UnitData.UnitType,GiantType.None,0, out var info )) return false;
earn += info.Cost / 2;
//如果是有carry技能那么船和船上单位分开计费
if (actionParams.UnitData.CarryUnitType != UnitType.None
&& Table.Instance.UnitTypeDataAssets.GetUnitTypeInfo(actionParams.UnitData.CarryUnitType,
GiantType.None,0, out var carryInfo))
earn += carryInfo.Cost / 2;
actionParams.PlayerData.PlayerWealth += earn;
//AddCoin自带动画考量
actionParams.PlayerData.AddCoin(earn,gridData);
//Step #3 如果是真map需要播放单位死亡动画
if (actionParams.MapData == Main.MapData)
{
//播放雾效
gridData.Renderer(actionParams.MapData)?.PlayVFX(new GridVFXParams(GridVFXType.Fog));
//通知渲染器播放死亡
if(MapRenderer.Instance.ROUnitMap.TryGetValue(actionParams.UnitData.Id,out var renderer))
renderer.Die();
//播放获得钱的动画 legace 已经改了 ,没错就可以删了
//var v1 = Table.Instance.GridToWorld(gridData);
//var startPos = Table.Instance.GridToWorld(gridData);
//var moneyPanel = GameObject.Find("UICanvas/TopBarPanel/MoneyPanel/Icon").transform;
//var endPos = moneyPanel.position;
//if(playerData.Id == actionParams.MapData.PlayerMap.SelfPlayerId)
//MapRenderer.Instance.ProjectileManager.CreateProjectileMulti(startPos,endPos,ProjectileType.Coin,ProjectileMoveType.CoinParabola,earn,0.05f);
}
//Step #4 单位彻底死亡
Main.UnitLogic.Die(actionParams.MapData,actionParams.UnitData);
return true;
}
public override bool CheckCan(CommonActionParams actionParam)
{
//step #1 check基本信息
if (!UnitActionCheckBaseInfo(actionParam)) return false;
//#step #2 check unit属于player
if (!UnitActionCheckUnitBelongPlayer(actionParam)) return false;
return true;
}
}
}