using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using HexGrid.MapHelper; using HexGrid.Math; using TMPro; using UnityEngine; namespace HexGrid { // 区域管理 public class HexZoneManager : MonoBehaviour,IHexGridMediatable { // private List _zones; private List _buildings; // private HexGridMapUserData _userMapData; // private Transform transformRoot; // private List zoneControllers; // private IHexGridMediator _mediator; // private HexMapManager _hexMapManager; public void SetMediator(IHexGridMediator mediator) { _mediator = mediator; } private void Awake() { zoneControllers = new List(); } private void Start() { } // public void SetHexMapManager(HexMapManager manager) { _hexMapManager = manager; } // public void SetRoot(Transform root) { transformRoot = root; } public HexZone GetZoneById(int zoneId) { return _zones.Find(z => z.zoneId == zoneId); } //TODO:LF 侵入了数据块, 正式版需要分开,生成User版本,然后和固定的刷在一起提供出更好 public void BuildMapData(HexGridMapUserData userMapData) { var currZoneIndex = userMapData.zoneCurrentIndex; for (var i = 0; i < currZoneIndex; ++i) { _zones[i].isUnlocked = true; foreach (var tile in _zones[i].tiles) { tile.tileStatus = 2; // _mediator.CheckBuildingAfterBuildImme(tile); } //BuildBuildingData(_zones[i].subZones); } // 全部隐藏 for (var i = currZoneIndex + 1; i < _zones.Count; ++i) { _zones[i].isUnlocked = false; foreach (var tile in _zones[i].tiles) { tile.tileStatus = 0; } } // var subZoneCurrentIndex = userMapData.subZoneCurrentIndex; if (currZoneIndex > _zones.Count -1) { return; } // var zoneCur = _zones[currZoneIndex]; zoneCur.isUnlocked = true; for (var i = 0; i < subZoneCurrentIndex; ++i) { var tileNames = zoneCur.subZones[i].tileNames; foreach (var tile in tileNames.SelectMany(tileName => zoneCur.tiles.Where(tile => string.Equals(tile.tileId, tileName)))) { tile.tileStatus = 2; // _mediator.CheckBuildingAfterBuildImme(tile); } } for (var i = subZoneCurrentIndex + 1; i < zoneCur.subZones.Count; ++i) { var tileNames = zoneCur.subZones[i].tileNames; foreach (var tile in tileNames.SelectMany(tileName => zoneCur.tiles.Where(tile => string.Equals(tile.tileId, tileName)))) { tile.tileStatus = 0; } } var subZone = zoneCur.subZones[subZoneCurrentIndex]; var curTiles = subZone.tileNames; var completeTiles = userMapData.completeTiles; int count = 0; foreach (var tile in curTiles.SelectMany(tileName => zoneCur.tiles.Where(tile => string.Equals(tile.tileId, tileName)))) { Log($"curTile -> {tile.tileId}"); if (count != 0) { tile.tileStatus = 0; continue; } tile.tileStatus = completeTiles.Contains(tile.tileId) ? 2 : 1; if (tile.tileStatus == 1) { count++; } if (tile.tileStatus == 2) { // _mediator.CheckBuildingAfterBuildImme(tile); } } } //TODO: 构建完成版家住的数据 public void LoadZonesFromSave(HexGridMap mapInfo,HexGridMapUserData userMapData) { _zones = mapInfo.zones; _buildings = mapInfo.buildings; _userMapData = userMapData; _mediator.LoadBuildings(mapInfo.buildings); BuildMapData(userMapData); LoadZones(_zones); LoadBuildings(); } private void LoadBuildings() { foreach (var tile in _zones.SelectMany(zone => zone.tiles)) { if (tile.tileStatus == 2) { _mediator.CheckBuildingAfterBuildImme(tile); } } } public void LoadZones(List zones) { foreach (var zone in _zones) { var zoneTrans = transformRoot.Find(zone?.zoneName); if (zone != null) { var zoneObject = zoneTrans.gameObject; zone.zoneObject = zoneObject; var hexZoneController = zoneObject.GetComponent(); if(hexZoneController == null) hexZoneController = zoneObject.AddComponent(); zoneControllers.Add(hexZoneController); hexZoneController.LoadData(zone); var statusText = zoneTrans.Find("LockStatus").GetComponent(); statusText.text = zone.isUnlocked ? "" : "LOCK"; foreach (var tileData in zone.tiles) { var tileTransform = zoneTrans.Find(tileData.tileOriName); if (!tileTransform) continue; tileData.visual = tileTransform.gameObject; var tiler = tileTransform.GetComponent(); if (tiler) { tiler.SetMediator(_mediator); tiler.LoadTileData(tileData); tiler.UpdateVisual(); } } } } } public void SaveZonesToFile() { foreach (var zone in _zones) { // PlayerPrefs.SetInt("Zone_" + zone.id, zone.isUnlocked ? 1 : 0); } // PlayerPrefs.Save(); } public bool UpdateZoneStatus() { return false; } // TODO: 没有检测邻居的数值,先当前子区域里的全部显示,都完成进入下一个 public bool UpdateSubZoneStatus(HexZone zone, int subZoneId) { Log($"UpdateSubZoneStatus -> {subZoneId}"); //return false; //TODO:LF 先这样用吧.可以绑定一下或者存 MONObehavier 的 List var subZoneCurrentIndex = _userMapData.subZoneCurrentIndex; var subzone = zone?.subZones[subZoneCurrentIndex]; var zoneTrans = zone?.zoneObject.transform; if (subzone?.tileNames != null) foreach (var tiler in (subzone?.tileNames).Select(tileName => zoneTrans.Find(tileName)).Select(tileTransform => tileTransform.GetComponent()).Where(tiler => tiler)) { //tiler.LoadTileData(); //this.UpdateTileData(tiler); tiler.UpdateVisual(); } return false; } public bool UpdateMapStatus() { return false; } public bool OnHexTileData(HexTile tiler) { var zone = _zones.FirstOrDefault(zone => zone.zoneId == tiler.zoneId); var result = zone?.tiles.FirstOrDefault(myTile => myTile.tileId == tiler.tileId); Log($"tiler -> {tiler} result: {result}"); // 更新数据 if (result != null && result.tileStatus == 1) { result.tileStatus = 2; _userMapData.completeTiles.Add(result.tileId); return true; } return false; // 更新View // var rt = UpdateSubZoneStatus(zone,tiler.subZoneIndex); // if (!rt) return; // var rt2 = UpdateZoneStatus(); // if (!rt2) return; // var rt3 = UpdateMapStatus(); // if (!rt3) return; // _userMapData. // UpdateUserData(); } // private List GetTilesFromName(HexZone zone,List tileNames) { return zone.tiles.Where(tile => tileNames.Contains(tile.tileId)).ToList(); } public async Task OnActiveNextTile(HexTile result) { //TODO:LF 注意,这里有报错,Camera 完成之后需要修复 var subZoneCurrentIndex = _userMapData.subZoneCurrentIndex; var zone = GetZoneById(result.zoneId); var zoneSubTileNames = zone.subZones[subZoneCurrentIndex].tileNames; var rt = GetNeighborsInZone(result,zone,zone.subZones[subZoneCurrentIndex]); foreach (var name in rt) { Log($"{result.tileCoords} neighbor: {name}" ); } var rtList = GetTilesFromName(zone, rt); var nexTile = rtList.FirstOrDefault(c => c.tileStatus == 0); if (nexTile == null) { var subzoneTiles = GetTilesFromName(zone, zoneSubTileNames); nexTile = subzoneTiles.FirstOrDefault(c => c.tileStatus == 0); } if (nexTile != null) { await ActiveHexTile(nexTile); } else { // 进入下一个阶段 if (CheckSubZoneFinished(zone.subZones[subZoneCurrentIndex])) { await OnActiveNextPart(); } } DoSave(); } private async Task ActiveHexTile(HexTile nexTile) { Log($"ActiveHexTile ->{nexTile}"); await Awaiters.Seconds(0.7f); ChangeTileStatus(nexTile,1); } private static void ChangeTileStatus(HexTile nexTile,int tileStatus) { nexTile.tileStatus = tileStatus; nexTile.visual.GetComponent().UpdateVisual(); } // private async Task CheckBuilding(HexZone zone,HexSubZone subZone) // { // Log("CheckBuilding-> "); // var buildList = subZone.buildings; // var parents = zone.zoneObject; // // if (buildList is { Count: > 0 }) // { // foreach (var building in buildList) // { // // if (true) // { // var build = Instantiate(building.buildModel, parents.transform); // build.transform.position = new Vector3(-1.38f, 2.69f, 8.41f); // } // } // } // // } private bool CheckSubZoneFinished(HexSubZone zoneSubZone) { var zoneCur = _zones[_userMapData.zoneCurrentIndex]; bool ret = true; foreach (var tileName in zoneSubZone.tileNames) { foreach (var tile in zoneCur.tiles.Where(tile => string.Equals(tile.tileId, tileName))) { if (tile.tileStatus != 2) { ret = false; break; } } } Log($"CheckSubZoneFinished ->{_userMapData.subZoneCurrentIndex}, {zoneSubZone.subZoneId } {ret}" ); return ret; } private async Task OnActiveNextPart() { Log("OnActiveNextSubZone -> "); await Awaiters.Seconds(0.7f); // _userMapData.subZoneCurrentIndex++; var nextSubzoneIndex = _userMapData.subZoneCurrentIndex + 1; var zoneCur = _zones[_userMapData.zoneCurrentIndex]; if (nextSubzoneIndex >= zoneCur.subZones.Count) { StartNextZone(); } else { StartSubZone(); } } public GameObject GetCurZoneRoot() { var currZoneIndex = _userMapData.zoneCurrentIndex; var zoneCur = _zones[currZoneIndex]; if (zoneCur == null) return null; if (zoneCur.zoneObject) { return zoneCur.zoneObject; } var zoneTrans = transformRoot.Find(zoneCur?.zoneName); return zoneTrans.gameObject; } public GameObject GetBuildingRoot(int id) { var mergeTrans = transformRoot.Find("merge"); return mergeTrans.gameObject; } public GameObject GetZoneObject(int id) { var zoneCur = GetZoneById(id); if (zoneCur == null) return null; if (zoneCur.zoneObject) { return zoneCur.zoneObject; } var zoneTrans = transformRoot.Find(zoneCur?.zoneName); return zoneTrans.gameObject; } private void UpdateCurrZoneStatus() { var currZoneIndex = _userMapData.zoneCurrentIndex; var subZoneCurrentIndex = _userMapData.subZoneCurrentIndex; var zoneCur = _zones[currZoneIndex]; var zoneObject = zoneCur.zoneObject; if (zoneObject) { var statusText = zoneObject.transform.Find("LockStatus").GetComponent(); statusText.text = zoneCur.isUnlocked ? "" : "LOCK"; } for (var i = 0; i < subZoneCurrentIndex; ++i) { var tileNames = zoneCur.subZones[i].tileNames; foreach (var tile in tileNames.SelectMany(tileName => zoneCur.tiles.Where(tile => string.Equals(tile.tileId, tileName)))) { tile.tileStatus = 2; } } for (var i = subZoneCurrentIndex + 1; i < zoneCur.subZones.Count; ++i) { var tileNames = zoneCur.subZones[i].tileNames; foreach (var tile in tileNames.SelectMany(tileName => zoneCur.tiles.Where(tile => string.Equals(tile.tileId, tileName)))) { tile.tileStatus = 0; } } var subZone = zoneCur.subZones[subZoneCurrentIndex]; var curTiles = subZone.tileNames; var completeTiles = _userMapData.completeTiles; int count = 0; foreach (var tile in curTiles.SelectMany(tileName => zoneCur.tiles.Where(tile => string.Equals(tile.tileId, tileName)))) { if (count != 0) { tile.tileStatus = 0; continue; } tile.tileStatus = completeTiles.Contains(tile.tileId) ? 2 : 1; if (tile.tileStatus == 1) { tile.visual.GetComponent().UpdateVisual(); count++; } Log($"curTile -> {tile.tileId} : {tile.tileStatus}"); } } private void StartNextZone() { Log("StartNextZone() -> "); _userMapData.zoneCurrentIndex++; _userMapData.subZoneCurrentIndex = 0; _userMapData.completeTiles.Clear(); // if (_userMapData.zoneCurrentIndex > _zones.Count -1) { DoSave(); return; } var zoneCur = _zones[_userMapData.zoneCurrentIndex]; Log($"解锁 Zone -> {zoneCur.zoneId}"); zoneCur.isUnlocked = true; UpdateCurrZoneStatus(); } private void StartSubZone() { var subZoneCurrentIndex = ++_userMapData.subZoneCurrentIndex; var zoneCur = _zones[_userMapData.zoneCurrentIndex]; var subZone = zoneCur.subZones[subZoneCurrentIndex]; var curTiles = subZone.tileNames; var completeTiles = _userMapData.completeTiles; completeTiles.Clear(); Log($"StartSubZone -> {subZoneCurrentIndex} {subZone.subZoneId} "); // 查找第一个地块,激活 int count = 0; foreach (var tile in curTiles.SelectMany(tileName => zoneCur.tiles.Where(tile => string.Equals(tile.tileId, tileName)))) { if (count == 0) { tile.tileStatus = 1; } count++; var hexGridTiler = tile.visual.GetComponent(); if (hexGridTiler) { hexGridTiler.UpdateVisual(); } // tile.visual.GetComponent().UpdateVisual(); Log($"StartSubZone -> curTile -> {tile.tileId} {tile.tileStatus}"); } } private static List GetNeighborsInZone(HexTile hexTile,HexZone zone, HexSubZone subZone) { // foreach (var neighbor in neighbors) // { // // var x = tile.tileCoords.x + neighbor.x; // // var y = tile.tileCoords.y + neighbor.y; // Vector2Int user = HexUtils.GetNeighborList(tile,i); // var tileCoord = new Vector2Int(x,y); // var tileName = HexUtils.MakeTileId(tileCoord); // list.AddRange(from elem in zone.tiles where elem.tileCoords == tileCoord select tileName); // } // var listNeighbor = ; var listNeighbor = HexUtils.GetNeighborList(hexTile).Select(HexUtils.MakeTileId).ToList(); return listNeighbor.Intersect(subZone.tileNames).ToList(); // return listNeighbor.Select(HexUtils.MakeTileId).Where(tileId => zone.tiles.Any(tile => string.Equals(tile.tileId, tileId))).ToList(); } // 返回邻居,需要使用HexMatrix 整体流程 // private List GetNeighbors(HexTile tile) // { // Dictionary> colls = new() // { // { "cube001", new List { "cube002" } }, // { "cube002", new List { "cube001","cube003","cube004","cube009","cube008" } }, // { "cube003", new List {"cube002","cube009","cube010"}}, // { "cube004", new List {"cube001","cube002","cube005","cube007","cube008"}}, // { "cube005", new List {"cube004","cube006","cube007"}}, // { "cube006", new List {"cube014","cube013","cube007","cube005"}}, // { "cube007", new List {"cube005","cube006","cube004","cube008","cube012","cube013"}}, // { "cube008", new List {"cube002","cube007","cube004","cube009","cube012","cube011"}}, // { "cube009", new List {"cube003","cube010","cube016","cube008","cube002","cube011"}}, // { "cube010", new List {"cube003","cube009","cube016"}}, // { "cube011", new List {"cube008","cube009","cube016","cube018","cube015","cube012"}}, // { "cube012", new List {"cube007","cube008","cube011","cube013","cube015"}}, // { "cube013", new List {"cube014","cube006","cube007","cube013","cube012"}}, // { "cube014", new List {"cube013","cube006"}}, // { "cube015", new List {"cube012","cube019","cube017","cube011","cube018"}}, // { "cube016", new List {"cube009","cube010","cube011","cube018","cube020"}}, // { "cube017", new List {"cube015","cube019"}}, // { "cube018", new List {"cube015","cube016","cube019","cube021","cube011","cube020"}}, // { "cube019", new List {"cube015","cube018","cube021","cube017"}}, // { "cube020", new List {"cube016","cube018","cube021"}}, // { "cube021", new List {"cube018","cube019","cube020"}}, // // }; // return colls[tile.tileId]; // } // 解锁子区域,激活第一块 private void UnlockSubZone(int zoneId, int subZoneId) { } // private void UpdateUserData() // { // // } private void DoSave() { //const string saveKey = HexMapManager.SaveKey; //PlayFabMgr.Instance.UpdateUserDataValue(saveKey, JsonConvert.SerializeObject(_userMapData)); _hexMapManager.SaveUserData(); } private static void Log(object t) { Debug.Log($"HexZoneManager -> {t} "); } public HexTile GetTileByName(int zoneId, string tileName) { var zone = GetZoneById(zoneId); return zone.tiles.FirstOrDefault(hexTile => hexTile.tileId.Equals(tileName)); } } }