2025-09-18 01:21:59 +08:00

1537 lines
64 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 Logic.AI;
using Logic.CrashSight;
using MemoryPack;
using RuntimeData;
using TH1_Logic.Action;
using TH1_Logic.Core;
using TH1_Logic.Steam;
using UnityEngine;
using TH1Renderer;
public enum GridMiscActionType{None,GrowForest,ClearForest,BurnForest,Destroy,UpgradeTemple,GrowForestOutside}
namespace Logic.Action
{
// 行为类型枚举
public enum CommonActionType
{
Gain,
Build,
StartWonder,
BuildWonder,
TrainUnit,
GridMisc,
UnitAction,
CityLevelUpAction,
UnitSkill,
LearnTech,
UnitMove,
UnitAttack,
PlayerAction
}
public enum ActionShowState
{
None,
Available,
Unavailable,
Expensive,
Finished
}
// 通用行为参数类
[MemoryPackable]
public partial class CommonActionParams
{
[MemoryPackIgnore]
public MapData MapData;
[MemoryPackIgnore]
public PlayerData PlayerData;
[MemoryPackIgnore]
public UnitData UnitData;
[MemoryPackIgnore]
public CityData CityData;
[MemoryPackIgnore]
public GridData GridData;
[MemoryPackIgnore]
public UnitData TargetUnitData;
[MemoryPackIgnore]
public GridData TargetGridData;
[MemoryPackIgnore]
public PlayerData TargetPlayerData;
public MainObjectType MainObjectType;
public uint PlayerId;
public uint UnitId;
public uint CityId;
public uint GridId;
public uint TargetUnitId;
public uint TargetGridId;
public uint TargetPlayerId;
[MemoryPackConstructor]
public CommonActionParams()
{
}
public CommonActionParams(MapData mapData=null, PlayerData playerData=null,
UnitData unitData=null, CityData cityData=null, GridData gridData=null, UnitData targetUnit=null, GridData targetGrid=null, PlayerData targetPlayer = null,MainObjectType mainObjectType=MainObjectType.None)
{
MapData = mapData;
PlayerData = playerData;
UnitData = unitData;
CityData = cityData;
GridData = gridData;
TargetUnitData = targetUnit;
TargetGridData = targetGrid;
TargetPlayerData = targetPlayer;
MainObjectType = mainObjectType;
PlayerId = 0;
UnitId = 0;
CityId = 0;
GridId = 0;
TargetUnitId = 0;
TargetGridId = 0;
TargetPlayerId = 0;
if (PlayerData != null) PlayerId = PlayerData.Id;
if (UnitData != null) UnitId = UnitData.Id;
if (CityData != null) CityId = CityData.Id;
if (GridData != null) GridId = GridData.Id;
if (TargetUnitData != null) TargetUnitId = TargetUnitData.Id;
if (TargetGridData != null) TargetGridId = TargetGridData.Id;
if (TargetPlayerData != null) TargetPlayerId = TargetPlayerData.Id;
}
public void RefreshParams()
{
if (PlayerId != 0 && MapData.PlayerMap.GetPlayerDataByPlayerID(PlayerId, out var player))
{
PlayerData = player;
}
if (UnitId != 0 && MapData.UnitMap.GetUnitDataByUnitId(UnitId, out var unit))
{
UnitData = unit;
}
if (CityId != 0 && MapData.CityMap.GetCityById(CityId, out var city))
{
CityData = city;
}
if (GridId != 0 && MapData.GridMap.GetGridDataByGid(GridId, out var grid))
{
GridData = grid;
}
if (TargetUnitId != 0 && MapData.UnitMap.GetUnitDataByUnitId(TargetUnitId, out var target))
{
TargetUnitData = target;
}
if (TargetGridId != 0 && MapData.GridMap.GetGridDataByGid(TargetGridId, out var targetGrid))
{
TargetGridData = targetGrid;
}
if (TargetPlayerId != 0 && MapData.PlayerMap.GetPlayerDataByPlayerID(TargetPlayerId, out var targetPlayer))
{
TargetPlayerData = targetPlayer;
}
}
public void OnParamChanged()
{
if (PlayerData != null) PlayerId = PlayerData.Id;
if (UnitData != null) UnitId = UnitData.Id;
if (CityData != null) CityId = CityData.Id;
if (GridData != null) GridId = GridData.Id;
if (TargetUnitData != null) TargetUnitId = TargetUnitData.Id;
if (TargetGridData != null) TargetGridId = TargetGridData.Id;
if (TargetPlayerData != null) TargetPlayerId = TargetPlayerData.Id;
}
public CommonActionParams GetCopyParam()
{
var param = new CommonActionParams();
param.MapData = MapData;
param.PlayerData = PlayerData;
param.UnitData = UnitData;
param.CityData = CityData;
param.GridData = GridData;
param.TargetUnitData = TargetUnitData;
param.TargetGridData = TargetGridData;
param.TargetPlayerData = TargetPlayerData;
param.MainObjectType = MainObjectType;
param.PlayerId = PlayerId;
param.UnitId = UnitId;
param.CityId = CityId;
param.GridId = GridId;
param.TargetUnitId = TargetUnitId;
param.TargetGridId = TargetGridId;
param.TargetPlayerId = TargetPlayerId;
return param;
}
}
// 通用行为ID类
[Serializable]
[MemoryPackable]
public partial class CommonActionId
{
public CommonActionType ActionType;
public WonderTypeEnum WonderType;
public ResourceType ResourceType;
public TerrainFeature FeatureType;
public TerrainType TerrainType;
public UnitType UnitType;
public GiantType GiantType;
public uint UnitLevel;
public Vegetation Vegetation;
public UnitActionType UnitActionType;
public CityLevelUpActionType CityLevelUpActionType;
public GridMiscActionType GridMiscActionType;
public SkillType SkillType;
public TechType TechType;
public PlayerActionType PlayerActionType;
[MemoryPackConstructor]
public CommonActionId()
{
}
//自动生成唯一Id Hash
public uint Id => ComputeId();
private uint ComputeId()
{
unchecked // 溢出安全
{
int hash = 17;
hash = hash * 31 + ActionType.GetHashCode();
hash = hash * 31 + WonderType.GetHashCode();
hash = hash * 31 + ResourceType.GetHashCode();
hash = hash * 31 + FeatureType.GetHashCode();
hash = hash * 31 + TerrainType.GetHashCode();
hash = hash * 31 + UnitType.GetHashCode();
hash = hash * 31 + GiantType.GetHashCode();
hash = hash * 31 + UnitLevel.GetHashCode();
hash = hash * 31 + Vegetation.GetHashCode();
hash = hash * 31 + UnitActionType.GetHashCode();
hash = hash * 31 + CityLevelUpActionType.GetHashCode();
hash = hash * 31 + GridMiscActionType.GetHashCode();
hash = hash * 31 + SkillType.GetHashCode();
hash = hash * 31 + TechType.GetHashCode();
hash = hash * 31 + PlayerActionType.GetHashCode();
return (uint)hash;
}
}
// 重载 == 运算符 当属性被修改时需要修改运算符重载方法
public static bool operator ==(CommonActionId a, CommonActionId b)
{
if (a is null) return b is null;
if (b is null) return false;
if (a.ActionType != b.ActionType) return false;
if (a.WonderType != b.WonderType) return false;
if (a.ResourceType != b.ResourceType) return false;
if (a.TerrainType != b.TerrainType) return false;
if (a.FeatureType != b.FeatureType) return false;
if (a.UnitType != b.UnitType) return false;
if (a.GiantType != b.GiantType) return false;
if (a.UnitLevel != b.UnitLevel) return false;
if (a.Vegetation != b.Vegetation) return false;
if (a.UnitActionType != b.UnitActionType) return false;
if (a.CityLevelUpActionType != b.CityLevelUpActionType) return false;
if (a.GridMiscActionType != b.GridMiscActionType) return false;
if (a.SkillType != b.SkillType) return false;
if (a.TechType != b.TechType) return false;
if (a.PlayerActionType != b.PlayerActionType) return false;
return true;
}
// 必须同时重载 != 运算符
public static bool operator !=(CommonActionId a, CommonActionId b)
{
return !(a == b);
}
public override int GetHashCode()
{
// 直接调用你的哈希计算逻辑并转换为int
return (int)ComputeId();
}
public override bool Equals(object obj)
{
// 调用类型安全的Equals方法
return Equals(obj as CommonActionId);
}
public bool Equals(CommonActionId other)
{
// 如果另一个对象是null它们不相等
if (other is null)
{
return false;
}
// 如果它们是同一个内存中的对象,它们肯定相等
if (ReferenceEquals(this, other))
{
return true;
}
// 调用你已经写好的比较逻辑!
// 我们可以直接使用你重载的 `==` 运算符,这样可以重用代码。
return this == other;
}
public string GetStringLog()
{
var log = $"";
log += $"ActionType : {ActionType}\n";
log += $"WonderType : {WonderType}\n";
log += $"ResourceType : {ResourceType}\n";
log += $"FeatureType : {FeatureType}\n";
log += $"TerrainType : {TerrainType}\n";
log += $"UnitType : {UnitType}\n";
log += $"GiantType : {GiantType}\n";
log += $"Vegetation : {Vegetation}\n";
log += $"UnitActionType : {UnitActionType}\n";
log += $"CityLevelUpActionType : {CityLevelUpActionType}\n";
log += $"GridMiscActionType : {GridMiscActionType}\n";
log += $"SkillType : {SkillType}\n";
log += $"TechType : {TechType}\n";
log += $"PlayerActionType : {PlayerActionType}\n";
log += $"PlayerId : {TechType}\n";
return log;
}
}
// 行为逻辑工厂类
public static class ActionLogicFactory
{
private static Dictionary<CommonActionId, ActionLogicBase> ActionLogicDict;
private static Dictionary<uint, ActionLogicBase> _actionLogicIdDict;
public static Dictionary<CommonActionId, ActionLogicBase> GetActionLogicDict()
{
Refresh();
return ActionLogicDict;
}
public static Dictionary<uint, ActionLogicBase> GetActionLogicIDDict()
{
Refresh();
return _actionLogicIdDict;
}
public static void RefreshPlayerAction()
{
CommonActionId commonActionId;
//填加外交行为
foreach (PlayerActionType playerActionType in System.Enum.GetValues(typeof(PlayerActionType)))
{
if (playerActionType == PlayerActionType.None) continue;
commonActionId = new CommonActionId
{
ActionType = CommonActionType.PlayerAction,
PlayerActionType = playerActionType
};
ActionLogicDict[commonActionId] = new PlayerActionDiplomacy(commonActionId);
}
//填加英雄相关行为
foreach (GiantType giantType in System.Enum.GetValues(typeof(GiantType)))
{
if (giantType == GiantType.None) continue;
//选择英雄
commonActionId = new CommonActionId
{
ActionType = CommonActionType.PlayerAction,
PlayerActionType = PlayerActionType.SelectHero,
GiantType = giantType
};
ActionLogicDict[commonActionId] = new PlayerActionSelectHero(commonActionId);
//强制完成英雄的任务
commonActionId = new CommonActionId
{
ActionType = CommonActionType.PlayerAction,
PlayerActionType = PlayerActionType.FinishHeroTask,
GiantType = giantType
};
ActionLogicDict[commonActionId] = new PlayerActionFinishHeroTask(commonActionId);
}
}
public static void Refresh()
{
if (ActionLogicDict != null)
return;
ActionLogicDict = new Dictionary<CommonActionId, ActionLogicBase>();
CommonActionId commonActionId;
commonActionId = new CommonActionId { ActionType = CommonActionType.UnitMove };
ActionLogicDict[commonActionId] = new UnitMoveAction(commonActionId);
commonActionId = new CommonActionId { ActionType = CommonActionType.UnitAttack };
ActionLogicDict[commonActionId] = new UnitAttackAction(commonActionId);
for (int i = (int)PlayerActionType.OfferAlly; i < (int)PlayerActionType.Max; i++)
{
commonActionId = new CommonActionId
{
ActionType = CommonActionType.PlayerAction,
PlayerActionType = (PlayerActionType)i,
};
ActionLogicDict[commonActionId] = new PlayerActionDiplomacy(commonActionId);
}
foreach (ResourceType resourceType in System.Enum.GetValues(typeof(ResourceType)))
{
if (resourceType == ResourceType.None) continue;
// 先登记所有Gain 收获一次性资源的行为逻辑
if (resourceType == ResourceType.Animal || resourceType == ResourceType.Fish ||
resourceType == ResourceType.Fruit)
{
commonActionId = new CommonActionId
{
ActionType = CommonActionType.Gain,
ResourceType = resourceType,
};
ActionLogicDict[commonActionId] = new GainResourceAction(commonActionId);
continue;
}
// 登记Build 建设建筑的行为逻辑
commonActionId = new CommonActionId
{
ActionType = CommonActionType.Build,
ResourceType = resourceType,
};
if(resourceType is ResourceType.Sawmill or ResourceType.Windmill or ResourceType.Mine or ResourceType.Farm
or ResourceType.Forge or ResourceType.LumberHut or ResourceType.Port or ResourceType.Bridge
or ResourceType.Market or ResourceType.Academy or ResourceType.Military)
ActionLogicDict[commonActionId] = new BuildAction(commonActionId);
else if (resourceType is ResourceType.ForestTemple or ResourceType.WaterTemple
or ResourceType.Temple or ResourceType.MountainTemple or ResourceType.KingTemple)
ActionLogicDict[commonActionId] = new BuildActionBuildTemple(commonActionId);
else if (resourceType == ResourceType.Preserve)
ActionLogicDict[commonActionId] = new BuildActionBuildPreserve(commonActionId);
else if (resourceType == ResourceType.NavalBase)
ActionLogicDict[commonActionId] = new BuildActionBuildNavalBase(commonActionId);
else if (resourceType == ResourceType.KaguyaFrenchYard)
ActionLogicDict[commonActionId] = new BuildActionBuildKaguyaFrenchYard(commonActionId);
}
//登记build road这种特殊情况
commonActionId = new CommonActionId
{
ActionType = CommonActionType.Build,
FeatureType = TerrainFeature.Road
};
ActionLogicDict[commonActionId] = new BuildAction(commonActionId);
//GridMisc grid的杂类行为逻辑
foreach (GridMiscActionType gridMiscActionType in System.Enum.GetValues(typeof(GridMiscActionType)))
{
if (gridMiscActionType == GridMiscActionType.None) continue;
commonActionId = new CommonActionId
{
ActionType = CommonActionType.GridMisc,
GridMiscActionType = gridMiscActionType
};
if (gridMiscActionType == GridMiscActionType.UpgradeTemple)
ActionLogicDict[commonActionId] = new GridMiscActionUpgradeTemple(commonActionId);
else if (gridMiscActionType == GridMiscActionType.GrowForestOutside)
ActionLogicDict[commonActionId] = new GridMiscActionGrowTreeOutside(commonActionId);
else
ActionLogicDict[commonActionId] = new GridMiscAction(commonActionId);
}
//登记BuildWonder建造奇观的行为逻辑
foreach (WonderTypeEnum wonderType in System.Enum.GetValues(typeof(WonderTypeEnum)))
{
if(wonderType == WonderTypeEnum.None) continue;
//登记建造奇观的action
commonActionId = new CommonActionId
{
ActionType = CommonActionType.BuildWonder,
WonderType = wonderType,
};
ActionLogicDict[commonActionId] = new BuildWonderAction(commonActionId);
//登记建造开启奇观任务的action
commonActionId = new CommonActionId
{
ActionType = CommonActionType.StartWonder,
WonderType = wonderType,
};
ActionLogicDict[commonActionId] = new StartWonderAction(commonActionId);
}
// TrainUnit 建造unit的行为逻辑
foreach (UnitType unitType in Enum.GetValues(typeof(UnitType)))
{
if(unitType == UnitType.None) continue;
if (unitType == UnitType.Giant)
{
foreach (GiantType giantType in Enum.GetValues(typeof(GiantType)))
{
if(giantType == GiantType.None) continue;
commonActionId = new CommonActionId
{
ActionType = CommonActionType.TrainUnit,
UnitType = unitType,
GiantType = giantType
};
ActionLogicDict[commonActionId] = new TrainUnitActionTrainGiant(commonActionId);
}
continue;
}
commonActionId = new CommonActionId
{
ActionType = CommonActionType.TrainUnit,
UnitType = unitType,
};
if (unitType == UnitType.KaguyaFrenchAnimalWarrior)
ActionLogicDict[commonActionId] = new TrainUnitActionTrainKaguyaFrenchAnimalWarrior(commonActionId);
else
ActionLogicDict[commonActionId] = new TrainUnitAction(commonActionId);
}
//cityLevelUp的各个行为逻辑
foreach (CityLevelUpActionType cityLevelUpActionType in System.Enum.GetValues(typeof(CityLevelUpActionType)))
{
if(cityLevelUpActionType == CityLevelUpActionType.None) continue;
commonActionId = new CommonActionId
{
ActionType = CommonActionType.CityLevelUpAction,
CityLevelUpActionType = cityLevelUpActionType
};
ActionLogicDict[commonActionId] = new CityLevelUpActionAction(commonActionId);
}
//unitAction自身行为的各个行为逻辑
foreach (UnitActionType unitActionType in System.Enum.GetValues(typeof(UnitActionType)))
{
commonActionId = new CommonActionId
{
ActionType = CommonActionType.UnitAction,
UnitActionType = unitActionType
};
switch (unitActionType)
{
case UnitActionType.None:
continue;
case UnitActionType.HeroUpgrade:
ActionLogicDict[commonActionId] = new UnitActionGiantUpgrade(commonActionId);
continue;
case UnitActionType.ROYALFLAMESPRO:
ActionLogicDict[commonActionId] = new UnitActionROYALFLAMESPRO(commonActionId);
continue;
case UnitActionType.HEAL:
ActionLogicDict[commonActionId] = new UnitActionHEAL(commonActionId);
continue;
case UnitActionType.TEWIFRENCHBUFF:
ActionLogicDict[commonActionId] = new UnitActionTEWIFRENCHBUFF(commonActionId);
continue;
case UnitActionType.MOKOUFRENCHBOOM:
ActionLogicDict [commonActionId] = new UnitActionMOKOUFRENCHBOOM(commonActionId);
continue;
default:
ActionLogicDict[commonActionId] = new UnitActionAction(commonActionId);
continue;
}
}
foreach (UnitType unitType in Enum.GetValues(typeof(UnitType)))
if(!(unitType is UnitType.None or UnitType.Giant)
&& Table.Instance.UnitTypeDataAssets.GetUnitTypeInfo(unitType,GiantType.None,0,out var info)
&& info.LandType == LandType.WaterAndAshore)
{
if (unitType == UnitType.Boat) continue;
commonActionId = new CommonActionId
{
ActionType = CommonActionType.UnitAction,
UnitType = unitType
};
ActionLogicDict[commonActionId] = new UnitActionAction(commonActionId);
}
//登记所有学习科技的action
foreach (TechType techType in System.Enum.GetValues(typeof(TechType)))
{
commonActionId = new CommonActionId
{
ActionType = CommonActionType.LearnTech,
TechType = techType
};
ActionLogicDict[commonActionId] = new LearnTechAction(commonActionId);
}
//登记6种unitskill类的科技该科技会让该玩家当前的和未来的所有unit都拥有某个skill
foreach (SkillType skillType in System.Enum.GetValues(typeof(SkillType)))
{
if (skillType == SkillType.MOUNTAINMOVE || skillType == SkillType.MOUNTAINDEFENSE ||
skillType == SkillType.WATERMOVE || skillType == SkillType.WATERDEFENSE ||
skillType == SkillType.OCEANMOVE || skillType == SkillType.OCEANDEFENSE ||
skillType == SkillType.FORESTDEFENSE)
{
commonActionId = new CommonActionId
{
ActionType = CommonActionType.UnitSkill,
SkillType = skillType
};
ActionLogicDict[commonActionId] = new UnitSkillAction(commonActionId);
}
}
//登记playerAction
RefreshPlayerAction();
if (_actionLogicIdDict == null)
{
_actionLogicIdDict = new Dictionary<uint, ActionLogicBase>();
foreach (var kv in ActionLogicDict)
{
_actionLogicIdDict[kv.Key.Id] = kv.Value;
}
}
}
public static ActionLogicBase GetActionLogic(CommonActionId actionId)
{
Refresh();
foreach (var kv in ActionLogicDict)
{
if (kv.Key != actionId) continue;
return kv.Value;
}
return null;
}
// 返回一个玩家有什么 Action
public static bool PlayerHasAction(CommonActionParams param, out List<ActionLogicBase> actionList)
{
param.MainObjectType = MainObjectType.Player;
actionList = new List<ActionLogicBase>();
var actionDict = GetActionLogicDict();
foreach (var action in actionDict.Values)
{
if(action.CheckCan(param))
actionList.Add(action);
}
return actionList.Count > 0;
}
//返回一个 grid 对于 player data 而言有什么 action
public static bool GridHasAction(CommonActionParams param, out List<ActionLogicBase> actionList)
{
param.MainObjectType = MainObjectType.Grid;
actionList = new List<ActionLogicBase>();
var actionDict = GetActionLogicDict();
foreach (var action in actionDict.Values)
{
if (!action.CheckCan(param)) continue;
actionList.Add(action);
}
return actionList.Count > 0;
}
//返回一个 grid 对于 player data 而言有什么 action
public static bool GridHasAction(CommonActionParams param, List<ActionLogicBase> actionList)
{
param.MainObjectType = MainObjectType.Grid;
var actionDict = GetActionLogicDict();
bool hasAction = false;
foreach (var action in actionDict.Values)
{
if (!action.CheckCan(param)) continue;
actionList.Add(action);
hasAction = true;
}
return hasAction;
}
public static bool CityHasAction(CommonActionParams param, out List<ActionLogicBase> actionList)
{
param.MainObjectType = MainObjectType.City;
actionList = new List<ActionLogicBase>();
var actionDict = GetActionLogicDict();
foreach (var action in actionDict.Values)
{
if(action.CheckCan(param))
actionList.Add(action);
}
return actionList.Count > 0;
}
//返回一个 unit 对于 player data 而言有什么 action
public static bool UnitHasAction(CommonActionParams param, out List<ActionLogicBase> actionList)
{
param.MainObjectType = MainObjectType.Unit;
actionList = new List<ActionLogicBase>();
if (param.UnitData.CP <= 0) return false;
var actionDict = GetActionLogicDict();
foreach (var action in actionDict.Values)
{
if (!action.CheckCan(param)) continue;
actionList.Add(action);
}
return actionList.Count > 0;
}
// 返回一个 unit 的移动和攻击行为
public static bool UnitHasMoveAndAttackAction(MapData map, UnitData unit, out List<AIActionBase> actionList)
{
if (!unit.Alive)
{
actionList = null;
return false;
}
var attackID = new CommonActionId { ActionType = CommonActionType.UnitAttack };
var moveId = new CommonActionId { ActionType = CommonActionType.UnitMove };
var attackAction = new UnitAttackAction(attackID);
var moveAction = new UnitMoveAction(moveId);
actionList = new List<AIActionBase>();
Main.UnitLogic.CalcUnitMoveInfo(map, unit.Id);
foreach (var grid in map.GridMap.GridList)
{
var result = Main.UnitLogic.CheckUnitCanMoveOrAttack(map, unit, grid);
if (result == MoveAttackType.None) continue;
if (result == MoveAttackType.Attack)
{
if (unit.AP <= 0 || !map.GetUnitDataByGid(grid.Id, out var targetUnit)) continue;
var param = new CommonActionParams(map, unitData:unit, targetUnit:targetUnit);
param.RefreshParams();
actionList.Add(new AIActionBase(param, attackAction));
if (map.GetGridDataByUnitId(unit.Id, out var unitGrid))
{
//Debug.Log($"生成Action 小兵攻击 {unit.Id}, 攻击范围{unit.GetAttackRange()}" +$"位置{unitGrid.Pos.X}, {unitGrid.Pos.Y}, " + $"目标 {targetUnit.Id}, " + $"目标位置{grid.Pos.X}, {grid.Pos.Y}");
}
continue;
}
if (unit.MP > 0)
{
var param = new CommonActionParams(map, unitData:unit, gridData:grid);
param.RefreshParams();
actionList.Add(new AIActionBase(param, moveAction));
}
}
return actionList.Count > 0;
}
//返回一个主体能够显示的action注意并非能“做”的action有些行为没钱或者没科技他也可以显示
public static bool MainObjectCanShowAction(CommonActionParams param, out List<ActionLogicBase> actionList)
{
actionList = new List<ActionLogicBase>();
var actionDict = GetActionLogicDict();
foreach (var action in actionDict.Values)
{
if (!action.CheckShow(param)) continue;
actionList.Add(action);
}
return actionList.Count > 0;
}
public static List<ActionLogicBase> GetActionLogicByType(CommonActionType type)
{
var actionList = new List<ActionLogicBase>();
foreach (var action in GetActionLogicDict().Values)
{
if (action.ActionId.ActionType != type) continue;
actionList.Add(action);
}
return actionList;
}
public static MainObjectType GetMainObjectType(CommonActionType actionType)
{
if (actionType == CommonActionType.Gain) return MainObjectType.Grid;
if (actionType == CommonActionType.Build) return MainObjectType.Grid;
if (actionType == CommonActionType.StartWonder) return MainObjectType.Player;
if (actionType == CommonActionType.BuildWonder) return MainObjectType.Grid;
if (actionType == CommonActionType.TrainUnit) return MainObjectType.City;
if (actionType == CommonActionType.GridMisc) return MainObjectType.Grid;
if (actionType == CommonActionType.UnitAction) return MainObjectType.Unit;
if (actionType == CommonActionType.CityLevelUpAction) return MainObjectType.City;
if (actionType == CommonActionType.UnitSkill) return MainObjectType.Unit;
if (actionType == CommonActionType.LearnTech) return MainObjectType.Player;
if (actionType == CommonActionType.UnitMove) return MainObjectType.Unit;
if (actionType == CommonActionType.UnitAttack) return MainObjectType.Unit;
if (actionType == CommonActionType.PlayerAction) return MainObjectType.Player;
return MainObjectType.Player;
}
}
// 行为基类
public abstract class ActionLogicBase
{
protected CommonActionId _actionId;
public CommonActionId ActionId => _actionId;
protected float _duration;
public float Duration
{
get => _duration;
set => _duration = value;
}
public ActionLogicBase(CommonActionId id)
{
_actionId = id;
_duration = 0;
}
public bool CheckEqualActionId(CommonActionId actionId)
{
return _actionId == actionId;
}
public int GetCost(int buildingLevel = 0)
{
if (!Table.Instance.ActionDataAssets.GetActionInfo(_actionId, out var info)) return 0;
//temple特别的计算cost方式
if (_actionId.GridMiscActionType == GridMiscActionType.UpgradeTemple) return buildingLevel >= 5 ? 0 : (buildingLevel + 1) * info.Cost;
return info.Cost;
}
public virtual float GetAnimTime(CommonActionParams actionParams)
{
//TODO 这里通用返回值要读表,暂时先直接返回0.1f
return 0.05f;
}
public virtual bool CameraControl(CommonActionParams actionParams)
{
return false;
}
public float GetValue()
{
return 1f;
}
public abstract bool ExecuteViewBefore(CommonActionParams actionParams);
public abstract bool ExecuteViewAfter(CommonActionParams actionParams);
// 完整的执行调用, 供外部使用
public virtual bool CompleteExecute(CommonActionParams actionParams, bool isMoment)
{
var ret = Execute(actionParams, isMoment);
AfterExecute(actionParams, isMoment);
return ret;
}
// 实际的执行逻辑
protected abstract bool Execute(CommonActionParams actionParams, bool isMoment);
// 执行后逻辑
protected virtual void AfterExecute(CommonActionParams actionParams, bool isMoment)
{
//更新所有人的外交好感情况。临时用的。必须真map才做AI预测的不做性能爆炸了
if (actionParams.MapData == Main.MapData)
{
foreach (var pData in actionParams.MapData.PlayerMap.PlayerDataList)
pData.RefreshFeelingValue(actionParams.MapData);
}
}
public abstract bool CheckCan(CommonActionParams actionParams);
public abstract bool CheckShow(CommonActionParams actionParams);
public abstract ActionShowState CheckShowState(CommonActionParams actionParams);
public void TH1Debug()
{
Debug.Log($"{_actionId.ActionType} : {_actionId.ResourceType}/{_actionId.UnitType}/{_actionId.WonderType}");
}
}
// 建造奇观逻辑类 #buildwonder
public class BuildWonderAction : ActionLogicBase
{
public BuildWonderAction(CommonActionId id) : base(id)
{
}
protected override bool Execute(CommonActionParams actionParams, bool isMoment)
{
if(!actionParams.MapData.GetCityDataByTerritoryGid(actionParams.GridData.Id,out var city))
return false;
//给city增加3点exp
if (!Table.Instance.GridAndResourceDataAssets.GetWonderInfoByType(_actionId.WonderType,actionParams.PlayerData, out var wonderInfo))
return false;
if (actionParams.PlayerData == null)
return false;
var player = actionParams.PlayerData;
//临时做法用来播放VFX,获取Main理应向MapData写入一个VFX的RenderMark的
var main = GameObject.Find("Main").GetComponent<Main>();
if (actionParams.MapData == Main.MapData && actionParams.PlayerData.Id == actionParams.MapData.PlayerMap.SelfPlayerData.Id)
{
var v1 = Table.Instance.GridToWorld(actionParams.GridData);
actionParams.MapData.GetGridDataByCityId(city.Id, out var g2);
var v2 = Table.Instance.GridToWorld(g2);
Timer.Instance.TimerRegister(Main.CityLogic, () =>
{
int score = wonderInfo.Exp * 5;
MapRenderer.Instance.ROGridMap[g2.Id].SetBounceAnim();
score += 50 * Main.CityLogic.CityUpdateExp(actionParams.MapData,city,wonderInfo.Exp);
if (actionParams.PlayerData.Id == actionParams.MapData.PlayerMap.SelfPlayerData.Id)
{
var faithPanel = GameObject.Find("UICanvas/TopBarPanel/FaithPanel/Icon").transform;
var endPos = faithPanel.position;
MapRenderer.Instance.ProjectileManager.CreateProjectile(v2,endPos,ProjectileType.Faith,ProjectileMoveType.CoinParabola,score);
}
},
Table.Instance.AnimDataAssets.ProjectileCityExpMoveTime,"ActionLogic_BuildWonder_Execute_728");
//播放雾效和丢出cityexp & 丢出信仰分 的动画
actionParams.GridData.VFXRenderMarkFog = true;
MapRenderer.Instance.ProjectileManager.CreateProjectileMulti(v1,v2,ProjectileType.CityExp,ProjectileMoveType.CityExpHighParabola,wonderInfo.Exp);
if (actionParams.PlayerData.Id == actionParams.MapData.PlayerMap.SelfPlayerData.Id)
{
var faithPanel = GameObject.Find("UICanvas/TopBarPanel/FaithPanel/Icon").transform;
var endPos = faithPanel.position;
MapRenderer.Instance.ProjectileManager.CreateProjectile( v1, endPos,
ProjectileType.Faith, ProjectileMoveType.CoinParabola, 300);
}
}
else Main.CityLogic.CityUpdateExp(actionParams.MapData,city,wonderInfo.Exp);
actionParams.GridData.ResourceUnderBuilding = actionParams.GridData.Resource;
actionParams.GridData.Resource = ResourceType.Wonder;
actionParams.GridData.Wonder = wonderInfo.Wonder;
player.Wonder.SetWonderState(wonderInfo.WonderType,WonderState.FINISH_BUILD);
actionParams.GridData.RenderMark = true;
AchievementDataManager.Instance.OnBuildWonder(actionParams.MapData, player, city, actionParams.GridData);
return true;
}
public override bool CheckCan(CommonActionParams actionParam)
{
//鲁棒性+基础数据准备必须准备player(谁来建设和grid(在哪里建设?)
if (actionParam.PlayerData == null) return false;
if (actionParam.GridData == null) return false;
var player = actionParam.PlayerData;
var grid = actionParam.GridData;
var map = actionParam.MapData;
//找到grid所属于的player如果是无主领土就return
if (!map.GetPlayerDataByTerritoryGridId(grid.Id, out var gridPlayer))
return false;
//如果player操作的grid都不属于自己return
if (player != gridPlayer) return false;
//如果根本无法建设这个奇观 return
if (player.Wonder.GetWonderState(_actionId.WonderType) != WonderState.FINISH_NOT_BUILD) return false;
//如果是山地或者深海,无法建设这个奇观 return false
if (grid.Feature == TerrainFeature.Mountain
|| grid.Terrain == TerrainType.DeepSea
|| grid.Vegetation == Vegetation.Trees)
return false;
//如果有非联盟的敌人站在上面
if (map.GetUnitDataByGid(grid.Id, out var unit) && !map.CheckUnitIdBelongPlayerIdUnion(unit.Id, player.Id))
return false;
//如果上面是常规资源,那么就是可以建设的 return true
if (grid.Resource == ResourceType.None
|| grid.Resource == ResourceType.Fish
|| grid.Resource == ResourceType.Starfish
|| grid.Resource == ResourceType.Crop
|| grid.Resource == ResourceType.Fruit
)
return true;
if (GetCost() > actionParam.PlayerData.PlayerWealth)
return false;
return false;
}
public override bool CheckShow(CommonActionParams actionParam)
{
return CheckCan(actionParam);
}
public override ActionShowState CheckShowState(CommonActionParams actionParams) { return ActionShowState.None; }
public override bool ExecuteViewBefore(CommonActionParams actionParams)
{
return false;
}
public override bool ExecuteViewAfter(CommonActionParams actionParams)
{
return false;
}
}
// Gain 收获资源逻辑类
public class GainResourceAction : ActionLogicBase
{
public GainResourceAction(CommonActionId id) : base(id)
{
}
protected override bool Execute(CommonActionParams actionParams, bool isMoment)
{
if (!CheckCan(actionParams)) return false;
CityData cityData = actionParams.CityData;
if (cityData == null)
actionParams.MapData.GetCityDataByTerritoryGid(actionParams.GridData.Id,out cityData);
//扣钱,收获资产,把资产送往city
actionParams.PlayerData.PlayerWealth -= GetCost();
//如果是玩家,执行一整套播放动画的逻辑
//临时做法用来播放VFX,获取Main理应向MapData写入一个VFX的RenderMark的
if (Main.MapData == actionParams.MapData && actionParams.PlayerData.Id == actionParams.MapData.PlayerMap.SelfPlayerData.Id)
{
var v1 = Table.Instance.GridToWorld(actionParams.GridData);
actionParams.MapData.GetGridDataByCityId(cityData.Id, out var g2);
var v2 = Table.Instance.GridToWorld(g2);
//播放城市增加exp的动画
Timer.Instance.TimerRegister(Main.CityLogic, () =>
{
int score = Table.Instance.QueryActionExp(_actionId) * 5;
MapRenderer.Instance.ROGridMap[g2.Id].SetBounceAnim();
score += 50 * Main.CityLogic.CityUpdateExp(actionParams.MapData,cityData,Table.Instance.QueryActionExp(_actionId));
if (actionParams.PlayerData.Id == actionParams.MapData.PlayerMap.SelfPlayerData.Id)
{
var faithPanel = GameObject.Find("UICanvas/TopBarPanel/FaithPanel/Icon").transform;
var endPos = faithPanel.position;
MapRenderer.Instance.ProjectileManager.CreateProjectile(v2,endPos,ProjectileType.Faith,ProjectileMoveType.CoinParabola,score);
}
},
Table.Instance.AnimDataAssets.ProjectileCityExpMoveTime,"ActionLogic_Gain_ExpAnim");
//播放雾效和丢出cityexp的动画
actionParams.GridData.VFXRenderMarkFog = true;
MapRenderer.Instance.ProjectileManager.CreateProjectile(v1,v2,ProjectileType.CityExp,ProjectileMoveType.CityExpHighParabola);
}
//否则执行常规
else
{
Main.CityLogic.CityUpdateExp(actionParams.MapData,cityData,Table.Instance.QueryActionExp(_actionId));
}
//消除水果
actionParams.GridData.Resource = ResourceType.None;
actionParams.GridData.RenderMark = true;
//更新所有建筑的buildingLevel
Main.PlayerLogic.UpdateTerritoryAllBuildingLevel(actionParams.MapData,actionParams.PlayerData.Id);
return true;
}
public override bool CheckCan(CommonActionParams actionParam)
{
//如果是unit或者city来执行gain操作直接return false
if (actionParam.MainObjectType != MainObjectType.Grid) return false;
var grid = actionParam.GridData;
var map = actionParam.MapData;
var player = actionParam.PlayerData;
if (grid == null || map == null || player == null) return false;
//如果没有对应科技return false
if (!player.TechTree.CheckActionCan(_actionId)) return false;
//确认grid实际属于的player是谁
map.GetPlayerDataByTerritoryGridId(actionParam.GridData.Id, out var gridPlayer);
//如果不在我方领土return false
if (gridPlayer == null || player.Id != gridPlayer.Id) return false;
//钱不够 return
if (GetCost() > actionParam.PlayerData.PlayerWealth)
return false;
//如果有非联盟的敌人站在上面
if (map.GetUnitDataByGid(grid.Id, out var unit) && !map.CheckUnitIdBelongPlayerIdUnion(unit.Id, player.Id))
return false;
return _actionId.ResourceType == actionParam.GridData.Resource;
}
public override bool CheckShow(CommonActionParams actionParam)
{
if (actionParam.MainObjectType != MainObjectType.Grid) return false;
var grid = actionParam.GridData;
var map = actionParam.MapData;
var player = actionParam.PlayerData;
if (grid == null || map == null || player == null) return false;
//如果没有对应科技也会显示 钱不够也会显示
//确认grid实际属于的player是谁
map.GetPlayerDataByTerritoryGridId(actionParam.GridData.Id, out var gridPlayer);
//如果不在我方领土return false
if (gridPlayer == null || player.Id != gridPlayer.Id) return false;
//如果有非联盟的敌人站在上面
if (map.GetUnitDataByGid(grid.Id, out var unit) && !map.CheckUnitIdBelongPlayerIdUnion(unit.Id, player.Id))
return false;
//如果techpool里就没有这个技能,不显示
if (!Table.Instance.PlayerDataAssets.CheckActionInTechPool(_actionId, actionParam.PlayerData)) return false;
return _actionId.ResourceType == actionParam.GridData.Resource;
}
public override ActionShowState CheckShowState(CommonActionParams actionParams) { return ActionShowState.None; }
public override bool ExecuteViewBefore(CommonActionParams actionParams)
{
return false;
}
public override bool ExecuteViewAfter(CommonActionParams actionParams)
{
return false;
}
}
//CityLevelUp 行动逻辑类
public class CityLevelUpActionAction : ActionLogicBase
{
public CityLevelUpActionAction(CommonActionId id) : base(id)
{
}
protected override bool Execute(CommonActionParams actionParams, bool isMoment)
{
//鲁棒性判断
if (actionParams.CityData == null) return false;
if (!actionParams.MapData.GetGridDataByCityId(actionParams.CityData.Id, out var gridData)) return false;
if (actionParams.CityData.CityLevelUpPoint <= 0) return false;
if (!actionParams.MapData.GetPlayerDataByCityId(actionParams.CityData.Id, out var playerData)) return false;
actionParams.CityData.CityLevelUpPoint --;
if (_actionId.CityLevelUpActionType == CityLevelUpActionType.Explorer)
{
// 1. 锁定玩家输入
Main main = GameObject.FindObjectOfType<Main>();
main.InputLogic.LockInput();
//Debug.Log("玩家输入已锁定");
// 2. 创建临时探索者图像3秒后自动销毁
MapRenderer.Instance.CreateTemporaryExplorer(gridData, 3f);
actionParams.CityData.CityInfoRenderMark = true;
return true;
}
if (_actionId.CityLevelUpActionType == CityLevelUpActionType.Workshop)
{
actionParams.CityData.Workshop = true;
actionParams.CityData.CityInfoRenderMark = true;
return true;
}
if (_actionId.CityLevelUpActionType == CityLevelUpActionType.CityWealth)
{
playerData.PlayerWealth += 5;
actionParams.CityData.CityInfoRenderMark = true;
return true;
}
if (_actionId.CityLevelUpActionType == CityLevelUpActionType.CityWall)
{
actionParams.CityData.CityWall = true;
gridData.RenderMark = true;
//如果city上有单位也要更新单位的渲染
if (actionParams.MapData.GetUnitDataByGid(gridData.Id, out var unit))
unit.RenderMark = true;
return true;
}
if (_actionId.CityLevelUpActionType == CityLevelUpActionType.Expand)
{
Main.CityLogic.CityLevelUpActionExpand(actionParams.MapData,actionParams.CityData);
actionParams.CityData.CityInfoRenderMark = true;
//要更新玩家所有城市所有格子的levelbuilding
Main.PlayerLogic.UpdateTerritoryAllBuildingLevel(actionParams.MapData,playerData.Id);
//更新所有国家的联通情况
Main.PlayerLogic.UpdateAllPlayerConnected(actionParams.MapData);
//更新特殊占领技能
if(playerData.GetSkill(SkillType.KaguyaFrenchNapoleonicCode,out var _))
Main.PlayerLogic.SetCityTerritoryGridSp(actionParams.MapData,actionParams.CityData,GridSpType.KaguyaGrid);
return true;
}
if (_actionId.CityLevelUpActionType == CityLevelUpActionType.Population)
{
Main.CityLogic.CityUpdateExp(actionParams.MapData,actionParams.CityData,3);
actionParams.CityData.CityInfoRenderMark = true;
return true;
}
if (_actionId.CityLevelUpActionType == CityLevelUpActionType.Park)
{
actionParams.CityData.ParkCount++;
actionParams.CityData.CityInfoRenderMark = true;
return true;
}
if (_actionId.CityLevelUpActionType == CityLevelUpActionType.BigGuy)
{
if(actionParams.MapData.GetUnitDataByGid(gridData.Id,out var unitData))
Main.UnitLogic.PassiveMoveAway(actionParams.MapData, unitData);
actionParams.MapData.AddUnitData(gridData.Id,actionParams.CityData.Id,UnitType.BigGuy);
actionParams.CityData.CityInfoRenderMark = true;
return true;
}
return false;
}
public override bool CheckCan(CommonActionParams actionParams)
{
if (actionParams.CityData == null) return false;
//如果没有升级行动的点数,退出
if (actionParams.CityData.CityLevelUpPoint <= 0)
return false;
if (_actionId.CityLevelUpActionType == CityLevelUpActionType.Explorer)
return actionParams.CityData.Level == 3;
if (_actionId.CityLevelUpActionType == CityLevelUpActionType.Workshop)
return actionParams.CityData.Level == 3;
if (_actionId.CityLevelUpActionType == CityLevelUpActionType.CityWall)
return actionParams.CityData.Level == 4;
if (_actionId.CityLevelUpActionType == CityLevelUpActionType.CityWealth)
return actionParams.CityData.Level == 4;
if (_actionId.CityLevelUpActionType == CityLevelUpActionType.Population)
return actionParams.CityData.Level == 5;
if (_actionId.CityLevelUpActionType == CityLevelUpActionType.Expand)
return actionParams.CityData.Level == 5;
if (_actionId.CityLevelUpActionType == CityLevelUpActionType.Park)
return actionParams.CityData.Level > 5;
if (_actionId.CityLevelUpActionType == CityLevelUpActionType.BigGuy)
return actionParams.CityData.Level > 5;
return false;
}
public override bool CheckShow(CommonActionParams actionParams)
{
if (actionParams.CityData == null) return false;
//如果没有升级行动的点数,退出
if (actionParams.CityData.CityLevelUpPoint <= 0)
return false;
if (_actionId.CityLevelUpActionType == CityLevelUpActionType.Explorer)
return actionParams.CityData.Level == 3;
if (_actionId.CityLevelUpActionType == CityLevelUpActionType.Workshop)
return actionParams.CityData.Level == 3;
if (_actionId.CityLevelUpActionType == CityLevelUpActionType.CityWall)
return actionParams.CityData.Level == 4;
if (_actionId.CityLevelUpActionType == CityLevelUpActionType.CityWealth)
return actionParams.CityData.Level == 4;
if (_actionId.CityLevelUpActionType == CityLevelUpActionType.Population)
return actionParams.CityData.Level == 5;
if (_actionId.CityLevelUpActionType == CityLevelUpActionType.Expand)
return actionParams.CityData.Level == 5;
if (_actionId.CityLevelUpActionType == CityLevelUpActionType.Park)
return actionParams.CityData.Level > 5;
if (_actionId.CityLevelUpActionType == CityLevelUpActionType.BigGuy)
return actionParams.CityData.Level > 5;
return false;
}
public override ActionShowState CheckShowState(CommonActionParams actionParams) { return ActionShowState.None; }
public override bool ExecuteViewBefore(CommonActionParams actionParams)
{
return false;
}
public override bool ExecuteViewAfter(CommonActionParams actionParams)
{
return false;
}
}
// 小兵移动,目前只用于 AI 的行为
public class UnitMoveAction : ActionLogicBase
{
public UnitMoveAction(CommonActionId id) : base(id)
{
}
protected override bool Execute(CommonActionParams actionParams, bool isMoment)
{
if (actionParams.MapData.GetGridDataByUnitId(actionParams.UnitData.Id, out var unitGrid))
{
var distance = actionParams.MapData.GridMap.CalcDistance(unitGrid, actionParams.GridData);
}
Main.UnitLogic.MoveTo(actionParams.MapData, actionParams.UnitData, actionParams.GridData,
MoveType.ActiveMove);
return true;
}
public override bool CheckCan(CommonActionParams actionParams)
{
return true;
}
public override bool CheckShow(CommonActionParams actionParams)
{
return false;
}
public override ActionShowState CheckShowState(CommonActionParams actionParams) { return ActionShowState.None; }
public override bool CameraControl(CommonActionParams actionParams)
{
var main = GameObject.Find("Main").GetComponent<Main>();
if (actionParams.GridData != null && main != null && MapRenderer.Instance.CameraController != null
&& actionParams.MapData.PlayerMap.SelfPlayerData.Sight.CheckIsInSight(actionParams.GridData.Id))
MapRenderer.Instance.CameraController?.CameraFocusOnGrid(actionParams.GridData);
return true;
}
/*public override float GetAnimTime(CommonActionParams actionParams)
{
return Table.Instance.AnimDataAssets.MoveAnimTime + Table.Instance.AnimDataAssets.AIAfterMoveColdDownTime;// + Table.Instance.AnimDataAssets.AIBeforeAnimWaitTime;
}*/
public override bool ExecuteViewBefore(CommonActionParams actionParams)
{
return false;
}
public override bool ExecuteViewAfter(CommonActionParams actionParams)
{
return false;
}
}
// 小兵攻击,目前只用于 AI 的行为
public class UnitAttackAction : ActionLogicBase
{
public UnitAttackAction(CommonActionId id) : base(id)
{
}
protected override bool Execute(CommonActionParams actionParams, bool isMoment)
{
Main.UnitLogic.Attack(actionParams.MapData, actionParams.UnitData, actionParams.TargetUnitData, out _duration, isMoment);
return true;
}
public override bool CheckCan(CommonActionParams actionParams)
{
if (actionParams.UnitData.IsLimitSelfAttack(actionParams.MapData)) return false;
if (!actionParams.MapData.GetPlayerDataByUnitId(actionParams.UnitData.Id, out _)) return false;
if (!actionParams.MapData.GetPlayerDataByUnitId(actionParams.TargetUnitData.Id, out _)) return false;
if (!actionParams.MapData.GetCityDataByUnitId(actionParams.UnitData.Id, out _)) return false;
if (!actionParams.MapData.GetCityDataByUnitId(actionParams.TargetUnitData.Id, out _)) return false;
return true;
}
public override bool CheckShow(CommonActionParams actionParams)
{
return false;
}
public override ActionShowState CheckShowState(CommonActionParams actionParams) { return ActionShowState.None; }
public override bool CameraControl(CommonActionParams actionParams)
{
var main = GameObject.Find("Main").GetComponent<Main>();
if(actionParams.GridData != null && main != null && MapRenderer.Instance.CameraController != null
&& actionParams.MapData.PlayerMap.SelfPlayerData.Sight.CheckIsInSight(actionParams.GridData.Id))
MapRenderer.Instance.CameraController?.CameraFocusOnGrid(actionParams.GridData);
return true;
}
/*public override float GetAnimTime(CommonActionParams actionParams)
{
var unit1 = actionParams.UnitData;
if(actionParams.UnitData == null || !actionParams.MapData.UnitMap.GetUnitDataByUnitId(actionParams.TargetUnitId, out var unit2))
return 0.05f;
return Main.UnitLogic.AttackAnimTime(actionParams.MapData, unit1, unit2) +
Table.Instance.AnimDataAssets.AIAfterAttackColdDownTime;// + Table.Instance.AnimDataAssets.AIBeforeAnimWaitTime;
}*/
public override bool ExecuteViewBefore(CommonActionParams actionParams)
{
return false;
}
public override bool ExecuteViewAfter(CommonActionParams actionParams)
{
return false;
}
}
public class StartWonderAction : ActionLogicBase
{
public StartWonderAction(CommonActionId id) : base(id)
{
}
protected override bool Execute(CommonActionParams actionParams, bool isMoment)
{
return false;
}
public override bool CheckCan(CommonActionParams actionParams)
{
return false;
}
public override bool CheckShow(CommonActionParams actionParams)
{
return false;
}
public override ActionShowState CheckShowState(CommonActionParams actionParams) { return ActionShowState.None; }
public override bool ExecuteViewBefore(CommonActionParams actionParams)
{
return false;
}
public override bool ExecuteViewAfter(CommonActionParams actionParams)
{
return false;
}
}
//TODO 没有填写Skill
public class UnitSkillAction : ActionLogicBase
{
public UnitSkillAction(CommonActionId id) : base(id)
{
}
protected override bool Execute(CommonActionParams actionParams, bool isMoment)
{
return false;
}
public override bool CheckCan(CommonActionParams actionParams)
{
return false;
}
public override bool CheckShow(CommonActionParams actionParams)
{
return false;
}
public override ActionShowState CheckShowState(CommonActionParams actionParams) { return ActionShowState.None; }
public override bool ExecuteViewBefore(CommonActionParams actionParams)
{
return false;
}
public override bool ExecuteViewAfter(CommonActionParams actionParams)
{
return false;
}
}
public class LearnTechAction : ActionLogicBase
{
public LearnTechAction(CommonActionId id) : base(id)
{
}
protected override bool Execute(CommonActionParams actionParams, bool isMoment)
{
if (actionParams.MainObjectType != MainObjectType.Player)
return false;
if (actionParams.PlayerData == null)
return false;
int cost = Main.PlayerLogic.GetRealCost(actionParams.MapData, actionParams.PlayerData, _actionId.TechType);
Main.PlayerLogic.ResearchTech(actionParams.MapData,actionParams.PlayerData,_actionId.TechType,cost);
return true;
}
public override bool CheckCan(CommonActionParams actionParams)
{
//鲁棒性判断,不是玩家执行这个操作就退出
if (actionParams.MainObjectType != MainObjectType.Player)
return false;
if (actionParams.PlayerData == null)
return false;
if (actionParams.PlayerData.TechTree.CheckIfHasTech(_actionId.TechType))
return false;
//如果科技不在该玩家的tech pool里return
if (!Table.Instance.PlayerDataAssets.GetPlayerInfo(actionParams.PlayerData, out var playerInfo))
return false;
if (!playerInfo.TechPool.Contains(_actionId.TechType))
return false;
//如果没有父科技
var techInfo = Table.Instance.TechDataAssets.GetTechInfo(_actionId.TechType);
if (!actionParams.PlayerData.TechTree.CheckIfHasTech(techInfo.FatherTechType))
return false;
//判断钱够不够
if (GetCost() > actionParams.PlayerData.PlayerWealth)
return false;
int cost = Main.PlayerLogic.GetRealCost(actionParams.MapData, actionParams.PlayerData, _actionId.TechType);
if(cost > actionParams.PlayerData.PlayerWealth)
return false;
return true;
}
public override bool CheckShow(CommonActionParams actionParams)
{
return false;
}
public override ActionShowState CheckShowState(CommonActionParams actionParams) { return ActionShowState.None; }
public override bool ExecuteViewBefore(CommonActionParams actionParams)
{
return false;
}
public override bool ExecuteViewAfter(CommonActionParams actionParams)
{
return false;
}
}
}