/* * @Author: 白哉 * @Description: 行为逻辑类 * @Date: 2025年04月10日 星期四 11:04:44 * @Modify: */ using System; using System.Collections.Generic; using System.Linq; using ET; using Logic.AI; using Logic.CrashSight; using ParadoxNotion; using RuntimeData; using TH1_Anim.Fragments; using TH1_Core.Managers; using TH1_Logic.Core; using UnityEngine; using TH1Renderer; using TH1Resource; //这里是所有BuildAction派生子类的实现模块 namespace Logic.Action { // Build 建造逻辑类 public class BuildAction : ActionLogicBase { public BuildAction(CommonActionId id) : base(id) { } protected override bool Execute(CommonActionParams actionParams) { //Step #1鲁棒性用 if (!CheckCan(actionParams)) return false; CityData cityData = actionParams.CityData; if (cityData == null) actionParams.MapData.GetCityDataByTerritoryGid(actionParams.GridData.Id,out cityData); //Step #2 扣钱,收获资产,把资产送往city actionParams.PlayerData.PlayerWealth -= GetCost(); int cityExp = 0; //处理farm、mine、lumberhut if (_actionId.ResourceType is ResourceType.Farm or ResourceType.Mine or ResourceType.LumberHut) { cityExp = Table.Instance.QueryActionExp(_actionId); actionParams.GridData.ResourceUnderBuilding = actionParams.GridData.Resource; actionParams.GridData.Resource = _actionId.ResourceType; actionParams.GridData.Renderer(actionParams.MapData)?.SetUpdateGrid(true); } //处理windmill sawmill forge market else if (_actionId.ResourceType is ResourceType.Windmill or ResourceType.Forge or ResourceType.Sawmill or ResourceType.Market ) { actionParams.GridData.Resource = _actionId.ResourceType; actionParams.GridData.Renderer(actionParams.MapData)?.SetUpdateGrid(true); Main.CityLogic.CalcGridBuildingLevel(actionParams.MapData,actionParams.GridData, _actionId.ResourceType,out var buildingLevel); actionParams.GridData.buildingLevel = buildingLevel; cityExp = buildingLevel * (_actionId.ResourceType == ResourceType.Forge ? 2 : 1); if (_actionId.ResourceType == ResourceType.Market) cityExp = 0; } //处理port else if (_actionId.ResourceType is ResourceType.Port) { cityExp = Table.Instance.QueryActionExp(_actionId); actionParams.GridData.Resource = _actionId.ResourceType; //港口会自动设置格子的feature为road actionParams.GridData.Feature = TerrainFeature.Road; actionParams.GridData.Renderer(actionParams.MapData)?.SetUpdateGrid(true); } //处理bridge或者road else if (_actionId.ResourceType == ResourceType.Bridge || _actionId.FeatureType == TerrainFeature.Road ) { actionParams.GridData.Feature = TerrainFeature.Road; if(_actionId.ResourceType == ResourceType.Bridge) actionParams.GridData.Resource = ResourceType.Bridge; var tlist = actionParams.MapData.GridMap.GetAroundGridData(1, 1, actionParams.GridData); foreach (var tgrid in tlist) tgrid.Renderer(actionParams.MapData)?.SetUpdateGrid(true); actionParams.GridData.Renderer(actionParams.MapData)?.SetUpdateGrid(true); } //处理temple else if (_actionId.ResourceType == ResourceType.Temple || _actionId.ResourceType == ResourceType.ForestTemple || _actionId.ResourceType == ResourceType.WaterTemple || _actionId.ResourceType == ResourceType.MountainTemple || _actionId.ResourceType == ResourceType.KingTemple) { cityExp = Table.Instance.QueryActionExp(_actionId); actionParams.GridData.Resource = _actionId.ResourceType; actionParams.GridData.buildingLevel = 1; actionParams.GridData.BuildTime = actionParams.PlayerData.Turn; actionParams.GridData.Renderer(actionParams.MapData)?.SetUpdateGrid(true); } else if (_actionId.ResourceType == ResourceType.Military) { cityExp = Table.Instance.QueryActionExp(_actionId); actionParams.GridData.Resource = _actionId.ResourceType; actionParams.GridData.Renderer(actionParams.MapData)?.SetUpdateGrid(true); //如果有人站在军营上,要更新他的renderMark if (actionParams.MapData.GetUnitDataByGid(actionParams.GridData.Id, out var unit)) unit.Renderer(actionParams.MapData)?.InstantUpdateUnit(true); } else if (_actionId.ResourceType == ResourceType.Academy) { Main.CityLogic.CalcGridBuildingLevel(actionParams.MapData,actionParams.GridData, _actionId.ResourceType,out var buildingLevel); actionParams.GridData.buildingLevel = buildingLevel; cityExp = Table.Instance.QueryActionExp(_actionId); actionParams.GridData.Resource = _actionId.ResourceType; actionParams.GridData.Renderer(actionParams.MapData)?.SetUpdateGrid(true); } //Step #6 处理cityExp获取相关 Main.CityLogic.GridGiveCityExp(actionParams.MapData,actionParams.PlayerData,actionParams.GridData,cityData,cityExp); //Step #7 重新计算所有领土上的buildinglevel,并跟随相应动画 Main.PlayerLogic.UpdateTerritoryAllBuildingLevel(actionParams.MapData,actionParams.PlayerData.Id); //Step #8 重新计算连通性 Main.PlayerLogic.UpdateCityConnect(actionParams.MapData,actionParams.PlayerData); return true; } public override bool CheckCan(CommonActionParams actionParam) { //如果是unit或者city来执行build操作,直接return false if (actionParam.MainObjectType != MainObjectType.Grid) return false; if (actionParam.GridData == null) return false; //如果没有对应科技,return false if (!actionParam.PlayerData.TechTree.CheckActionCan(_actionId)) return false; //判断钱够不够 if (GetCost() > actionParam.PlayerData.PlayerWealth) return false; //如果在有主领土,判断是敌人还是自己 if (actionParam.MapData.GetPlayerDataByTerritoryGridId(actionParam.GridData.Id, out var playerData)) { //在敌人领土上,直接return false if (playerData != actionParam.PlayerData) return false; } //如果在无主领土,且不是bridge或者road,也要return false else if (_actionId.ResourceType != ResourceType.Bridge && _actionId.FeatureType != TerrainFeature.Road) return false; //如果有非联盟的敌人站在上面 if (actionParam.MapData.GetUnitDataByGid(actionParam.GridData.Id, out var unit) && !actionParam.MapData.CheckUnitIdBelongPlayerIdUnion(unit.Id, actionParam.PlayerData.Id)) return false; //处理bridge if (_actionId.ResourceType == ResourceType.Bridge) { //如果不是none或者fish的浅水,直接return false if (actionParam.GridData.Terrain != TerrainType.ShallowSea || (actionParam.GridData.Resource != ResourceType.None && actionParam.GridData.Resource != ResourceType.Fish)) return false; //如果不存在桥两侧的陆地以供建桥梁 if (!actionParam.MapData.HasBridgeSideLand(actionParam.GridData,out var isMirror)) return false; return true; } //处理road if (_actionId.FeatureType == TerrainFeature.Road) { //如果是非陆地、村庄 if (actionParam.GridData.Terrain != TerrainType.Land || actionParam.GridData.Resource == ResourceType.CityCenter) return false; //如果已经有路或者是山体,return false if (actionParam.GridData.Feature != TerrainFeature.None) return false; return true; } //处理完了road和bridge,剩下建筑必须都在自己领土上,否则就return false if (playerData == null) return false; //-------- 以下先处理改造资源的建筑 //处理lumberhut if (_actionId.ResourceType == ResourceType.LumberHut) { //只有林子上空着或者有animal 才可能建lumberhut if(actionParam.GridData.Vegetation == Vegetation.Trees && (actionParam.GridData.Resource == ResourceType.Animal || actionParam.GridData.Resource == ResourceType.None)) return true; return false; } //处理mine if (_actionId.ResourceType == ResourceType.Mine) { //只要resource是metal就可以建 if(actionParam.GridData.Resource == ResourceType.Metal) return true; return false; } //处理farm if (_actionId.ResourceType == ResourceType.Farm) { //只要resource是crop就可以建 if(actionParam.GridData.Resource == ResourceType.Crop){ return true; } return false; } //-------- 再处理直接建设的建筑 //处理学院 if (_actionId.ResourceType == ResourceType.Academy) { //确认city是否已经有一个对应的特殊建筑 if(actionParam.MapData.GetCityDataByTerritoryGid(actionParam.GridData.Id,out var academyCity) && Main.CityLogic.GetBuildingLevelByCity(actionParam.MapData,academyCity,_actionId.ResourceType,out var academyLevel)) return false; //必须是没有其他建筑的山脉 if (actionParam.GridData.Feature == TerrainFeature.Mountain && actionParam.GridData.Resource is ResourceType.None or ResourceType.Metal) return true; return false; } //处理军营 if (_actionId.ResourceType == ResourceType.Military) { //确认city是否已经有一个对应的特殊建筑 if(actionParam.MapData.GetCityDataByTerritoryGid(actionParam.GridData.Id,out var militaryCity) && Main.CityLogic.GetBuildingLevelByCity(actionParam.MapData,militaryCity,_actionId.ResourceType,out var militaryLevel)) return false; //必须是没有其他建筑的无树林平地 if (actionParam.GridData.Terrain == TerrainType.Land && actionParam.GridData.Feature != TerrainFeature.Mountain && actionParam.GridData.Vegetation != Vegetation.Trees && actionParam.GridData.Resource is ResourceType.None or ResourceType.Fruit or ResourceType.Crop) return true; return false; } //处理port if (_actionId.ResourceType == ResourceType.Port) { //如果不是none或者fish的浅水,直接return false if (actionParam.GridData.Terrain != TerrainType.ShallowSea) return false; if(actionParam.GridData.Resource is ResourceType.None or ResourceType.Fish or ResourceType.Starfish) return true; return false; } //剩下windmill sawmill forge market四天王,先确定平地情况 if (actionParam.GridData.Terrain != TerrainType.Land || (actionParam.GridData.Feature == TerrainFeature.Mountain) || (actionParam.GridData.Vegetation == Vegetation.Trees) || (actionParam.GridData.Resource != ResourceType.None && actionParam.GridData.Resource != ResourceType.Crop && actionParam.GridData.Resource != ResourceType.Fruit)) return false; //再确认周围有没有支持这个特殊建筑的附属建筑 if (!Main.CityLogic .CalcGridBuildingLevel(actionParam.MapData, actionParam.GridData, _actionId.ResourceType,out var level1)) return false; //再确认city是否已经有一个对应的特殊建筑 if(actionParam.MapData.GetCityDataByTerritoryGid(actionParam.GridData.Id,out var cityData) && Main.CityLogic.GetBuildingLevelByCity(actionParam.MapData,cityData,_actionId.ResourceType,out var level2)) return false; return true; } public override bool CheckShow(CommonActionParams actionParam) { //如果是unit或者city来执行build操作,直接return false if (actionParam.MainObjectType != MainObjectType.Grid) return false; if (actionParam.GridData == null) return false; //如果没有对应科技,return false if (!actionParam.PlayerData.TechTree.CheckActionCan(_actionId)) return false; //如果在有主领土,判断是敌人还是自己 if (actionParam.MapData.GetPlayerDataByTerritoryGridId(actionParam.GridData.Id, out var playerData)) { //在敌人领土上,直接return false if (playerData != actionParam.PlayerData) return false; } //如果在无主领土,且不是bridge或者road,也要return false else if (_actionId.ResourceType != ResourceType.Bridge && _actionId.FeatureType != TerrainFeature.Road) return false; //如果有非联盟的敌人站在上面 if (actionParam.MapData.GetUnitDataByGid(actionParam.GridData.Id, out var unit) && !actionParam.MapData.CheckUnitIdBelongPlayerIdUnion(unit.Id, actionParam.PlayerData.Id)) return false; //处理bridge if (_actionId.ResourceType == ResourceType.Bridge) { //如果不是none或者fish的浅水,直接return false if (actionParam.GridData.Terrain != TerrainType.ShallowSea || (actionParam.GridData.Resource != ResourceType.None && actionParam.GridData.Resource != ResourceType.Fish)) return false; //如果不存在桥两侧的陆地以供建桥梁 if (!actionParam.MapData.HasBridgeSideLand(actionParam.GridData,out var isMirror)) return false; return true; } //处理road if (_actionId.FeatureType == TerrainFeature.Road) { //如果是非陆地、村庄 if (actionParam.GridData.Terrain != TerrainType.Land || actionParam.GridData.Resource == ResourceType.CityCenter) return false; //如果已经有路或者是山体,return false if (actionParam.GridData.Feature != TerrainFeature.None) return false; return true; } //处理完了road和bridge,剩下建筑必须都在自己领土上,否则就return false if (playerData == null) return false; //-------- 以下先处理改造资源的建筑 //处理lumberhut if (_actionId.ResourceType == ResourceType.LumberHut) { //只有林子上空着或者有animal 才可能建lumberhut if(actionParam.GridData.Vegetation == Vegetation.Trees && (actionParam.GridData.Resource == ResourceType.Animal || actionParam.GridData.Resource == ResourceType.None)) return true; return false; } //处理mine if (_actionId.ResourceType == ResourceType.Mine) { //只要resource是metal就可以建 if(actionParam.GridData.Resource == ResourceType.Metal) return true; return false; } //处理farm if (_actionId.ResourceType == ResourceType.Farm) { //只要resource是crop就可以建 if(actionParam.GridData.Resource == ResourceType.Crop){ return true; } return false; } //-------- 再处理直接建设的建筑 //处理学院 if (_actionId.ResourceType == ResourceType.Academy) { //确认city是否已经有一个对应的特殊建筑 if(actionParam.MapData.GetCityDataByTerritoryGid(actionParam.GridData.Id,out var academyCity) && Main.CityLogic.GetBuildingLevelByCity(actionParam.MapData,academyCity,_actionId.ResourceType,out var academyLevel)) return false; //必须是没有其他建筑的山脉 if (actionParam.GridData.Feature == TerrainFeature.Mountain && actionParam.GridData.Resource is ResourceType.None or ResourceType.Metal) return true; return false; } //处理军营 if (_actionId.ResourceType == ResourceType.Military) { //确认city是否已经有一个对应的特殊建筑 if(actionParam.MapData.GetCityDataByTerritoryGid(actionParam.GridData.Id,out var militaryCity) && Main.CityLogic.GetBuildingLevelByCity(actionParam.MapData,militaryCity,_actionId.ResourceType,out var militaryLevel)) return false; //必须是没有其他建筑的无树林平地 if (actionParam.GridData.Terrain == TerrainType.Land && actionParam.GridData.Feature != TerrainFeature.Mountain && actionParam.GridData.Vegetation != Vegetation.Trees && actionParam.GridData.Resource is ResourceType.None or ResourceType.Fruit) return true; return false; } //处理temple if (_actionId.ResourceType == ResourceType.Temple) { //必须平地,必须是none或者 if (actionParam.GridData.Feature == TerrainFeature.Mountain || actionParam.GridData.Vegetation == Vegetation.Trees || actionParam.GridData.Terrain != TerrainType.Land || (actionParam.GridData.Resource != ResourceType.None && actionParam.GridData.Resource != ResourceType.Metal)) return false; return true; } if(_actionId.ResourceType == ResourceType.WaterTemple) { //必须在水上,必须是none starfish或者fish,才能建设watertemple if (actionParam.GridData.Terrain == TerrainType.Land || (actionParam.GridData.Resource != ResourceType.None && actionParam.GridData.Resource != ResourceType.Fish && actionParam.GridData.Resource != ResourceType.Starfish)) return false; return true; } if (_actionId.ResourceType == ResourceType.ForestTemple) { //必须在林中,必须是none或者animals if (actionParam.GridData.Vegetation != Vegetation.Trees || (actionParam.GridData.Resource != ResourceType.None && actionParam.GridData.Resource != ResourceType.Animal)) return false; return true; } if (_actionId.ResourceType == ResourceType.MountainTemple) { //必须在山上,必须是none或者metal if (actionParam.GridData.Feature != TerrainFeature.Mountain || (actionParam.GridData.Resource != ResourceType.None && actionParam.GridData.Resource != ResourceType.Metal)) return false; return true; } //处理port if (_actionId.ResourceType == ResourceType.Port) { //如果不是none或者fish的浅水,直接return false if (actionParam.GridData.Terrain != TerrainType.ShallowSea) return false; if(actionParam.GridData.Resource is ResourceType.None or ResourceType.Fish or ResourceType.Starfish) return true; return false; } //剩下windmill sawmill forge market四天王,先确定平地情况 if (actionParam.GridData.Terrain != TerrainType.Land || (actionParam.GridData.Feature == TerrainFeature.Mountain) || (actionParam.GridData.Vegetation == Vegetation.Trees) || (actionParam.GridData.Resource != ResourceType.None && actionParam.GridData.Resource != ResourceType.Crop && actionParam.GridData.Resource != ResourceType.Fruit)) return false; //再确认周围有没有支持这个特殊建筑的附属建筑 if (!Main.CityLogic .CalcGridBuildingLevel(actionParam.MapData, actionParam.GridData, _actionId.ResourceType,out var level1)) return false; //再确认city是否已经有一个对应的特殊建筑 if(actionParam.MapData.GetCityDataByTerritoryGid(actionParam.GridData.Id,out var cityData) && Main.CityLogic.GetBuildingLevelByCity(actionParam.MapData,cityData,_actionId.ResourceType,out var level2)) return false; return true; } //付钱 protected bool BuildActionPayMoney(CommonActionParams actionParam) { if (actionParam.PlayerData.PlayerWealth - GetCost() < 0) return false; actionParam.PlayerData.PlayerWealth -= GetCost(); return true; } //确认是否满足基本信息 protected bool BuildActionCheckBaseInfo(CommonActionParams actionParam) { //如果是unit或者city来执行build操作,直接return false if (actionParam.MainObjectType != MainObjectType.Grid) return false; if (actionParam.GridData == null) return false; return true; } //确认是否有科技 protected bool BuildActionCheckHasTech(CommonActionParams actionParam) { //如果没有对应科技,return false if (!actionParam.PlayerData.TechTree.CheckActionCan(_actionId)) return false; return true; } //确认是否有钱 protected bool BuildActionCheckHasMoney(CommonActionParams actionParam) { //判断钱够不够 if (GetCost() > actionParam.PlayerData.PlayerWealth) return false; return true; } //确认是否在自己领土 protected bool BuildActionCheckInTerritory(CommonActionParams actionParam) { //如果在有主领土,判断是敌人还是自己 if (actionParam.MapData.GetPlayerDataByTerritoryGridId(actionParam.GridData.Id, out var playerData) && playerData == actionParam.PlayerData) return true; return false; } //确认是否有敌人占领 protected bool BuildActionCheckEnemyOccupy(CommonActionParams actionParam) { //如果有非联盟的敌人站在上面 if (actionParam.MapData.GetUnitDataByGid(actionParam.GridData.Id, out var unit) && !actionParam.MapData.CheckUnitIdBelongPlayerIdUnion(unit.Id, actionParam.PlayerData.Id)) return true; return false; } //确认该城市的唯一性并获得对应的building level protected bool BuildActionCheckHasOne(CommonActionParams actionParam,out int level) { if(actionParam.MapData.GetCityDataByTerritoryGid(actionParam.GridData.Id,out var city) && Main.CityLogic.GetBuildingLevelByCity(actionParam.MapData,city,_actionId.ResourceType,out level)) return true; level = 0; return false; } protected bool BuildActionCheckHasAnotherNearby(CommonActionParams actionParam) { var map = actionParam.MapData; var grid = actionParam.GridData; var list = map.GridMap.GetAroundGridData(1, 1, grid); foreach (var g in list) if (g.Resource == _actionId.ResourceType) return true; return false; } } public class BuildActionBuildPreserve : BuildAction { public BuildActionBuildPreserve(CommonActionId id) : base(id) { } protected override bool Execute(CommonActionParams actionParams) { if (actionParams.PlayerData == null) { LogSystem.LogError("PRESERVE !! playerData Not Found!!!!"); return false; } if (!CheckCan(actionParams)) { LogSystem.LogError("PRESERVE !! CheckCan No!!!!"); return false; } if (!BuildActionPayMoney(actionParams)) { LogSystem.LogError("PRESERVE !! PayMoney NO!!!!"); return false; } actionParams.GridData.ResourceUnderBuilding = actionParams.GridData.Resource; actionParams.GridData.Resource = ResourceType.Preserve; Main.CityLogic.CalcGridBuildingLevel(actionParams.MapData,actionParams.GridData, _actionId.ResourceType,out var buildingLevel); actionParams.GridData.buildingLevel = buildingLevel; //更新附近的Academy var gridDataList = Main.PlayerLogic.GetPlayerResourceNearbyList(actionParams.MapData, actionParams.PlayerData, actionParams.GridData, ResourceType.Academy); foreach(var gridData in gridDataList) Main.CityLogic.UpdateGridBuildingData(actionParams.MapData,gridData); Main.PlayerLogic.UpdateTerritoryAllBuildingLevel(actionParams.MapData,actionParams.PlayerData.Id); //更新显示地块 if (Main.MapData.IsCurrentShowMap()) PresentationManager.EnqueueGridUpdate(actionParams.MapData,actionParams.GridData,GridUpdateType.BuildingUpdate); return true; } public override bool CheckCan(CommonActionParams actionParam) { //step #1 check基本信息 if (!BuildActionCheckBaseInfo(actionParam)) return false; //step #2 check是否有科技 if (!BuildActionCheckHasTech(actionParam)) return false; //step #3 check是否有钱 if (!BuildActionCheckHasMoney(actionParam)) return false; //step #4 check是否在我方领土 if (!BuildActionCheckInTerritory(actionParam)) return false; //step #5 check是否有敌人占领 if (BuildActionCheckEnemyOccupy(actionParam)) return false; //step #6 check改成是是否尚未持有保护区 if (BuildActionCheckHasOne(actionParam, out var _)) return false; //step #7 保护区特有条件判断 var grid = actionParam.GridData; //保护区必须建立在没有其他建筑的树林 if (grid.Vegetation != Vegetation.Trees) return false; if (!(grid.Resource is ResourceType.None or ResourceType.Animal)) return false; return true; } public override bool CheckShow(CommonActionParams actionParam) { //step #1 check基本信息 if (!BuildActionCheckBaseInfo(actionParam)) return false; //step #2 check是否有科技 if (!BuildActionCheckHasTech(actionParam)) return false; //step #3 check是否有钱 - 跳过,CheckShow不需要判断钱 //if (!BuildActionCheckHasMoney(actionParam)) return false; //step #4 check是否在我方领土 if (!BuildActionCheckInTerritory(actionParam)) return false; //step #5 check是否有敌人占领 if (BuildActionCheckEnemyOccupy(actionParam)) return false; //step #6 check改成是是否尚未持有保护区 if (BuildActionCheckHasOne(actionParam, out var _)) return false; //step #7 保护区特有条件判断 var grid = actionParam.GridData; //保护区必须建立在没有其他建筑的树林 if (grid.Vegetation != Vegetation.Trees) return false; if (!(grid.Resource is ResourceType.None or ResourceType.Animal)) return false; return true; } } public class BuildActionBuildNavalBase : BuildAction { public BuildActionBuildNavalBase(CommonActionId id) : base(id) { } protected override bool Execute(CommonActionParams actionParams) { if (!BuildActionPayMoney(actionParams)) return false; actionParams.GridData.ResourceUnderBuilding = actionParams.GridData.Resource; actionParams.GridData.Resource = ResourceType.NavalBase; //如果不是真mapdata在播放动画 if (Main.MapData.IsCurrentShowMap()) { PresentationManager.EnqueueGridUpdate(actionParams.MapData,actionParams.GridData,GridUpdateType.BuildingUpdate); //如果有人站在军港上,要更新他的renderMark if (actionParams.MapData.GetUnitDataByGid(actionParams.GridData.Id, out var unit)) unit.Renderer(actionParams.MapData)?.InstantUpdateUnit(true); } return true; } public override bool CheckCan(CommonActionParams actionParam) { //step #1 check基本信息 if (!BuildActionCheckBaseInfo(actionParam)) return false; //step #2 check是否有科技 if (!BuildActionCheckHasTech(actionParam)) return false; //step #3 check是否有钱 if (!BuildActionCheckHasMoney(actionParam)) return false; //step #4 check是否在我方领土 if (!BuildActionCheckInTerritory(actionParam)) return false; //step #5 check是否有敌人占领 if (BuildActionCheckEnemyOccupy(actionParam)) return false; //step #6 check是否尚未持有军港 if (BuildActionCheckHasOne(actionParam, out var _)) return false; //step #7 军港特有条件判断 var grid = actionParam.GridData; //军港必须建立在我方深海或者浅海,没有其他建筑 if (grid.Terrain == TerrainType.Land) return false; if (!(grid.Resource is ResourceType.None or ResourceType.Fish or ResourceType.Starfish)) return false; //军港必须建立在我方港口周围 if (!Main.CityLogic.CheckAroundGridHasSomeResourceBelongPlayer(actionParam.MapData, grid, actionParam.PlayerData, ResourceType.Port)) return false; return true; } public override bool CheckShow(CommonActionParams actionParam) { //step #1 check基本信息 if (!BuildActionCheckBaseInfo(actionParam)) return false; //step #2 check是否有科技 if (!BuildActionCheckHasTech(actionParam)) return false; //step #3 check是否有钱 checkshow不需要! //if (!BuildActionCheckHasMoney(actionParam)) return false; //step #4 check是否在我方领土 if (!BuildActionCheckInTerritory(actionParam)) return false; //step #5 check是否有敌人占领 if (BuildActionCheckEnemyOccupy(actionParam)) return false; //step #6 check是否尚未持有军港 if (BuildActionCheckHasOne(actionParam, out var _)) return false; //step #7 军港特有条件判断 var grid = actionParam.GridData; //军港必须建立在我方深海或者浅海,没有其他建筑 if (grid.Terrain == TerrainType.Land) return false; if (!(grid.Resource is ResourceType.None or ResourceType.Fish or ResourceType.Starfish)) return false; //军港必须建立在我方港口周围 if (!Main.CityLogic.CheckAroundGridHasSomeResourceBelongPlayer(actionParam.MapData, grid, actionParam.PlayerData, ResourceType.Port)) return false; return true; } } public class BuildActionBuildTemple : BuildAction { public BuildActionBuildTemple(CommonActionId id) : base(id) { } //确定一个城市是否已经拥有一座英雄神像 private bool CheckGridCityHasTemple(CommonActionParams actionParam) { if (!actionParam.MapData.GetCityDataByTerritoryGid(actionParam.GridData.Id, out var city)) { LogSystem.LogError($"Can't find City with id {actionParam.GridData.Id} In BuildActionBuildTemple CheckGridCityHasTemple"); return true; } if(Main.CityLogic.GetBuildingLevelByCity(actionParam.MapData,city,ResourceType.KingTemple,out var _) || Main.CityLogic.GetBuildingLevelByCity(actionParam.MapData,city,ResourceType.ForestTemple,out var _) || Main.CityLogic.GetBuildingLevelByCity(actionParam.MapData,city,ResourceType.WaterTemple,out var _) || Main.CityLogic.GetBuildingLevelByCity(actionParam.MapData,city,ResourceType.Temple,out var _) || Main.CityLogic.GetBuildingLevelByCity(actionParam.MapData,city,ResourceType.MountainTemple,out var _)) return true; return false; } private bool CheckTemplePlaceOK(CommonActionParams actionParam) { if (_actionId.ResourceType == ResourceType.Temple || _actionId.ResourceType == ResourceType.KingTemple) { //必须平地,必须是none或者crop if (actionParam.GridData.Feature == TerrainFeature.Mountain || actionParam.GridData.Vegetation == Vegetation.Trees || actionParam.GridData.Terrain != TerrainType.Land || (actionParam.GridData.Resource != ResourceType.None && actionParam.GridData.Resource != ResourceType.Crop && actionParam.GridData.Resource != ResourceType.Fruit)) return false; return true; } if(_actionId.ResourceType == ResourceType.WaterTemple) { //必须在水上,必须是none starfish或者fish,才能建设watertemple if (actionParam.GridData.Terrain == TerrainType.Land || (actionParam.GridData.Resource != ResourceType.None && actionParam.GridData.Resource != ResourceType.Fish && actionParam.GridData.Resource != ResourceType.Starfish)) return false; return true; } if (_actionId.ResourceType == ResourceType.ForestTemple) { //必须在林中,必须是none或者animals if (actionParam.GridData.Vegetation != Vegetation.Trees || (actionParam.GridData.Resource != ResourceType.None && actionParam.GridData.Resource != ResourceType.Animal)) return false; return true; } if (_actionId.ResourceType == ResourceType.MountainTemple) { //必须在山上,必须是none或者metal if (actionParam.GridData.Feature != TerrainFeature.Mountain || (actionParam.GridData.Resource != ResourceType.None && actionParam.GridData.Resource != ResourceType.Metal)) return false; return true; } return true; } protected override bool Execute(CommonActionParams actionParams) { if (!BuildActionPayMoney(actionParams)) return false; actionParams.GridData.ResourceUnderBuilding = actionParams.GridData.Resource; actionParams.GridData.Resource = _actionId.ResourceType; actionParams.GridData.buildingLevel = 1; Table.Instance.GridAndResourceDataAssets.GetResourceInfo(actionParams.GridData.Resource,out var info); if (!actionParams.MapData.GetCityDataByTerritoryGid(actionParams.GridData.Id, out var city)) return false; //更新citylevel //Main.CityLogic.CityUpdateExp(actionParams.MapData,city,info?.Exp??0); Main.CityLogic.GridGiveCityExp(actionParams.MapData,actionParams.PlayerData,actionParams.GridData,city,info?.Exp??0); return true; } public override bool CheckCan(CommonActionParams actionParam) { //step #1 check基本信息 if (!BuildActionCheckBaseInfo(actionParam)) return false; //step #2 check是否有科技 if (!BuildActionCheckHasTech(actionParam)) return false; //step #3 check是否有钱 if (!BuildActionCheckHasMoney(actionParam)) return false; //step #4 check是否在我方领土 if (!BuildActionCheckInTerritory(actionParam)) return false; //step #5 check是否有敌人占领 if (BuildActionCheckEnemyOccupy(actionParam)) return false; //step #6 check是否尚未持有其他神像 if (CheckGridCityHasTemple(actionParam)) return false; //step #7 不同神像特有的建造条件 if (!CheckTemplePlaceOK(actionParam)) return false; return true; } public override bool CheckShow(CommonActionParams actionParam) { //step #1 check基本信息 if (!BuildActionCheckBaseInfo(actionParam)) return false; //step #2 check是否有科技 if (!BuildActionCheckHasTech(actionParam)) return false; //step #3 check是否有钱 --- 这一步不需要! //if (!BuildActionCheckHasMoney(actionParam)) return false; //step #4 check是否在我方领土 if (!BuildActionCheckInTerritory(actionParam)) return false; //step #5 check是否有敌人占领 if (BuildActionCheckEnemyOccupy(actionParam)) return false; //step #6 check是否尚未持有其他神像 if (CheckGridCityHasTemple(actionParam)) return false; //step #7 不同神像特有的建造条件 if (!CheckTemplePlaceOK(actionParam)) return false; return true; } } public class BuildActionBuildKaguyaFrenchYard : BuildAction { public BuildActionBuildKaguyaFrenchYard(CommonActionId id) : base(id) { } protected override bool Execute(CommonActionParams actionParams) { if (actionParams.PlayerData == null) return false; if (!CheckCan(actionParams)) return false; if (!BuildActionPayMoney(actionParams)) return false; actionParams.GridData.ResourceUnderBuilding = actionParams.GridData.Resource; actionParams.GridData.Resource = ResourceType.KaguyaFrenchYard; actionParams.GridData.CommonColdTime = 0; Main.CityLogic.CalcGridBuildingLevel(actionParams.MapData,actionParams.GridData, _actionId.ResourceType,out var buildingLevel); actionParams.GridData.buildingLevel = buildingLevel; Main.PlayerLogic.UpdateTerritoryAllBuildingLevel(actionParams.MapData,actionParams.PlayerData.Id); //如果不是真mapdata在播放动画 if (Main.MapData.IsCurrentShowMap()) PresentationManager.EnqueueGridUpdate(actionParams.MapData,actionParams.GridData,GridUpdateType.BuildingUpdate); return true; } public override bool CheckCan(CommonActionParams actionParam) { //step #1 check基本信息 if (!BuildActionCheckBaseInfo(actionParam)) return false; //step #2 check是否有科技 if (!BuildActionCheckHasTech(actionParam)) return false; //step #3 check是否有钱 if (!BuildActionCheckHasMoney(actionParam)) return false; //step #4 check是否在我方领土 if (!BuildActionCheckInTerritory(actionParam)) return false; //step #5 check是否有敌人占领 if (BuildActionCheckEnemyOccupy(actionParam)) return false; //step #6 check改成是是否尚未持有优昙华庭院 if (BuildActionCheckHasOne(actionParam, out var _)) return false; //step #7 优昙华庭院特有条件判断 var grid = actionParam.GridData; if (!(grid.Resource is ResourceType.None or ResourceType.Animal or ResourceType.Fruit or ResourceType.Metal or ResourceType.Crop)) return false; if (grid.Terrain != TerrainType.Land) return false; return true; } public override bool CheckShow(CommonActionParams actionParam) { //step #1 check基本信息 if (!BuildActionCheckBaseInfo(actionParam)) return false; //step #2 check是否有科技 if (!BuildActionCheckHasTech(actionParam)) return false; //step #3 check是否有钱 跳过 没有钱也可以显示 //if (!BuildActionCheckHasMoney(actionParam)) return false; //step #4 check是否在我方领土 if (!BuildActionCheckInTerritory(actionParam)) return false; //step #5 check是否有敌人占领 if (BuildActionCheckEnemyOccupy(actionParam)) return false; //step #6 check改成是是否尚未持有优昙华庭院 if (BuildActionCheckHasOne(actionParam, out var _)) return false; //step #7 优昙华庭院特有条件判断 var grid = actionParam.GridData; if (!(grid.Resource is ResourceType.None or ResourceType.Animal or ResourceType.Fruit or ResourceType.Metal or ResourceType.Crop)) return false; if (grid.Terrain != TerrainType.Land) return false; return true; } } //更新所有building的level public class BuildActionUpdateAllBuildingLevel : BuildAction { public BuildActionUpdateAllBuildingLevel(CommonActionId id) : base(id) { } protected override bool Execute(CommonActionParams actionParams) { return true; } } public class BuildActionBuildEgyptianIrrigation : BuildAction { public BuildActionBuildEgyptianIrrigation(CommonActionId id) : base(id) { } private bool BuildActionBuildEgyptianIrrigationSpecial(CommonActionParams actionParams,bool onWater = false) { var grid = actionParams.GridData; if (!onWater) { if (!actionParams.GridData.Player(actionParams.MapData)?.TechTree .CheckIfHasTech(TechType.RemiliaFarming) ?? true) return false; if (grid.Terrain != TerrainType.Land) return false; if (grid.Feature == TerrainFeature.Mountain) return false; if (grid.Vegetation == Vegetation.Trees) return false; if (!(grid.Resource is ResourceType.None or ResourceType.Fruit or ResourceType.Crop)) return false; var list = actionParams.MapData.GridMap.GetAroundGridData(1, 1, grid); int waterSide = 0; foreach (var g in list) { if (Mathf.Abs(g.Pos.X - grid.Pos.X) + Mathf.Abs(g.Pos.Y - grid.Pos.Y) != 1) continue; if (g.Terrain is TerrainType.ShallowSea) waterSide++; } if (waterSide < 2) return false; } if (onWater) { if (!actionParams.GridData.Player(actionParams.MapData)?.TechTree .CheckIfHasTech(TechType.RemiliaRamming) ?? true) return false; if (grid.Terrain != TerrainType.ShallowSea) return false; if (!(grid.Resource is ResourceType.None or ResourceType.Fish or ResourceType.Starfish)) return false; var list = actionParams.MapData.GridMap.GetAroundGridData(1, 1, grid); int landSide = 0; foreach (var g in list) { if (Mathf.Abs(g.Pos.X - grid.Pos.X) + Mathf.Abs(g.Pos.Y - grid.Pos.Y) != 1) continue; if (g.Terrain is TerrainType.Land) landSide++; } if (landSide < 2) return false; } return true; } protected override bool Execute(CommonActionParams actionParams) { if (actionParams.PlayerData == null) return false; if (!BuildActionPayMoney(actionParams)) return false; actionParams.GridData.ResourceUnderBuilding = actionParams.GridData.Resource; actionParams.GridData.Resource = ResourceType.EgyptianIrrigation; actionParams.GridData.CommonColdTime = 0; Main.CityLogic.CalcGridBuildingLevel(actionParams.MapData,actionParams.GridData, _actionId.ResourceType,out var buildingLevel); actionParams.GridData.buildingLevel = buildingLevel; //如果不是真mapdata在播放动画 if (Main.MapData.IsCurrentShowMap()) { PresentationManager.EnqueueGridUpdate(actionParams.MapData,actionParams.GridData,GridUpdateType.BuildingUpdate); var city = actionParams.GridData.City(actionParams.MapData); Main.CityLogic.GridGiveCityExp(actionParams.MapData,actionParams.PlayerData,actionParams.GridData,city,buildingLevel); } Main.PlayerLogic.UpdateTerritoryAllBuildingLevel(actionParams.MapData,actionParams.PlayerData.Id); return true; } public override bool CheckCan(CommonActionParams actionParam) { //step #1 check基本信息 if (!BuildActionCheckBaseInfo(actionParam)) return false; //step #2 check是否有科技 if (!BuildActionCheckHasTech(actionParam)) return false; //step #3 check是否有钱 if (!BuildActionCheckHasMoney(actionParam)) return false; //step #4 check是否在我方领土 if (!BuildActionCheckInTerritory(actionParam)) return false; //step #5 check是否有敌人占领 if (BuildActionCheckEnemyOccupy(actionParam)) return false; //step #6 check附近一格内是否有其他灌溉工程 if (BuildActionCheckHasAnotherNearby(actionParam)) return false; //step #7 灌溉工程的特有条件判断:2个边相邻的水域 if (!BuildActionBuildEgyptianIrrigationSpecial(actionParam,actionParam.GridData.Terrain != TerrainType.Land )) return false; return true; } public override bool CheckShow(CommonActionParams actionParam) { //step #1 check基本信息 if (!BuildActionCheckBaseInfo(actionParam)) return false; //step #2 check是否有科技 if (!BuildActionCheckHasTech(actionParam)) return false; //step #3 check是否有钱 / CheckShow不用判断有钱 //if (!BuildActionCheckHasMoney(actionParam)) return false; //step #4 check是否在我方领土 if (!BuildActionCheckInTerritory(actionParam)) return false; //step #5 check是否有敌人占领 if (BuildActionCheckEnemyOccupy(actionParam)) return false; //step #6 check附近一格内是否有其他灌溉工程 if (BuildActionCheckHasAnotherNearby(actionParam)) return false; //step #7 灌溉工程的特有条件判断:2个边相邻的水域 if (!BuildActionBuildEgyptianIrrigationSpecial(actionParam,actionParam.GridData.Terrain != TerrainType.Land)) return false; return true; } } }