2024-05-19 12:29:32 +00:00
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using ColdMint.scripts.levelGraphEditor;
|
|
|
|
|
using ColdMint.scripts.map.dateBean;
|
|
|
|
|
using ColdMint.scripts.map.interfaces;
|
2024-05-20 14:38:41 +00:00
|
|
|
|
using ColdMint.scripts.map.room;
|
2024-05-19 12:29:32 +00:00
|
|
|
|
using Godot;
|
|
|
|
|
|
|
|
|
|
namespace ColdMint.scripts.map.RoomPlacer;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <para>Patchwork room placement strategy</para>
|
|
|
|
|
/// <para>拼接的房间放置策略</para>
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <remarks>
|
|
|
|
|
///<para>Under this strategy, think of each room template as a puzzle piece, find their "slots", and then connect them together.</para>
|
|
|
|
|
///<para>在此策略下,将每个房间模板看作是一块拼图,找到他们的“槽”,然后将其连接在一起。</para>
|
|
|
|
|
/// </remarks>
|
|
|
|
|
public class PatchworkRoomPlacementStrategy : IRoomPlacementStrategy
|
|
|
|
|
{
|
2024-05-20 14:38:41 +00:00
|
|
|
|
private readonly Vector2 _halfCell = new Vector2(Config.CellSize / 2f, Config.CellSize / 2f);
|
|
|
|
|
|
|
|
|
|
public Task<bool> PlaceRoom(Node mapRoot, RoomPlacementData roomPlacementData)
|
2024-05-19 12:29:32 +00:00
|
|
|
|
{
|
2024-05-20 14:38:41 +00:00
|
|
|
|
if (roomPlacementData.Room == null || roomPlacementData.Position == null)
|
|
|
|
|
{
|
|
|
|
|
return Task.FromResult(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (roomPlacementData.Room.RootNode == null)
|
|
|
|
|
{
|
|
|
|
|
return Task.FromResult(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var rootNode = roomPlacementData.Room.RootNode;
|
2024-05-21 14:50:33 +00:00
|
|
|
|
mapRoot.AddChild(rootNode);
|
2024-05-20 14:38:41 +00:00
|
|
|
|
rootNode.Position = roomPlacementData.Position.Value;
|
|
|
|
|
return Task.FromResult(true);
|
2024-05-19 12:29:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-05-21 14:50:33 +00:00
|
|
|
|
public Task<RoomPlacementData?> CalculateNewRoomPlacementData(RandomNumberGenerator randomNumberGenerator,
|
|
|
|
|
Room? parentRoomNode,
|
|
|
|
|
RoomNodeData newRoomNodeData)
|
2024-05-19 12:29:32 +00:00
|
|
|
|
{
|
2024-05-20 14:38:41 +00:00
|
|
|
|
if (newRoomNodeData.RoomTemplateSet == null || newRoomNodeData.RoomTemplateSet.Length == 0)
|
|
|
|
|
{
|
|
|
|
|
return Task.FromResult<RoomPlacementData?>(null);
|
|
|
|
|
}
|
2024-05-19 12:29:32 +00:00
|
|
|
|
|
2024-05-20 14:38:41 +00:00
|
|
|
|
if (parentRoomNode == null)
|
|
|
|
|
{
|
2024-05-21 14:50:33 +00:00
|
|
|
|
return Task.FromResult<RoomPlacementData?>(null);
|
2024-05-20 14:38:41 +00:00
|
|
|
|
}
|
2024-05-21 14:50:33 +00:00
|
|
|
|
// var roomResArray = RoomFactory.RoomTemplateSetToRoomRes(newRoomNodeData.RoomTemplateSet);
|
|
|
|
|
//TODO:在这里实现房间的放置策略。
|
|
|
|
|
return Task.FromResult<RoomPlacementData?>(null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Task<RoomPlacementData?> CalculatePlacementDataForStartingRoom(RandomNumberGenerator randomNumberGenerator,
|
|
|
|
|
RoomNodeData startRoomNodeData)
|
|
|
|
|
{
|
|
|
|
|
if (startRoomNodeData.RoomTemplateSet == null || startRoomNodeData.RoomTemplateSet.Length == 0)
|
2024-05-20 14:38:41 +00:00
|
|
|
|
{
|
|
|
|
|
return Task.FromResult<RoomPlacementData?>(null);
|
|
|
|
|
}
|
2024-05-21 14:50:33 +00:00
|
|
|
|
|
|
|
|
|
var roomResArray = RoomFactory.RoomTemplateSetToRoomRes(startRoomNodeData.RoomTemplateSet);
|
|
|
|
|
if (roomResArray.Length == 0)
|
|
|
|
|
{
|
|
|
|
|
return Task.FromResult<RoomPlacementData?>(null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var index = randomNumberGenerator.Randi() % roomResArray.Length;
|
|
|
|
|
var roomPlacementData = new RoomPlacementData
|
|
|
|
|
{
|
|
|
|
|
Room = RoomFactory.CreateRoom(roomResArray[index]),
|
|
|
|
|
Position = Vector2.Zero
|
|
|
|
|
};
|
|
|
|
|
return Task.FromResult<RoomPlacementData?>(roomPlacementData);
|
2024-05-20 14:38:41 +00:00
|
|
|
|
}
|
2024-05-19 12:29:32 +00:00
|
|
|
|
|
2024-05-21 14:50:33 +00:00
|
|
|
|
|
2024-05-20 14:38:41 +00:00
|
|
|
|
private Task<Vector2?> CalculatedPosition(Room mainRoom, Room newRoom, RoomSlot? mainRoomSlot,
|
2024-05-21 14:50:33 +00:00
|
|
|
|
RoomSlot? newRoomSlot, bool roomSlotOverlap)
|
2024-05-19 12:29:32 +00:00
|
|
|
|
{
|
2024-05-20 14:38:41 +00:00
|
|
|
|
if (mainRoom.RootNode == null || mainRoom.TileMap == null || newRoom.TileMap == null || mainRoomSlot == null ||
|
|
|
|
|
newRoomSlot == null)
|
|
|
|
|
{
|
|
|
|
|
return Task.FromResult<Vector2?>(null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//计算主插槽中点在世界中的位置。
|
|
|
|
|
//mainRoom.RootNode.Position意为房间所在的世界位置
|
|
|
|
|
//mainRoom.TileMap.MapToLocal(mainRoomSlot.StartPosition)意为主插槽在房间中的位置
|
|
|
|
|
var result = mainRoom.RootNode.Position + mainRoom.TileMap.MapToLocal(mainRoomSlot.StartPosition);
|
|
|
|
|
if (roomSlotOverlap)
|
|
|
|
|
{
|
|
|
|
|
//执行减法,从槽中点偏移到左上角
|
|
|
|
|
result -= _halfCell;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//执行减法,从槽中点偏移到右下角
|
|
|
|
|
result += _halfCell;
|
|
|
|
|
}
|
|
|
|
|
//我们不能将新房间的原点设置在主房间槽的左上角或右下角,这会导致插槽不对应。
|
|
|
|
|
|
|
|
|
|
//竖直槽,我们需要在同一水平上。
|
|
|
|
|
if (mainRoomSlot.IsHorizontal)
|
|
|
|
|
{
|
|
|
|
|
result += newRoom.TileMap.MapToLocal(new Vector2I(newRoomSlot.EndPosition.X, 0)) - _halfCell;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
result -= newRoom.TileMap.MapToLocal(new Vector2I(0, newRoomSlot.EndPosition.Y)) - _halfCell;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Task.FromResult<Vector2?>(result);
|
2024-05-19 12:29:32 +00:00
|
|
|
|
}
|
|
|
|
|
}
|