579 lines
22 KiB
C#
579 lines
22 KiB
C#
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));
|
||
}
|
||
}
|
||
} |