Skip to content

Commit

Permalink
Merge pull request #1005 from Miepee/roomglobal
Browse files Browse the repository at this point in the history
Add global grid width, height and thickness settings
  • Loading branch information
Grossley committed Jun 27, 2022
2 parents cc1b673 + 5364aca commit cdb5bbb
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 71 deletions.
83 changes: 43 additions & 40 deletions UndertaleModLib/Models/UndertaleRoom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -365,8 +365,9 @@ public void Unserialize(UndertaleReader reader)
/// Initialize the room by setting every <see cref="Background.ParentRoom"/> or <see cref="Layer.ParentRoom"/>
/// (depending on the GameMaker version), and optionally calculate the room grid size.
/// </summary>
/// <param name="calculateGrid">Whether to calculate the room grid size.</param>
public void SetupRoom(bool calculateGrid = true)
/// <param name="calculateGridWidth">Whether to calculate the room grid width.</param>
/// <param name="calculateGridHeight">Whether to calculate the room grid height.</param>
public void SetupRoom(bool calculateGridWidth = true, bool calculateGridHeight = true)
{
foreach (Layer layer in Layers)
{
Expand All @@ -376,54 +377,56 @@ public void SetupRoom(bool calculateGrid = true)
foreach (UndertaleRoom.Background bgnd in Backgrounds)
bgnd.ParentRoom = this;

if (calculateGrid)
{
// Automagically set the grid size to whatever most tiles are sized
if (!(calculateGridWidth || calculateGridHeight)) return;

// Automatically set the grid size to whatever most tiles are sized

Dictionary<Point, uint> tileSizes = new();
IEnumerable<Tile> tileList;
Dictionary<Point, uint> tileSizes = new();
IEnumerable<Tile> tileList;

if (Layers.Count > 0)
if (Layers.Count > 0)
{
tileList = new List<Tile>();
foreach (Layer layer in Layers)
{
tileList = new List<Tile>();
foreach (Layer layer in Layers)
if (layer.LayerType == LayerType.Assets)
tileList = tileList.Concat(layer.AssetsData.LegacyTiles);
else if (layer.LayerType == LayerType.Tiles && layer.TilesData.TileData.Length != 0)
{
if (layer.LayerType == LayerType.Assets)
tileList = tileList.Concat(layer.AssetsData.LegacyTiles);
else if (layer.LayerType == LayerType.Tiles && layer.TilesData.TileData.Length != 0)
{
int w = (int)(Width / layer.TilesData.TilesX);
int h = (int)(Height / layer.TilesData.TilesY);
tileSizes[new(w, h)] = layer.TilesData.TilesX * layer.TilesData.TilesY;
}
int w = (int) (Width / layer.TilesData.TilesX);
int h = (int) (Height / layer.TilesData.TilesY);
tileSizes[new(w, h)] = layer.TilesData.TilesX * layer.TilesData.TilesY;
}

}

}
else
tileList = Tiles;

// Loop through each tile and save how many times their sizes are used
foreach (Tile tile in tileList)
{
Point scale = new((int) tile.Width, (int) tile.Height);
if (tileSizes.ContainsKey(scale))
tileSizes[scale]++;
else
tileList = Tiles;
tileSizes.Add(scale, 1);
}

// Loop through each tile and save how many times their sizes are used
foreach (Tile tile in tileList)
{
Point scale = new((int)tile.Width, (int)tile.Height);
if (tileSizes.ContainsKey(scale))
{
tileSizes[scale]++;
}
else
{
tileSizes.Add(scale, 1);
}
}

// If tiles exist at all, grab the most used tile size and use that as our grid size
if (tileSizes.Count > 0)
{
var largestKey = tileSizes.Aggregate((x, y) => x.Value > y.Value ? x : y).Key;
GridWidth = largestKey.X;
GridHeight = largestKey.Y;
}
if (tileSizes.Count <= 0)
{
GridWidth = 16;
GridHeight = 16;
return;
}

// If tiles exist at all, grab the most used tile size and use that as our grid size
var largestKey = tileSizes.Aggregate((x, y) => x.Value > y.Value ? x : y).Key;
if (calculateGridWidth)
GridWidth = largestKey.X;
if (calculateGridHeight)
GridHeight = largestKey.Y;
}

/// <inheritdoc />
Expand Down
7 changes: 5 additions & 2 deletions UndertaleModTool/Controls/UndertaleRoomRenderer.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,11 @@ public UndertaleRoomRenderer()

private void RoomRenderer_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
(DataContext as UndertaleRoom)?.SetupRoom(!bgGridDisabled);
UndertaleRoomEditor.GenerateSpriteCache(DataContext as UndertaleRoom);
if (DataContext is not UndertaleRoom room)
return;

UndertaleRoomEditor.SetupRoomWithGrids(room);
UndertaleRoomEditor.GenerateSpriteCache(room);
}

private void RoomCanvas_Loaded(object sender, RoutedEventArgs e)
Expand Down
58 changes: 37 additions & 21 deletions UndertaleModTool/Editors/UndertaleRoomEditor.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ private void UndertaleRoomEditor_DataContextChanged(object sender, DependencyPro
GameObjItems.Header = room.Flags.HasFlag(RoomEntryFlags.IsGMS2)
? "Game objects (from all layers)"
: "Game objects";
room.SetupRoom();
SetupRoomWithGrids(room);
GenerateSpriteCache(DataContext as UndertaleRoom);

if (room.Layers.Count > 0) // if GMS 2+
Expand Down Expand Up @@ -476,7 +476,7 @@ private UndertaleObject AddObjectCopy(UndertaleRoom room, Layer layer, Undertale
}

// recalculates room grid size
room.SetupRoom();
SetupRoomWithGrids(room);
}
else if (obj is GameObject gameObj)
{
Expand Down Expand Up @@ -1163,31 +1163,30 @@ public void Command_Copy(object sender, ExecutedRoutedEventArgs e)

public void Command_Undo(object sender, ExecutedRoutedEventArgs e)
{
if (undoStack.Any())
if (!undoStack.Any()) return;

var undoObject = undoStack.Pop();
if (undoObject is GameObject && ObjectEditor.Content is GameObject)
{
var undoObject = undoStack.Pop();
if (undoObject is GameObject && ObjectEditor.Content is GameObject)
var toChange = ObjectEditor.Content as GameObject;
var undoGameObject = undoObject as GameObject;
if (toChange.InstanceID == undoGameObject.InstanceID)
{
var toChange = ObjectEditor.Content as GameObject;
var undoGameObject = undoObject as GameObject;
if (toChange.InstanceID == undoGameObject.InstanceID)
{
toChange.X = undoGameObject.X;
toChange.Y = undoGameObject.Y;
}
toChange.X = undoGameObject.X;
toChange.Y = undoGameObject.Y;
}
if (undoObject is Tile && ObjectEditor.Content is Tile)
}
if (undoObject is Tile && ObjectEditor.Content is Tile)
{
var toChange = ObjectEditor.Content as Tile;
var undoGameObject = undoObject as Tile;
if (toChange.InstanceID == undoGameObject.InstanceID)
{
var toChange = ObjectEditor.Content as Tile;
var undoGameObject = undoObject as Tile;
if (toChange.InstanceID == undoGameObject.InstanceID)
{
toChange.X = undoGameObject.X;
toChange.Y = undoGameObject.Y;
}
toChange.X = undoGameObject.X;
toChange.Y = undoGameObject.Y;
}
(this.DataContext as UndertaleRoom)?.SetupRoom(false);
}
(this.DataContext as UndertaleRoom)?.SetupRoom(false, false);
}

public void Command_Paste(object sender, ExecutedRoutedEventArgs e)
Expand Down Expand Up @@ -1692,6 +1691,23 @@ private void LayerCanvas_Unloaded(object sender, RoutedEventArgs e)
if (canvas.CurrentLayer is not null)
ObjElemDict.Remove(canvas.CurrentLayer);
}

public static void SetupRoomWithGrids(UndertaleRoom room)
{
if (Settings.Instance.GridWidthEnabled)
room.GridWidth = Settings.Instance.GlobalGridWidth;
if (Settings.Instance.GridHeightEnabled)
room.GridHeight = Settings.Instance.GlobalGridHeight;

// SetupRoom already overrides GridWidth and GridHeight if the global setting is disabled, but does
// not do that for the thickness. Hence why we're overriding it here manually to the default value should
// the setting be disabled.
if (Settings.Instance.GridThicknessEnabled)
room.GridThicknessPx = Settings.Instance.GlobalGridThickness;
else
room.GridThicknessPx = 1;
room.SetupRoom(!Settings.Instance.GridWidthEnabled, !Settings.Instance.GridHeightEnabled);
}
}

public partial class RoomCanvas : Canvas
Expand Down
8 changes: 8 additions & 0 deletions UndertaleModTool/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ public class Settings
public bool DeleteOldProfileOnSave { get; set; } = false;
public bool WarnOnClose { get; set; } = true;

public double GlobalGridWidth { get; set; } = 20;
public bool GridWidthEnabled { get; set; } = false;
public double GlobalGridHeight { get; set; } = 20;
public bool GridHeightEnabled { get; set; } = false;

public double GlobalGridThickness { get; set; } = 1;
public bool GridThicknessEnabled { get; set; } = false;

public static Settings Instance;

public static JsonSerializerOptions JsonOptions = new JsonSerializerOptions
Expand Down
27 changes: 19 additions & 8 deletions UndertaleModTool/Windows/SettingsWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
<TextBox Grid.Row="2" Grid.Column="1" Margin="3" Grid.ColumnSpan="3" Text="{Binding GameMakerStudio2RuntimesPath}"/>

<CheckBox Grid.Row="3" Grid.Column="0" Margin="3" Content="" IsChecked="{Binding AssetOrderSwappingEnabled}"/>
<TextBlock Grid.Row="3" Grid.Column="0" Margin="25 2 2 2" Text="Enable asset order swapping" ToolTip="Toggles dragging &amp; dropping assets in the asset tabs to different positions in the list. Disabled by default."/>
<TextBlock Grid.Row="3" Grid.Column="0" Margin="25 2 2 2" Text="Enable asset order swapping" ToolTip="Toggles dragging &amp; dropping assets in the asset tabs to different positions in the list. Disabled by default."/>
<CheckBox Grid.Row="3" Grid.Column="2" Margin="3" Content="" IsChecked="{Binding WarnOnClose}"/>
<TextBlock Grid.Row="3" Grid.Column="2" Margin="25 2 2 2" Text="Warn about saving before closing" ToolTip="Warn about saving before closing. Enabled by default."/>

Expand All @@ -56,21 +56,32 @@
<CheckBox Grid.Row="5" Grid.Column="2" Margin="3" Content="" IsChecked="{Binding UseGMLCache}"/>
<TextBlock Grid.Row="5" Grid.Column="2" Margin="25 2 2 2" Text="Use decompiled code cache (experimental)" ToolTip="Used by some scripts (e.g. &quot;Search.csx&quot;) for acceleration. Disabled by default."/>

<Separator Grid.Row="6" Grid.ColumnSpan="4" Margin="10"/>

<CheckBox Grid.Row="7" Grid.Column="0" Margin="3" VerticalAlignment="Center" Name="gridWidthCheckbox" Content="" IsChecked="{Binding GridWidthEnabled}"/>
<TextBlock Grid.Row="7" Grid.Column="0" Margin="25 2 2 2" VerticalAlignment="Center" Text="Global grid width" ToolTip="This option globally overrides the automatic assignment of a room's grid width based on the most used tile's width in that room."/>
<TextBox Grid.Row="7" Grid.Column="1" Margin="3" IsEnabled="{Binding ElementName=gridWidthCheckbox, Path=IsChecked}" Text="{Binding GlobalGridWidth}"/>

<Separator Grid.Row="11" Grid.ColumnSpan="4" Margin="10"/>
<CheckBox Grid.Row="8" Grid.Column="0" Margin="3" VerticalAlignment="Center" Name="gridHeightCheckbox" Content="" IsChecked="{Binding GridHeightEnabled}"/>
<TextBlock Grid.Row="8" Grid.Column="0" Margin="25 2 2 2" VerticalAlignment="Center" Text="Global grid height" ToolTip="This option globally overrides the automatic assignment of a room's grid height based on the most used tile's height in that room."/>
<TextBox Grid.Row="8" Grid.Column="1" Margin="3" IsEnabled="{Binding ElementName=gridHeightCheckbox, Path=IsChecked}" Text="{Binding GlobalGridHeight}"/>

<CheckBox Grid.Row="7" Grid.Column="2" Margin="3" VerticalAlignment="Center" Name="gridThicknessCheckBox" Content="" IsChecked="{Binding GridThicknessEnabled}"/>
<TextBlock Grid.Row="7" Grid.Column="2" Margin="25 2 2 2" VerticalAlignment="Center" Text="Global grid thickness" ToolTip="This option globally overrides the automatic assignment of a room's grid thickness."/>
<TextBox Grid.Row="7" Grid.Column="3" Margin="3" IsEnabled="{Binding ElementName=gridThicknessCheckBox, Path=IsChecked}" Text="{Binding GlobalGridThickness}"/>

<Separator Grid.Row="11" Grid.ColumnSpan="4" Margin="10"/>

<TextBlock Grid.Row="12" Grid.Column="0" Grid.ColumnSpan="4" Margin="3" TextWrapping="Wrap" Foreground="Red" FontWeight="Bold" Text="Warning: the following options are currently experimental, as the profile system is a work in progress. Usage of the system is at your own risk, and though it is relatively stable, it may not be compatible in the future."/>

<CheckBox Grid.Row="13" Grid.Column="0" Margin="3" Content="" IsChecked="{Binding ProfileModeEnabled}"/>
<TextBlock Grid.Row="13" Grid.Column="0" Margin="25 2 2 2" Text="Enable profile mode" ToolTip="Toggles the 'decompile once and compile many' profile mode. Enabled by default. May need to be disabled for certain operations."/>
<CheckBox Grid.Row="13" Grid.Column="0" Margin="3" VerticalAlignment="Center" Content="" IsChecked="{Binding ProfileModeEnabled}"/>
<TextBlock Grid.Row="13" Grid.Column="0" Margin="25 2 2 2" VerticalAlignment="Center" Text="Enable profile mode" ToolTip="Toggles the 'decompile once and compile many' profile mode. Enabled by default. May need to be disabled for certain operations."/>

<CheckBox Grid.Row="13" Grid.Column="2" Margin="3" Content="" IsChecked="{Binding ProfileMessageShown}"/>
<TextBlock Grid.Row="13" Grid.Column="2" Margin="25 2 2 2" Text="Profile mode message shown" ToolTip="On first load, this will show you the profile mode loaded message. If this somehow breaks, you can manually toggle it here."/>
<CheckBox Grid.Row="13" Grid.Column="2" Margin="3" VerticalAlignment="Center" Content="" IsChecked="{Binding ProfileMessageShown}"/>
<TextBlock Grid.Row="13" Grid.Column="2" Margin="25 2 2 2" VerticalAlignment="Center" Text="Profile mode message shown" ToolTip="On first load, this will show you the profile mode loaded message. If this somehow breaks, you can manually toggle it here."/>

<CheckBox Grid.Row="15" Grid.Column="0" Margin="3" Content="" IsChecked="{Binding DeleteOldProfileOnSave}"/>
<TextBlock Grid.Row="15" Grid.Column="0" Margin="25 2 2 2" Text="Delete old profile on saving" ToolTip="Deletes the profile obsoleted on saving. Saves on file space at the expense of losing code information for variants. Enabled by default."/>
<CheckBox Grid.Row="15" Grid.Column="0" Margin="3" VerticalAlignment="Center" Content="" IsChecked="{Binding DeleteOldProfileOnSave}"/>
<TextBlock Grid.Row="15" Grid.Column="0" Margin="25 2 2 2" VerticalAlignment="Center" Text="Delete old profile on saving" ToolTip="Deletes the profile obsoleted on saving. Saves on file space at the expense of losing code information for variants. Enabled by default."/>

<Separator Grid.Row="16" Grid.ColumnSpan="4" Margin="10"/>
<Button Grid.Row="17" Grid.Column="0" Grid.ColumnSpan="1" Margin="5" Click="AppDataButton_Click">Open application data folder</Button>
Expand Down
60 changes: 60 additions & 0 deletions UndertaleModTool/Windows/SettingsWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,66 @@ public static bool WarnOnClose
}
}

public static double GlobalGridWidth
{
get => Settings.Instance.GlobalGridWidth;
set
{
Settings.Instance.GlobalGridWidth = value;
Settings.Save();
}
}

public static bool GridWidthEnabled
{
get => Settings.Instance.GridWidthEnabled;
set
{
Settings.Instance.GridWidthEnabled = value;
Settings.Save();
}
}

public static double GlobalGridHeight
{
get => Settings.Instance.GlobalGridHeight;
set
{
Settings.Instance.GlobalGridHeight = value;
Settings.Save();
}
}

public static bool GridHeightEnabled
{
get => Settings.Instance.GridHeightEnabled;
set
{
Settings.Instance.GridHeightEnabled = value;
Settings.Save();
}
}

public static double GlobalGridThickness
{
get => Settings.Instance.GlobalGridThickness;
set
{
Settings.Instance.GlobalGridThickness = value;
Settings.Save();
}
}

public static bool GridThicknessEnabled
{
get => Settings.Instance.GridThicknessEnabled;
set
{
Settings.Instance.GridThicknessEnabled = value;
Settings.Save();
}
}

public bool UpdateButtonEnabled
{
get => UpdateAppButton.IsEnabled;
Expand Down

0 comments on commit cdb5bbb

Please sign in to comment.