From 754d8b14195c757fa7471b0e39f80ab5270decbc Mon Sep 17 00:00:00 2001 From: Marcin Badurowicz Date: Fri, 13 Mar 2026 13:44:31 +0100 Subject: [PATCH 01/18] refactor: move moving into a separate service --- Server/Components/Pages/GamePage.razor | 3 +- Server/Components/Pages/GamePage.razor.cs | 11 +- Server/Components/Popups/MapPopup.razor | 13 +- Server/Modules/MapGenerator/UI/MapView.razor | 344 +++++++++--------- ...MapDisplayData.cs => MapDisplayOptions.cs} | 2 +- .../ImageChangers/BackgroundImageChanger.cs | 154 ++++---- .../Modules/Users/Services/MovementService.cs | 36 ++ Server/Program.cs | 2 + 8 files changed, 303 insertions(+), 262 deletions(-) rename Server/Modules/MapGenerator/UI/Models/{MapDisplayData.cs => MapDisplayOptions.cs} (85%) create mode 100644 Server/Modules/Users/Services/MovementService.cs diff --git a/Server/Components/Pages/GamePage.razor b/Server/Components/Pages/GamePage.razor index b2ff905..f777aa4 100644 --- a/Server/Components/Pages/GamePage.razor +++ b/Server/Components/Pages/GamePage.razor @@ -28,6 +28,7 @@ @inject VersionInfoProvider VersionInfoProvider @inject BackgroundImageChanger BackgroundImageChanger @inject UserService UserService +@inject MovementService MovementService @@ -132,7 +133,7 @@ - +
diff --git a/Server/Components/Pages/GamePage.razor.cs b/Server/Components/Pages/GamePage.razor.cs index 542dba3..172e356 100644 --- a/Server/Components/Pages/GamePage.razor.cs +++ b/Server/Components/Pages/GamePage.razor.cs @@ -10,13 +10,12 @@ namespace Fracture.Server.Components.Pages; public partial class GamePage { private Dictionary _mapPopupParameters = null!; - public static Map Map { get; set; } private PopupContainer _popup = null!; public static BackgroundImage BackgroundImage { get; set; } = new(string.Empty); - private readonly MapDisplayData _mapDisplayData = new(); + private readonly MapDisplayOptions _mapDisplayOptions = new(); private List? Path { get; set; } @@ -28,12 +27,12 @@ protected override async Task OnInitializedAsync() NavigationManager.NavigateTo("/"); } - Map = MapManagerService.GetWorldMap() ?? throw new InvalidOperationException(); - _mapDisplayData.ShowColorMap = true; + MovementService.Initialize(); + + _mapDisplayOptions.ShowColorMap = true; _mapPopupParameters = new Dictionary { - { "Map", Map }, - { "MapDisplayData", _mapDisplayData }, + { "MapDisplayData", _mapDisplayOptions }, }; BackgroundImageChanger.BackgroundImage = BackgroundImage; diff --git a/Server/Components/Popups/MapPopup.razor b/Server/Components/Popups/MapPopup.razor index b0b37c6..28223d8 100644 --- a/Server/Components/Popups/MapPopup.razor +++ b/Server/Components/Popups/MapPopup.razor @@ -1,18 +1,17 @@ @inject NavigationManager NavigationManager +@inject MovementService MovementService @page "/map" @using Fracture.Server.Modules.MapGenerator.Models.Map @using Fracture.Server.Modules.MapGenerator.UI @using Fracture.Server.Modules.MapGenerator.UI.Models +@using Fracture.Server.Modules.Users.Services +
- +
-@code { - [Parameter] public required Map Map { get; set; } - [Parameter] public required MapDisplayData MapDisplayData { get; set; } - readonly int x = MapView.CharacterXX; - readonly int y = MapView.CharacterYY; +@code { + [Parameter] public required MapDisplayOptions MapDisplayData { get; set; } } \ No newline at end of file diff --git a/Server/Modules/MapGenerator/UI/MapView.razor b/Server/Modules/MapGenerator/UI/MapView.razor index 3a646b2..549d73e 100644 --- a/Server/Modules/MapGenerator/UI/MapView.razor +++ b/Server/Modules/MapGenerator/UI/MapView.razor @@ -3,180 +3,186 @@ @using Fracture.Server.Modules.MapGenerator.UI.Models @using Fracture.Server.Modules.Pathfinding.Models @using Fracture.Server.Modules.Shared.ImageChangers +@using Fracture.Server.Modules.Users.Services @using Microsoft.AspNetCore.Components.Web + @inject BackgroundImageChanger BackgroundImageChanger +@inject MovementService MovementService + +
- @if (Map != null && MapDisplayData != null) { - - @for (var y = 0; y < Map.Grid.GetLength(1); y++) { - - @for (var x = 0; x < Map.Grid.GetLength(0); x++) { - var node = Map.Grid[x, y]; - - @if (x == CharacterXX && y == CharacterYY) { - - } - else if (MapDisplayData.TileInformationDisplay == TileInformationDisplay.Position) { - - x:@x
y:@y -
- } - else if (MapDisplayData.TileInformationDisplay == TileInformationDisplay.Noise) { - - @Math.Round(node.NoiseValue, 2) - - } - else if (MapDisplayData.TileInformationDisplay == TileInformationDisplay.None) { - - @RenderLocation(node) - - } - else if (MapDisplayData.TileInformationDisplay == TileInformationDisplay.Path) { - - @GetPathForTile(node) - - } - else { - - @RenderLocation(node) - - } - } - - } -
- 😐 -
- } + @if (Map != null && MapDisplayOptions != null) + { + + @for (var y = 0; y < Map.Grid.GetLength(1); y++) + { + + @for (var x = 0; x < Map.Grid.GetLength(0); x++) + { + var node = Map.Grid[x, y]; + + @if (x == MovementService.CurrentX && y == MovementService.CurrentY) + { + + } + else if (MapDisplayOptions.TileInformationDisplay == TileInformationDisplay.Position) + { + + x:@x
y:@y +
+ } + else if (MapDisplayOptions.TileInformationDisplay == TileInformationDisplay.Noise) + { + + @Math.Round(node.NoiseValue, 2) + + } + else if (MapDisplayOptions.TileInformationDisplay == TileInformationDisplay.None) + { + + @RenderLocation(node) + + } + else if (MapDisplayOptions.TileInformationDisplay == TileInformationDisplay.Path) + { + + @GetPathForTile(node) + + } + else + { + + @RenderLocation(node) + + } + } + + } +
+ 😐 +
+ }
@code { - [Parameter] public Map? Map { get; set; } - - [Parameter] public MapDisplayData? MapDisplayData { get; set; } - - [Parameter] public List? Path { get; set; } - - [Parameter] public bool IsMiniMap { get; set; } = true; - - - private bool isMoving = false; - public static int CharacterXX { get; set; } = 16; - public static int CharacterYY { get; set; } = 16; - [Parameter] public int CharacterX { get; set; } = CharacterXX; - [Parameter] public int CharacterY { get; set; } = CharacterXX; - - private readonly HashSet _blockingColors = new() { - "#21618C", "#2E86C1" - }; - - private string GetTileColor(Node node) { - if (MapDisplayData!.ShowColorMap) { - var color = node.Biome.Color; - var hex = $"#{color.R:X2}{color.G:X2}{color.B:X2}"; // rgb -> hex - return hex ?? string.Empty; - } - - var hexValue = string.Format("{0:x}", (int)(node.NoiseValue * 255)); - if (hexValue.Length == 1) { - hexValue = "0" + hexValue; - } - - return $"#{hexValue}{hexValue}{hexValue}"; - } - - private string GetPathForTile(Node node) { - if (Path == null) { - return ""; - } - - var pathNodeIndex = Path.FindIndex(n => n.XId == node.XId && n.YId == node.YId); - if (pathNodeIndex != -1 && pathNodeIndex + 1 < Path.Count) { - var xDirection = Path[pathNodeIndex + 1].XId - Path[pathNodeIndex].XId; - var yDirection = Path[pathNodeIndex].YId - Path[pathNodeIndex + 1].YId; - return GetArrowForDirection(xDirection, yDirection); - } - - return ""; - } - - protected override void OnInitialized() { - BackgroundImageChanger.BackgroundImage = GamePage.BackgroundImage; - } - - private string GetArrowForDirection(int xDirection, int yDirection) { - return yDirection switch { - 1 when xDirection == 0 => SpecialChars.Arrows.Up, - 1 when xDirection == 1 => SpecialChars.Arrows.UpRight, - 0 when xDirection == 1 => SpecialChars.Arrows.Right, - -1 when xDirection == 1 => SpecialChars.Arrows.DownRight, - -1 when xDirection == 0 => SpecialChars.Arrows.Down, - -1 when xDirection == -1 => SpecialChars.Arrows.DownLeft, - 0 when xDirection == -1 => SpecialChars.Arrows.Left, - 1 when xDirection == -1 => SpecialChars.Arrows.UpLeft, - _ => "" - }; - } - - private string RenderLocation(Node node) { - return node.LocationType switch { - LocationType.None => string.Empty, - LocationType.Town => "T", - LocationType.Cave => "C", - _ => string.Empty - }; - } - - private async void HandleKeyDown(KeyboardEventArgs e) { - if (IsMiniMap == false) { - if (isMoving) return; - isMoving = true; - var newX = CharacterXX; - var newY = CharacterYY; - switch (e.Key) { - case "ArrowUp": - if (CharacterYY > 0) { - newY--; - } - - break; - case "ArrowDown": - if (CharacterYY < Map.Grid.GetLength(1) - 1) { - newY++; - } - - break; - case "ArrowLeft": - if (CharacterXX > 0) { - newX--; - } - - break; - case "ArrowRight": - if (CharacterXX < Map.Grid.GetLength(0) - 1) { - newX++; - } - - break; - } - - if (CanMoveToTile(newX, newY)) { - CharacterXX = newX; - CharacterYY = newY; - await BackgroundImageChanger.ChangeBackgroundImageAsync(); - StateHasChanged(); - } - - Task.Delay(100).ContinueWith(_ => { isMoving = false; }); - } - } - - private bool CanMoveToTile(int x, int y) { - if (Map != null && Map.Grid[x, y].Walkable) { - return true; - } - - return false; - } + [Parameter] public Map? Map { get; set; } + + [Parameter] public MapDisplayOptions? MapDisplayOptions { get; set; } + + [Parameter] public List? Path { get; set; } + + [Parameter] public bool IsMiniMap { get; set; } = true; + + + private bool isMoving = false; + + private readonly HashSet _blockingColors = new() { + "#21618C", "#2E86C1" + }; + + private string GetTileColor(Node node) + { + if (MapDisplayOptions!.ShowColorMap) + { + var color = node.Biome.Color; + var hex = $"#{color.R:X2}{color.G:X2}{color.B:X2}"; // rgb -> hex + return hex ?? string.Empty; + } + + var hexValue = string.Format("{0:x}", (int)(node.NoiseValue * 255)); + if (hexValue.Length == 1) + { + hexValue = "0" + hexValue; + } + + return $"#{hexValue}{hexValue}{hexValue}"; + } + + private string GetPathForTile(Node node) + { + if (Path == null) + { + return ""; + } + + var pathNodeIndex = Path.FindIndex(n => n.XId == node.XId && n.YId == node.YId); + if (pathNodeIndex != -1 && pathNodeIndex + 1 < Path.Count) + { + var xDirection = Path[pathNodeIndex + 1].XId - Path[pathNodeIndex].XId; + var yDirection = Path[pathNodeIndex].YId - Path[pathNodeIndex + 1].YId; + return GetArrowForDirection(xDirection, yDirection); + } + + return ""; + } + + protected override void OnInitialized() + { + BackgroundImageChanger.BackgroundImage = GamePage.BackgroundImage; + } + + private string GetArrowForDirection(int xDirection, int yDirection) + { + return yDirection switch + { + 1 when xDirection == 0 => SpecialChars.Arrows.Up, + 1 when xDirection == 1 => SpecialChars.Arrows.UpRight, + 0 when xDirection == 1 => SpecialChars.Arrows.Right, + -1 when xDirection == 1 => SpecialChars.Arrows.DownRight, + -1 when xDirection == 0 => SpecialChars.Arrows.Down, + -1 when xDirection == -1 => SpecialChars.Arrows.DownLeft, + 0 when xDirection == -1 => SpecialChars.Arrows.Left, + 1 when xDirection == -1 => SpecialChars.Arrows.UpLeft, + _ => "" + }; + } + + private string RenderLocation(Node node) + { + return node.LocationType switch + { + LocationType.None => string.Empty, + LocationType.Town => "T", + LocationType.Cave => "C", + _ => string.Empty + }; + } + + private async void HandleKeyDown(KeyboardEventArgs e) + { + if (IsMiniMap == false) + { + if (isMoving) return; + isMoving = true; + + var newX = MovementService.CurrentX; + var newY = MovementService.CurrentY; + switch (e.Key) + { + case "ArrowUp": + newY--; + break; + case "ArrowDown": + newY++; + break; + case "ArrowLeft": + newX--; + break; + case "ArrowRight": + newX++; + break; + } + + if (MovementService.CanMove(newX, newY)) + { + await MovementService.MoveAsync(newX, newY); + + await BackgroundImageChanger.ChangeBackgroundImageAsync(); + StateHasChanged(); + } + + //Task.Delay(100).ContinueWith(_ => { isMoving = false; }); + } + } } diff --git a/Server/Modules/MapGenerator/UI/Models/MapDisplayData.cs b/Server/Modules/MapGenerator/UI/Models/MapDisplayOptions.cs similarity index 85% rename from Server/Modules/MapGenerator/UI/Models/MapDisplayData.cs rename to Server/Modules/MapGenerator/UI/Models/MapDisplayOptions.cs index c5ab102..c1cab75 100644 --- a/Server/Modules/MapGenerator/UI/Models/MapDisplayData.cs +++ b/Server/Modules/MapGenerator/UI/Models/MapDisplayOptions.cs @@ -1,6 +1,6 @@ namespace Fracture.Server.Modules.MapGenerator.UI.Models; -public class MapDisplayData +public class MapDisplayOptions { public bool ShowColorMap { get; set; } = true; public TileInformationDisplay TileInformationDisplay { get; set; } diff --git a/Server/Modules/Shared/ImageChangers/BackgroundImageChanger.cs b/Server/Modules/Shared/ImageChangers/BackgroundImageChanger.cs index 6c41b21..ec2aa7e 100644 --- a/Server/Modules/Shared/ImageChangers/BackgroundImageChanger.cs +++ b/Server/Modules/Shared/ImageChangers/BackgroundImageChanger.cs @@ -14,90 +14,88 @@ MapManagerService mapManagerService public Task ChangeBackgroundImageAsync() { - if (BackgroundImage is null) - { - logger.LogError("BackgroundImage is null"); - return Task.CompletedTask; - } - var currentMap = MapManagerService.CurrentMap; - if (currentMap.Grid is null) - { - logger.LogError("Grid is null"); - return Task.CompletedTask; - } + //if (BackgroundImage is null) + //{ + // logger.LogError("BackgroundImage is null"); + // return Task.CompletedTask; + //} + //var currentMap = MapManagerService.CurrentMap; + //if (currentMap.Grid is null) + //{ + // logger.LogError("Grid is null"); + // return Task.CompletedTask; + //} - var x = MapView.CharacterXX; - var y = MapView.CharacterYY; - if (x < 0 || y < 0 || x >= currentMap.Width || y >= currentMap.Height) - { - logger.LogError("Character is out of map"); - return Task.CompletedTask; - } - var cell = currentMap.Grid[x, y]; - var biome = cell.Biome; + //if (x < 0 || y < 0 || x >= currentMap.Width || y >= currentMap.Height) + //{ + // logger.LogError("Character is out of map"); + // return Task.CompletedTask; + //} + //var cell = currentMap.Grid[x, y]; + //var biome = cell.Biome; - if (biome is null) - { - logger.LogError("Biome is null"); - return Task.CompletedTask; - } + //if (biome is null) + //{ + // logger.LogError("Biome is null"); + // return Task.CompletedTask; + //} - string? imagePath = null; - if (cell.LocationType != LocationType.None) - { - var currentLocationName = cell.LocationType.ToString(); - var location = biome.Locations.FirstOrDefault(l => - string.Equals(l.Name, currentLocationName, StringComparison.OrdinalIgnoreCase) - ); + //string? imagePath = null; + //if (cell.LocationType != LocationType.None) + //{ + // var currentLocationName = cell.LocationType.ToString(); + // var location = biome.Locations.FirstOrDefault(l => + // string.Equals(l.Name, currentLocationName, StringComparison.OrdinalIgnoreCase) + // ); - if (location is null) - { - logger.LogWarning( - "No matching location config for LocationType {LocationType} at ({X},{Y}) in biome {BiomeName}. Available: {Locations}", - cell.LocationType, - x, - y, - biome.Name, - string.Join( - ", ", - biome - .Locations.Where(l => !string.IsNullOrWhiteSpace(l.Name)) - .Select(l => l.Name) - ) - ); - } - else - { - imagePath = location.BackgroundImage; - logger.LogInformation( - "Using location background image '{ImagePath}' for LocationType {LocationType} at ({X},{Y})", - imagePath, - cell.LocationType, - x, - y - ); - } - } - if (string.IsNullOrWhiteSpace(imagePath)) - { - imagePath = biome.BackgroundImage; - logger.LogInformation( - "Using biome background image '{ImagePath}' for biome {BiomeName} at ({X},{Y})", - imagePath, - biome.Name, - x, - y - ); - } + // if (location is null) + // { + // logger.LogWarning( + // "No matching location config for LocationType {LocationType} at ({X},{Y}) in biome {BiomeName}. Available: {Locations}", + // cell.LocationType, + // x, + // y, + // biome.Name, + // string.Join( + // ", ", + // biome + // .Locations.Where(l => !string.IsNullOrWhiteSpace(l.Name)) + // .Select(l => l.Name) + // ) + // ); + // } + // else + // { + // imagePath = location.BackgroundImage; + // logger.LogInformation( + // "Using location background image '{ImagePath}' for LocationType {LocationType} at ({X},{Y})", + // imagePath, + // cell.LocationType, + // x, + // y + // ); + // } + //} + //if (string.IsNullOrWhiteSpace(imagePath)) + //{ + // imagePath = biome.BackgroundImage; + // logger.LogInformation( + // "Using biome background image '{ImagePath}' for biome {BiomeName} at ({X},{Y})", + // imagePath, + // biome.Name, + // x, + // y + // ); + //} - if (string.IsNullOrWhiteSpace(imagePath)) - { - logger.LogError("Background image path is null or empty"); - return Task.CompletedTask; - } + //if (string.IsNullOrWhiteSpace(imagePath)) + //{ + // logger.LogError("Background image path is null or empty"); + // return Task.CompletedTask; + //} - BackgroundImage.ImagePath = imagePath; - NotifyListChanged(this, EventArgs.Empty); + //BackgroundImage.ImagePath = imagePath; + //NotifyListChanged(this, EventArgs.Empty); return Task.CompletedTask; } diff --git a/Server/Modules/Users/Services/MovementService.cs b/Server/Modules/Users/Services/MovementService.cs new file mode 100644 index 0000000..ed789de --- /dev/null +++ b/Server/Modules/Users/Services/MovementService.cs @@ -0,0 +1,36 @@ +using Fracture.Server.Modules.MapGenerator.Models.Map; +using Fracture.Server.Modules.MapGenerator.Services; + +namespace Fracture.Server.Modules.Users.Services; + +public class MovementService(UserService _userService, MapManagerService _mapManagerService) +{ + public Map? CurrentMap { get; private set; } + + public int CurrentX { get; private set; } + public int CurrentY { get; private set; } + + public void Initialize() + { + CurrentMap = + _mapManagerService.GetWorldMap() + ?? throw new InvalidOperationException("Map cannot be loaded, critical error"); + } + + public bool CanMove(int x, int y) + { + return CurrentMap != null + && x >= 0 + && y >= 0 + && x < CurrentMap!.Width + && y < CurrentMap.Height + && CurrentMap.Grid[x, y].Walkable; + } + + public async Task MoveAsync(int x, int y) + { + await Task.Delay(100); + CurrentX = x; + CurrentY = y; + } +} diff --git a/Server/Program.cs b/Server/Program.cs index 5e61fe1..88ce56d 100644 --- a/Server/Program.cs +++ b/Server/Program.cs @@ -44,6 +44,8 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); + builder.Services.AddTransient(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); From fdb90a1fa8f844236f1e8a6ec9efde4dfe64beba Mon Sep 17 00:00:00 2001 From: Marcin Badurowicz Date: Fri, 13 Mar 2026 14:02:02 +0100 Subject: [PATCH 02/18] fix: character location taken from parameters --- Server/Components/Pages/GamePage.razor.cs | 5 ++++- Server/Modules/MapGenerator/UI/MapView.razor | 12 ++++++++++-- Server/Modules/Users/Services/MovementService.cs | 13 ++++++++++++- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/Server/Components/Pages/GamePage.razor.cs b/Server/Components/Pages/GamePage.razor.cs index 172e356..06900da 100644 --- a/Server/Components/Pages/GamePage.razor.cs +++ b/Server/Components/Pages/GamePage.razor.cs @@ -27,7 +27,10 @@ protected override async Task OnInitializedAsync() NavigationManager.NavigateTo("/"); } - MovementService.Initialize(); + if (MovementService.CurrentMap is null) + { + MovementService.Initialize(); + } _mapDisplayOptions.ShowColorMap = true; _mapPopupParameters = new Dictionary diff --git a/Server/Modules/MapGenerator/UI/MapView.razor b/Server/Modules/MapGenerator/UI/MapView.razor index 549d73e..2481be4 100644 --- a/Server/Modules/MapGenerator/UI/MapView.razor +++ b/Server/Modules/MapGenerator/UI/MapView.razor @@ -21,7 +21,7 @@ { var node = Map.Grid[x, y]; - @if (x == MovementService.CurrentX && y == MovementService.CurrentY) + @if (x == CharacterX && y == CharacterY) { 😐 @@ -73,6 +73,9 @@ [Parameter] public bool IsMiniMap { get; set; } = true; + [Parameter] public int CharacterX { get; set; } + [Parameter] public int CharacterY { get; set; } + private bool isMoving = false; @@ -118,6 +121,9 @@ protected override void OnInitialized() { + CharacterX = MovementService.CurrentX; + CharacterY = MovementService.CurrentY; + BackgroundImageChanger.BackgroundImage = GamePage.BackgroundImage; } @@ -176,12 +182,14 @@ if (MovementService.CanMove(newX, newY)) { await MovementService.MoveAsync(newX, newY); + CharacterX = newX; + CharacterY = newY; await BackgroundImageChanger.ChangeBackgroundImageAsync(); StateHasChanged(); } - //Task.Delay(100).ContinueWith(_ => { isMoving = false; }); + await Task.Delay(100).ContinueWith(_ => { isMoving = false; }); } } diff --git a/Server/Modules/Users/Services/MovementService.cs b/Server/Modules/Users/Services/MovementService.cs index ed789de..f73bad7 100644 --- a/Server/Modules/Users/Services/MovementService.cs +++ b/Server/Modules/Users/Services/MovementService.cs @@ -10,11 +10,21 @@ public class MovementService(UserService _userService, MapManagerService _mapMan public int CurrentX { get; private set; } public int CurrentY { get; private set; } + public Action? OnMoved; + public Action? OnMapEntered; + public void Initialize() { CurrentMap = _mapManagerService.GetWorldMap() ?? throw new InvalidOperationException("Map cannot be loaded, critical error"); + + OnMapEntered?.Invoke(); + + CurrentX = 16; + CurrentY = 16; + + OnMoved?.Invoke(); } public bool CanMove(int x, int y) @@ -29,8 +39,9 @@ public bool CanMove(int x, int y) public async Task MoveAsync(int x, int y) { - await Task.Delay(100); CurrentX = x; CurrentY = y; + + OnMoved?.Invoke(); } } From 364e6e5c38c8d036128015c4e95307edaca0c3a1 Mon Sep 17 00:00:00 2001 From: Marcin Badurowicz Date: Fri, 13 Mar 2026 14:03:48 +0100 Subject: [PATCH 03/18] fix: character location on minimap --- Server/Components/Pages/GamePage.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Server/Components/Pages/GamePage.razor b/Server/Components/Pages/GamePage.razor index f777aa4..108ffbb 100644 --- a/Server/Components/Pages/GamePage.razor +++ b/Server/Components/Pages/GamePage.razor @@ -133,7 +133,7 @@
- +
From 02600eac72fbf13ac82fa20a45129cd1b4795385 Mon Sep 17 00:00:00 2001 From: Marcin Badurowicz Date: Fri, 13 Mar 2026 14:24:06 +0100 Subject: [PATCH 04/18] refactor: changing background image --- Server/Components/Pages/GamePage.razor | 7 +- Server/Components/Pages/GamePage.razor.cs | 124 +++++++++++++++--- Server/Modules/MapGenerator/UI/MapView.razor | 7 +- .../ImageChangers/BackgroundImageChanger.cs | 104 +-------------- .../Modules/Users/Services/MovementService.cs | 16 ++- 5 files changed, 125 insertions(+), 133 deletions(-) diff --git a/Server/Components/Pages/GamePage.razor b/Server/Components/Pages/GamePage.razor index 108ffbb..01b5cbb 100644 --- a/Server/Components/Pages/GamePage.razor +++ b/Server/Components/Pages/GamePage.razor @@ -16,7 +16,7 @@ @using Fracture.Server.Modules.Users @using Fracture.Server.Modules.Users.Services @using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage -@implements IDisposable +@* @implements IDisposable *@ @page "/game" @rendermode @(new InteractiveServerRenderMode(false)) @@ -29,6 +29,7 @@ @inject BackgroundImageChanger BackgroundImageChanger @inject UserService UserService @inject MovementService MovementService +@inject ILogger Logger @@ -69,8 +70,8 @@
-
+ style="background: url(@BackgroundImage);background-repeat: no-repeat; background-size: cover; "> +
Fracture @VersionInfoProvider.InformationalVersion
tutaj log mojej gry
diff --git a/Server/Components/Pages/GamePage.razor.cs b/Server/Components/Pages/GamePage.razor.cs index 06900da..e1ecb48 100644 --- a/Server/Components/Pages/GamePage.razor.cs +++ b/Server/Components/Pages/GamePage.razor.cs @@ -4,16 +4,17 @@ using Fracture.Server.Modules.Pathfinding.Models; using Fracture.Server.Modules.Shared.ImageChangers; using Fracture.Server.Modules.Users.Models; +using Fracture.Server.Modules.Users.Services; namespace Fracture.Server.Components.Pages; -public partial class GamePage +public partial class GamePage // : IDisposable { private Dictionary _mapPopupParameters = null!; private PopupContainer _popup = null!; - public static BackgroundImage BackgroundImage { get; set; } = new(string.Empty); + public string BackgroundImage { get; set; } = string.Empty; private readonly MapDisplayOptions _mapDisplayOptions = new(); @@ -32,17 +33,24 @@ protected override async Task OnInitializedAsync() MovementService.Initialize(); } + MovementService.OnMapEntered += async (sender, args) => + { + BackgroundImage = GetBackgroundImagePath(); + StateHasChanged(); + }; + + MovementService.OnMoved += async (sender, args) => + { + BackgroundImage = GetBackgroundImagePath(); + StateHasChanged(); + }; + _mapDisplayOptions.ShowColorMap = true; _mapPopupParameters = new Dictionary { { "MapDisplayData", _mapDisplayOptions }, }; - BackgroundImageChanger.BackgroundImage = BackgroundImage; - await GetBacgroundAsync(); - - BackgroundImageChanger.BackgroundImageChanged += OnBgChanged!; - await base.OnInitializedAsync(); } @@ -76,19 +84,99 @@ private void Logout() ProtectedSessionStore.DeleteAsync("username"); } - //this piece of codes refreshes GamePage after changing background image. It is necessary to show new background. - private async Task GetBacgroundAsync() - { - await BackgroundImageChanger.ChangeBackgroundImageAsync(); - } + //BackgroundImage = MapBackgroundImageChanger.GetBackgroundImageForTile( + //MovementService.CurrentMap!.GetTile(args.NewPosition) - private void OnBgChanged(object sender, EventArgs e) + private string GetBackgroundImagePath() { - this.InvokeAsync(this.StateHasChanged); - } + if (MovementService.CurrentMap is null) + { + Logger.LogError("Current map is null"); + return string.Empty; + } - public void Dispose() - { - BackgroundImageChanger.BackgroundImageChanged -= OnBgChanged!; + if ( + MovementService.CurrentX < 0 + || MovementService.CurrentY < 0 + || MovementService.CurrentX >= MovementService.CurrentMap.Width + || MovementService.CurrentY >= MovementService.CurrentMap.Height + ) + { + Logger.LogError("Character is out of map"); + return string.Empty; + } + var cell = MovementService.CurrentMap.Grid[ + MovementService.CurrentX, + MovementService.CurrentY + ]; + var biome = cell.Biome; + + if (biome is null) + { + Logger.LogError("Biome is null"); + return string.Empty; + } + + string? imagePath = null; + if (cell.LocationType != LocationType.None) + { + var currentLocationName = cell.LocationType.ToString(); + var location = biome.Locations.FirstOrDefault(l => + string.Equals(l.Name, currentLocationName, StringComparison.OrdinalIgnoreCase) + ); + + if (location is null) + { + Logger.LogWarning( + "No matching location config for LocationType {LocationType} at ({X},{Y}) in biome {BiomeName}. Available: {Locations}", + cell.LocationType, + MovementService.CurrentX, + MovementService.CurrentY, + biome.Name, + string.Join( + ", ", + biome + .Locations.Where(l => !string.IsNullOrWhiteSpace(l.Name)) + .Select(l => l.Name) + ) + ); + } + else + { + imagePath = location.BackgroundImage; + Logger.LogInformation( + "Using location background image '{ImagePath}' for LocationType {LocationType} at ({X},{Y})", + imagePath, + cell.LocationType, + MovementService.CurrentX, + MovementService.CurrentY + ); + } + } + if (string.IsNullOrWhiteSpace(imagePath)) + { + imagePath = biome.BackgroundImage; + Logger.LogInformation( + "Using biome background image '{ImagePath}' for biome {BiomeName} at ({X},{Y})", + imagePath, + biome.Name, + MovementService.CurrentX, + MovementService.CurrentY + ); + } + + if (string.IsNullOrWhiteSpace(imagePath)) + { + Logger.LogError("Background image path is null or empty"); + return string.Empty; + } + + return imagePath; } + + //public override void Dispose() + //{ + // //MovementService.OnMoved -= + // return base.Dispose(); + //} } diff --git a/Server/Modules/MapGenerator/UI/MapView.razor b/Server/Modules/MapGenerator/UI/MapView.razor index 2481be4..5c24d62 100644 --- a/Server/Modules/MapGenerator/UI/MapView.razor +++ b/Server/Modules/MapGenerator/UI/MapView.razor @@ -122,9 +122,7 @@ protected override void OnInitialized() { CharacterX = MovementService.CurrentX; - CharacterY = MovementService.CurrentY; - - BackgroundImageChanger.BackgroundImage = GamePage.BackgroundImage; + CharacterY = MovementService.CurrentY; } private string GetArrowForDirection(int xDirection, int yDirection) @@ -184,8 +182,7 @@ await MovementService.MoveAsync(newX, newY); CharacterX = newX; CharacterY = newY; - - await BackgroundImageChanger.ChangeBackgroundImageAsync(); + StateHasChanged(); } diff --git a/Server/Modules/Shared/ImageChangers/BackgroundImageChanger.cs b/Server/Modules/Shared/ImageChangers/BackgroundImageChanger.cs index ec2aa7e..50b662c 100644 --- a/Server/Modules/Shared/ImageChangers/BackgroundImageChanger.cs +++ b/Server/Modules/Shared/ImageChangers/BackgroundImageChanger.cs @@ -1,109 +1,11 @@ using Fracture.Server.Modules.MapGenerator.Models.Map; using Fracture.Server.Modules.MapGenerator.Services; using Fracture.Server.Modules.MapGenerator.UI; +using Fracture.Server.Modules.Users.Services; namespace Fracture.Server.Modules.Shared.ImageChangers; public class BackgroundImageChanger( ILogger logger, - MapManagerService mapManagerService -) -{ - public required BackgroundImage? BackgroundImage { get; set; } - public required MapManagerService MapManagerService { get; set; } = mapManagerService; - - public Task ChangeBackgroundImageAsync() - { - //if (BackgroundImage is null) - //{ - // logger.LogError("BackgroundImage is null"); - // return Task.CompletedTask; - //} - //var currentMap = MapManagerService.CurrentMap; - //if (currentMap.Grid is null) - //{ - // logger.LogError("Grid is null"); - // return Task.CompletedTask; - //} - - //if (x < 0 || y < 0 || x >= currentMap.Width || y >= currentMap.Height) - //{ - // logger.LogError("Character is out of map"); - // return Task.CompletedTask; - //} - //var cell = currentMap.Grid[x, y]; - //var biome = cell.Biome; - - //if (biome is null) - //{ - // logger.LogError("Biome is null"); - // return Task.CompletedTask; - //} - - //string? imagePath = null; - //if (cell.LocationType != LocationType.None) - //{ - // var currentLocationName = cell.LocationType.ToString(); - // var location = biome.Locations.FirstOrDefault(l => - // string.Equals(l.Name, currentLocationName, StringComparison.OrdinalIgnoreCase) - // ); - - // if (location is null) - // { - // logger.LogWarning( - // "No matching location config for LocationType {LocationType} at ({X},{Y}) in biome {BiomeName}. Available: {Locations}", - // cell.LocationType, - // x, - // y, - // biome.Name, - // string.Join( - // ", ", - // biome - // .Locations.Where(l => !string.IsNullOrWhiteSpace(l.Name)) - // .Select(l => l.Name) - // ) - // ); - // } - // else - // { - // imagePath = location.BackgroundImage; - // logger.LogInformation( - // "Using location background image '{ImagePath}' for LocationType {LocationType} at ({X},{Y})", - // imagePath, - // cell.LocationType, - // x, - // y - // ); - // } - //} - //if (string.IsNullOrWhiteSpace(imagePath)) - //{ - // imagePath = biome.BackgroundImage; - // logger.LogInformation( - // "Using biome background image '{ImagePath}' for biome {BiomeName} at ({X},{Y})", - // imagePath, - // biome.Name, - // x, - // y - // ); - //} - - //if (string.IsNullOrWhiteSpace(imagePath)) - //{ - // logger.LogError("Background image path is null or empty"); - // return Task.CompletedTask; - //} - - //BackgroundImage.ImagePath = imagePath; - //NotifyListChanged(this, EventArgs.Empty); - - return Task.CompletedTask; - } - - public event EventHandler? BackgroundImageChanged; - - public void NotifyListChanged(object? sender, EventArgs e) - { - BackgroundImageChanged?.Invoke(sender, e); - } -} + MovementService movementService +) { } diff --git a/Server/Modules/Users/Services/MovementService.cs b/Server/Modules/Users/Services/MovementService.cs index f73bad7..5717327 100644 --- a/Server/Modules/Users/Services/MovementService.cs +++ b/Server/Modules/Users/Services/MovementService.cs @@ -3,6 +3,12 @@ namespace Fracture.Server.Modules.Users.Services; +public record struct Location(int X, int Y) +{ + public int X { get; init; } = X; + public int Y { get; init; } = Y; +} + public class MovementService(UserService _userService, MapManagerService _mapManagerService) { public Map? CurrentMap { get; private set; } @@ -10,8 +16,8 @@ public class MovementService(UserService _userService, MapManagerService _mapMan public int CurrentX { get; private set; } public int CurrentY { get; private set; } - public Action? OnMoved; - public Action? OnMapEntered; + public EventHandler? OnMoved; + public EventHandler<(Map, Location)>? OnMapEntered; public void Initialize() { @@ -19,12 +25,10 @@ public void Initialize() _mapManagerService.GetWorldMap() ?? throw new InvalidOperationException("Map cannot be loaded, critical error"); - OnMapEntered?.Invoke(); - CurrentX = 16; CurrentY = 16; - OnMoved?.Invoke(); + OnMapEntered?.Invoke(this, new(CurrentMap, new Location(CurrentX, CurrentY))); } public bool CanMove(int x, int y) @@ -42,6 +46,6 @@ public async Task MoveAsync(int x, int y) CurrentX = x; CurrentY = y; - OnMoved?.Invoke(); + OnMoved?.Invoke(this, new Location(CurrentX, CurrentY)); } } From 449cfd331c21d817d1721123bd4772416748aae8 Mon Sep 17 00:00:00 2001 From: Marcin Badurowicz Date: Fri, 13 Mar 2026 14:29:41 +0100 Subject: [PATCH 05/18] refactor: remove old background changing logic --- Server/Components/Pages/GamePage.razor | 3 --- Server/Components/Pages/GamePage.razor.cs | 16 +++------------- Server/Modules/MapGenerator/UI/MapView.razor | 2 -- .../Shared/ImageChangers/BackgroundImage.cs | 14 -------------- .../ImageChangers/BackgroundImageChanger.cs | 11 ----------- .../ImageChangers/IBackgroundImageChanger.cs | 11 ----------- Server/Program.cs | 2 -- 7 files changed, 3 insertions(+), 56 deletions(-) delete mode 100644 Server/Modules/Shared/ImageChangers/BackgroundImage.cs delete mode 100644 Server/Modules/Shared/ImageChangers/BackgroundImageChanger.cs delete mode 100644 Server/Modules/Shared/ImageChangers/IBackgroundImageChanger.cs diff --git a/Server/Components/Pages/GamePage.razor b/Server/Components/Pages/GamePage.razor index 01b5cbb..3a861e2 100644 --- a/Server/Components/Pages/GamePage.razor +++ b/Server/Components/Pages/GamePage.razor @@ -12,11 +12,9 @@ @using Fracture.Server.Modules.MapGenerator.UI.Models @using Fracture.Server.Modules.Pathfinding.Models @using Fracture.Server.Modules.Shared -@using Fracture.Server.Modules.Shared.ImageChangers @using Fracture.Server.Modules.Users @using Fracture.Server.Modules.Users.Services @using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage -@* @implements IDisposable *@ @page "/game" @rendermode @(new InteractiveServerRenderMode(false)) @@ -26,7 +24,6 @@ @inject NavigationManager NavigationManager @inject IItemsRepository ItemsRepository @inject VersionInfoProvider VersionInfoProvider -@inject BackgroundImageChanger BackgroundImageChanger @inject UserService UserService @inject MovementService MovementService @inject ILogger Logger diff --git a/Server/Components/Pages/GamePage.razor.cs b/Server/Components/Pages/GamePage.razor.cs index e1ecb48..8f55fa9 100644 --- a/Server/Components/Pages/GamePage.razor.cs +++ b/Server/Components/Pages/GamePage.razor.cs @@ -2,13 +2,12 @@ using Fracture.Server.Modules.MapGenerator.Models.Map; using Fracture.Server.Modules.MapGenerator.UI.Models; using Fracture.Server.Modules.Pathfinding.Models; -using Fracture.Server.Modules.Shared.ImageChangers; using Fracture.Server.Modules.Users.Models; using Fracture.Server.Modules.Users.Services; namespace Fracture.Server.Components.Pages; -public partial class GamePage // : IDisposable +public partial class GamePage { private Dictionary _mapPopupParameters = null!; @@ -84,9 +83,6 @@ private void Logout() ProtectedSessionStore.DeleteAsync("username"); } - //BackgroundImage = MapBackgroundImageChanger.GetBackgroundImageForTile( - //MovementService.CurrentMap!.GetTile(args.NewPosition) - private string GetBackgroundImagePath() { if (MovementService.CurrentMap is null) @@ -144,7 +140,7 @@ private string GetBackgroundImagePath() else { imagePath = location.BackgroundImage; - Logger.LogInformation( + Logger.LogDebug( "Using location background image '{ImagePath}' for LocationType {LocationType} at ({X},{Y})", imagePath, cell.LocationType, @@ -156,7 +152,7 @@ private string GetBackgroundImagePath() if (string.IsNullOrWhiteSpace(imagePath)) { imagePath = biome.BackgroundImage; - Logger.LogInformation( + Logger.LogDebug( "Using biome background image '{ImagePath}' for biome {BiomeName} at ({X},{Y})", imagePath, biome.Name, @@ -173,10 +169,4 @@ private string GetBackgroundImagePath() return imagePath; } - - //public override void Dispose() - //{ - // //MovementService.OnMoved -= - // return base.Dispose(); - //} } diff --git a/Server/Modules/MapGenerator/UI/MapView.razor b/Server/Modules/MapGenerator/UI/MapView.razor index 5c24d62..eca11ab 100644 --- a/Server/Modules/MapGenerator/UI/MapView.razor +++ b/Server/Modules/MapGenerator/UI/MapView.razor @@ -2,11 +2,9 @@ @using Fracture.Server.Modules.MapGenerator.Models.Map @using Fracture.Server.Modules.MapGenerator.UI.Models @using Fracture.Server.Modules.Pathfinding.Models -@using Fracture.Server.Modules.Shared.ImageChangers @using Fracture.Server.Modules.Users.Services @using Microsoft.AspNetCore.Components.Web -@inject BackgroundImageChanger BackgroundImageChanger @inject MovementService MovementService diff --git a/Server/Modules/Shared/ImageChangers/BackgroundImage.cs b/Server/Modules/Shared/ImageChangers/BackgroundImage.cs deleted file mode 100644 index 85f7835..0000000 --- a/Server/Modules/Shared/ImageChangers/BackgroundImage.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace Fracture.Server.Modules.Shared.ImageChangers; - -public class BackgroundImage -{ - public BackgroundImage(string path) - { - ImagePath = path; - } - - [Required] - public string ImagePath { get; set; } -} diff --git a/Server/Modules/Shared/ImageChangers/BackgroundImageChanger.cs b/Server/Modules/Shared/ImageChangers/BackgroundImageChanger.cs deleted file mode 100644 index 50b662c..0000000 --- a/Server/Modules/Shared/ImageChangers/BackgroundImageChanger.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Fracture.Server.Modules.MapGenerator.Models.Map; -using Fracture.Server.Modules.MapGenerator.Services; -using Fracture.Server.Modules.MapGenerator.UI; -using Fracture.Server.Modules.Users.Services; - -namespace Fracture.Server.Modules.Shared.ImageChangers; - -public class BackgroundImageChanger( - ILogger logger, - MovementService movementService -) { } diff --git a/Server/Modules/Shared/ImageChangers/IBackgroundImageChanger.cs b/Server/Modules/Shared/ImageChangers/IBackgroundImageChanger.cs deleted file mode 100644 index 94d737f..0000000 --- a/Server/Modules/Shared/ImageChangers/IBackgroundImageChanger.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Microsoft.AspNetCore.Components; - -namespace Fracture.Server.Modules.Shared.ImageChangers; - -public interface IBackgroundImageChanger -{ - [Parameter] - BackgroundImage BackgroundImage { get; set; } - - void Change(); -} diff --git a/Server/Program.cs b/Server/Program.cs index 88ce56d..0c39034 100644 --- a/Server/Program.cs +++ b/Server/Program.cs @@ -11,7 +11,6 @@ using Fracture.Server.Modules.MapGenerator.Services.TownGen; using Fracture.Server.Modules.Shared; using Fracture.Server.Modules.Shared.Configuration; -using Fracture.Server.Modules.Shared.ImageChangers; using Fracture.Server.Modules.Shared.NameGenerators; using Fracture.Server.Modules.Users.Services; using Hangfire; @@ -40,7 +39,6 @@ builder.Services.AddSingleton(); builder.Services.AddSingleton(); -builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); From e05b33a7181c9cb25d2bdd015fcf37d77c266a07 Mon Sep 17 00:00:00 2001 From: Marcin Badurowicz Date: Fri, 13 Mar 2026 14:31:39 +0100 Subject: [PATCH 06/18] fix: loading background image on map load --- Server/Components/Pages/GamePage.razor.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Server/Components/Pages/GamePage.razor.cs b/Server/Components/Pages/GamePage.razor.cs index 8f55fa9..7e08fd6 100644 --- a/Server/Components/Pages/GamePage.razor.cs +++ b/Server/Components/Pages/GamePage.razor.cs @@ -30,6 +30,7 @@ protected override async Task OnInitializedAsync() if (MovementService.CurrentMap is null) { MovementService.Initialize(); + BackgroundImage = GetBackgroundImagePath(); } MovementService.OnMapEntered += async (sender, args) => From 36e3f1248029d4ee8bcf3238baadb7d93538d317 Mon Sep 17 00:00:00 2001 From: Marcin Badurowicz Date: Fri, 13 Mar 2026 14:36:35 +0100 Subject: [PATCH 07/18] refactor: events --- Server/Modules/Users/Services/MovementService.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Server/Modules/Users/Services/MovementService.cs b/Server/Modules/Users/Services/MovementService.cs index 5717327..7336b36 100644 --- a/Server/Modules/Users/Services/MovementService.cs +++ b/Server/Modules/Users/Services/MovementService.cs @@ -16,8 +16,8 @@ public class MovementService(UserService _userService, MapManagerService _mapMan public int CurrentX { get; private set; } public int CurrentY { get; private set; } - public EventHandler? OnMoved; - public EventHandler<(Map, Location)>? OnMapEntered; + public event EventHandler? OnMoved; + public event EventHandler<(Map, Location)>? OnMapEntered; public void Initialize() { From 05d7975ffe4b7fd2ae8487f24c8b56c4e5c6422b Mon Sep 17 00:00:00 2001 From: Marcin Badurowicz Date: Fri, 13 Mar 2026 14:43:18 +0100 Subject: [PATCH 08/18] refactor: splitting Position --- Server/Modules/Users/Services/MovementService.cs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/Server/Modules/Users/Services/MovementService.cs b/Server/Modules/Users/Services/MovementService.cs index 7336b36..ea03ffa 100644 --- a/Server/Modules/Users/Services/MovementService.cs +++ b/Server/Modules/Users/Services/MovementService.cs @@ -3,12 +3,6 @@ namespace Fracture.Server.Modules.Users.Services; -public record struct Location(int X, int Y) -{ - public int X { get; init; } = X; - public int Y { get; init; } = Y; -} - public class MovementService(UserService _userService, MapManagerService _mapManagerService) { public Map? CurrentMap { get; private set; } @@ -16,8 +10,8 @@ public class MovementService(UserService _userService, MapManagerService _mapMan public int CurrentX { get; private set; } public int CurrentY { get; private set; } - public event EventHandler? OnMoved; - public event EventHandler<(Map, Location)>? OnMapEntered; + public event EventHandler? OnMoved; + public event EventHandler<(Map, Position)>? OnMapEntered; public void Initialize() { @@ -28,7 +22,7 @@ public void Initialize() CurrentX = 16; CurrentY = 16; - OnMapEntered?.Invoke(this, new(CurrentMap, new Location(CurrentX, CurrentY))); + OnMapEntered?.Invoke(this, new(CurrentMap, new Position(CurrentX, CurrentY))); } public bool CanMove(int x, int y) @@ -46,6 +40,6 @@ public async Task MoveAsync(int x, int y) CurrentX = x; CurrentY = y; - OnMoved?.Invoke(this, new Location(CurrentX, CurrentY)); + OnMoved?.Invoke(this, new Position(CurrentX, CurrentY)); } } From 2d1bc941ee20b01b303eef422f825637a7e780d7 Mon Sep 17 00:00:00 2001 From: Marcin Badurowicz Date: Fri, 13 Mar 2026 14:44:24 +0100 Subject: [PATCH 09/18] refactor: temporarily remove dependency on userservice --- Server/Modules/Users/Services/MovementService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Server/Modules/Users/Services/MovementService.cs b/Server/Modules/Users/Services/MovementService.cs index ea03ffa..435d12c 100644 --- a/Server/Modules/Users/Services/MovementService.cs +++ b/Server/Modules/Users/Services/MovementService.cs @@ -3,7 +3,7 @@ namespace Fracture.Server.Modules.Users.Services; -public class MovementService(UserService _userService, MapManagerService _mapManagerService) +public class MovementService(MapManagerService _mapManagerService) { public Map? CurrentMap { get; private set; } From 1a98b08c0efbdab4f595feb60b03a45eaefa1e32 Mon Sep 17 00:00:00 2001 From: Marcin Badurowicz Date: Fri, 13 Mar 2026 14:46:32 +0100 Subject: [PATCH 10/18] refactor: change namespaces --- Server/Modules/MapGenerator/Models/Map/Position.cs | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 Server/Modules/MapGenerator/Models/Map/Position.cs diff --git a/Server/Modules/MapGenerator/Models/Map/Position.cs b/Server/Modules/MapGenerator/Models/Map/Position.cs new file mode 100644 index 0000000..88ad463 --- /dev/null +++ b/Server/Modules/MapGenerator/Models/Map/Position.cs @@ -0,0 +1,7 @@ +namespace Fracture.Server.Modules.MapGenerator.Models.Map; + +public record struct Position(int X, int Y) +{ + public int X { get; init; } = X; + public int Y { get; init; } = Y; +} From eaf67eafe79623278adff8b424c977aadddef9a4 Mon Sep 17 00:00:00 2001 From: Marcin Badurowicz Date: Fri, 13 Mar 2026 15:03:16 +0100 Subject: [PATCH 11/18] feat: random start location --- Server/Modules/MapGenerator/Models/Map/Map.cs | 15 ++++++++++++++- Server/Modules/Users/Services/MovementService.cs | 5 +++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Server/Modules/MapGenerator/Models/Map/Map.cs b/Server/Modules/MapGenerator/Models/Map/Map.cs index 81d5f87..2b6a55e 100644 --- a/Server/Modules/MapGenerator/Models/Map/Map.cs +++ b/Server/Modules/MapGenerator/Models/Map/Map.cs @@ -10,5 +10,18 @@ public class Map public int Width { get; set; } public int Height { get; set; } - public Node[,] Grid { get; set; } + public required Node[,] Grid { get; set; } + + public Position GetRandomWalkableNode() + { + var rnd = new Random(); + + Position node; + do + { + node = new Position() { X = rnd.Next(0, Width), Y = rnd.Next(0, Height) }; + } while (!Grid[node.X, node.Y].Walkable); + + return node; + } } diff --git a/Server/Modules/Users/Services/MovementService.cs b/Server/Modules/Users/Services/MovementService.cs index 435d12c..ccbecaf 100644 --- a/Server/Modules/Users/Services/MovementService.cs +++ b/Server/Modules/Users/Services/MovementService.cs @@ -19,8 +19,9 @@ public void Initialize() _mapManagerService.GetWorldMap() ?? throw new InvalidOperationException("Map cannot be loaded, critical error"); - CurrentX = 16; - CurrentY = 16; + var start = CurrentMap.GetRandomWalkableNode(); + CurrentX = start.X; + CurrentY = start.Y; OnMapEntered?.Invoke(this, new(CurrentMap, new Position(CurrentX, CurrentY))); } From 9f01a731146f3ef93f0940fbdb0daee1d28c5c88 Mon Sep 17 00:00:00 2001 From: Marcin Badurowicz Date: Fri, 13 Mar 2026 15:12:19 +0100 Subject: [PATCH 12/18] feat: remove (temporarily) scheduled map generation --- .../Services/MapManagerService.cs | 55 +++++-------------- Server/Program.cs | 10 +--- 2 files changed, 16 insertions(+), 49 deletions(-) diff --git a/Server/Modules/MapGenerator/Services/MapManagerService.cs b/Server/Modules/MapGenerator/Services/MapManagerService.cs index 83c5549..3282291 100644 --- a/Server/Modules/MapGenerator/Services/MapManagerService.cs +++ b/Server/Modules/MapGenerator/Services/MapManagerService.cs @@ -3,26 +3,13 @@ namespace Fracture.Server.Modules.MapGenerator.Services; -public class MapManagerService +public class MapManagerService( + IMapRepository mapRepository, + ILogger logger, + IWorldGenerationService worldGenerationService +) { - private readonly IRecurringJobManager _jobManager; - private readonly IServiceScopeFactory _scopeFactory; - private readonly object _lock = new(); - private readonly ILogger _logger; - private readonly IMapRepository _mapRepository; - - public MapManagerService( - IServiceScopeFactory scopeFactory, - IRecurringJobManager jobManager, - IMapRepository mapRepository, - ILogger logger - ) - { - _scopeFactory = scopeFactory; - _jobManager = jobManager; - _mapRepository = mapRepository; - _logger = logger; - } + private readonly Lock _lock = new(); public Map CurrentMap { get; private set; } = default!; @@ -42,40 +29,24 @@ public void SetWorldMap(Map map) } } - public async Task InitializeAndScheduleMapsAsync() + public async Task GenerateWorldAsync() { - using var scope = _scopeFactory.CreateScope(); - var worldGenerationService = - scope.ServiceProvider.GetRequiredService(); - - _mapRepository.ClearMaps(); + mapRepository.ClearMaps(); var map = await worldGenerationService.GenerateWorldMapAsync(); - _mapRepository.SaveMap(map); + mapRepository.SaveMap(map); SetWorldMap(map); - _jobManager.AddOrUpdate( - "cykliczny-import-map", - service => service.RefreshMapsAndSetNewAsync(), - Cron.Minutely - ); - - _logger.LogInformation( - "Mapy zostały zainicjalizowane, a zadanie cykliczne zarejestrowane." - ); + logger.LogInformation("Maps initialized."); } public async Task RefreshMapsAndSetNewAsync() { - using var scope = _scopeFactory.CreateScope(); - var worldGenerationService = - scope.ServiceProvider.GetRequiredService(); - - _logger.LogInformation("Rozpoczynanie generowania nowej mapy..."); + logger.LogInformation("Generating new world..."); var newMap = await worldGenerationService.GenerateWorldMapAsync(); - _mapRepository.SaveMap(newMap); + mapRepository.SaveMap(newMap); SetWorldMap(newMap); - _logger.LogInformation($"Nowa mapa ustawiona: {newMap.Name}"); + logger.LogInformation($"New map set: {newMap.Name}"); } } diff --git a/Server/Program.cs b/Server/Program.cs index 0c39034..11b874d 100644 --- a/Server/Program.cs +++ b/Server/Program.cs @@ -47,16 +47,14 @@ builder.Services.AddTransient(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); -builder.Services.AddScoped(); +builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); -builder.Services.AddHangfire(config => config.UseInMemoryStorage()); // lub .UseSqlServerStorage(connectionString) builder.Services.AddSingleton(typeof(IFloodFillService<>), typeof(FloodFillService<>)); -builder.Services.AddHangfireServer(); builder.Services.AddFeatureManagement(); builder.Services.AddSingleton(); @@ -108,9 +106,6 @@ app.UseExceptionHandler("/Error", true); } -app.UseHangfireDashboard(); -app.UseHangfireServer(); - app.UseStaticFiles(); app.UseAuthorization(); @@ -125,7 +120,8 @@ using (var scope = app.Services.CreateScope()) { var mapManagerService = scope.ServiceProvider.GetRequiredService(); - await mapManagerService.InitializeAndScheduleMapsAsync(); + await mapManagerService.GenerateWorldAsync(); + var db = scope.ServiceProvider.GetRequiredService(); db.Database.Migrate(); } From 37c81047fabe2b094741c5c8697f68c3342582bd Mon Sep 17 00:00:00 2001 From: Marcin Badurowicz Date: Fri, 13 Mar 2026 15:27:05 +0100 Subject: [PATCH 13/18] refactor: add required --- .../Modules/MapGenerator/Models/Map/Node.cs | 26 ++++-------- .../Services/MapGeneratorService.cs | 21 ++++++++-- .../Services/WorldGenerationService.cs | 41 ++++++------------- 3 files changed, 37 insertions(+), 51 deletions(-) diff --git a/Server/Modules/MapGenerator/Models/Map/Node.cs b/Server/Modules/MapGenerator/Models/Map/Node.cs index 87168e4..1c2dcc5 100644 --- a/Server/Modules/MapGenerator/Models/Map/Node.cs +++ b/Server/Modules/MapGenerator/Models/Map/Node.cs @@ -7,32 +7,20 @@ namespace Fracture.Server.Modules.MapGenerator.Models.Map; public class Node : IPathfindingNode { - public Node(int xId, int yId, Biome.Biome biome) - { - XId = xId; - YId = yId; - Biome = biome; - } + public required Biome.Biome Biome { get; set; } - [Required] - public Biome.Biome Biome { get; set; } + public required string TerrainType { get; set; } - [Required] - public string TerrainType { get; set; } + public required float NoiseValue { get; set; } - [Required] - public float NoiseValue { get; set; } - - public string GroupName { get; set; } + public string? GroupName { get; set; } public LocationType LocationType { get; set; } = LocationType.None; - public IMapObject MapObject { get; set; } + public IMapObject? MapObject { get; set; } - [Required] - public int XId { get; set; } + public required int XId { get; set; } - [Required] - public int YId { get; set; } + public required int YId { get; set; } public int GCost { get; set; } public int HCost { get; set; } diff --git a/Server/Modules/MapGenerator/Services/MapGeneratorService.cs b/Server/Modules/MapGenerator/Services/MapGeneratorService.cs index 687ecc3..77993d6 100644 --- a/Server/Modules/MapGenerator/Services/MapGeneratorService.cs +++ b/Server/Modules/MapGenerator/Services/MapGeneratorService.cs @@ -111,27 +111,42 @@ public async Task GetMap(MapParameters? mapParameters) ) ); - Biome biome = null; + Biome? biome = null; if (biomeCategory != null) { biome = biomeCategory.Biomes.FirstOrDefault(sb => temperatureMap[x, y] >= sb.MinTemperature && temperatureMap[x, y] < sb.MaxTemperature )!; + if (biome == null) + { _logger.LogError( string.Format( - "No biome found for temperature {0} at ({1}, {2}) within category {3}", + "No biome found for temperature {0} at ({1}, {2}) within category {3}: using default", temperatureMap[x, y], x, y, biomeCategory.TerrainType ) ); + + biome = biomeCategory.Biomes.FirstOrDefault()!; + ArgumentNullException.ThrowIfNull( + biome, + string.Format( + "Biome category {0} has no biomes defined.", + biomeCategory.TerrainType + ) + ); + } } - grid[x, y] = new Node(x, y, biome) + grid[x, y] = new Node() { + XId = x, + YId = y, + Biome = biome!, NoiseValue = heightMap[x, y], Walkable = biome?.Walkable == true, TerrainType = biomeCategory!.TerrainType, diff --git a/Server/Modules/MapGenerator/Services/WorldGenerationService.cs b/Server/Modules/MapGenerator/Services/WorldGenerationService.cs index 5e4bd4d..b36efd6 100644 --- a/Server/Modules/MapGenerator/Services/WorldGenerationService.cs +++ b/Server/Modules/MapGenerator/Services/WorldGenerationService.cs @@ -1,39 +1,22 @@ -using Fracture.Server.Modules.FloodFill; -using Fracture.Server.Modules.MapGenerator.Models.Map; -using Fracture.Server.Modules.MapGenerator.Models.Map.Biome; -using Fracture.Server.Modules.MapGenerator.Models.Map.MapObjects; -using Fracture.Server.Modules.MapGenerator.Models.Map.Town; -using Fracture.Server.Modules.MapGenerator.Services.TownGen; +using Fracture.Server.Modules.MapGenerator.Models.Map; namespace Fracture.Server.Modules.MapGenerator.Services; -public class WorldGenerationService : IWorldGenerationService +public class WorldGenerationService( + IMapParameterSelectorService parameterSelector, + IMapGeneratorService mapGenerator, + ISubMapAssignmentService subMapAssigner, + ILogger logger +) : IWorldGenerationService { - private readonly IMapParameterSelectorService _parameterSelector; - private readonly IMapGeneratorService _mapGenerator; - private readonly ISubMapAssignmentService _subMapAssigner; - private readonly ILogger _logger; - - public WorldGenerationService( - IMapParameterSelectorService parameterSelector, - IMapGeneratorService mapGenerator, - ISubMapAssignmentService subMapAssigner, - ILogger logger - ) - { - _parameterSelector = parameterSelector; - _mapGenerator = mapGenerator; - _subMapAssigner = subMapAssigner; - _logger = logger; - } - public async Task GenerateWorldMapAsync() { - var parameters = await _parameterSelector.GetParametersAsync(); - var mainParameter = _parameterSelector.SelectRandom(parameters, LocationType.MainLocation); - var map = await _mapGenerator.GetMap(mainParameter); + logger.LogInformation("Generating main world..."); + var parameters = await parameterSelector.GetParametersAsync(); + var mainParameter = parameterSelector.SelectRandom(parameters, LocationType.MainLocation); + var map = await mapGenerator.GetMap(mainParameter); - await _subMapAssigner.AssignSubMapsAsync(map, parameters); + await subMapAssigner.AssignSubMapsAsync(map, parameters); return map; } From fef257178fbd02c843a0f5b023123a7fb02d34bd Mon Sep 17 00:00:00 2001 From: Marcin Badurowicz Date: Fri, 13 Mar 2026 15:32:16 +0100 Subject: [PATCH 14/18] chore: fix warnings --- Server/Modules/Items/Models/ItemStatistics.cs | 2 +- Server/Modules/MapGenerator/Models/Map/Biome/Biome.cs | 2 +- .../MapGenerator/Models/Map/Biome/BiomeCategory.cs | 9 ++++----- Server/Modules/MapGenerator/Models/Map/Biome/Location.cs | 4 ++-- .../MapGenerator/Models/Map/MapObjects/IMapObject.cs | 2 +- .../Models/Map/MapObjects/LocationMapObject.cs | 2 +- .../MapGenerator/Models/Map/MapObjects/NPCMapObject.cs | 2 +- .../Modules/MapGenerator/Services/MapGeneratorService.cs | 4 ++-- .../Services/TownGen/LocationBiomeWeightGenService.cs | 6 +++--- .../Modules/Pathfinding/Services/PathfindingService.cs | 2 +- 10 files changed, 17 insertions(+), 18 deletions(-) diff --git a/Server/Modules/Items/Models/ItemStatistics.cs b/Server/Modules/Items/Models/ItemStatistics.cs index f830f9a..1875278 100644 --- a/Server/Modules/Items/Models/ItemStatistics.cs +++ b/Server/Modules/Items/Models/ItemStatistics.cs @@ -20,7 +20,7 @@ public class ItemStatistics [InverseProperty(nameof(Item.Statistics))] [JsonIgnore] - public virtual Item Item { get; set; } + public virtual required Item Item { get; set; } public int GetStatFromItemStat(ItemStat stat) { diff --git a/Server/Modules/MapGenerator/Models/Map/Biome/Biome.cs b/Server/Modules/MapGenerator/Models/Map/Biome/Biome.cs index be9f13e..e985062 100644 --- a/Server/Modules/MapGenerator/Models/Map/Biome/Biome.cs +++ b/Server/Modules/MapGenerator/Models/Map/Biome/Biome.cs @@ -9,6 +9,6 @@ public class Biome public float MinTemperature { get; set; } public float MaxTemperature { get; set; } public bool Walkable { get; set; } = true; - public string BackgroundImage { get; set; } + public string? BackgroundImage { get; set; } public List Locations { get; set; } = new(); } diff --git a/Server/Modules/MapGenerator/Models/Map/Biome/BiomeCategory.cs b/Server/Modules/MapGenerator/Models/Map/Biome/BiomeCategory.cs index 8d8f0af..b60dd19 100644 --- a/Server/Modules/MapGenerator/Models/Map/Biome/BiomeCategory.cs +++ b/Server/Modules/MapGenerator/Models/Map/Biome/BiomeCategory.cs @@ -4,14 +4,13 @@ namespace Fracture.Server.Modules.MapGenerator.Models.Map.Biome; public class BiomeCategory { - public string BiomeType { get; set; } - public string TerrainType { get; set; } + public required string BiomeType { get; set; } + public required string TerrainType { get; set; } - public string BackgroundImage { get; set; } + public string? BackgroundImage { get; set; } public float MaxHeight { get; set; } public float MinHeight { get; set; } - [Required] - public List Biomes { get; set; } + public required List Biomes { get; set; } = []; } diff --git a/Server/Modules/MapGenerator/Models/Map/Biome/Location.cs b/Server/Modules/MapGenerator/Models/Map/Biome/Location.cs index 70c1e10..f113142 100644 --- a/Server/Modules/MapGenerator/Models/Map/Biome/Location.cs +++ b/Server/Modules/MapGenerator/Models/Map/Biome/Location.cs @@ -2,8 +2,8 @@ public class Location { - public string? Name { get; set; } // name of the location what you want to generate for example town + public string? Name { get; set; } // name of the location what you want to generate, for example: town public int Weight { get; set; } public float Mult { get; set; } - public string BackgroundImage { get; set; } + public string? BackgroundImage { get; set; } } diff --git a/Server/Modules/MapGenerator/Models/Map/MapObjects/IMapObject.cs b/Server/Modules/MapGenerator/Models/Map/MapObjects/IMapObject.cs index 5dd7e1a..590351a 100644 --- a/Server/Modules/MapGenerator/Models/Map/MapObjects/IMapObject.cs +++ b/Server/Modules/MapGenerator/Models/Map/MapObjects/IMapObject.cs @@ -2,6 +2,6 @@ public interface IMapObject { - string Type { get; set; } + string Id { get; set; } bool IsInteractive { get; set; } } diff --git a/Server/Modules/MapGenerator/Models/Map/MapObjects/LocationMapObject.cs b/Server/Modules/MapGenerator/Models/Map/MapObjects/LocationMapObject.cs index f1ea1e7..6aa8d37 100644 --- a/Server/Modules/MapGenerator/Models/Map/MapObjects/LocationMapObject.cs +++ b/Server/Modules/MapGenerator/Models/Map/MapObjects/LocationMapObject.cs @@ -3,7 +3,7 @@ public class LocationMapObject : IMapObject { public Map? SubMap { get; set; } - public string Type { get; set; } = "Location"; + public string Id { get; set; } = "Location"; public bool IsInteractive { get; set; } } diff --git a/Server/Modules/MapGenerator/Models/Map/MapObjects/NPCMapObject.cs b/Server/Modules/MapGenerator/Models/Map/MapObjects/NPCMapObject.cs index c240296..ac42be8 100644 --- a/Server/Modules/MapGenerator/Models/Map/MapObjects/NPCMapObject.cs +++ b/Server/Modules/MapGenerator/Models/Map/MapObjects/NPCMapObject.cs @@ -2,6 +2,6 @@ public class NpcMapObject : IMapObject { - public string Type { get; set; } + public required string Id { get; set; } public bool IsInteractive { get; set; } } diff --git a/Server/Modules/MapGenerator/Services/MapGeneratorService.cs b/Server/Modules/MapGenerator/Services/MapGeneratorService.cs index 77993d6..bb3fcde 100644 --- a/Server/Modules/MapGenerator/Services/MapGeneratorService.cs +++ b/Server/Modules/MapGenerator/Services/MapGeneratorService.cs @@ -19,9 +19,9 @@ public async Task GetMap(MapParameters? mapParameters) return await Task.FromResult(GenerateMap(mapParameters)); } - private Node[,] GenerateGrid(MapParameters? mapParameters) + private Node[,] GenerateGrid(MapParameters mapParameters) { - var noiseParameters = mapParameters?.NoiseParameters; + var noiseParameters = mapParameters.NoiseParameters; noiseParameters.Seed = noiseParameters.UseRandomSeed ? _rnd.Next(-100000, 100000) : noiseParameters.Seed; diff --git a/Server/Modules/MapGenerator/Services/TownGen/LocationBiomeWeightGenService.cs b/Server/Modules/MapGenerator/Services/TownGen/LocationBiomeWeightGenService.cs index 541882f..bbba266 100644 --- a/Server/Modules/MapGenerator/Services/TownGen/LocationBiomeWeightGenService.cs +++ b/Server/Modules/MapGenerator/Services/TownGen/LocationBiomeWeightGenService.cs @@ -6,7 +6,7 @@ namespace Fracture.Server.Modules.MapGenerator.Services.TownGen; public class LocationBiomeWeightGenService : ILocationWeightGeneratorService { private readonly ILogger _logger; - private LocationParameters _locationParameters; + private LocationParameters? _locationParameters; public LocationBiomeWeightGenService(ILogger logger) { @@ -64,14 +64,14 @@ private int CalculateWeight(Node[,] nodes, int height, int width, int x, int y) private int GetWeight(Node node) { - var biomeParams = _locationParameters.Get(node.Biome.Name); + var biomeParams = _locationParameters!.Get(node.Biome.Name); return biomeParams.Weight; } // Self multipliers to make a mountain city surrounded mountains or hills less likely private float GetMultiplier(Node node) { - var biomeParams = _locationParameters.Get(node.Biome.Name); + var biomeParams = _locationParameters!.Get(node.Biome.Name); return biomeParams.Mult; } } diff --git a/Server/Modules/Pathfinding/Services/PathfindingService.cs b/Server/Modules/Pathfinding/Services/PathfindingService.cs index 3655ea4..b55a367 100644 --- a/Server/Modules/Pathfinding/Services/PathfindingService.cs +++ b/Server/Modules/Pathfinding/Services/PathfindingService.cs @@ -80,7 +80,7 @@ private List GetNeighbors(IPathfindingNode node) return neighbors; } - private List ReconstructPath(IPathfindingNode node) + private List ReconstructPath(IPathfindingNode? node) { List path = new List(); From acdf457c0b14acf2cc692f35ec8fecd3f4509436 Mon Sep 17 00:00:00 2001 From: Marcin Badurowicz Date: Fri, 13 Mar 2026 15:39:44 +0100 Subject: [PATCH 15/18] feat: showing that biome is not walkable --- Server/Modules/MapGenerator/UI/NodeInfo.razor | 17 +++++++++++------ .../MapGenerator/UI/NoiseParametersView.razor | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/Server/Modules/MapGenerator/UI/NodeInfo.razor b/Server/Modules/MapGenerator/UI/NodeInfo.razor index 4aa57ab..45f8fe9 100644 --- a/Server/Modules/MapGenerator/UI/NodeInfo.razor +++ b/Server/Modules/MapGenerator/UI/NodeInfo.razor @@ -1,12 +1,17 @@ @using Fracture.Server.Modules.MapGenerator.Models.Map +
- Biome: @Node?.Biome.Name - Location: @(string.IsNullOrWhiteSpace(Node?.GroupName) - ? Node.LocationType - : Node.GroupName) + Biome: @Node.Biome.Name + @if (!string.IsNullOrWhiteSpace(Node.GroupName)) + { + Location: @Node.GroupName + } + @if (!Node.Walkable) + { + Not walkable! + }
@code { - [Parameter] public Node? Node { get; set; } - + [Parameter] public required Node Node { get; set; } } \ No newline at end of file diff --git a/Server/Modules/MapGenerator/UI/NoiseParametersView.razor b/Server/Modules/MapGenerator/UI/NoiseParametersView.razor index f7a7696..d5551ac 100644 --- a/Server/Modules/MapGenerator/UI/NoiseParametersView.razor +++ b/Server/Modules/MapGenerator/UI/NoiseParametersView.razor @@ -13,7 +13,7 @@
@code { - [Parameter] public NoiseParameters NoiseParameters { get; set; } + [Parameter] public required NoiseParameters NoiseParameters { get; set; } [Parameter] public EventCallback NoiseParametersChanged { get; set; } private Task OnNoiseParametersChanged(ChangeEventArgs e) { From 72c5c4f8fded56653e95cad665bd05fcb9ef802a Mon Sep 17 00:00:00 2001 From: Marcin Badurowicz Date: Fri, 13 Mar 2026 15:46:53 +0100 Subject: [PATCH 16/18] chore: fix warnings --- Server/Modules/MapGenerator/Models/Map/Map.cs | 10 +++++----- .../Models/Map/MapObjects/LocationMapObject.cs | 1 + Server/Modules/MapGenerator/Models/Map/Node.cs | 6 ++---- .../MapGenerator/Models/Map/Town/LocationParameters.cs | 5 +---- 4 files changed, 9 insertions(+), 13 deletions(-) diff --git a/Server/Modules/MapGenerator/Models/Map/Map.cs b/Server/Modules/MapGenerator/Models/Map/Map.cs index 2b6a55e..e2bf9c7 100644 --- a/Server/Modules/MapGenerator/Models/Map/Map.cs +++ b/Server/Modules/MapGenerator/Models/Map/Map.cs @@ -4,13 +4,13 @@ public class Map { public string? Name { get; set; } - public LocationType LocationType { get; set; } + public LocationType LocationType { get; init; } - public List LocationGroups { get; set; } = new(); + public List LocationGroups { get; init; } = []; - public int Width { get; set; } - public int Height { get; set; } - public required Node[,] Grid { get; set; } + public int Width { get; init; } + public int Height { get; init; } + public required Node[,] Grid { get; init; } public Position GetRandomWalkableNode() { diff --git a/Server/Modules/MapGenerator/Models/Map/MapObjects/LocationMapObject.cs b/Server/Modules/MapGenerator/Models/Map/MapObjects/LocationMapObject.cs index 6aa8d37..6687084 100644 --- a/Server/Modules/MapGenerator/Models/Map/MapObjects/LocationMapObject.cs +++ b/Server/Modules/MapGenerator/Models/Map/MapObjects/LocationMapObject.cs @@ -3,6 +3,7 @@ public class LocationMapObject : IMapObject { public Map? SubMap { get; set; } + public string Id { get; set; } = "Location"; public bool IsInteractive { get; set; } diff --git a/Server/Modules/MapGenerator/Models/Map/Node.cs b/Server/Modules/MapGenerator/Models/Map/Node.cs index 1c2dcc5..45638b1 100644 --- a/Server/Modules/MapGenerator/Models/Map/Node.cs +++ b/Server/Modules/MapGenerator/Models/Map/Node.cs @@ -1,6 +1,4 @@ -using System.ComponentModel.DataAnnotations; -using Fracture.Server.Modules.MapGenerator.Models.Map.Biome; -using Fracture.Server.Modules.MapGenerator.Models.Map.MapObjects; +using Fracture.Server.Modules.MapGenerator.Models.Map.MapObjects; using Fracture.Server.Modules.Pathfinding.Models; namespace Fracture.Server.Modules.MapGenerator.Models.Map; @@ -11,7 +9,7 @@ public class Node : IPathfindingNode public required string TerrainType { get; set; } - public required float NoiseValue { get; set; } + public float NoiseValue { get; set; } public string? GroupName { get; set; } diff --git a/Server/Modules/MapGenerator/Models/Map/Town/LocationParameters.cs b/Server/Modules/MapGenerator/Models/Map/Town/LocationParameters.cs index d2ff07b..adb3e68 100644 --- a/Server/Modules/MapGenerator/Models/Map/Town/LocationParameters.cs +++ b/Server/Modules/MapGenerator/Models/Map/Town/LocationParameters.cs @@ -1,7 +1,4 @@ -using System.Text.Json; -using Fracture.Server.Modules.MapGenerator.Models.Map.Biome; - -namespace Fracture.Server.Modules.MapGenerator.Models.Map.Town; +namespace Fracture.Server.Modules.MapGenerator.Models.Map.Town; public class LocationParameters { From 00d6a0975fab0f07b961c03d4bf7cfc95ec6d699 Mon Sep 17 00:00:00 2001 From: Marcin Badurowicz Date: Fri, 13 Mar 2026 15:57:23 +0100 Subject: [PATCH 17/18] feat: add naming towns --- .../Services/LocationGroupGeneratorService.cs | 27 +++++++------------ .../Services/WorldGenerationService.cs | 22 +++++++++++++++ 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/Server/Modules/MapGenerator/Services/LocationGroupGeneratorService.cs b/Server/Modules/MapGenerator/Services/LocationGroupGeneratorService.cs index 74a61b9..907999c 100644 --- a/Server/Modules/MapGenerator/Services/LocationGroupGeneratorService.cs +++ b/Server/Modules/MapGenerator/Services/LocationGroupGeneratorService.cs @@ -1,27 +1,18 @@ using Fracture.Server.Modules.FloodFill; using Fracture.Server.Modules.MapGenerator.Models.Map; using Fracture.Server.Modules.MapGenerator.Services.TownGen; +using Fracture.Server.Modules.Shared; namespace Fracture.Server.Modules.MapGenerator.Services; -public class LocationGroupGeneratorService : ILocationGroupGeneratorService +public class LocationGroupGeneratorService( + ILocationWeightGeneratorService weightGen, + ILocationGeneratorService locationGen, + IFloodFillService floodFill +) : ILocationGroupGeneratorService { - private readonly ILocationWeightGeneratorService _weightGen; - private readonly ILocationGeneratorService _locationGen; - private readonly IFloodFillService _floodFill; private readonly Random _rnd = new(); - public LocationGroupGeneratorService( - ILocationWeightGeneratorService weightGen, - ILocationGeneratorService locationGen, - IFloodFillService floodFill - ) - { - _weightGen = weightGen; - _locationGen = locationGen; - _floodFill = floodFill; - } - public List GenerateGroups( Node[,] grid, int width, @@ -30,10 +21,10 @@ LocationType type ) { var count = _rnd.Next(5, 9); - var weights = _weightGen.GenerateWeights(grid, height, width); - var updated = _locationGen.Generate(grid, weights, height, width, _rnd, count, type); + var weights = weightGen.GenerateWeights(grid, height, width); + var updated = locationGen.Generate(grid, weights, height, width, _rnd, count, type); - var groups = _floodFill.FindGroups( + var groups = floodFill.FindGroups( updated, n => n.LocationType == type, (a, b) => a.LocationType == b.LocationType, diff --git a/Server/Modules/MapGenerator/Services/WorldGenerationService.cs b/Server/Modules/MapGenerator/Services/WorldGenerationService.cs index b36efd6..6f22b7e 100644 --- a/Server/Modules/MapGenerator/Services/WorldGenerationService.cs +++ b/Server/Modules/MapGenerator/Services/WorldGenerationService.cs @@ -1,4 +1,5 @@ using Fracture.Server.Modules.MapGenerator.Models.Map; +using Fracture.Server.Modules.Shared; namespace Fracture.Server.Modules.MapGenerator.Services; @@ -6,6 +7,7 @@ public class WorldGenerationService( IMapParameterSelectorService parameterSelector, IMapGeneratorService mapGenerator, ISubMapAssignmentService subMapAssigner, + INameGenerator nameGenerator, ILogger logger ) : IWorldGenerationService { @@ -13,11 +15,31 @@ public async Task GenerateWorldMapAsync() { logger.LogInformation("Generating main world..."); var parameters = await parameterSelector.GetParametersAsync(); + + // generate main map var mainParameter = parameterSelector.SelectRandom(parameters, LocationType.MainLocation); var map = await mapGenerator.GetMap(mainParameter); + // generate submaps await subMapAssigner.AssignSubMapsAsync(map, parameters); + // rename locations + foreach (var item in map.LocationGroups) + { + item.GroupName = item.LocationType switch + { + LocationType.MainLocation => "The World", + LocationType.Town => "Town " + await nameGenerator.GenerateNameAsync(), + LocationType.Cave => "Cave " + await nameGenerator.GenerateNameAsync(), + _ => item.GroupName, + }; + + foreach (var node in item.Nodes) + { + node.GroupName = item.GroupName; + } + } + return map; } } From e40762899fe024f6115517e57488574e5e78bbc0 Mon Sep 17 00:00:00 2001 From: Marcin Badurowicz Date: Fri, 13 Mar 2026 16:14:52 +0100 Subject: [PATCH 18/18] feat: add possibility to not show player in a map --- Server/Modules/MapGenerator/UI/MapView.razor | 4 ++-- Server/Modules/MapGenerator/UI/Models/MapDisplayOptions.cs | 1 + Server/Modules/MapGenerator/UI/Models/SpecialChars.cs | 5 +++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Server/Modules/MapGenerator/UI/MapView.razor b/Server/Modules/MapGenerator/UI/MapView.razor index eca11ab..3107414 100644 --- a/Server/Modules/MapGenerator/UI/MapView.razor +++ b/Server/Modules/MapGenerator/UI/MapView.razor @@ -19,10 +19,10 @@ { var node = Map.Grid[x, y]; - @if (x == CharacterX && y == CharacterY) + @if (MapDisplayOptions.ShowPlayer && x == CharacterX && y == CharacterY) { - 😐 + @SpecialChars.Icons.Player } else if (MapDisplayOptions.TileInformationDisplay == TileInformationDisplay.Position) diff --git a/Server/Modules/MapGenerator/UI/Models/MapDisplayOptions.cs b/Server/Modules/MapGenerator/UI/Models/MapDisplayOptions.cs index c1cab75..10a185b 100644 --- a/Server/Modules/MapGenerator/UI/Models/MapDisplayOptions.cs +++ b/Server/Modules/MapGenerator/UI/Models/MapDisplayOptions.cs @@ -3,5 +3,6 @@ public class MapDisplayOptions { public bool ShowColorMap { get; set; } = true; + public bool ShowPlayer { get; set; } = true; public TileInformationDisplay TileInformationDisplay { get; set; } } diff --git a/Server/Modules/MapGenerator/UI/Models/SpecialChars.cs b/Server/Modules/MapGenerator/UI/Models/SpecialChars.cs index 2be6fa9..0e22eaa 100644 --- a/Server/Modules/MapGenerator/UI/Models/SpecialChars.cs +++ b/Server/Modules/MapGenerator/UI/Models/SpecialChars.cs @@ -13,4 +13,9 @@ public static class Arrows public const string Left = "\U00002190"; public const string UpLeft = "\U00002196"; } + + public static class Icons + { + public const string Player = "😐"; + } }