Files
back_cantanBuilding/Assets/Scripts/HexGrid/HexZoneManager.cs
2026-05-26 16:15:54 +08:00

579 lines
22 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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<HexZone> _zones;
private List<HexBuilding> _buildings;
//
private HexGridMapUserData _userMapData;
//
private Transform transformRoot;
//
private List<HexZoneController> zoneControllers;
//
private IHexGridMediator _mediator;
//
private HexMapManager _hexMapManager;
public void SetMediator(IHexGridMediator mediator)
{
_mediator = mediator;
}
private void Awake()
{
zoneControllers = new List<HexZoneController>();
}
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<HexZone> 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<HexZoneController>();
if(hexZoneController == null)
hexZoneController = zoneObject.AddComponent<HexZoneController>();
zoneControllers.Add(hexZoneController);
hexZoneController.LoadData(zone);
var statusText = zoneTrans.Find("LockStatus").GetComponent<TMP_Text>();
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<HexGridTiler>();
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<HexGridTiler>()).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<HexTile> GetTilesFromName(HexZone zone,List<string> 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<HexGridTiler>().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<TMP_Text>();
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<HexGridTiler>().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<HexGridTiler>();
if (hexGridTiler)
{
hexGridTiler.UpdateVisual();
}
// tile.visual.GetComponent<HexGridTiler>().UpdateVisual();
Log($"StartSubZone -> curTile -> {tile.tileId} {tile.tileStatus}");
}
}
private static List<string> 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<string> GetNeighbors(HexTile tile)
// {
// Dictionary<string, List<string>> colls = new()
// {
// { "cube001", new List<string> { "cube002" } },
// { "cube002", new List<string> { "cube001","cube003","cube004","cube009","cube008" } },
// { "cube003", new List<string> {"cube002","cube009","cube010"}},
// { "cube004", new List<string> {"cube001","cube002","cube005","cube007","cube008"}},
// { "cube005", new List<string> {"cube004","cube006","cube007"}},
// { "cube006", new List<string> {"cube014","cube013","cube007","cube005"}},
// { "cube007", new List<string> {"cube005","cube006","cube004","cube008","cube012","cube013"}},
// { "cube008", new List<string> {"cube002","cube007","cube004","cube009","cube012","cube011"}},
// { "cube009", new List<string> {"cube003","cube010","cube016","cube008","cube002","cube011"}},
// { "cube010", new List<string> {"cube003","cube009","cube016"}},
// { "cube011", new List<string> {"cube008","cube009","cube016","cube018","cube015","cube012"}},
// { "cube012", new List<string> {"cube007","cube008","cube011","cube013","cube015"}},
// { "cube013", new List<string> {"cube014","cube006","cube007","cube013","cube012"}},
// { "cube014", new List<string> {"cube013","cube006"}},
// { "cube015", new List<string> {"cube012","cube019","cube017","cube011","cube018"}},
// { "cube016", new List<string> {"cube009","cube010","cube011","cube018","cube020"}},
// { "cube017", new List<string> {"cube015","cube019"}},
// { "cube018", new List<string> {"cube015","cube016","cube019","cube021","cube011","cube020"}},
// { "cube019", new List<string> {"cube015","cube018","cube021","cube017"}},
// { "cube020", new List<string> {"cube016","cube018","cube021"}},
// { "cube021", new List<string> {"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($"<color=yellow>HexZoneManager -> {t} </color>");
}
public HexTile GetTileByName(int zoneId, string tileName)
{
var zone = GetZoneById(zoneId);
return zone.tiles.FirstOrDefault(hexTile => hexTile.tileId.Equals(tileName));
}
}
}