2024-04-28 13:55:19 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using ColdMint.scripts.debug;
|
|
|
|
|
using ColdMint.scripts.map.dateBean;
|
|
|
|
|
using ColdMint.scripts.utils;
|
|
|
|
|
using Godot;
|
|
|
|
|
|
|
|
|
|
namespace ColdMint.scripts.map.room;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <para>Room</para>
|
|
|
|
|
/// <para>房间模板</para>
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <remarks>
|
|
|
|
|
///<para>The room template is like a jigsaw puzzle and participates in the map building process.</para>
|
|
|
|
|
///<para>房间模板就像一个拼图,参与到地图的构建过程中。</para>
|
|
|
|
|
/// </remarks>
|
2024-05-20 14:38:41 +00:00
|
|
|
|
public class Room
|
2024-04-28 13:55:19 +00:00
|
|
|
|
{
|
2024-05-08 10:22:04 +00:00
|
|
|
|
private Node2D? _rootNode;
|
|
|
|
|
private RoomSlot?[]? _roomSlots;
|
|
|
|
|
private TileMap? _tileMap;
|
2024-04-28 13:55:19 +00:00
|
|
|
|
|
2024-05-08 10:22:04 +00:00
|
|
|
|
public PackedScene? RoomScene
|
2024-04-28 13:55:19 +00:00
|
|
|
|
{
|
|
|
|
|
get => default;
|
|
|
|
|
set => AnalyzeRoomData(value);
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-08 10:22:04 +00:00
|
|
|
|
public TileMap? TileMap
|
2024-04-28 13:55:19 +00:00
|
|
|
|
{
|
|
|
|
|
get => _tileMap;
|
|
|
|
|
set => _tileMap = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <para>Analyze the data of the room</para>
|
|
|
|
|
/// <para>解析房间的数据</para>
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="packedScene"></param>
|
2024-05-08 10:22:04 +00:00
|
|
|
|
private void AnalyzeRoomData(PackedScene? packedScene)
|
2024-04-28 13:55:19 +00:00
|
|
|
|
{
|
2024-05-08 10:22:04 +00:00
|
|
|
|
var node = packedScene?.Instantiate();
|
2024-04-28 13:55:19 +00:00
|
|
|
|
if (node is not Node2D node2D)
|
|
|
|
|
{
|
|
|
|
|
//房间节点不是Node2D类型,抛出异常
|
|
|
|
|
LogCat.LogError("room_root_node_must_be_node2d");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_rootNode = node2D;
|
|
|
|
|
_tileMap = node2D.GetNode<TileMap>("TileMap");
|
|
|
|
|
_roomSlots = GetRoomSlots(_tileMap, node2D.GetNode<Area2D>("RoomArea"),
|
|
|
|
|
node2D.GetNode<Node2D>("RoomSlotList"));
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-08 10:22:04 +00:00
|
|
|
|
public Node2D? RootNode => _rootNode;
|
2024-04-28 13:55:19 +00:00
|
|
|
|
|
2024-05-08 10:22:04 +00:00
|
|
|
|
public RoomSlot?[]? RoomSlots => _roomSlots;
|
2024-04-28 13:55:19 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <para>GetRoomSlots</para>
|
|
|
|
|
/// <para>在房间内获取所有插槽</para>
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="tileMap"></param>
|
2024-05-08 10:22:04 +00:00
|
|
|
|
/// <param name="roomArea2D"></param>
|
2024-04-28 13:55:19 +00:00
|
|
|
|
/// <param name="slotList"></param>
|
|
|
|
|
/// <returns></returns>
|
2024-05-08 10:22:04 +00:00
|
|
|
|
private RoomSlot?[]? GetRoomSlots(TileMap? tileMap, Area2D roomArea2D, Node2D slotList)
|
2024-04-28 13:55:19 +00:00
|
|
|
|
{
|
2024-05-08 10:22:04 +00:00
|
|
|
|
if (tileMap == null)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-28 13:55:19 +00:00
|
|
|
|
var slotCount = slotList.GetChildCount();
|
|
|
|
|
if (slotCount == 0)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-24 14:58:52 +00:00
|
|
|
|
//We calculate the midpoint of the room
|
|
|
|
|
//我们计算房间的中点
|
2024-04-28 13:55:19 +00:00
|
|
|
|
var roomAreaCollisionShape2D = roomArea2D.GetChild<CollisionShape2D>(0);
|
|
|
|
|
var roomAreaRect2 = roomAreaCollisionShape2D.Shape.GetRect();
|
|
|
|
|
var midpoint = roomAreaCollisionShape2D.Position + roomAreaRect2.Position + roomAreaRect2.Size / 2;
|
|
|
|
|
var roomSlots = new List<RoomSlot>();
|
2024-05-22 14:39:41 +00:00
|
|
|
|
for (var i = 0; i < slotCount; i++)
|
2024-04-28 13:55:19 +00:00
|
|
|
|
{
|
2024-05-24 14:58:52 +00:00
|
|
|
|
//Got the object in the room slot
|
|
|
|
|
//拿到了房间槽对象
|
2024-04-28 13:55:19 +00:00
|
|
|
|
var area2D = slotList.GetChild<Area2D>(i);
|
|
|
|
|
var collisionShape2D = area2D.GetChild<CollisionShape2D>(0);
|
|
|
|
|
var rect2 = collisionShape2D.Shape.GetRect();
|
2024-05-24 14:58:52 +00:00
|
|
|
|
//Round the size of the impactor to the tile size For example, the impactor size 44 is converted to the tile size 44/32=1.375 rounded to 1
|
2024-04-28 13:55:19 +00:00
|
|
|
|
//将碰撞体的尺寸四舍五入到瓦片尺寸例如:碰撞体尺寸44,转为瓦片尺寸为 44/32=1.375 四舍五入为1
|
|
|
|
|
var intSize = new Vector2I((int)Math.Round(rect2.Size.X / Config.CellSize),
|
|
|
|
|
(int)Math.Round(rect2.Size.Y / Config.CellSize));
|
|
|
|
|
if (intSize.X > 1 && intSize.Y > 1)
|
|
|
|
|
{
|
|
|
|
|
LogCat.LogError("width_or_height_of_room_slot_must_be_1");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-24 14:58:52 +00:00
|
|
|
|
//Gets the absolute position of the slot
|
2024-04-28 13:55:19 +00:00
|
|
|
|
//获取槽位的绝对位置
|
|
|
|
|
var startPosition = area2D.Position + collisionShape2D.Position + rect2.Position;
|
|
|
|
|
var endPosition = area2D.Position + collisionShape2D.Position + rect2.Position + rect2.Size;
|
|
|
|
|
var midpointOfRoomSlots = area2D.Position + collisionShape2D.Position + rect2.Position + rect2.Size / 2;
|
2024-05-24 14:58:52 +00:00
|
|
|
|
//Convert to tile map coordinates (midpoint)
|
2024-04-28 13:55:19 +00:00
|
|
|
|
//转为瓦片地图的坐标(中点)
|
|
|
|
|
var tileMapStartPosition = tileMap.LocalToMap(startPosition);
|
|
|
|
|
var tileMapEndPosition = tileMap.LocalToMap(endPosition);
|
2024-05-22 14:39:41 +00:00
|
|
|
|
var roomSlot = new RoomSlot
|
|
|
|
|
{
|
|
|
|
|
EndPosition = tileMapEndPosition,
|
|
|
|
|
StartPosition = tileMapStartPosition,
|
2024-05-24 14:58:52 +00:00
|
|
|
|
//Calculate the orientation of the slot (the midpoint of the room is the origin, the vector pointing to the midpoint of the slot)
|
2024-05-22 14:39:41 +00:00
|
|
|
|
//计算槽位的方向(房间中点为原点,指向槽位中点的向量)
|
|
|
|
|
DistanceToMidpointOfRoom = CoordinateUtils.VectorToOrientationArray(midpoint, midpointOfRoomSlots)
|
|
|
|
|
};
|
2024-04-28 13:55:19 +00:00
|
|
|
|
roomSlots.Add(roomSlot);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return roomSlots.ToArray();
|
|
|
|
|
}
|
|
|
|
|
}
|