15 [Icon(ManiaMapResources.Icons.RoomNode2DIcon)]
24 public Error EmitOnCellAreaEntered(
CellArea2D cell, Node collision) => EmitSignal(SignalName.OnCellAreaEntered, cell, collision);
32 public Error EmitOnCellAreaExited(
CellArea2D cell, Node collection) => EmitSignal(SignalName.OnCellAreaExited, cell, collection);
38 public Error EmitOnCellGridChanged() => EmitSignal(SignalName.OnCellGridChanged);
43 private int _rows = 1;
45 [Export(PropertyHint.Range,
"1,10,1,or_greater")]
public int Rows {
get => _rows;
set => SetSizeField(ref _rows, value); }
47 private int _columns = 1;
49 [Export(PropertyHint.Range,
"1,10,1,or_greater")]
public int Columns {
get => _columns;
set => SetSizeField(ref _columns, value); }
51 private Vector2 _cellSize =
new Vector2(96, 96);
55 [Export(PropertyHint.Range,
"0,100,1,or_greater")]
public Vector2
CellSize {
get => _cellSize;
set => SetCellSizeField(ref _cellSize, value); }
58 [Export]
public Godot.Collections.Array<Godot.Collections.Array<
bool>>
ActiveCells {
get;
set; } =
new Godot.Collections.Array<Godot.Collections.Array<
bool>>();
73 private bool MouseButtonPressed {
get;
set; }
74 private Vector2 MouseButtonDownPosition {
get;
set; }
77 private void SetSizeField(ref
int field,
int value)
79 field = Mathf.Max(value, 1);
80 this.SizeActiveCells();
81 EmitOnCellGridChanged();
84 private void SetCellSizeField(ref Vector2 field, Vector2 value)
86 field =
new Vector2(Mathf.Max(value.X, 0.001f), Mathf.Max(value.Y, 0.001f));
87 EmitOnCellGridChanged();
90 public override void _Ready()
95 if (Engine.IsEditorHint())
97 this.SizeActiveCells();
98 Editor.CellGrid2DGizmo.CreateInstance(
this);
107 public override void _ValidateProperty(Godot.Collections.Dictionary property)
109 base._ValidateProperty(property);
110 var name =
property[
"name"].AsStringName();
111 var usage =
property[
"usage"].As<PropertyUsageFlags>();
113 if (name == PropertyName.ActiveCells)
114 property[
"usage"] = (int)(usage & ~PropertyUsageFlags.Editor);
118 public override void _Process(
double delta)
120 base._Process(delta);
122 if (Engine.IsEditorHint())
123 ProcessEditCellInputs();
126 private static bool DisplayCells()
128 return Editor.ManiaMapPlugin.PluginIsValid()
129 && Editor.ManiaMapPlugin.Current.RoomNode2DToolbar.DisplayCells;
134 if (!Editor.ManiaMapPlugin.PluginIsValid())
136 return Editor.ManiaMapPlugin.Current.RoomNode2DToolbar.CellEditMode;
139 private void ProcessEditCellInputs()
144 if (Input.IsMouseButtonPressed(MouseButton.Left) && MouseIsInsideMainScreen())
146 if (!MouseButtonPressed)
147 MouseButtonDownPosition = GetViewport().GetMousePosition();
149 MouseButtonPressed =
true;
153 if (MouseButtonPressed && MouseIsInsideMainScreen())
157 this.SetCellActivities(startIndex, endIndex, CellEditMode());
158 EmitOnCellGridChanged();
161 MouseButtonPressed =
false;
164 private static bool MouseIsInsideMainScreen()
166 var mainScreen = EditorInterface.Singleton.GetEditorMainScreen();
167 var mousePosition = mainScreen.GetViewport().GetMousePosition();
168 var mainScreenRect =
new Rect2(mainScreen.GlobalPosition, mainScreen.Size);
169 return mainScreenRect.Encloses(
new Rect2(mousePosition, Vector2.Zero));
184 var roomLayout = layoutPack.
Layout.Rooms[id];
185 var roomState = layoutPack.
LayoutState.RoomStates[id];
187 return CreateInstance(scene, parent, layoutPack, roomLayout, roomState, collisionMask, assignLayoutPosition);
201 Room roomLayout,
RoomState roomState, uint cellCollisionMask,
bool assignLayoutPosition)
204 room.
Initialize(layoutPack, roomLayout, roomState, cellCollisionMask, assignLayoutPosition);
205 parent.AddChild(room);
222 uint cellCollisionMask,
bool assignLayoutPosition)
231 if (assignLayoutPosition)
247 if (this.CellIndexExists(fastIndex.X, fastIndex.Y) &&
ActiveCells[fastIndex.X][fastIndex.Y])
250 var index = Vector2I.Zero;
251 var minDistance =
float.PositiveInfinity;
257 for (
int j = 0; j < row.Count; j++)
262 var distance = delta.LengthSquared();
264 if (distance < minDistance)
266 minDistance = distance;
267 index =
new Vector2I(i, j);
285 Span<DoorDirection> directions = stackalloc DoorDirection[]
293 Span<Vector2> vectors = stackalloc Vector2[]
302 var maxDistance =
float.NegativeInfinity;
305 for (
int i = 0; i < vectors.Length; i++)
307 var distance = delta.Dot(vectors[i]);
309 if (distance > maxDistance)
311 maxDistance = distance;
316 return directions[index];
329 for (
int j = 0; j < row.Count; j++)
383 var column = Mathf.FloorToInt(position.X /
CellSize.X);
384 var row = Mathf.FloorToInt(position.Y /
CellSize.Y);
386 if (this.CellIndexExists(row, column))
387 return new Vector2I(row, column);
389 return new Vector2I(-1, -1);
Provides area and body entering and exiting detection for a cell.
static CellArea2D CreateInstance(int row, int column, RoomNode2D room, uint collisionMask)
Creates a new instance with child collision shape and adds it as a child of the specified room.
Raised if a room is not initialized when its on ready method is called.
Holds the current Layout and LayoutState.
LayoutState LayoutState
The layout state.
ManiaMapSettings Settings
The settings.
uint CellCollisionMask
The cell collision mask used for detecting objects entering or exiting a CellArea2D....
A node serving as the top level of a 2D room.
Godot.Collections.Array< Godot.Collections.Array< bool > > ActiveCells
void MoveToLayoutPosition()
Moves the room to its position in the Layout.
Vector2I LocalPositionToCellIndex(Vector2 position)
Returns the row (x) and column (y) index corresponding to the specified local position....
static RoomNode2D CreateInstance(Uid id, LayoutPack layoutPack, PackedScene scene, Node parent, bool assignLayoutPosition=false)
Creates and initializes an instance of a room. The layout and layout state are assigned to the room b...
bool Initialize(LayoutPack layoutPack, Room roomLayout, RoomState roomState, uint cellCollisionMask, bool assignLayoutPosition)
Initializes the room. The room should be initialized before adding it to the scene tree since cell ch...
static RoomNode2D CreateInstance(PackedScene scene, Node parent, LayoutPack layoutPack, Room roomLayout, RoomState roomState, uint cellCollisionMask, bool assignLayoutPosition)
Creates and initializes an instance of a room.
void CreateCellAreas(uint cellCollisionMask)
Creates CellArea2D for all active cells.
Vector2I GlobalPositionToCellIndex(Vector2 position)
Returns the row (x) and column (y) index corresponding to the specified global position....
delegate void OnCellGridChangedEventHandler()
Signal emitted when the cell grid size or cell sizes are set.
Vector2 CellCenterGlobalPosition(int row, int column)
Returns the cell center global position for the specified cell index.
delegate void OnCellAreaEnteredEventHandler(CellArea2D cell, Node collision)
Signal emitted when a cell area is entered by a tracked area or body.
RoomTemplateResource RoomTemplate
Vector2 CellCenterLocalPosition(int row, int column)
Returns the cell center local position for the specified cell index.
Vector2I FindClosestActiveCellIndex(Vector2 position)
Returns the closest active cell index to the specified global position.
delegate void OnCellAreaExitedEventHandler(CellArea2D cell, Node collision)
Signal emitted when a cell area is exited by a tracked area or body.
DoorDirection FindClosestDoorDirection(int row, int column, Vector2 position)
Returns the closest door direction based on the cell index and specified global position....
Vector2 CellSize
The width and height of the room cells.
Provides a reference to a room scene and information for the room required by the procedural generato...
The interface for a room node.
CellActivity
Option for setting cell activities.