/* * @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 RuntimeData; using TH1_Logic.Core; using UnityEngine; using TH1Renderer; using TH1Resource; //这里是所有BuildAction派生子类的实现模块 namespace Logic.Action { //GridMisc行为逻辑类,包括Destroy, ClearForest GrowForest BurnForest public class GridMiscAction : ActionLogicBase { public GridMiscAction(CommonActionId id) : base(id) { } protected override bool Execute(CommonActionParams actionParams, bool isMoment) { if (actionParams.PlayerData == null || actionParams.GridData == null) return false; if (!Table.Instance.ActionDataAssets.GetActionInfo(_actionId, out var actionInfo)) return false; if (!CheckCan(actionParams)) return false; //处理grow forest if (_actionId.GridMiscActionType == GridMiscActionType.GrowForest) { actionParams.PlayerData.PlayerWealth -= actionInfo.Cost; actionParams.GridData.Resource = ResourceType.None; actionParams.GridData.Vegetation = Vegetation.Trees; actionParams.GridData.RenderMark = true; //处理因为树林变化带来的上方单位防御状态变化的情况 if (actionParams.MapData.GetUnitDataByGid(actionParams.GridData.Id, out var unit)) unit.RenderMark = true; //更新所有领土内的levelbuilding Main.PlayerLogic.UpdateTerritoryAllBuildingLevel(actionParams.MapData,actionParams.PlayerData.Id); return true; } //处理clear forest if (_actionId.GridMiscActionType == GridMiscActionType.ClearForest) { actionParams.PlayerData.PlayerWealth -= actionInfo.Cost; actionParams.GridData.Resource = ResourceType.None; actionParams.GridData.Vegetation = Vegetation.None; actionParams.GridData.RenderMark = true; //处理因为树林变化带来的上方单位防御状态变化的情况 if (actionParams.MapData.GetUnitDataByGid(actionParams.GridData.Id, out var unit)) unit.RenderMark = true; //更新所有领土内的levelbuilding Main.PlayerLogic.UpdateTerritoryAllBuildingLevel(actionParams.MapData,actionParams.PlayerData.Id); return true; } //处理 burn forest if (_actionId.GridMiscActionType == GridMiscActionType.BurnForest) { actionParams.PlayerData.PlayerWealth -= actionInfo.Cost; actionParams.GridData.Vegetation = Vegetation.None; actionParams.GridData.Resource = ResourceType.Crop; actionParams.GridData.RenderMark = true; //更新所有领土内的levelbuilding Main.PlayerLogic.UpdateTerritoryAllBuildingLevel(actionParams.MapData,actionParams.PlayerData.Id); return true; } //TODO Destroy整个改成更鲁棒的写法,不要逐一判断了,全部刷一遍levelbuilding就行了 //处理Destroy if (_actionId.GridMiscActionType == GridMiscActionType.Destroy) { //Debug.Log($"执行拆除!目标是{actionParams.GridData.Resource}"); if (!Table.Instance.GridAndResourceDataAssets.GetResourceInfo(actionParams.GridData.Resource, out var resourceInfo)) return false; //如果destroy的位置是无主地块 if (!actionParams.MapData.GetCityDataByTerritoryGid(actionParams.GridData.Id, out var cityData)) return false; var destroyGrid = actionParams.GridData; if (actionParams.GridData.Resource == ResourceType.Farm || actionParams.GridData.Resource == ResourceType.Mine || actionParams.GridData.Resource == ResourceType.LumberHut) { //在已经拆除前,记录下来周围的什么样的milllike建筑要被同时更新 ResourceType needUpdate = Table.Instance.GridAndResourceDataAssets.GetMillLikeRelative(actionParams.GridData.Resource); Main.CityLogic.CityUpdateExp(actionParams.MapData, cityData, -resourceInfo.Exp); actionParams.GridData.Resource = actionParams.GridData.ResourceUnderBuilding; actionParams.GridData.ResourceUnderBuilding = ResourceType.None; //更新周围的milllike建筑 var gridDataList1 = Main.PlayerLogic.GetPlayerResourceNearbyList(actionParams.MapData, actionParams.PlayerData, actionParams.GridData, needUpdate); //Debug.Log($"执行拆除!目标影响到了周围的{needUpdate},数量有是{gridDataList1.Count}"); foreach (var gridData1 in gridDataList1) { Main.CityLogic.UpdateGridBuildingData(actionParams.MapData, gridData1); //还要额外连带影响附近的market var gridDataList2 = Main.PlayerLogic.GetPlayerResourceNearbyList(actionParams.MapData, actionParams.PlayerData, gridData1, ResourceType.Market); foreach (var gridData2 in gridDataList2) Main.CityLogic.UpdateGridBuildingData(actionParams.MapData, gridData2); } } //处理windmill sawmill forge else if (actionParams.GridData.Resource == ResourceType.Windmill || actionParams.GridData.Resource == ResourceType.Forge || actionParams.GridData.Resource == ResourceType.Sawmill) { //对应城市先丢失exp Main.CityLogic.CityUpdateExp(actionParams.MapData, cityData, -actionParams.GridData.buildingLevel * (actionParams.GridData.Resource == ResourceType.Forge ? 2 : 1)); //删除格子的内容 actionParams.GridData.Resource = actionParams.GridData.ResourceUnderBuilding; actionParams.GridData.ResourceUnderBuilding = ResourceType.None; actionParams.GridData.buildingLevel = 0; //更新周围的market情况 var gridDataList = Main.PlayerLogic.GetPlayerResourceNearbyList(actionParams.MapData, actionParams.PlayerData, actionParams.GridData, ResourceType.Market); foreach (var gridData in gridDataList) Main.CityLogic.UpdateGridBuildingData(actionParams.MapData, gridData); //更新周围的academy情况 gridDataList = Main.PlayerLogic.GetPlayerResourceNearbyList(actionParams.MapData, actionParams.PlayerData, actionParams.GridData, ResourceType.Academy); foreach (var gridData in gridDataList) Main.CityLogic.UpdateGridBuildingData(actionParams.MapData, gridData); } //处理market else if (actionParams.GridData.Resource == ResourceType.Market) { actionParams.GridData.Resource = actionParams.GridData.ResourceUnderBuilding; actionParams.GridData.ResourceUnderBuilding = ResourceType.None; actionParams.GridData.buildingLevel = 0; } //处理港口和桥梁 else if(actionParams.GridData.Resource == ResourceType.Port || actionParams.GridData.Resource == ResourceType.Bridge) { Main.CityLogic.CityUpdateExp(actionParams.MapData, cityData, -resourceInfo.Exp); actionParams.GridData.Resource = actionParams.GridData.ResourceUnderBuilding; actionParams.GridData.ResourceUnderBuilding = ResourceType.None; Main.PlayerLogic.UpdateCityConnect(actionParams.MapData,actionParams.PlayerData); } else if (actionParams.GridData.Resource == ResourceType.Preserve) { actionParams.GridData.Resource = actionParams.GridData.ResourceUnderBuilding; actionParams.GridData.ResourceUnderBuilding = ResourceType.None; //更新所有领土内的levelbuilding Main.PlayerLogic.UpdateTerritoryAllBuildingLevel(actionParams.MapData,actionParams.PlayerData.Id); } //处理其他情况 else { actionParams.GridData.Resource = actionParams.GridData.ResourceUnderBuilding; actionParams.GridData.ResourceUnderBuilding = ResourceType.None; Main.CityLogic.CityUpdateExp(actionParams.MapData, cityData, -resourceInfo.Exp); } //如果上面有unit,更新对应的rendermakr if (actionParams.MapData.GetUnitDataByGid(actionParams.GridData.Id, out var unit)) unit.RenderMark = true; //保险起见,全部跑一遍builddinglevel的更新 (例如lumberhut destroy影响周围的保护区) Main.PlayerLogic.UpdateTerritoryAllBuildingLevel(actionParams.MapData,actionParams.PlayerData.Id); cityData.CityInfoRenderMark = true; actionParams.GridData.RenderMark = true; //播放雾效 destroyGrid.VFXRenderMarkFog = true; return true; } return false; } public override bool CheckCan(CommonActionParams actionParams) { //如果是unit或者city来执行gridMisc操作,直接return false if (actionParams.MainObjectType != MainObjectType.Grid) return false; if (actionParams.GridData == null) return false; //如果没有对应科技,return false if (!actionParams.PlayerData.TechTree.CheckActionCan(_actionId)) return false; //如果有非联盟的敌人站在上面 if (actionParams.MapData.GetUnitDataByGid(actionParams.GridData.Id, out var unit) && !actionParams.MapData.CheckUnitIdBelongPlayerIdUnion(unit.Id, actionParams.PlayerData.Id)) return false; //如果在有主领土,判断是敌人还是自己 if (actionParams.MapData.GetPlayerDataByTerritoryGridId(actionParams.GridData.Id, out var playerData)) { //在敌人领土上,直接return false if (playerData != actionParams.PlayerData) return false; } //如果在无主领土 return false else return false; //判断钱够不够 if (GetCost() > actionParams.PlayerData.PlayerWealth) return false; //处理grow forest if (_actionId.GridMiscActionType == GridMiscActionType.GrowForest) { //如果不是crop或者none的land,直接return false if (actionParams.GridData.Terrain != TerrainType.Land ||(actionParams.GridData.Resource != ResourceType.None && actionParams.GridData.Resource != ResourceType.Crop && actionParams.GridData.Resource != ResourceType.Fruit)) return false; if (actionParams.GridData.Feature == TerrainFeature.Mountain) return false; if (actionParams.GridData.Vegetation == Vegetation.Trees) return false; return true; } //处理clear forest 和 burn forest if (_actionId.GridMiscActionType == GridMiscActionType.ClearForest || _actionId.GridMiscActionType == GridMiscActionType.BurnForest ) { //如果没有树林 或者 树林已经不是none或animal return false if (actionParams.GridData.Vegetation != Vegetation.Trees || (actionParams.GridData.Resource != ResourceType.None && actionParams.GridData.Resource != ResourceType.Animal)) return false; return true; } //处理Destroy if (_actionId.GridMiscActionType == GridMiscActionType.Destroy) { if (actionParams.GridData.Resource == ResourceType.Temple || actionParams.GridData.Resource == ResourceType.ForestTemple || actionParams.GridData.Resource == ResourceType.MountainTemple || actionParams.GridData.Resource == ResourceType.WaterTemple || actionParams.GridData.Resource == ResourceType.KingTemple || actionParams.GridData.Resource == ResourceType.Windmill || actionParams.GridData.Resource == ResourceType.Sawmill || actionParams.GridData.Resource == ResourceType.Forge || actionParams.GridData.Resource == ResourceType.LumberHut || actionParams.GridData.Resource == ResourceType.Farm || actionParams.GridData.Resource == ResourceType.Mine || actionParams.GridData.Resource == ResourceType.Port || actionParams.GridData.Resource == ResourceType.Bridge || actionParams.GridData.Resource == ResourceType.Market || actionParams.GridData.Resource == ResourceType.Wonder || actionParams.GridData.Resource == ResourceType.Academy || actionParams.GridData.Resource == ResourceType.Preserve || actionParams.GridData.Resource == ResourceType.Military || actionParams.GridData.Resource == ResourceType.NavalBase) return true; return false; } return false; } public override bool CheckShow(CommonActionParams actionParams) { return CheckCan(actionParams); } 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; } //付钱 protected bool GridMiscActionPayMoney(CommonActionParams actionParam) { if (actionParam.PlayerData.PlayerWealth - GetCost() < 0) return false; actionParam.PlayerData.PlayerWealth -= GetCost(); return true; } //确认是否满足基本信息 protected bool GridMiscActionCheckBaseInfo(CommonActionParams actionParam) { //如果是unit或者city来执行gridMisc操作,直接return false if (actionParam.MainObjectType != MainObjectType.Grid) return false; if (actionParam.GridData == null) return false; return true; } //确认是否有科技 protected bool GridMiscActionCheckHasTech(CommonActionParams actionParam) { //如果没有对应科技,return false if (!actionParam.PlayerData.TechTree.CheckActionCan(_actionId)) return false; return true; } //确认是否有钱 protected bool GridMiscActionCheckHasMoney(CommonActionParams actionParam) { //如果是upgradeTemple这种带参数的gridMisc,走这里 if (_actionId.GridMiscActionType == GridMiscActionType.UpgradeTemple) { if (GetCost(actionParam.GridData.buildingLevel) > actionParam.PlayerData.PlayerWealth) return false; return true; } //否则走这里 if (GetCost() > actionParam.PlayerData.PlayerWealth) return false; return true; } //确认是否在自己领土 protected bool GridMiscActionCheckInTerritory(CommonActionParams actionParam) { //如果在有主领土,判断是敌人还是自己 if (actionParam.MapData.GetPlayerDataByTerritoryGridId(actionParam.GridData.Id, out var playerData) && playerData == actionParam.PlayerData) return true; return false; } //确认是否有敌人占领 protected bool GridMiscActionCheckEnemyOccupy(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 GridMiscActionCheckHasOne(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; } } public class GridMiscActionUpgradeTemple : GridMiscAction { public GridMiscActionUpgradeTemple(CommonActionId id) : base(id) { } protected override bool Execute(CommonActionParams actionParams, bool isMoment) { if (!CheckCan(actionParams)) return false; //step #1 扣钱 actionParams.PlayerData.PlayerWealth -= GetCost(actionParams.GridData.buildingLevel); //step #2 办事 升级temple actionParams.GridData.buildingLevel++; return true; } public override bool CheckCan(CommonActionParams actionParam) { //step #1 check基本信息 if (!GridMiscActionCheckBaseInfo(actionParam)) return false; //Step #2 check是否是temple if (!(actionParam.GridData.Resource is ResourceType.Temple or ResourceType.KingTemple or ResourceType.MountainTemple or ResourceType.WaterTemple or ResourceType.ForestTemple)) return false; //step #3 check是否有科技 if (!GridMiscActionCheckHasTech(actionParam)) return false; //step #4 check是否有钱 if (!GridMiscActionCheckHasMoney(actionParam)) return false; //step #5 check是否在我方领土 if (!GridMiscActionCheckInTerritory(actionParam)) return false; //step #6 check是否有敌人占领 if (GridMiscActionCheckEnemyOccupy(actionParam)) return false; //step #7 check 是否已经满级 if (actionParam.GridData.buildingLevel >= 5) return false; return true; } public override bool CheckShow(CommonActionParams actionParam) { //step #1 check基本信息 if (!GridMiscActionCheckBaseInfo(actionParam)) return false; //Step #2 check是否是temple if (!(actionParam.GridData.Resource is ResourceType.Temple or ResourceType.KingTemple or ResourceType.MountainTemple or ResourceType.WaterTemple or ResourceType.ForestTemple)) return false; //step #3 check是否有科技 if (!GridMiscActionCheckHasTech(actionParam)) return false; //step #4 check是否有钱 //if (!GridMiscActionCheckHasMoney(actionParam)) return false; //step #5 check是否在我方领土 if (!GridMiscActionCheckInTerritory(actionParam)) return false; //step #6 check是否有敌人占领 if (GridMiscActionCheckEnemyOccupy(actionParam)) return false; //step #7 check 是否已经满级 if (actionParam.GridData.buildingLevel >= 5) return false; return true; } public override bool ExecuteViewBefore(CommonActionParams actionParams) { return true; } public override bool ExecuteViewAfter(CommonActionParams actionParams) { //如果不是真mapdata在播放动画 if (Main.MapData != actionParams.MapData) return false; //更新地块视觉,播放烟雾特效 actionParams.GridData.RenderMark = true; actionParams.GridData.SetGridVFXRenderMark(new GridVFXRenderMark(GridVFXType.Fog)); return true; } } }