Merge branch '地图编辑器' of https://gitee.com/xlljc/DungeonShooting into 地图编辑器

# Conflicts:
#	DungeonShooting_Godot/resource/map/tileMaps/Test1/reward/Award1/Preview.png.import
This commit is contained in:
王晗智 2024-01-24 18:32:47 +08:00
commit 0d765f2cbc
21 changed files with 246 additions and 118 deletions

View File

@ -24,7 +24,12 @@
"Path": "resource/map/tileMaps/Test1/outlet/End1"
}
],
"BossList": [],
"BossList": [
{
"ErrorType": 0,
"Path": "resource/map/tileMaps/Test1/boss/Boss1"
}
],
"RewardList": [
{
"ErrorType": 0,

View File

@ -0,0 +1 @@
[{"Name":"Preinstall1","Weight":100,"Remark":"","AutoFill":true,"WaveList":[[]]}]

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dp0vxdpgngsj8"
path="res://.godot/imported/Preview.png-46acff5fa2872af249169769a17dd53e.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://resource/map/tileMaps/Test1/boss/Boss1/Preview.png"
dest_files=["res://.godot/imported/Preview.png-46acff5fa2872af249169769a17dd53e.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

View File

@ -0,0 +1 @@
{"Position":{"X":-7,"Y":-13},"Size":{"X":24,"Y":20},"DoorAreaInfos":[],"GroupName":"Test1","RoomType":3,"RoomName":"Boss1","Weight":100,"Remark":""}

File diff suppressed because one or more lines are too long

View File

@ -2,7 +2,11 @@
importer="texture"
type="CompressedTexture2D"
<<<<<<< HEAD
uid="uid://wew7xnxc4d50"
=======
uid="uid://c08d7xo84ssqp"
>>>>>>> faff39f870b1097c233b529865b4f3ee2311c8a3
path="res://.godot/imported/Preview.png-e48e389971aff40736b911be53ae62ea.ctex"
metadata={
"vram_texture": false

View File

@ -11,21 +11,45 @@ public class DungeonConfig
/// </summary>
public string GroupName;
/// <summary>
/// 战斗房间数量
/// </summary>
public int BattleRoomCount = 15;
/// <summary>
/// 奖励房间数量
/// </summary>
public int RewardRoomCount = 2;
/// <summary>
/// 商店数量
/// </summary>
public int ShopRoomCount = 1;
/// <summary>
/// 出口房间数量
/// </summary>
public int OutRoomCount = 1;
/// <summary>
/// Boss房间数量
/// </summary>
public int BossRoomCount = 1;
/// <summary>
/// 房间数量
/// </summary>
public int RoomCount = 15;
public int RoomCount => BattleRoomCount + RewardRoomCount + ShopRoomCount + OutRoomCount + BossRoomCount;
//----------------------- 地牢编辑使用 -------------------------
/// <summary>
/// 是否指定了房间
/// </summary>
public bool HasDesignatedRoom => DesignatedRoom != null && DesignatedRoom.Count > 0;
/// <summary>
/// 指定房间类型
/// </summary>
public DungeonRoomType DesignatedType;
/// <summary>
/// 指定房间列表
/// </summary>

View File

@ -18,27 +18,49 @@ public class DungeonGenerator
/// 起始房间
/// </summary>
public RoomInfo StartRoomInfo { get; private set; }
/// <summary>
/// 战斗房间
/// </summary>
public List<RoomInfo> BattleRoomInfos { get; } = new List<RoomInfo>();
/// <summary>
/// 结束房间
/// </summary>
public RoomInfo EndRoomInfo { get; private set; }
public List<RoomInfo> EndRoomInfos { get; } = new List<RoomInfo>();
/// <summary>
/// boss房间
/// </summary>
public List<RoomInfo> BossRoom { get; } = new List<RoomInfo>();
public List<RoomInfo> BossRoomInfos { get; } = new List<RoomInfo>();
/// <summary>
/// 奖励房间
/// </summary>
public List<RoomInfo> RewardRoomInfos { get; } = new List<RoomInfo>();
/// <summary>
/// 商店房间
/// </summary>
public List<RoomInfo> ShopRoomInfos { get; } = new List<RoomInfo>();
/// <summary>
/// 地牢配置数据
/// </summary>
public DungeonConfig Config { get; }
/// <summary>
/// 所属地牢组
/// </summary>
public DungeonRoomGroup RoomGroup { get; }
/// <summary>
/// 随机数对象
/// </summary>
private SeedRandom _random;
public SeedRandom Random;
//用于标记地图上的坐标是否被占用
private InfiniteGrid<bool> _roomGrid { get; } = new InfiniteGrid<bool>();
//当前房间数量
private int _count = 0;
//房间id
private int _id;
@ -73,9 +95,8 @@ public class DungeonGenerator
private int _maxTryCount = 10;
private int _currMaxLayer = 0;
//地牢配置
private DungeonConfig _config;
private DungeonRoomGroup _roomGroup;
//地牢房间规则处理类
private DungeonRule _rule;
private enum GenerateRoomErrorCode
{
@ -92,9 +113,9 @@ public class DungeonGenerator
public DungeonGenerator(DungeonConfig config, SeedRandom seedRandom)
{
_config = config;
_random = seedRandom;
_roomGroup = GameApplication.Instance.RoomConfig[config.GroupName];
Config = config;
Random = seedRandom;
RoomGroup = GameApplication.Instance.RoomConfig[config.GroupName];
//验证该组是否满足生成地牢的条件
var result = DungeonManager.CheckDungeon(config.GroupName);
@ -103,8 +124,8 @@ public class DungeonGenerator
throw new Exception("当前组'" + config.GroupName + "'" + result.ErrorMessage + ", 不能生成地牢!");
}
Debug.Log("创建地牢生成器, 随机种子: " + _random.Seed);
_roomGroup.InitWeight(_random);
Debug.Log("创建地牢生成器, 随机种子: " + Random.Seed);
RoomGroup.InitWeight(Random);
}
/// <summary>
@ -154,11 +175,12 @@ public class DungeonGenerator
/// <summary>
/// 生成房间
/// </summary>
public bool Generate()
public bool Generate(DungeonRule rule)
{
if (StartRoomInfo != null) return false;
_rule = rule;
CalcNextRoomType(null);
_nextRoomType = _rule.GetNextRoomType(null);
//用于排除上一级房间
var excludePrevRoom = new List<RoomInfo>();
//上一个房间
@ -174,9 +196,9 @@ public class DungeonGenerator
var currTryCount = 0;
//如果房间数量不够, 就一直生成
while (_count < _config.RoomCount || EndRoomInfo == null)
while (!_rule.CanOverGenerator() || EndRoomInfos.Count == 0)
{
var nextRoomType = GetNextRoomType();
var nextRoomType = _nextRoomType;
//上一个房间
RoomInfo tempPrevRoomInfo;
@ -188,11 +210,7 @@ public class DungeonGenerator
{
tempPrevRoomInfo = FindMaxLayerRoom(excludePrevRoom);
}
else if (nextRoomType == DungeonRoomType.Outlet)
{
tempPrevRoomInfo = prevRoomInfo;
}
else if (nextRoomType == DungeonRoomType.Reward)
else if (nextRoomType == DungeonRoomType.Outlet || nextRoomType == DungeonRoomType.Reward || nextRoomType == DungeonRoomType.Shop || nextRoomType == DungeonRoomType.Event)
{
tempPrevRoomInfo = prevRoomInfo;
}
@ -211,12 +229,12 @@ public class DungeonGenerator
}
else
{
tempPrevRoomInfo = _random.RandomChoose(RoomInfos);
tempPrevRoomInfo = Random.RandomChoose(RoomInfos);
}
}
else
{
tempPrevRoomInfo = _random.RandomChoose(RoomInfos);
tempPrevRoomInfo = Random.RandomChoose(RoomInfos);
}
//生成下一个房间
@ -231,20 +249,29 @@ public class DungeonGenerator
}
else if (nextRoomType == DungeonRoomType.Boss) //boss房间
{
BossRoom.Add(nextRoom);
BossRoomInfos.Add(nextRoom);
excludePrevRoom.Clear();
}
else if (nextRoomType == DungeonRoomType.Outlet)
{
EndRoomInfo = nextRoom;
EndRoomInfos.Add(nextRoom);
}
else if (nextRoomType == DungeonRoomType.Battle)
{
BattleRoomInfos.Add(nextRoom);
chainTryCount = 0;
chainMaxTryCount = _random.RandomRangeInt(1, 3);
chainMaxTryCount = Random.RandomRangeInt(1, 3);
}
else if (nextRoomType == DungeonRoomType.Reward)
{
RewardRoomInfos.Add(nextRoom);
}
else if (nextRoomType == DungeonRoomType.Shop)
{
ShopRoomInfos.Add(nextRoom);
}
prevRoomInfo = nextRoom;
CalcNextRoomType(prevRoomInfo);
_nextRoomType = _rule.GetNextRoomType(prevRoomInfo);
}
else //生成失败
{
@ -264,9 +291,9 @@ public class DungeonGenerator
if (prevRoomInfo != null)
{
var bossPrev = prevRoomInfo.Prev;
BossRoom.Remove(prevRoomInfo);
BossRoomInfos.Remove(prevRoomInfo);
RollbackRoom(prevRoomInfo);
CalcNextRoomType(bossPrev);
_nextRoomType = _rule.GetNextRoomType(bossPrev);
prevRoomInfo = null;
}
}
@ -313,21 +340,21 @@ public class DungeonGenerator
// }
DungeonRoomSplit roomSplit;
if (_config.HasDesignatedRoom && _config.DesignatedType == roomType) //执行指定了房间
if (Config.HasDesignatedRoom && Config.DesignatedType == roomType) //执行指定了房间
{
roomSplit = _random.RandomChoose(_config.DesignatedRoom);
roomSplit = Random.RandomChoose(Config.DesignatedRoom);
}
else //没有指定房间
{
//随机选择一个房间
var list = _roomGroup.GetRoomList(roomType);
var list = RoomGroup.GetRoomList(roomType);
if (list.Count == 0) //如果没有指定类型的房间, 就生成战斗房间
{
roomSplit = _roomGroup.GetRandomRoom(DungeonRoomType.Battle);
roomSplit = RoomGroup.GetRandomRoom(DungeonRoomType.Battle);
}
else
{
roomSplit = _roomGroup.GetRandomRoom(roomType);
roomSplit = RoomGroup.GetRandomRoom(roomType);
}
}
@ -357,9 +384,9 @@ public class DungeonGenerator
for (; tryCount < maxTryCount; tryCount++)
{
//下一个房间方向
var direction = _random.RandomRangeInt(0, 3);
var direction = Random.RandomRangeInt(0, 3);
//房间间隔
var space = _random.RandomRangeInt(_roomMinInterval, _roomMaxInterval);
var space = Random.RandomRangeInt(_roomMinInterval, _roomMaxInterval);
if (direction == 0 || direction == 2)
{
space += 1;
@ -368,12 +395,12 @@ public class DungeonGenerator
int offset;
if (direction == 0 || direction == 2)
{
offset = _random.RandomRangeInt((int)(prevRoomInfo.Size.X * _roomVerticalMinDispersion),
offset = Random.RandomRangeInt((int)(prevRoomInfo.Size.X * _roomVerticalMinDispersion),
(int)(prevRoomInfo.Size.X * _roomVerticalMaxDispersion));
}
else
{
offset = _random.RandomRangeInt((int)(prevRoomInfo.Size.Y * _roomHorizontalMinDispersion),
offset = Random.RandomRangeInt((int)(prevRoomInfo.Size.Y * _roomHorizontalMinDispersion),
(int)(prevRoomInfo.Size.Y * _roomHorizontalMaxDispersion));
}
@ -445,11 +472,6 @@ public class DungeonGenerator
room.Layer = 0;
_roomGrid.SetRect(room.Position, room.Size, true);
}
if (IsParticipateCounting(room))
{
_count++;
}
_id++;
room.Prev = prevRoomInfo;
@ -461,47 +483,6 @@ public class DungeonGenerator
return GenerateRoomErrorCode.NoError;
}
//判断房间是否参与计数
private bool IsParticipateCounting(RoomInfo roomInfo)
{
return roomInfo.RoomType == DungeonRoomType.Battle || roomInfo.RoomType == DungeonRoomType.Boss || roomInfo.RoomType == DungeonRoomType.Reward;
}
//计算下一个房间类型
private void CalcNextRoomType(RoomInfo prev)
{
if (prev == null) //生成第一个房间
{
_nextRoomType = DungeonRoomType.Inlet;
}
else if (_count == 0) //奖励房间
{
_nextRoomType = DungeonRoomType.Reward;
}
else if (_count == _config.RoomCount - 1) //最后一个房间是boss房间
{
_nextRoomType = DungeonRoomType.Boss;
}
else if (_count >= _config.RoomCount) //结束房间
{
_nextRoomType = DungeonRoomType.Outlet;
}
else if (prev.RoomType == DungeonRoomType.Boss) //生成结束房间
{
_nextRoomType = DungeonRoomType.Outlet;
}
else
{
_nextRoomType = DungeonRoomType.Battle;
}
}
//获取下一个房间类型
private DungeonRoomType GetNextRoomType()
{
return _nextRoomType;
}
//回滚一个房间
private bool RollbackRoom(RoomInfo roomInfo)
{
@ -532,12 +513,6 @@ public class DungeonGenerator
RoomInfos.Remove(roomInfo);
roomInfo.Destroy();
if (IsParticipateCounting(roomInfo))
{
_count--;
}
_id--;
return true;
}
@ -577,7 +552,7 @@ public class DungeonGenerator
}
}
return _random.RandomChoose(list);
return Random.RandomChoose(list);
}
/// <summary>
@ -597,7 +572,7 @@ public class DungeonGenerator
nextRoomDoor.ConnectDoor = roomDoor;
//先寻找直通门
if (_random.RandomBoolean())
if (Random.RandomBoolean())
{
//直行通道, 优先横轴
if (TryConnectHorizontalDoor(roomInfo, roomDoor, nextRoomInfo, nextRoomDoor)
@ -637,8 +612,8 @@ public class DungeonGenerator
while (rangeList.Count > 0)
{
//找到重叠区域
var range = _random.RandomChooseAndRemove(rangeList);
var x = _random.RandomRangeInt(range.X, range.Y) + 2;
var range = Random.RandomChooseAndRemove(rangeList);
var x = Random.RandomRangeInt(range.X, range.Y) + 2;
if (roomInfo.GetVerticalStart() < nextRoomInfo.GetVerticalStart()) //room在上, nextRoom在下
{
@ -689,8 +664,8 @@ public class DungeonGenerator
while (rangeList.Count > 0)
{
//找到重叠区域
var range = _random.RandomChooseAndRemove(rangeList);
var y = _random.RandomRangeInt(range.X, range.Y) + 3;
var range = Random.RandomChooseAndRemove(rangeList);
var y = Random.RandomRangeInt(range.X, range.Y) + 3;
if (roomInfo.GetHorizontalStart() < nextRoomInfo.GetHorizontalStart()) //room在左, nextRoom在右
{
@ -736,7 +711,7 @@ public class DungeonGenerator
{
if (roomInfo.GetVerticalStart() > nextRoomInfo.GetVerticalStart())
{
if (_random.RandomBoolean()) //↑ //→
if (Random.RandomBoolean()) //↑ //→
{
if (!TryConnect_NE_Door(roomInfo, nextRoomInfo, roomDoor, nextRoomDoor, ref cross) &&
!TryConnect_WS_Door(roomInfo, nextRoomInfo, roomDoor, nextRoomDoor, ref cross))
@ -755,7 +730,7 @@ public class DungeonGenerator
}
else
{
if (_random.RandomBoolean()) //↓ //→
if (Random.RandomBoolean()) //↓ //→
{
if (!TryConnect_SE_Door(roomInfo, nextRoomInfo, roomDoor, nextRoomDoor, ref cross) &&
!TryConnect_WN_Door(roomInfo, nextRoomInfo, roomDoor, nextRoomDoor, ref cross))
@ -777,7 +752,7 @@ public class DungeonGenerator
{
if (roomInfo.GetVerticalStart() > nextRoomInfo.GetVerticalStart()) //→ //↓
{
if (_random.RandomBoolean())
if (Random.RandomBoolean())
{
if (!TryConnect_ES_Door(roomInfo, nextRoomInfo, roomDoor, nextRoomDoor, ref cross) &&
!TryConnect_NW_Door(roomInfo, nextRoomInfo, roomDoor, nextRoomDoor, ref cross))
@ -796,7 +771,7 @@ public class DungeonGenerator
}
else
{
if (_random.RandomBoolean()) //→ //↑
if (Random.RandomBoolean()) //→ //↑
{
if (!TryConnect_EN_Door(roomInfo, nextRoomInfo, roomDoor, nextRoomDoor, ref cross) &&
!TryConnect_SW_Door(roomInfo, nextRoomInfo, roomDoor, nextRoomDoor, ref cross))

View File

@ -0,0 +1,29 @@

/// <summary>
/// 用于自定义地牢房间生成规则
/// </summary>
public abstract class DungeonRule
{
public DungeonGenerator Generator { get; }
public DungeonConfig Config { get; }
public SeedRandom Random { get; }
public DungeonRule(DungeonGenerator generator)
{
Generator = generator;
Config = generator.Config;
Random = generator.Random;
}
/// <summary>
/// 是否可以结束生成了
/// </summary>
public abstract bool CanOverGenerator();
/// <summary>
/// 计算下一个房间类型
/// </summary>
public abstract DungeonRoomType GetNextRoomType(RoomInfo prev);
}

View File

@ -106,7 +106,7 @@ public partial class GameApplication : Node2D, ICoroutine
DungeonConfig = new DungeonConfig();
DungeonConfig.GroupName = "Test1";
DungeonConfig.RoomCount = 20;
DungeonConfig.BattleRoomCount = 20;
}
public override void _EnterTree()

View File

@ -3,7 +3,7 @@
/// <summary>
/// 通用Ui网格背景组件, 包含可拖拽的容器根节点
/// </summary>
public abstract partial class EditorGridBg<T> : ColorRect, IUiNodeScript where T : IUiNode
public abstract partial class EditorGridBg : ColorRect, IUiNodeScript
{
/// <summary>
/// 可拖拽容器根节点
@ -16,7 +16,7 @@ public abstract partial class EditorGridBg<T> : ColorRect, IUiNodeScript where T
/// <summary>
/// 当前对象绑定的Ui节点
/// </summary>
public T UiNode { get; private set; }
public IUiNode UiNode { get; private set; }
private ShaderMaterial _gridMaterial;
private bool _dragMoveFlag = false;
@ -40,7 +40,7 @@ public abstract partial class EditorGridBg<T> : ColorRect, IUiNodeScript where T
public virtual void SetUiNode(IUiNode uiNode)
{
UiNode = (T)uiNode;
UiNode = uiNode;
this.AddDragListener(DragButtonEnum.Middle, OnDrag);
Resized += RefreshGridTrans;
//打开Ui时刷新网格

View File

@ -177,6 +177,7 @@ public static class MapProjectManager
preinstallInfo.Name = "Preinstall1";
preinstallInfo.Weight = 100;
preinstallInfo.Remark = "";
preinstallInfo.AutoFill = true;
preinstallInfo.InitWaveList();
preinstallInfo.InitSpecialMark(roomSplit.RoomInfo.RoomType);
roomSplit.Preinstall.Add(preinstallInfo);

View File

@ -0,0 +1,40 @@

/// <summary>
/// 默认实现地牢房间规则
/// </summary>
public class DefaultDungeonRule : DungeonRule
{
public DefaultDungeonRule(DungeonGenerator generator) : base(generator)
{
}
public override bool CanOverGenerator()
{
return Generator.BattleRoomInfos.Count >= Config.BattleRoomCount;
}
public override DungeonRoomType GetNextRoomType(RoomInfo prev)
{
if (Generator.StartRoomInfo == null) //生成第一个房间
{
return DungeonRoomType.Inlet;
}
// else if (Generator.BattleRoomInfos.Count == 0) //奖励房间
// {
// return DungeonRoomType.Reward;
// }
else if (Generator.BattleRoomInfos.Count == Config.BattleRoomCount - 1) //最后一个房间是boss房间
{
return DungeonRoomType.Boss;
}
else if (Generator.BattleRoomInfos.Count >= Config.BattleRoomCount) //结束房间
{
return DungeonRoomType.Outlet;
}
else if (prev.RoomType == DungeonRoomType.Boss) //生成结束房间
{
return DungeonRoomType.Outlet;
}
return DungeonRoomType.Battle;
}
}

View File

@ -198,7 +198,8 @@ public partial class DungeonManager : Node2D
//生成地牢房间
var random = new SeedRandom();
_dungeonGenerator = new DungeonGenerator(CurrConfig, random);
if (!_dungeonGenerator.Generate()) //生成房间失败
var rule = new DefaultDungeonRule(_dungeonGenerator);
if (!_dungeonGenerator.Generate(rule)) //生成房间失败
{
_dungeonGenerator.EachRoom(DisposeRoomInfo);
_dungeonGenerator = null;
@ -218,7 +219,7 @@ public partial class DungeonManager : Node2D
{
UiManager.Open_Main();
}
EditorWindowManager.ShowTips("错误", "生成房间尝试次数过多,生成地牢房间失败,请加大房间门连接区域");
EditorWindowManager.ShowTips("错误", "生成房间尝试次数过多,生成地牢房间失败,请加大房间门连接区域,或者修改地牢生成规则");
yield break;
}
yield return 0;

View File

@ -2,8 +2,10 @@ using Godot;
namespace UI.EditorTileImage;
public partial class ImageBg : EditorGridBg<EditorTileImage.Bg>
public partial class ImageBg : EditorGridBg
{
public new EditorTileImage.Bg UiNode => (EditorTileImage.Bg)base.UiNode;
public override void SetUiNode(IUiNode uiNode)
{
base.SetUiNode(uiNode);

View File

@ -6,8 +6,10 @@ namespace UI.MapEditorMapTile;
/// <summary>
/// 自由笔刷页签
/// </summary>
public partial class FreeTileTab : EditorGridBg<MapEditorMapTile.Tab1>
public partial class FreeTileTab : EditorGridBg
{
public new MapEditorMapTile.Tab1 UiNode => (MapEditorMapTile.Tab1)base.UiNode;
private ImageTexture _texture;
private Sprite2D _sprite;
private Control _brush;

View File

@ -3,8 +3,10 @@ using Godot;
namespace UI.TileSetEditorCombination;
public partial class TileEditArea : EditorGridBg<TileSetEditorCombination.LeftBottomBg>
public partial class TileEditArea : EditorGridBg
{
public new TileSetEditorCombination.LeftBottomBg UiNode => (TileSetEditorCombination.LeftBottomBg)base.UiNode;
private UiGrid<TileSetEditorCombination.MaskRect, bool> _maskGrid;
private readonly HashSet<Vector2I> _useMask = new HashSet<Vector2I>();

View File

@ -5,8 +5,10 @@ using Godot;
namespace UI.TileSetEditorCombination;
public partial class TileEditCombination : EditorGridBg<TileSetEditorCombination.LeftTopBg>
public partial class TileEditCombination : EditorGridBg
{
public new TileSetEditorCombination.LeftTopBg UiNode => (TileSetEditorCombination.LeftTopBg)base.UiNode;
// ------------------------------- 笔刷相关 -------------------------------
//笔刷数据, kay: 代表原图中的坐标, 单位: 格
private Dictionary<Vector2I, CombinationCell> _brushData = new Dictionary<Vector2I, CombinationCell>();

View File

@ -2,8 +2,10 @@
namespace UI.TileSetEditorTerrain;
public partial class TileEditArea : EditorGridBg<TileSetEditorTerrain.BottomBg>
public partial class TileEditArea : EditorGridBg
{
public new TileSetEditorTerrain.BottomBg UiNode => (TileSetEditorTerrain.BottomBg)base.UiNode;
private bool _dragMoveFlag = false;
private MaskCell _hoverCell = null;

View File

@ -2,8 +2,10 @@
namespace UI.TileSetEditorTerrain;
public partial class TileEditTerrain : EditorGridBg<TileSetEditorTerrain.TopBg>
public partial class TileEditTerrain : EditorGridBg
{
public new TileSetEditorTerrain.TopBg UiNode => (TileSetEditorTerrain.TopBg)base.UiNode;
private bool _dragMoveFlag = false;
private TerrainCell _hoverCell = null;