243 lines
9.2 KiB
C#
243 lines
9.2 KiB
C#
// HintData.cs
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
using Logic;
|
||
using RuntimeData;
|
||
using Random = UnityEngine.Random;
|
||
|
||
namespace TH1Renderer
|
||
{
|
||
|
||
//TODO 做HintData序列化相关的工作
|
||
[Serializable]
|
||
public class HintData
|
||
{
|
||
public uint Id;
|
||
public uint GridId;
|
||
public HintType HintType;
|
||
|
||
public HintData(uint id, uint gridId, HintType hintType)
|
||
{
|
||
Id = id;
|
||
GridId = gridId;
|
||
HintType = hintType;
|
||
}
|
||
}
|
||
|
||
[Serializable]
|
||
public class HintManager
|
||
{
|
||
private Main _main;
|
||
private MapData _map;
|
||
public HashSet<HintData> HintSet = new();
|
||
private Dictionary<uint, HintData> _idToHintDict = new();
|
||
private uint _hintDataIdCounter;
|
||
private GameObject _prefabROHint;
|
||
private Dictionary<uint,HintRenderer> _ROHintRendererDict = new();
|
||
|
||
public void Init(Main main,MapData map)
|
||
{
|
||
_map = map;
|
||
_main = main;
|
||
_hintDataIdCounter = 0;
|
||
_prefabROHint = Resources.Load<GameObject>("Prefab/hintPrefab");
|
||
}
|
||
|
||
public uint HintDataIdGenerator()
|
||
{
|
||
return _hintDataIdCounter++;
|
||
}
|
||
|
||
//每帧调用所有hintRenderer的update,并且将已经结束的Renderer回收
|
||
public void Update()
|
||
{
|
||
List<uint> finishedList = new();
|
||
foreach (var pair in _ROHintRendererDict)
|
||
if (pair.Value.Finished)
|
||
finishedList.Add(pair.Key);
|
||
else
|
||
pair.Value.Update();
|
||
foreach (var kill in finishedList)
|
||
RemoveHint(_idToHintDict[kill]);
|
||
}
|
||
|
||
public void AddHint(HintData data)
|
||
{
|
||
if (_idToHintDict.ContainsKey(data.Id)) return;
|
||
HintSet.Add(data);
|
||
_idToHintDict[data.Id] = data;
|
||
_ROHintRendererDict[data.Id] = new HintRenderer(_main,_map,_prefabROHint,MapRenderer.Instance.HintRenderMap,data);
|
||
_ROHintRendererDict[data.Id].StartBubble();
|
||
}
|
||
|
||
public void RemoveHint(HintData data)
|
||
{
|
||
if (!_idToHintDict.TryGetValue(data.Id, out var _)) return;
|
||
if (!_ROHintRendererDict.TryGetValue(data.Id, out var renderer)) return;
|
||
Debug.Log("Destroy!!");
|
||
GameObject.Destroy(renderer.ROHint);
|
||
HintSet.Remove(data);
|
||
_idToHintDict.Remove(data.Id);
|
||
_ROHintRendererDict.Remove(data.Id);
|
||
}
|
||
|
||
|
||
public void SetAllFinished()
|
||
{
|
||
foreach (var hint in HintSet)
|
||
{
|
||
//设置了hideTextPanel后,会在动画播完时设置finished,然后会被本对象的update检测并删除
|
||
_ROHintRendererDict[hint.Id].HideTextPanel();
|
||
}
|
||
}
|
||
|
||
public void ClearAll()
|
||
{
|
||
foreach (var pair in _ROHintRendererDict)
|
||
pair.Value.SetFinished();
|
||
|
||
}
|
||
|
||
//处理 村庄/城市/遗迹的提示,将这些情况全部加入hintList
|
||
public void SetHintCommonCaptureExamineTrainUnit(MapData map,PlayerData player,List<HintData> hintDataList)
|
||
{
|
||
var sight = player.Sight.SightGidSet;
|
||
foreach (var gid in sight)
|
||
{
|
||
if (!map.GridMap.GetGridDataByGid(gid, out var grid)) continue;
|
||
//如果是城市/村庄
|
||
if (grid.Resource == ResourceType.CityCenter)
|
||
{
|
||
map.GetPlayerDataByTerritoryGridId(gid, out var gridPlayer);
|
||
map.GetUnitDataByGid(gid, out var unit);
|
||
|
||
//如果是无主村庄,那么就上
|
||
if (gridPlayer == null)
|
||
{
|
||
var hint = new HintData(HintDataIdGenerator(),gid,HintType.CommonCapture);
|
||
hintDataList.Add(hint);
|
||
}
|
||
//否则是城市,如果是我方城市,那么必须是上面没人且可以造兵,过一遍checkcan
|
||
else if (gridPlayer.Id == player.Id)
|
||
{
|
||
if (unit == null)
|
||
{
|
||
var hint = new HintData(HintDataIdGenerator(),gid,HintType.CommonTrainUnit);
|
||
hintDataList.Add(hint);
|
||
}
|
||
}
|
||
//否则是敌方城市,那么必须是敌方城市且有我方单位站在上面,才报提示
|
||
else
|
||
{
|
||
if (unit!= null && map.GetPlayerDataByUnitId(unit.Id,out var unitPlayer) && unitPlayer.Id == player.Id)
|
||
{
|
||
var hint = new HintData(HintDataIdGenerator(),gid,HintType.CommonCapture);
|
||
hintDataList.Add(hint);
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
//如果是遗迹
|
||
else if (grid.Resource == ResourceType.Treasure)
|
||
{
|
||
var hint = new HintData(HintDataIdGenerator(),gid,HintType.CommonExamine);
|
||
hintDataList.Add(hint);
|
||
}
|
||
}
|
||
}
|
||
|
||
//处理 城市领土存在fruit / fish / animal / farm / mine,将这些情况全部加入hintList
|
||
public void SetHintCommonBuild(MapData map,PlayerData player,List<HintData> hintDataList)
|
||
{
|
||
foreach (var city in map.CityMap.CityList)
|
||
if (map.GetPlayerIdByCityId(city.Id, out var cityPlayerId) && cityPlayerId == player.Id)
|
||
{
|
||
var gidSet = new HashSet<uint>();
|
||
city.Territory.GetAllTerritoryArea(gidSet);
|
||
foreach (var gid in gidSet)
|
||
{
|
||
if (!map.GridMap.GetGridDataByGid(gid, out var grid)) continue;
|
||
HintType hintType = HintType.None;
|
||
if (grid.Resource == ResourceType.Fruit) hintType = HintType.CommonFruit;
|
||
if (grid.Resource == ResourceType.Animal) hintType = HintType.CommonAnimal;
|
||
if (grid.Resource == ResourceType.Fish) hintType = HintType.CommonFish;
|
||
if (grid.Resource == ResourceType.Metal) hintType = HintType.CommonMetal;
|
||
if (grid.Resource == ResourceType.Crop) hintType = HintType.CommonCrop;
|
||
if (hintType != HintType.None)
|
||
{
|
||
var hint = new HintData(HintDataIdGenerator(),gid,hintType);
|
||
hintDataList.Add(hint);
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
// 处理 我方unit血量 <= 40% 的提示情况,全部加入hintDataList
|
||
public void SetHintCommonRecover(MapData map,PlayerData player,List<HintData> hintDataList)
|
||
{
|
||
foreach (var unit in map.UnitMap.UnitList)
|
||
if (unit.Health <= unit.GetMaxHealth() * 0.5 && map.CheckUnitIdBelongPlayerId(unit.Id, player.Id))
|
||
{
|
||
if (!map.GetGridIdByUnitId(unit.Id, out var gid)) continue;
|
||
var hint = new HintData(HintDataIdGenerator(),gid,HintType.CommonRecover);
|
||
hintDataList.Add(hint);
|
||
}
|
||
|
||
}
|
||
|
||
public void TurnEndSetHint(MapData mapData, PlayerData playerData)
|
||
{
|
||
//先清理上个回合的Hint
|
||
ClearAll();
|
||
}
|
||
|
||
public void TurnStartSetHint(MapData mapData, PlayerData playerData)
|
||
{
|
||
|
||
|
||
|
||
//目前方案就是先扫出所有的提示选项,然后随机两个进行播放
|
||
/*目前的情况有4种:
|
||
1. unit在遗迹/村庄上,可以直接占领;
|
||
2. 城市为空且能生产兵;
|
||
3. 我方unit血量 <= 40%
|
||
4. 城市领土存在fruit / fish / animal / farm / mine
|
||
5. 城市5格附近视野内存在村庄或者遗迹
|
||
*/
|
||
var HintDataList = new List<HintData>();
|
||
SetHintCommonBuild(mapData,playerData,HintDataList);
|
||
SetHintCommonCaptureExamineTrainUnit(mapData,playerData,HintDataList);
|
||
SetHintCommonRecover(mapData,playerData,HintDataList);
|
||
|
||
int choose = 2;
|
||
if (Random.Range(0, 100) < 90)
|
||
{
|
||
choose = 1;
|
||
if(Random.Range(0, 90) < 50)
|
||
choose = 0;
|
||
}
|
||
|
||
if (HintDataList.Count < choose) choose = HintDataList.Count;
|
||
while (choose > 0)
|
||
{
|
||
choose--;
|
||
var choosen = Random.Range(0, HintDataList.Count);
|
||
AddHint(HintDataList[choosen]);
|
||
}
|
||
}
|
||
|
||
public void UpdateAfterPlayerAction()
|
||
{
|
||
|
||
}
|
||
|
||
//public bool GetHint(uint id, out HintData data) => _idToHintDict.TryGetValue(id, out data);
|
||
|
||
public HashSet<HintData> GetAllHints() => HintSet;
|
||
|
||
|
||
}
|
||
} |