Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions src/Dapr/GameServer.Host/ConfigurationChangeController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace MUnique.OpenMU.GameServer.Host;
using MUnique.OpenMU.Dapr.Common;
using MUnique.OpenMU.Interfaces;
using MUnique.OpenMU.Persistence.EntityFramework;
using MUnique.OpenMU.PlugIns;

/// <summary>
/// The API controller which handles the calls of the <see cref="ConfigurationChangePublisher"/>
Expand All @@ -21,14 +22,17 @@ namespace MUnique.OpenMU.GameServer.Host;
public class ConfigurationChangeController : ControllerBase
{
private readonly IConfigurationChangeListener _changeListener;
private readonly PlugInManager _plugInManager;

/// <summary>
/// Initializes a new instance of the <see cref="ConfigurationChangeController" /> class.
/// </summary>
/// <param name="changeListener">The change listener.</param>
public ConfigurationChangeController(IConfigurationChangeListener changeListener)
/// <param name="plugInManager">The plugin manager.</param>
public ConfigurationChangeController(IConfigurationChangeListener changeListener, PlugInManager plugInManager)
{
this._changeListener = changeListener;
this._plugInManager = plugInManager;
}

/// <summary>
Expand All @@ -50,6 +54,7 @@ public ValueTask ConfigurationAddedAsync([FromBody] ConfigurationChangeArguments
[Topic("pubsub", nameof(IConfigurationChangePublisher.ConfigurationChangedAsync))]
public ValueTask ConfigurationChangedAsync([FromBody] ConfigurationChangeArguments arguments)
{
this._plugInManager.ApplyChangedConfiguration(arguments.Type, arguments.Id, arguments.Configuration);
return this._changeListener.ConfigurationChangedAsync(arguments.Type, arguments.Id, arguments.Configuration!, null);
}

Expand All @@ -61,6 +66,7 @@ public ValueTask ConfigurationChangedAsync([FromBody] ConfigurationChangeArgumen
[Topic("pubsub", nameof(IConfigurationChangePublisher.ConfigurationRemovedAsync))]
public ValueTask ConfigurationRemovedAsync([FromBody] ConfigurationChangeArguments arguments)
{
this._plugInManager.ApplyRemovedConfiguration(arguments.Type, arguments.Id);
return this._changeListener.ConfigurationRemovedAsync(arguments.Type, arguments.Id, null, null);
}
}
}
62 changes: 58 additions & 4 deletions src/GameLogic/GameMapTerrain.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// <copyright file="GameMapTerrain.cs" company="MUnique">
// <copyright file="GameMapTerrain.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>

Expand All @@ -12,11 +12,22 @@ namespace MUnique.OpenMU.GameLogic;
/// </summary>
public class GameMapTerrain
{
/// <summary>
/// The size of the map in each dimension (byte range: 0–255).
/// </summary>
private const int MapSize = 256;

/// <summary>
/// The default terrain where all coordinates are walkable and not a safezone.
/// </summary>
private static readonly byte[] DefaultTerrain = Enumerable.Repeat<byte>(0, short.MaxValue).ToArray();

/// <summary>
/// Pre-computed array of walkable, non-safezone points.
/// Built once during construction for O(1) random spawn lookups.
/// </summary>
private readonly Point[] _spawnPoints;

/// <summary>
/// Initializes a new instance of the <see cref="GameMapTerrain"/> class.
/// </summary>
Expand All @@ -40,22 +51,42 @@ public GameMapTerrain(byte[]? terrainData)
{
this.ReadTerrainData(DefaultTerrain);
}

this._spawnPoints = this.BuildSpawnPoints();
}

/// <summary>
/// Gets a grid of all safezone coordinates.
/// </summary>
public bool[,] SafezoneMap { get; } = new bool[256, 256];
public bool[,] SafezoneMap { get; } = new bool[MapSize, MapSize];

/// <summary>
/// Gets a grid of all walkable coordinates.
/// </summary>
public bool[,] WalkMap { get; } = new bool[256, 256];
public bool[,] WalkMap { get; } = new bool[MapSize, MapSize];

/// <summary>
/// Gets a grid of the walkable coordinates of monsters.
/// </summary>
public byte[,] AIgrid { get; } = new byte[256, 256];
public byte[,] AIgrid { get; } = new byte[MapSize, MapSize];

/// <summary>
/// Gets a random walkable, non-safezone point anywhere on the map.
/// Samples from a pre-computed array in O(1) per call.
/// </summary>
public Point? RandomWalkableCoordinate
{
get
{
var points = this._spawnPoints;
if (points.Length == 0)
{
return null;
}

return points[Random.Shared.Next(points.Length)];
}
}

/// <summary>
/// Gets a random drop coordinate at the specified point in the specified radius.
Expand Down Expand Up @@ -110,4 +141,27 @@ private void ReadTerrainData(ReadOnlySpan<byte> data)
this.UpdateAiGridValue(x, y);
}
}

/// <summary>
/// Builds the array of valid spawn points.
/// A valid spawn point is walkable and not in a safezone.
/// </summary>
/// <returns>Array of valid spawn points.</returns>
private Point[] BuildSpawnPoints()
{
var result = new List<Point>(MapSize * MapSize);

for (var x = 0; x < MapSize; x++)
{
for (var y = 0; y < MapSize; y++)
{
if (this.WalkMap[x, y] && !this.SafezoneMap[x, y])
{
result.Add(new Point((byte)x, (byte)y));
}
}
}

return result.ToArray();
}
}
Loading
Loading