1544 lines
64 KiB
C#
1544 lines
64 KiB
C#
/*
|
||
* @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;
|
||
case UnitActionType.KAGUYAFRENCHAROUND:
|
||
ActionLogicDict [commonActionId] = new UnitActionKAGUYAFRENCHAROUND(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);
|
||
var fullType = new UnitFullType(UnitType.BigGuy, GiantType.None, 0);
|
||
if(actionParams.PlayerData.PlayerCivId == 1 && actionParams.PlayerData.PlayerForceId == 1)
|
||
fullType = new UnitFullType(UnitType.KaguyaFrenchWolf, GiantType.None, 0);
|
||
if (!actionParams.MapData.AddUnitData(gridData.Id, actionParams.CityData.Id,fullType ,out var _))
|
||
return false;
|
||
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;
|
||
}
|
||
}
|
||
|
||
} |