376 lines
12 KiB
C#
376 lines
12 KiB
C#
using cfg.CampCfg;
|
|
using Framework;
|
|
using Gameplay.Building.Impl;
|
|
using PhxhSDK;
|
|
using System.Collections.Generic;
|
|
using TGS;
|
|
using UnityEngine;
|
|
using UnityEngine.InputSystem;
|
|
using UnityEngine.Rendering;
|
|
|
|
namespace Gameplay.Camp
|
|
{
|
|
public sealed partial class Camp
|
|
{
|
|
/// <summary>
|
|
/// 射线检测点列表
|
|
/// </summary>
|
|
private RaycastHit[] hits;
|
|
/// <summary>
|
|
/// 编辑模式下地板状态
|
|
/// </summary>
|
|
private Dictionary<int, E_CampCellState> dicEditCellState;
|
|
/// <summary>
|
|
/// 修改过的地板颜色集合
|
|
/// </summary>
|
|
private HashSet<Cell> setCellDrag;
|
|
/// <summary>
|
|
/// 当前拖动的建筑单位
|
|
/// </summary>
|
|
private BuildingCampUnit buildingCampUnit;
|
|
/// <summary>
|
|
/// 是否拖动状态
|
|
/// </summary>
|
|
private bool isDrag;
|
|
|
|
/// <summary>
|
|
/// 编辑模式下未保存的营地单位集合
|
|
/// </summary>
|
|
public HashSet<CampUnitBase> SetEditUnit { get; private set; }
|
|
|
|
/// <summary>
|
|
/// 编辑状态
|
|
/// </summary>
|
|
public bool IsEdit { get; private set; }
|
|
|
|
/// <summary>
|
|
/// 是否拖动状态
|
|
/// </summary>
|
|
public bool IsDrag { get; private set; }
|
|
|
|
private void InitEdit()
|
|
{
|
|
hits = new RaycastHit[1];
|
|
dicEditCellState = new Dictionary<int, E_CampCellState>();
|
|
SetEditUnit = new HashSet<CampUnitBase>();
|
|
setCellDrag = new HashSet<Cell>();
|
|
|
|
IsEdit = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 进入编辑模式
|
|
/// </summary>
|
|
public void SetInfoByEdit()
|
|
{
|
|
setCellDrag.Clear();
|
|
|
|
foreach (var kv in dicCellState)
|
|
{
|
|
dicEditCellState[kv.Key] = kv.Value;
|
|
}
|
|
|
|
#region 设置格子颜色
|
|
foreach (Cell cell in GridSystem.cells)
|
|
{
|
|
if (!TryGetCellStateByIndex(cell.index, out E_CampCellState cellState))
|
|
continue;
|
|
|
|
SetCellColorByCellState(cell, cellState);
|
|
}
|
|
#endregion
|
|
|
|
IsShowAllGrid = true;
|
|
|
|
IsEdit = true;
|
|
}
|
|
|
|
public void UpdateEdit()
|
|
{
|
|
if (!IsDrag)
|
|
return;
|
|
|
|
ClearDragCell(); // 还原拖动的格子
|
|
SetDragCell();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 退出编辑模式
|
|
/// </summary>
|
|
public void ExitEdit()
|
|
{
|
|
if (!IsEdit)
|
|
return;
|
|
|
|
IsShowAllGrid = false;
|
|
|
|
dicEditCellState.Clear();
|
|
|
|
foreach (CampUnitBase unit in SetEditUnit)
|
|
{
|
|
unit.Dispose();
|
|
}
|
|
SetEditUnit.Clear();
|
|
|
|
if (null != buildingCampUnit)
|
|
{
|
|
buildingCampUnit.Dispose();
|
|
buildingCampUnit = null;
|
|
}
|
|
|
|
setCellDrag.Clear();
|
|
|
|
IsDrag = false;
|
|
IsEdit = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 进入拖动状态
|
|
/// </summary>
|
|
public async void EnterDrag(DataCampObject dataCampObject)
|
|
{
|
|
if (IsDrag)
|
|
return;
|
|
|
|
GameObject goCampObject = await LoadCampObject(dataCampObject.Path);
|
|
buildingCampUnit = new(goCampObject, dataCampObject);
|
|
|
|
IsDrag = true;
|
|
}
|
|
|
|
public void ExitDrag()
|
|
{
|
|
if (!IsDrag)
|
|
return;
|
|
|
|
IsDrag = false;
|
|
|
|
if (!EditCheckPlace(buildingCampUnit.CellIndex, buildingCampUnit.Cfg.ListPosOffset))
|
|
{
|
|
UITipsManager.ShowTips("该位置不能放置");
|
|
buildingCampUnit.Dispose();
|
|
}
|
|
else
|
|
EditPlaceCampItem();
|
|
|
|
buildingCampUnit = null;
|
|
|
|
ClearDragCell();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 保存单位
|
|
/// </summary>
|
|
public void SaveCampUnit(CampUnitBase campUnitBase)
|
|
{
|
|
if (campUnitBase is not BuildingCampUnit buildingUnit)
|
|
return;
|
|
|
|
if (!SetEditUnit.Remove(campUnitBase))
|
|
return;
|
|
|
|
setUnit.Remove(campUnitBase);
|
|
|
|
EventManager.Instance.Send(EventManager.EventName.Camp_EditRemoveUnit);
|
|
|
|
// TODO 向服务器发送保存数据
|
|
|
|
PlaceCampItem(buildingUnit);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 移除未保存的营地单位
|
|
/// </summary>
|
|
public void RemoveCampUnit(CampUnitBase campUnitBase)
|
|
{
|
|
if (campUnitBase is not BuildingCampUnit buildingUnit)
|
|
return;
|
|
|
|
if (!SetEditUnit.Remove(campUnitBase))
|
|
return;
|
|
|
|
setUnit.Remove(campUnitBase);
|
|
|
|
EventManager.Instance.Send(EventManager.EventName.Camp_EditRemoveUnit);
|
|
|
|
#region 设置编辑模式营地地板状态
|
|
if (!dicCellByIndex.TryGetValue(buildingUnit.CellIndex, out Cell centerCell))
|
|
return;
|
|
|
|
foreach (Vector2 offset in buildingUnit.Cfg.ListPosOffset)
|
|
{
|
|
Vector2Int gridPos = GetCellPosByOffset(new Vector2Int(centerCell.row, centerCell.column), offset); // 计算格子位置
|
|
if (!dicCellByRowCol.TryGetValue(gridPos, out Cell cell))
|
|
continue;
|
|
|
|
dicEditCellState[cell.index] = E_CampCellState.Empty;
|
|
dicCellState[cell.index] = E_CampCellState.Empty;
|
|
|
|
SetCellColorByCellState(cell, E_CampCellState.Empty);
|
|
}
|
|
#endregion
|
|
|
|
campUnitBase.Dispose();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 编辑模式下点击
|
|
/// </summary>
|
|
/// <param name="screenPos"></param>
|
|
public void OnEditClick(Vector2 screenPos)
|
|
{
|
|
int cellIndex = GroundHitHelper.CalcHitCellIndex(screenPos, GridSystem);
|
|
if (!TryGetPlaceUnit(cellIndex, out CampUnitBase campUnit))
|
|
return;
|
|
|
|
if (campUnit is not BuildingCampUnit buildingCampUnit)
|
|
return;
|
|
|
|
// TODO 已放置保存建筑转到未保存状态
|
|
#region 还原营地地板为空状态
|
|
if (!dicCellByIndex.TryGetValue(buildingCampUnit.CellIndex, out Cell centerCell))
|
|
return;
|
|
|
|
foreach (Vector2 offset in buildingCampUnit.Cfg.ListPosOffset)
|
|
{
|
|
Vector2Int gridPos = GetCellPosByOffset(new Vector2Int(centerCell.row, centerCell.column), offset); // 计算格子位置
|
|
if (!dicCellByRowCol.TryGetValue(gridPos, out Cell cell))
|
|
continue;
|
|
|
|
dicCellState[cell.index] = E_CampCellState.Empty;
|
|
dicUnit.Remove(cell.index);
|
|
}
|
|
#endregion
|
|
|
|
SetEditUnit.Add(campUnit);
|
|
EventManager.Instance.Send(EventManager.EventName.Camp_EditPlaceUnit);
|
|
}
|
|
|
|
#region 私有方法
|
|
/// <summary>
|
|
/// 清除拖动的格子
|
|
/// </summary>
|
|
private void ClearDragCell()
|
|
{
|
|
foreach (Cell cell in setCellDrag)
|
|
{
|
|
if (dicEditCellState.TryGetValue(cell.index, out E_CampCellState cellState))
|
|
SetCellColorByCellState(cell, cellState);
|
|
}
|
|
|
|
setCellDrag.Clear();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置拖动建筑影响的格子
|
|
/// </summary>
|
|
private void SetDragCell()
|
|
{
|
|
Vector2 mousePos = Mouse.current.position.ReadValue();
|
|
// 发射射线
|
|
Ray ray = CameraManager.Instance.MainCamera.ScreenPointToRay(mousePos);
|
|
int hitNum = Physics.RaycastNonAlloc(ray.origin, ray.direction, hits);
|
|
if (hitNum <= 0)
|
|
return;
|
|
|
|
RaycastHit firstHit = hits[0];
|
|
Cell centerCell = GridSystem.CellGetAtPosition(firstHit.point, true); // 中心点
|
|
if (null == centerCell)
|
|
{
|
|
buildingCampUnit.CellIndex = -1;
|
|
buildingCampUnit.SetPos(new Vector3(firstHit.point.x, 0f, firstHit.point.z));
|
|
return;
|
|
}
|
|
|
|
foreach (Vector2 offset in buildingCampUnit.Cfg.ListPosOffset)
|
|
{
|
|
Vector2Int newPosInt = GetCellPosByOffset(new Vector2Int(centerCell.row, centerCell.column), offset);
|
|
if (!TryGetCellByRowCol(newPosInt, out Cell cell))
|
|
continue;
|
|
|
|
setCellDrag.Add(cell);
|
|
SetDragStateColor(cell);
|
|
|
|
if (Vector2Int.zero == offset)
|
|
{
|
|
buildingCampUnit.CellIndex = cell.index;
|
|
Vector3 pos = GridSystem.CellGetPosition(cell);
|
|
buildingCampUnit.SetPos(new Vector3(pos.x, 0f, pos.z));
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置拖动状态的颜色
|
|
/// </summary>
|
|
/// <param name="cell"></param>
|
|
private void SetDragStateColor(Cell cell)
|
|
{
|
|
if (!dicEditCellState.TryGetValue(cell.index, out E_CampCellState cellState))
|
|
return;
|
|
|
|
E_CampCellState tempState = cellState switch
|
|
{
|
|
E_CampCellState.Empty => E_CampCellState.Valid,
|
|
E_CampCellState.Occupancy => E_CampCellState.Invalid,
|
|
_ => throw new System.NotImplementedException(),
|
|
};
|
|
SetCellColorByCellState(cell, tempState);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 编辑检查能否放置
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private bool EditCheckPlace(int cellIndex, params Vector2[] offsets)
|
|
{
|
|
if (!TryGetCellByIndex(cellIndex, out Cell centerCell))
|
|
return false;
|
|
|
|
foreach (Vector2 offset in offsets)
|
|
{
|
|
Vector2Int cellPos = GetCellPosByOffset(new Vector2Int(centerCell.row, centerCell.column), offset); // 计算格子位置
|
|
if (!dicCellByRowCol.TryGetValue(cellPos, out Cell cell))
|
|
return false;
|
|
|
|
if (!dicEditCellState.TryGetValue(cell.index, out E_CampCellState cellState))
|
|
return false;
|
|
|
|
if (E_CampCellState.Empty != cellState)
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 编辑下放置营地物件
|
|
/// </summary>
|
|
/// <param name="goCampObject"></param>
|
|
/// <param name="gridIndex"></param>
|
|
private void EditPlaceCampItem()
|
|
{
|
|
#region 设置营地地板状态
|
|
if (!dicCellByIndex.TryGetValue(buildingCampUnit.CellIndex, out Cell centerCell))
|
|
return;
|
|
|
|
foreach (Vector2 offset in buildingCampUnit.Cfg.ListPosOffset)
|
|
{
|
|
Vector2Int gridPos = GetCellPosByOffset(new Vector2Int(centerCell.row, centerCell.column), offset); // 计算格子位置
|
|
if (!dicCellByRowCol.TryGetValue(gridPos, out Cell cell))
|
|
continue;
|
|
|
|
if (dicEditCellState.ContainsKey(cell.index))
|
|
dicEditCellState[cell.index] = E_CampCellState.Occupancy;
|
|
}
|
|
#endregion
|
|
|
|
Vector3 pos = GridSystem.CellGetPosition(centerCell.index);
|
|
buildingCampUnit.SetPos(new Vector3(pos.x, 0f, pos.z)); // 设置建筑物位置
|
|
|
|
SetEditUnit.Add(buildingCampUnit);
|
|
EventManager.Instance.Send(EventManager.EventName.Camp_EditPlaceUnit);
|
|
}
|
|
#endregion
|
|
}
|
|
} |