268 lines
9.6 KiB
C#
268 lines
9.6 KiB
C#
// BubbleData.cs
|
||
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using Logic.Action;
|
||
using RuntimeData;
|
||
using TH1_Logic.Core;
|
||
using TH1Renderer;
|
||
using UnityEngine;
|
||
using System.Linq;
|
||
using Logic;
|
||
using TH1_Core.Events;
|
||
using TH1_Core.Managers;
|
||
using UnityEngine.Tilemaps;
|
||
using Object = UnityEngine.Object;
|
||
using Random = UnityEngine.Random;
|
||
|
||
namespace TH1_Renderer
|
||
{
|
||
|
||
public enum BubbleType
|
||
{
|
||
None,
|
||
Gather,
|
||
Capture,
|
||
HeroUpgrade,
|
||
Upgrade,
|
||
Examine
|
||
}
|
||
|
||
//TODO 做BubbleData序列化相关的工作
|
||
[Serializable]
|
||
public struct BubbleData
|
||
{
|
||
public GridData Grid;
|
||
|
||
public UnitData Unit;
|
||
//public HintType HintType;
|
||
public BubbleType BubbleType;
|
||
|
||
public BubbleData(GridData grid , BubbleType bubbleType)
|
||
{
|
||
Grid = grid;
|
||
grid.MainSelfPlayerVisibleUnit(out Unit);
|
||
BubbleType = bubbleType;
|
||
}
|
||
}
|
||
|
||
[Serializable]
|
||
public class InGameBubbleManager
|
||
{
|
||
//public HashSet<BubbleData> HintSet = new();
|
||
//private Dictionary<uint, BubbleData> _idToHintDict = new();
|
||
private uint _bubbleRendererIdCounter;
|
||
private GameObject _prefabROHint;
|
||
|
||
private Transform _selfTransform;
|
||
//private Dictionary<uint,BubbleRenderer> _ROHintRendererDict = new();
|
||
//存储可用的bubbleRendererId
|
||
private HashSet<uint> _availableRenderer;
|
||
private Dictionary<uint, BubbleRenderer> _dict;
|
||
//gid -> rendererid
|
||
private Dictionary<uint,uint> _gridHasBubble;
|
||
|
||
//每次开启一局游戏前,都要初始化的模块
|
||
public void Init(Transform selfTransform)
|
||
{
|
||
_bubbleRendererIdCounter = 0;
|
||
_prefabROHint = Resources.Load<GameObject>("Prefab/bubblePrefab");
|
||
_selfTransform = selfTransform;
|
||
_availableRenderer = new HashSet<uint>();
|
||
_dict = new Dictionary<uint, BubbleRenderer>();
|
||
_gridHasBubble = new Dictionary<uint,uint>();
|
||
}
|
||
|
||
//每局游戏开始前都要更新的
|
||
public void OnGameStart()
|
||
{
|
||
_bubbleRendererIdCounter = 0;
|
||
_availableRenderer = new HashSet<uint>();
|
||
_dict = new Dictionary<uint, BubbleRenderer>();
|
||
_gridHasBubble = new Dictionary<uint,uint>();
|
||
|
||
foreach (Transform child in _selfTransform.transform)
|
||
{
|
||
// 对每个子对象调用Destroy
|
||
Object.Destroy(child.gameObject);
|
||
}
|
||
}
|
||
|
||
public void OnGameClosed()
|
||
{
|
||
CloseAllBubble();
|
||
ClearAllRenderer();
|
||
}
|
||
|
||
public void ClearAllRenderer()
|
||
{
|
||
foreach (var t in _dict)
|
||
t.Value.Destroy();
|
||
_dict.Clear();
|
||
}
|
||
|
||
public uint BubbleDataIdGenerator()
|
||
{
|
||
return _bubbleRendererIdCounter++;
|
||
}
|
||
|
||
//每帧调用所有hintRenderer的update,并且将已经结束的Renderer回收
|
||
public void Update()
|
||
{
|
||
if (Main.MapData == null) return;
|
||
if (!Main.MapData.CurPlayer?.IsSelfPlayer() ?? true) return;
|
||
|
||
//遍历所有unit,查看哪些单位需要更新bubble显示
|
||
foreach (var unit in Main.MapData.UnitMap.UnitList)
|
||
{
|
||
//如果不是本机玩家
|
||
if (!unit.Player(Main.MapData, out var player)||!player.IsSelfPlayer()) continue;
|
||
|
||
if(!unit.Grid(Main.MapData,out var grid)) continue;
|
||
|
||
//准备升级行为的参数
|
||
var upgradeAction = ActionLogicFactory.GetActionLogic(new CommonActionId()
|
||
{ ActionType = CommonActionType.UnitAction, UnitActionType = UnitActionType.Upgrade });
|
||
var heroUpgradeAction = ActionLogicFactory.GetActionLogic(new CommonActionId()
|
||
{ ActionType = CommonActionType.UnitAction, UnitActionType = UnitActionType.HeroUpgrade });
|
||
var captureAction = ActionLogicFactory.GetActionLogic(new CommonActionId()
|
||
{ ActionType = CommonActionType.UnitAction, UnitActionType = UnitActionType.Capture });
|
||
var starfishAction = ActionLogicFactory.GetActionLogic(new CommonActionId()
|
||
{ ActionType = CommonActionType.UnitAction, UnitActionType = UnitActionType.Gather });
|
||
var treasureAction = ActionLogicFactory.GetActionLogic(new CommonActionId()
|
||
{ ActionType = CommonActionType.UnitAction, UnitActionType = UnitActionType.Examine });
|
||
var actionParam = new CommonActionParams(mapData: Main.MapData,
|
||
playerData: Main.MapData.PlayerMap.SelfPlayerData, unitData: unit,
|
||
gridData: unit.Grid(Main.MapData));
|
||
//先判断是否已经有按钮,如果有
|
||
|
||
|
||
bool upgrade = upgradeAction.CheckCan(actionParam);
|
||
bool heroUpgrade = heroUpgradeAction.CheckCan(actionParam);
|
||
bool capture = captureAction.CheckCan(actionParam);
|
||
bool treasure = treasureAction.CheckCan(actionParam);
|
||
bool starfish = starfishAction.CheckCan(actionParam);
|
||
bool showBubble = upgrade || heroUpgrade || capture || treasure || starfish;
|
||
BubbleType bubbleType = BubbleType.Upgrade;
|
||
if(heroUpgrade)bubbleType = BubbleType.HeroUpgrade;
|
||
if(capture)bubbleType = BubbleType.Capture;
|
||
if(treasure)bubbleType = BubbleType.Examine;
|
||
if(starfish)bubbleType = BubbleType.Gather;
|
||
|
||
//判断是否能执行升级行为,可以的话,播放bubble
|
||
if (showBubble)
|
||
{
|
||
if (_gridHasBubble.ContainsKey(grid.Id)) continue;
|
||
if(ShowBubble(new BubbleData(grid,bubbleType),out var rendererId))
|
||
_gridHasBubble.Add(grid.Id,rendererId);
|
||
}
|
||
//如果不应该播放bubble但是有个bubble,关掉他
|
||
if(!showBubble)
|
||
{
|
||
if (_gridHasBubble.ContainsKey(grid.Id))
|
||
{
|
||
if (_dict.TryGetValue(_gridHasBubble[grid.Id], out var renderer))
|
||
renderer.ForceClose();
|
||
RecycleBubble(_gridHasBubble[grid.Id],grid.Id);
|
||
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
|
||
|
||
|
||
//遍历现在所有存在bubble的格子,如果格子上没有unit,让这个bubble自动关闭
|
||
var deleteList = new List<uint>();
|
||
foreach (var t in _gridHasBubble)
|
||
{
|
||
if (!Main.MapData.GridMap.GetGridDataByGid(t.Key, out var grid)) continue;
|
||
if (!grid.MainSelfPlayerVisibleUnit( out var _))
|
||
{
|
||
if (_dict.TryGetValue(t.Value, out var renderer))
|
||
renderer.ForceClose();
|
||
deleteList.Add(t.Key);
|
||
}
|
||
|
||
}
|
||
//回收这些bubble
|
||
foreach (var t in deleteList)
|
||
if(_gridHasBubble.TryGetValue(t,out var v))
|
||
RecycleBubble(v,t);
|
||
|
||
}
|
||
|
||
public bool ShowBubble(BubbleData data,out uint rendererId)
|
||
{
|
||
|
||
//Step #1 获取一个可用的renderer
|
||
var id = GetAvailableRenderer();
|
||
_availableRenderer.Remove(id);
|
||
if (!_dict.TryGetValue(id, out var renderer))
|
||
{
|
||
Debug.Log($"Fatal error Showbubble can't find dict key id = {id}");
|
||
rendererId = 0;
|
||
return false;
|
||
}
|
||
|
||
rendererId = renderer.Id;
|
||
//Step #2 设置对应的renderer
|
||
return renderer.SetInfo(data,onClick:ClickBubble);
|
||
}
|
||
|
||
public uint GetAvailableRenderer()
|
||
{
|
||
|
||
//如果池子里没有可用对象,新创建一个
|
||
if (_availableRenderer.Count == 0)
|
||
{
|
||
var renderer = new BubbleRenderer(BubbleDataIdGenerator(),_prefabROHint,_selfTransform);
|
||
_availableRenderer.Add(renderer.Id);
|
||
_dict[renderer.Id] = renderer;
|
||
return renderer.Id;
|
||
}
|
||
//否则随便给一个可以用的
|
||
return _availableRenderer.First();
|
||
}
|
||
|
||
public void CloseAllBubble()
|
||
{
|
||
//遍历所有renderer,查询是否有不在available set里的,有的话就强制关闭
|
||
foreach (var t in _dict)
|
||
if (!_availableRenderer.Contains(t.Key))
|
||
{
|
||
t.Value.ForceClose();
|
||
_availableRenderer.Add(t.Key);
|
||
}
|
||
_gridHasBubble.Clear();
|
||
}
|
||
|
||
//被动由逻辑触发
|
||
public void RecycleBubble(uint rendererId,uint gid)
|
||
{
|
||
_availableRenderer.Add(rendererId);
|
||
_gridHasBubble.Remove(gid);
|
||
|
||
|
||
}
|
||
|
||
|
||
//由玩家主动触发
|
||
public void ClickBubble(uint rendererId,uint gid)
|
||
{
|
||
RecycleBubble(rendererId,gid);
|
||
//UI收回
|
||
Main.Instance.MapInteractionLogic.CancelAllHighlight();
|
||
EventManager.Publish(new HideAllUIInfo(){});
|
||
|
||
}
|
||
|
||
public void TurnStartSetBubble(MapData mapData, PlayerData playerData)
|
||
{
|
||
|
||
|
||
}
|
||
|
||
}
|
||
} |