diff --git a/src/TextLore/Components/Layout/MainLayout.razor b/src/TextLore/Components/Layout/MainLayout.razor
index e1f0b6d..71f343c 100644
--- a/src/TextLore/Components/Layout/MainLayout.razor
+++ b/src/TextLore/Components/Layout/MainLayout.razor
@@ -1,7 +1,9 @@
@inherits LayoutComponentBase
-
TextLore — Stone_Red
+
+ TextLore — Stone_Red
+
diff --git a/src/TextLore/Components/Pages/Counter.razor b/src/TextLore/Components/Pages/Counter.razor
deleted file mode 100644
index ef23cb3..0000000
--- a/src/TextLore/Components/Pages/Counter.razor
+++ /dev/null
@@ -1,18 +0,0 @@
-@page "/counter"
-
-
Counter
-
-
Counter
-
-
Current count: @currentCount
-
-
-
-@code {
- private int currentCount = 0;
-
- private void IncrementCount()
- {
- currentCount++;
- }
-}
diff --git a/src/TextLore/Games/Roguelike/RoguelikePage.razor b/src/TextLore/Components/Pages/Games/Roguelike/RoguelikePage.razor
similarity index 100%
rename from src/TextLore/Games/Roguelike/RoguelikePage.razor
rename to src/TextLore/Components/Pages/Games/Roguelike/RoguelikePage.razor
diff --git a/src/TextLore/Games/Roguelike/RoguelikePage.razor.cs b/src/TextLore/Components/Pages/Games/Roguelike/RoguelikePage.razor.cs
similarity index 56%
rename from src/TextLore/Games/Roguelike/RoguelikePage.razor.cs
rename to src/TextLore/Components/Pages/Games/Roguelike/RoguelikePage.razor.cs
index cc99f3b..4c7d207 100644
--- a/src/TextLore/Games/Roguelike/RoguelikePage.razor.cs
+++ b/src/TextLore/Components/Pages/Games/Roguelike/RoguelikePage.razor.cs
@@ -1,11 +1,11 @@
using Microsoft.AspNetCore.Components;
using TextLore.Console;
-using TextLore.Console.Commands;
-using TextLore.Games.Roguelike.Commands;
-using TextLore.Games.Roguelike.Models;
+using TextLore.Shared.Commands;
+using TextLore.Shared.Logic;
+using TextLore.Shared.Models.Level;
-namespace TextLore.Games.Roguelike;
+namespace TextLore.Components.Pages.Games.Roguelike;
public partial class RoguelikePage
{
@@ -14,30 +14,33 @@ public partial class RoguelikePage
// Short description how to play the game
private readonly string desctiption = "This is a roguelike game. Use commands to play the game.";
- private Components.Shared.Console console = null!;
+ private Shared.Console console = null!;
private HelpCommand? helpCommand;
- private Level? level;
+ private GameManager? gameManager = null;
[Parameter]
public string Seed { get; set; } = string.Empty;
- public void OnLevelGenerated(Level level)
+ public async void OnLevelGenerated(Level level)
{
- this.level = level;
+ gameManager = new GameManager(level);
+
+ StateHasChanged();
}
protected override void OnInitialized()
{
helpCommand = new HelpCommand(commands);
commands.Add(helpCommand);
+ commands.Add(new ExitCommand(NavigationManager));
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
- await console.Execute(new GenerateLevelCommand(DatabaseContext.Rooms, NavigationManager, OnLevelGenerated), Seed);
+ await console.Execute(new GenerateLevelCommand("roguelike", DatabaseContext.Rooms, NavigationManager, OnLevelGenerated), Seed);
}
}
}
\ No newline at end of file
diff --git a/src/TextLore/Games/_Imports.razor b/src/TextLore/Components/Pages/Games/_Imports.razor
similarity index 93%
rename from src/TextLore/Games/_Imports.razor
rename to src/TextLore/Components/Pages/Games/_Imports.razor
index 93177f0..03ebe5c 100644
--- a/src/TextLore/Games/_Imports.razor
+++ b/src/TextLore/Components/Pages/Games/_Imports.razor
@@ -11,4 +11,4 @@
@using TextLore.Components
@using TextLore.Components.Shared
@using TextLore.Console
-@using TextLore.Console.Commands
\ No newline at end of file
+@using TextLore.Shared.Commands
\ No newline at end of file
diff --git a/src/TextLore/Components/Pages/Home.razor b/src/TextLore/Components/Pages/Home.razor
index 1802ce1..5363a46 100644
--- a/src/TextLore/Components/Pages/Home.razor
+++ b/src/TextLore/Components/Pages/Home.razor
@@ -1,5 +1,7 @@
@page "/"
+@inject NavigationManager NavigationManager
+
TextLore
@@ -16,5 +18,6 @@
{
helpCommand = new HelpCommand(commands);
commands.Add(helpCommand);
+ commands.Add(new PlayCommand(NavigationManager, "roguelike"));
}
}
\ No newline at end of file
diff --git a/src/TextLore/Components/Pages/Weather.razor b/src/TextLore/Components/Pages/Weather.razor
deleted file mode 100644
index 43a1ecb..0000000
--- a/src/TextLore/Components/Pages/Weather.razor
+++ /dev/null
@@ -1,64 +0,0 @@
-@page "/weather"
-@attribute [StreamRendering]
-
-
Weather
-
-
Weather
-
-
This component demonstrates showing data.
-
-@if (forecasts == null)
-{
-
Loading...
-}
-else
-{
-
-
-
- | Date |
- Temp. (C) |
- Temp. (F) |
- Summary |
-
-
-
- @foreach (var forecast in forecasts)
- {
-
- | @forecast.Date.ToShortDateString() |
- @forecast.TemperatureC |
- @forecast.TemperatureF |
- @forecast.Summary |
-
- }
-
-
-}
-
-@code {
- private WeatherForecast[]? forecasts;
-
- protected override async Task OnInitializedAsync()
- {
- // Simulate asynchronous loading to demonstrate streaming rendering
- await Task.Delay(500);
-
- var startDate = DateOnly.FromDateTime(DateTime.Now);
- var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" };
- forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast
- {
- Date = startDate.AddDays(index),
- TemperatureC = Random.Shared.Next(-20, 55),
- Summary = summaries[Random.Shared.Next(summaries.Length)]
- }).ToArray();
- }
-
- private class WeatherForecast
- {
- public DateOnly Date { get; set; }
- public int TemperatureC { get; set; }
- public string? Summary { get; set; }
- public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
- }
-}
diff --git a/src/TextLore/Components/Shared/Console.razor b/src/TextLore/Components/Shared/Console.razor
index 64a0bc9..ed26dfc 100644
--- a/src/TextLore/Components/Shared/Console.razor
+++ b/src/TextLore/Components/Shared/Console.razor
@@ -56,7 +56,7 @@
[Parameter]
public Command? HelpCommand { get; set; }
- private string Placeholder => $"Enter a command{(HelpCommand is null ? "." : ", type 'help' for avaliable commands.")}";
+ private string Placeholder => disabled ? "Processing..." : $"Enter a command{(HelpCommand is null ? "." : ", type 'help' for avaliable commands.")}";
private ConsoleInput ConsoleInput { get; set; } = new();
private List
consoleOutputs = new();
private ConsoleOutput? currentOutput;
diff --git a/src/TextLore/Components/_Imports.razor b/src/TextLore/Components/_Imports.razor
index 7f50a8c..120d061 100644
--- a/src/TextLore/Components/_Imports.razor
+++ b/src/TextLore/Components/_Imports.razor
@@ -10,4 +10,4 @@
@using TextLore.Components
@using TextLore.Components.Shared
@using TextLore.Console
-@using TextLore.Console.Commands
\ No newline at end of file
+@using TextLore.Shared.Commands
\ No newline at end of file
diff --git a/src/TextLore/Database/GamesDatabaseContext.cs b/src/TextLore/Database/GamesDatabaseContext.cs
index 4affdb1..ff1445e 100644
--- a/src/TextLore/Database/GamesDatabaseContext.cs
+++ b/src/TextLore/Database/GamesDatabaseContext.cs
@@ -1,8 +1,10 @@
using Microsoft.EntityFrameworkCore;
+using TextLore.Shared.Models.Level;
+
namespace TextLore.Database;
public class GamesDatabaseContext(DbContextOptions options) : DbContext(options)
{
- public DbSet Rooms { get; set; }
+ public DbSet Rooms { get; set; }
}
\ No newline at end of file
diff --git a/src/TextLore/Program.cs b/src/TextLore/Program.cs
index 5ac509a..2858ada 100644
--- a/src/TextLore/Program.cs
+++ b/src/TextLore/Program.cs
@@ -2,6 +2,7 @@ using Microsoft.EntityFrameworkCore;
using TextLore.Components;
using TextLore.Database;
+using TextLore.Shared.Models.Level;
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
@@ -29,14 +30,14 @@ GamesDatabaseContext databaseContext = serviceScope.ServiceProvider.GetRequiredS
if (await databaseContext.Database.EnsureCreatedAsync())
{
databaseContext.Rooms.AddRange(
- new TextLore.Games.Roguelike.Models.RoomDefinition(1, TextLore.Games.Roguelike.Models.RoomTag.Start, "rogelike") { Name = "Start Room" },
- new TextLore.Games.Roguelike.Models.RoomDefinition(1, TextLore.Games.Roguelike.Models.RoomTag.Unique, "rogelike") { Name = "Unique Room" },
- new TextLore.Games.Roguelike.Models.RoomDefinition(2, TextLore.Games.Roguelike.Models.RoomTag.None, "rogelike") { Name = "Normal Room 1" },
- new TextLore.Games.Roguelike.Models.RoomDefinition(3, TextLore.Games.Roguelike.Models.RoomTag.None, "rogelike") { Name = "Normal Room 2" },
- new TextLore.Games.Roguelike.Models.RoomDefinition(4, TextLore.Games.Roguelike.Models.RoomTag.None, "rogelike") { Name = "Normal Room 3" },
- new TextLore.Games.Roguelike.Models.RoomDefinition(5, TextLore.Games.Roguelike.Models.RoomTag.None, "rogelike") { Name = "Normal Room 4" },
- new TextLore.Games.Roguelike.Models.RoomDefinition(6, TextLore.Games.Roguelike.Models.RoomTag.None, "rogelike") { Name = "Normal Room 5" },
- new TextLore.Games.Roguelike.Models.RoomDefinition(1, TextLore.Games.Roguelike.Models.RoomTag.End, "rogelike") { Name = "End Room" }
+ new RoomDefinition(1, RoomTag.Start, "roguelike") { Name = "Start Room" },
+ new RoomDefinition(1, RoomTag.Unique, "roguelike") { Name = "Unique Room" },
+ new RoomDefinition(2, RoomTag.None, "roguelike") { Name = "Normal Room 1" },
+ new RoomDefinition(3, RoomTag.None, "roguelike") { Name = "Normal Room 2" },
+ new RoomDefinition(4, RoomTag.None, "roguelike") { Name = "Normal Room 3" },
+ new RoomDefinition(5, RoomTag.None, "roguelike") { Name = "Normal Room 4" },
+ new RoomDefinition(6, RoomTag.None, "roguelike") { Name = "Normal Room 5" },
+ new RoomDefinition(1, RoomTag.End, "roguelike") { Name = "End Room" }
);
_ = await databaseContext.SaveChangesAsync();
diff --git a/src/TextLore/Console/Commands/ClearCommand.cs b/src/TextLore/Shared/Commands/ClearCommand.cs
similarity index 87%
rename from src/TextLore/Console/Commands/ClearCommand.cs
rename to src/TextLore/Shared/Commands/ClearCommand.cs
index 4ed93ac..b59b1ba 100644
--- a/src/TextLore/Console/Commands/ClearCommand.cs
+++ b/src/TextLore/Shared/Commands/ClearCommand.cs
@@ -1,4 +1,6 @@
-namespace TextLore.Console.Commands;
+using TextLore.Console;
+
+namespace TextLore.Shared.Commands;
public class ClearCommand : Command
{
diff --git a/src/TextLore/Shared/Commands/EchoCommand.cs b/src/TextLore/Shared/Commands/EchoCommand.cs
new file mode 100644
index 0000000..5d6d354
--- /dev/null
+++ b/src/TextLore/Shared/Commands/EchoCommand.cs
@@ -0,0 +1,17 @@
+using TextLore.Console;
+
+namespace TextLore.Shared.Commands;
+
+public class EchoCommand : Command
+{
+ public override string Name => "echo";
+
+ public override string Description => "Echoes the input.";
+
+ public override Task Execute(ConsoleWriter consoleOutput, string args)
+ {
+ consoleOutput.WriteLine(args);
+
+ return CommandResult.Success();
+ }
+}
\ No newline at end of file
diff --git a/src/TextLore/Shared/Commands/ExitCommand.cs b/src/TextLore/Shared/Commands/ExitCommand.cs
new file mode 100644
index 0000000..502b78f
--- /dev/null
+++ b/src/TextLore/Shared/Commands/ExitCommand.cs
@@ -0,0 +1,21 @@
+using Microsoft.AspNetCore.Components;
+
+using TextLore.Console;
+
+namespace TextLore.Shared.Commands;
+
+public class ExitCommand(NavigationManager navigationManager) : Command
+{
+ public override string Name => "exit";
+
+ public override string Description => "Exits the game.";
+
+ public override Task Execute(ConsoleWriter consoleOutput, string args)
+ {
+ consoleOutput.WriteLine("Exiting the game...");
+
+ navigationManager.NavigateTo("/");
+
+ return CommandResult.Success();
+ }
+}
\ No newline at end of file
diff --git a/src/TextLore/Games/Roguelike/Commands/GenerateLevelCommand.cs b/src/TextLore/Shared/Commands/GenerateLevelCommand.cs
similarity index 79%
rename from src/TextLore/Games/Roguelike/Commands/GenerateLevelCommand.cs
rename to src/TextLore/Shared/Commands/GenerateLevelCommand.cs
index d1bd3cc..51405dd 100644
--- a/src/TextLore/Games/Roguelike/Commands/GenerateLevelCommand.cs
+++ b/src/TextLore/Shared/Commands/GenerateLevelCommand.cs
@@ -2,21 +2,18 @@
using Microsoft.EntityFrameworkCore;
using TextLore.Console;
-using TextLore.Games.Roguelike.Logic;
-using TextLore.Games.Roguelike.Models;
-using TextLore.Utilities.Logic;
-using TextLore.Utilities.Models;
+using TextLore.Shared.Logic;
+using TextLore.Shared.Models;
+using TextLore.Shared.Models.Level;
-namespace TextLore.Games.Roguelike.Commands;
+namespace TextLore.Shared.Commands;
-public class GenerateLevelCommand(IQueryable roomDefinitions, NavigationManager navigationManager, Action levelGeneratedCallback) : Command
+public class GenerateLevelCommand(string gameName, IQueryable roomDefinitions, NavigationManager navigationManager, Action levelGeneratedCallback) : Command
{
private bool isGenerated = false;
public override string Name => "generatelevel";
public override string Description => "Generates a new level.";
- public override string[] Aliases => ["genlevel"];
-
public override bool NoHistoryIfNoOutput => true;
public override async Task Execute(ConsoleWriter consoleOutput, string args)
@@ -26,12 +23,12 @@ public class GenerateLevelCommand(IQueryable roomDefinitions, Na
consoleOutput.WriteLine("Invalid seed. Generating a new one...");
seed = await GenerateSeed();
- navigationManager.NavigateTo($"/roguelike/{seed.ToBase64()}");
+ navigationManager.NavigateTo($"/{gameName}/{seed.ToBase64()}");
}
consoleOutput.WriteLine("Generating level...");
- LevelGenerator levelGenerator = new LevelGenerator(seed, roomDefinitions);
+ LevelGenerator levelGenerator = new LevelGenerator(seed, roomDefinitions.Where(r => r.Game == gameName));
IProgress progress = new Progress(p => ReportProgress(p, consoleOutput));
@@ -88,8 +85,8 @@ public class GenerateLevelCommand(IQueryable roomDefinitions, Na
private async Task GenerateSeed()
{
int baseSeed = Guid.NewGuid().GetHashCode();
- int min = await roomDefinitions.MinAsync(r => r.Id);
- int max = await roomDefinitions.MaxAsync(r => r.Id);
+ int min = await roomDefinitions.Where(r => r.Game == gameName).MinAsync(r => r.Id);
+ int max = await roomDefinitions.Where(r => r.Game == gameName).MaxAsync(r => r.Id);
return new DeterministicRandom(baseSeed, min, max);
}
diff --git a/src/TextLore/Console/Commands/HelpCommand.cs b/src/TextLore/Shared/Commands/HelpCommand.cs
similarity index 96%
rename from src/TextLore/Console/Commands/HelpCommand.cs
rename to src/TextLore/Shared/Commands/HelpCommand.cs
index 929ebc9..9a20e1a 100644
--- a/src/TextLore/Console/Commands/HelpCommand.cs
+++ b/src/TextLore/Shared/Commands/HelpCommand.cs
@@ -1,4 +1,6 @@
-namespace TextLore.Console.Commands;
+using TextLore.Console;
+
+namespace TextLore.Shared.Commands;
public class HelpCommand(IEnumerable commands) : Command
{
diff --git a/src/TextLore/Shared/Commands/PlayCommand.cs b/src/TextLore/Shared/Commands/PlayCommand.cs
new file mode 100644
index 0000000..462ec48
--- /dev/null
+++ b/src/TextLore/Shared/Commands/PlayCommand.cs
@@ -0,0 +1,49 @@
+using Microsoft.AspNetCore.Components;
+
+using TextLore.Console;
+
+namespace TextLore.Shared.Commands;
+
+public class PlayCommand(NavigationManager navigationManager, params string[] gameNames) : Command
+{
+ public override string Name => "play";
+
+ public override string Description => "Starts a new game.";
+
+ public override string Usage => "play (You only have to type the first few letters of the game name.)";
+
+ public override Task Execute(ConsoleWriter consoleOutput, string args)
+ {
+ if (string.IsNullOrWhiteSpace(args))
+ {
+ consoleOutput.WriteLine("Available games:");
+
+ foreach (string availableGame in gameNames)
+ {
+ consoleOutput.WriteLine($"- {availableGame}");
+ }
+
+ return Task.FromResult(CommandResult.Failure("You need to specify a game to play."));
+ }
+
+ string? game = Array.Find(gameNames, g => g.StartsWith(args, StringComparison.CurrentCultureIgnoreCase));
+
+ if (game is null)
+ {
+ consoleOutput.WriteLine("Available games:");
+
+ foreach (string availableGame in gameNames)
+ {
+ consoleOutput.WriteLine($"- {availableGame}");
+ }
+
+ return Task.FromResult(CommandResult.Failure($"Game '{args}' not found."));
+ }
+
+ consoleOutput.WriteLine($"Starting game '{game}'...");
+
+ navigationManager.NavigateTo($"/{game}");
+
+ return Task.FromResult(CommandResult.Success());
+ }
+}
\ No newline at end of file
diff --git a/src/TextLore/Console/Commands/TestCommand.cs b/src/TextLore/Shared/Commands/TestCommand.cs
similarity index 86%
rename from src/TextLore/Console/Commands/TestCommand.cs
rename to src/TextLore/Shared/Commands/TestCommand.cs
index 6fbef94..9c578f3 100644
--- a/src/TextLore/Console/Commands/TestCommand.cs
+++ b/src/TextLore/Shared/Commands/TestCommand.cs
@@ -1,4 +1,6 @@
-namespace TextLore.Console.Commands;
+using TextLore.Console;
+
+namespace TextLore.Shared.Commands;
public class TestCommand : Command
{
diff --git a/src/TextLore/Utilities/Logic/DeterministicRandom.cs b/src/TextLore/Shared/Logic/DeterministicRandom.cs
similarity index 98%
rename from src/TextLore/Utilities/Logic/DeterministicRandom.cs
rename to src/TextLore/Shared/Logic/DeterministicRandom.cs
index 93f16f6..b694342 100644
--- a/src/TextLore/Utilities/Logic/DeterministicRandom.cs
+++ b/src/TextLore/Shared/Logic/DeterministicRandom.cs
@@ -2,7 +2,7 @@
using System.Diagnostics.CodeAnalysis;
-namespace TextLore.Utilities.Logic;
+namespace TextLore.Shared.Logic;
public class DeterministicRandom(int seed, int min, int max) : IParsable
{
diff --git a/src/TextLore/Shared/Logic/GameManager.cs b/src/TextLore/Shared/Logic/GameManager.cs
new file mode 100644
index 0000000..2c0b81f
--- /dev/null
+++ b/src/TextLore/Shared/Logic/GameManager.cs
@@ -0,0 +1,63 @@
+using Microsoft.ClearScript;
+using Microsoft.ClearScript.V8;
+
+using TextLore.Console;
+using TextLore.Shared.Models;
+using TextLore.Shared.Models.Level;
+using TextLore.Shared.Models.Player;
+
+namespace TextLore.Shared.Logic;
+
+public partial class GameManager
+{
+ private readonly V8ScriptEngine scriptEngine = new V8ScriptEngine();
+
+ public PlayState PlayState { get; }
+
+ public GameManager(Level level)
+ {
+ PlayState = new(level, new());
+
+ ScriptContext currentScriptContext = new(() => PlayState.Player, () => PlayState.CurrentRoom?.Definition);
+
+ scriptEngine.AddHostObject("context", currentScriptContext);
+ }
+
+ public void MovePlayer(Direction direction)
+ {
+ Position newPosition = PlayState.Player.Position + direction;
+ if (PlayState.Level.IsPositionInBounds(newPosition))
+ {
+ PlayState.Player.Position = newPosition;
+
+ SetScript(PlayState.CurrentRoom?.Definition.Script ?? string.Empty);
+ }
+ }
+
+ public void ExecuteMethod(string method, ConsoleWriter consoleWriter)
+ {
+ try
+ {
+ _ = scriptEngine.Invoke(method, consoleWriter);
+ }
+ catch (ScriptEngineException ex)
+ {
+ consoleWriter.WriteLine(ex.Message);
+ }
+ catch (ScriptInterruptedException ex)
+ {
+ consoleWriter.WriteLine(ex.Message);
+ }
+ }
+
+ private void SetScript(string script)
+ {
+ scriptEngine.Execute(script);
+ }
+
+ public sealed class ScriptContext(Func player, Func room)
+ {
+ public Player Player => player();
+ public RoomDefinition? Room => room();
+ }
+}
\ No newline at end of file
diff --git a/src/TextLore/Games/Roguelike/Logic/LevelGenerator.cs b/src/TextLore/Shared/Logic/LevelGenerator.cs
similarity index 95%
rename from src/TextLore/Games/Roguelike/Logic/LevelGenerator.cs
rename to src/TextLore/Shared/Logic/LevelGenerator.cs
index 3d790f2..a2ccef8 100644
--- a/src/TextLore/Games/Roguelike/Logic/LevelGenerator.cs
+++ b/src/TextLore/Shared/Logic/LevelGenerator.cs
@@ -1,10 +1,9 @@
using Microsoft.EntityFrameworkCore;
-using TextLore.Games.Roguelike.Models;
-using TextLore.Utilities.Logic;
-using TextLore.Utilities.Models;
+using TextLore.Shared.Models;
+using TextLore.Shared.Models.Level;
-namespace TextLore.Games.Roguelike.Logic;
+namespace TextLore.Shared.Logic;
public class LevelGenerator(DeterministicRandom seed, IQueryable rooms)
{
diff --git a/src/TextLore/Shared/Logic/PlayState.cs b/src/TextLore/Shared/Logic/PlayState.cs
new file mode 100644
index 0000000..d70ecd9
--- /dev/null
+++ b/src/TextLore/Shared/Logic/PlayState.cs
@@ -0,0 +1,13 @@
+using TextLore.Shared.Models.Level;
+using TextLore.Shared.Models.Player;
+
+namespace TextLore.Shared.Logic;
+
+public class PlayState(Level level, Player player)
+{
+ public Level Level { get; } = level;
+
+ public Player Player { get; } = player;
+
+ public Room? CurrentRoom => Level.GetRoom(Player.Position);
+}
\ No newline at end of file
diff --git a/src/TextLore/Utilities/Models/Direction.cs b/src/TextLore/Shared/Models/Direction.cs
similarity index 83%
rename from src/TextLore/Utilities/Models/Direction.cs
rename to src/TextLore/Shared/Models/Direction.cs
index 3b914e3..6e12dc4 100644
--- a/src/TextLore/Utilities/Models/Direction.cs
+++ b/src/TextLore/Shared/Models/Direction.cs
@@ -1,4 +1,4 @@
-namespace TextLore.Utilities.Models;
+namespace TextLore.Shared.Models;
public readonly struct Direction(int x, int y)
{
@@ -10,6 +10,6 @@ public readonly struct Direction(int x, int y)
public static Direction UpRight => new Direction(1, -1);
public static Direction DownLeft => new Direction(-1, 1);
public static Direction DownRight => new Direction(1, 1);
- public int X { get; } = x;
- public int Y { get; } = y;
+ public int X => x;
+ public int Y => y;
}
\ No newline at end of file
diff --git a/src/TextLore/Games/Roguelike/Models/Level.cs b/src/TextLore/Shared/Models/Level/Level.cs
similarity index 93%
rename from src/TextLore/Games/Roguelike/Models/Level.cs
rename to src/TextLore/Shared/Models/Level/Level.cs
index dcd4b7b..af210c2 100644
--- a/src/TextLore/Games/Roguelike/Models/Level.cs
+++ b/src/TextLore/Shared/Models/Level/Level.cs
@@ -1,7 +1,7 @@
-using TextLore.Utilities.Logic;
-using TextLore.Utilities.Models;
+using TextLore.Shared.Logic;
+using TextLore.Shared.Models;
-namespace TextLore.Games.Roguelike.Models;
+namespace TextLore.Shared.Models.Level;
public class Level(Size size, DeterministicRandom seed)
{
diff --git a/src/TextLore/Games/Roguelike/Models/Room.cs b/src/TextLore/Shared/Models/Level/Room.cs
similarity index 78%
rename from src/TextLore/Games/Roguelike/Models/Room.cs
rename to src/TextLore/Shared/Models/Level/Room.cs
index 344d87a..cb9f54d 100644
--- a/src/TextLore/Games/Roguelike/Models/Room.cs
+++ b/src/TextLore/Shared/Models/Level/Room.cs
@@ -1,6 +1,6 @@
-using TextLore.Utilities.Models;
+using TextLore.Shared.Models;
-namespace TextLore.Games.Roguelike.Models;
+namespace TextLore.Shared.Models.Level;
public class Room(Position position, RoomDefinition roomDefinition)
{
diff --git a/src/TextLore/Games/Roguelike/Models/RoomDefinition.cs b/src/TextLore/Shared/Models/Level/RoomDefinition.cs
similarity index 92%
rename from src/TextLore/Games/Roguelike/Models/RoomDefinition.cs
rename to src/TextLore/Shared/Models/Level/RoomDefinition.cs
index 8d2b2c8..ec07df9 100644
--- a/src/TextLore/Games/Roguelike/Models/RoomDefinition.cs
+++ b/src/TextLore/Shared/Models/Level/RoomDefinition.cs
@@ -2,7 +2,7 @@
using System.ComponentModel.DataAnnotations.Schema;
-namespace TextLore.Games.Roguelike.Models;
+namespace TextLore.Shared.Models.Level;
[PrimaryKey(nameof(Id), nameof(Tag), nameof(Game))]
public class RoomDefinition(int id, RoomTag tag, string game)
diff --git a/src/TextLore/Games/Roguelike/Models/RoomTag.cs b/src/TextLore/Shared/Models/Level/RoomTag.cs
similarity index 63%
rename from src/TextLore/Games/Roguelike/Models/RoomTag.cs
rename to src/TextLore/Shared/Models/Level/RoomTag.cs
index 374daba..aa300c4 100644
--- a/src/TextLore/Games/Roguelike/Models/RoomTag.cs
+++ b/src/TextLore/Shared/Models/Level/RoomTag.cs
@@ -1,4 +1,4 @@
-namespace TextLore.Games.Roguelike.Models;
+namespace TextLore.Shared.Models.Level;
public enum RoomTag
{
diff --git a/src/TextLore/Shared/Models/PercentageProgress.cs b/src/TextLore/Shared/Models/PercentageProgress.cs
new file mode 100644
index 0000000..5a5dd1c
--- /dev/null
+++ b/src/TextLore/Shared/Models/PercentageProgress.cs
@@ -0,0 +1,9 @@
+namespace TextLore.Shared.Models;
+
+public readonly struct PercentageProgress(int current, int total)
+{
+ public int Current => current;
+ public int Total => total;
+ public int Percentage => (int)((double)Current / Total * 100);
+ public bool IsComplete => Current >= Total;
+}
\ No newline at end of file
diff --git a/src/TextLore/Shared/Models/Player/InventoryItem.cs b/src/TextLore/Shared/Models/Player/InventoryItem.cs
new file mode 100644
index 0000000..cdb5be0
--- /dev/null
+++ b/src/TextLore/Shared/Models/Player/InventoryItem.cs
@@ -0,0 +1,10 @@
+namespace TextLore.Shared.Models.Player;
+
+public class InventoryItem(string name, string description, string tag)
+{
+ public string Name { get; set; } = name;
+
+ public string Description { get; set; } = description;
+
+ public string Tag { get; set; } = tag;
+}
\ No newline at end of file
diff --git a/src/TextLore/Shared/Models/Player/Player.cs b/src/TextLore/Shared/Models/Player/Player.cs
new file mode 100644
index 0000000..4dff1e3
--- /dev/null
+++ b/src/TextLore/Shared/Models/Player/Player.cs
@@ -0,0 +1,10 @@
+namespace TextLore.Shared.Models.Player;
+
+public class Player
+{
+ public int Health { get; set; } = 100;
+
+ public List Inventory { get; } = [];
+
+ public Position Position { get; set; } = new Position(0, 0);
+}
\ No newline at end of file
diff --git a/src/TextLore/Utilities/Models/Position.cs b/src/TextLore/Shared/Models/Position.cs
similarity index 77%
rename from src/TextLore/Utilities/Models/Position.cs
rename to src/TextLore/Shared/Models/Position.cs
index 03bb4cc..ed7d4a4 100644
--- a/src/TextLore/Utilities/Models/Position.cs
+++ b/src/TextLore/Shared/Models/Position.cs
@@ -1,9 +1,9 @@
-namespace TextLore.Utilities.Models;
+namespace TextLore.Shared.Models;
-public struct Position(int x, int y)
+public readonly struct Position(int x, int y)
{
- public int X { get; set; } = x;
- public int Y { get; set; } = y;
+ public int X => x;
+ public int Y => y;
public static Position operator +(Position a, Position b)
{
diff --git a/src/TextLore/Shared/Models/Size.cs b/src/TextLore/Shared/Models/Size.cs
new file mode 100644
index 0000000..e143db6
--- /dev/null
+++ b/src/TextLore/Shared/Models/Size.cs
@@ -0,0 +1,7 @@
+namespace TextLore.Shared.Models;
+
+public readonly struct Size(int width, int height)
+{
+ public int Width => width;
+ public int Height => height;
+}
\ No newline at end of file
diff --git a/src/TextLore/TextLore.csproj b/src/TextLore/TextLore.csproj
index 46cf575..36ea2a9 100644
--- a/src/TextLore/TextLore.csproj
+++ b/src/TextLore/TextLore.csproj
@@ -7,8 +7,11 @@
+
+
+
-
+
diff --git a/src/TextLore/Utilities/Models/PercentageProgress.cs b/src/TextLore/Utilities/Models/PercentageProgress.cs
deleted file mode 100644
index a1f9d49..0000000
--- a/src/TextLore/Utilities/Models/PercentageProgress.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace TextLore.Utilities.Models;
-
-public class PercentageProgress(int current, int total)
-{
- public int Current { get; set; } = current;
- public int Total { get; set; } = total;
- public int Percentage => (int)((double)Current / Total * 100);
- public bool IsComplete => Current >= Total;
-}
\ No newline at end of file
diff --git a/src/TextLore/Utilities/Models/Size.cs b/src/TextLore/Utilities/Models/Size.cs
deleted file mode 100644
index 315d32b..0000000
--- a/src/TextLore/Utilities/Models/Size.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace TextLore.Utilities.Models;
-
-public readonly struct Size(int width, int height)
-{
- public int Width { get; } = width;
- public int Height { get; } = height;
-}
\ No newline at end of file
diff --git a/src/TextLore/games.sqlite b/src/TextLore/games.sqlite
index 9a47220..692b5dd 100644
Binary files a/src/TextLore/games.sqlite and b/src/TextLore/games.sqlite differ