2025-07-18 02:43:08 +08:00

243 lines
9.2 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.

// 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;
}
}