mirror of
https://github.com/Stone-Red-Code/TextLore.git
synced 2026-09-04 00:56:26 +02:00
Make room system generic
This commit is contained in:
+4
-2
@@ -302,8 +302,6 @@ node_modules/
|
|||||||
*.dsp
|
*.dsp
|
||||||
|
|
||||||
# Visual Studio 6 technical files
|
# Visual Studio 6 technical files
|
||||||
*.ncb
|
|
||||||
*.aps
|
|
||||||
|
|
||||||
# Visual Studio LightSwitch build output
|
# Visual Studio LightSwitch build output
|
||||||
**/*.HTMLClient/GeneratedArtifacts
|
**/*.HTMLClient/GeneratedArtifacts
|
||||||
@@ -396,3 +394,7 @@ FodyWeavers.xsd
|
|||||||
|
|
||||||
# JetBrains Rider
|
# JetBrains Rider
|
||||||
*.sln.iml
|
*.sln.iml
|
||||||
|
|
||||||
|
# SQLite
|
||||||
|
/src/TextLore/games.sqlite-shm
|
||||||
|
/src/TextLore/games.sqlite-wal
|
||||||
|
|||||||
@@ -4,5 +4,5 @@ namespace TextLore.Database;
|
|||||||
|
|
||||||
public class GamesDatabaseContext(DbContextOptions<GamesDatabaseContext> options) : DbContext(options)
|
public class GamesDatabaseContext(DbContextOptions<GamesDatabaseContext> options) : DbContext(options)
|
||||||
{
|
{
|
||||||
public DbSet<Games.Roguelike.Models.RoomDefinition> RoguelikeRooms { get; set; }
|
public DbSet<Games.Roguelike.Models.RoomDefinition> Rooms { get; set; }
|
||||||
}
|
}
|
||||||
@@ -19,12 +19,12 @@ public class LevelGenerator(DeterministicRandom seed, IQueryable<RoomDefinition>
|
|||||||
Level level = new Level(size, seed);
|
Level level = new Level(size, seed);
|
||||||
Queue<Room> generationQueue = new Queue<Room>();
|
Queue<Room> generationQueue = new Queue<Room>();
|
||||||
|
|
||||||
RoomDefinition startRoomDefinition = await GetRandomRoomDefinition() ?? throw new InvalidOperationException("No rooms found in the database.");
|
RoomDefinition startRoomDefinition = await GetRandomRoomDefinition(level) ?? throw new InvalidOperationException("No rooms found in the database.");
|
||||||
Position startRoomPosition = new Position(seed.Next(0, size.Width), seed.Next(0, size.Height));
|
Position startRoomPosition = new Position(seed.Next(0, size.Width), seed.Next(0, size.Height));
|
||||||
|
|
||||||
Room startRoom = new Room(startRoomPosition, startRoomDefinition);
|
Room startRoom = new Room(startRoomPosition, startRoomDefinition);
|
||||||
|
|
||||||
level.AddRoom(startRoom);
|
_ = level.AddRoom(startRoom);
|
||||||
generationQueue.Enqueue(startRoom);
|
generationQueue.Enqueue(startRoom);
|
||||||
|
|
||||||
while (generationQueue.Count > 0)
|
while (generationQueue.Count > 0)
|
||||||
@@ -43,11 +43,11 @@ public class LevelGenerator(DeterministicRandom seed, IQueryable<RoomDefinition>
|
|||||||
|
|
||||||
if (level.IsPositionInBounds(newPosition) && level.GetRoom(newPosition) is null)
|
if (level.IsPositionInBounds(newPosition) && level.GetRoom(newPosition) is null)
|
||||||
{
|
{
|
||||||
RoomDefinition? newRoomDefinition = await GetRandomRoomDefinition();
|
RoomDefinition? newRoomDefinition = await GetRandomRoomDefinition(level);
|
||||||
|
|
||||||
Room newRoom = new Room(newPosition, newRoomDefinition ?? throw new InvalidOperationException("No rooms found in the database."));
|
Room newRoom = new Room(newPosition, newRoomDefinition ?? throw new InvalidOperationException("No rooms found in the database."));
|
||||||
|
|
||||||
level.AddRoom(newRoom);
|
_ = level.AddRoom(newRoom);
|
||||||
generationQueue.Enqueue(newRoom);
|
generationQueue.Enqueue(newRoom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,7 +74,7 @@ public class LevelGenerator(DeterministicRandom seed, IQueryable<RoomDefinition>
|
|||||||
return level;
|
return level;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<RoomDefinition?> GetRandomRoomDefinition()
|
private async Task<RoomDefinition?> GetRandomRoomDefinition(Level level)
|
||||||
{
|
{
|
||||||
RoomDefinition? room = null;
|
RoomDefinition? room = null;
|
||||||
int randomRoomIndex = seed.Next();
|
int randomRoomIndex = seed.Next();
|
||||||
@@ -87,6 +87,11 @@ public class LevelGenerator(DeterministicRandom seed, IQueryable<RoomDefinition>
|
|||||||
{
|
{
|
||||||
room = await rooms.FirstOrDefaultAsync(x => x.Id == randomRoomIndex);
|
room = await rooms.FirstOrDefaultAsync(x => x.Id == randomRoomIndex);
|
||||||
|
|
||||||
|
if (room?.Tag == RoomTag.Unique && level.RoomExists(room))
|
||||||
|
{
|
||||||
|
room = null;
|
||||||
|
}
|
||||||
|
|
||||||
if (room is not null)
|
if (room is not null)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -22,14 +22,26 @@ public class Level(Size size, DeterministicRandom seed)
|
|||||||
return rooms;
|
return rooms;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddRoom(Room room)
|
public bool AddRoom(Room room)
|
||||||
{
|
{
|
||||||
if (!IsRoomInBounds(room))
|
if (!IsRoomInBounds(room))
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("Room is out of bounds.");
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (room.Definition.Tag == RoomTag.Unique && RoomExists(room.Definition))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (room.Definition.Tag == RoomTag.Start && rooms.Values.Any(r => r.Definition.Tag == RoomTag.Start))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
rooms[room.Position] = room;
|
rooms[room.Position] = room;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsPositionInBounds(Position point)
|
public bool IsPositionInBounds(Position point)
|
||||||
@@ -47,6 +59,11 @@ public class Level(Size size, DeterministicRandom seed)
|
|||||||
return rooms.ContainsKey(point);
|
return rooms.ContainsKey(point);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool RoomExists(RoomDefinition definition)
|
||||||
|
{
|
||||||
|
return rooms.Values.Any(r => r.Definition.Id == definition.Id);
|
||||||
|
}
|
||||||
|
|
||||||
public void ClearRoom(Position point)
|
public void ClearRoom(Position point)
|
||||||
{
|
{
|
||||||
_ = rooms.Remove(point);
|
_ = rooms.Remove(point);
|
||||||
|
|||||||
@@ -1,14 +1,22 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
namespace TextLore.Games.Roguelike.Models;
|
namespace TextLore.Games.Roguelike.Models;
|
||||||
|
|
||||||
public class RoomDefinition(string name)
|
[PrimaryKey(nameof(Id), nameof(Tag), nameof(Game))]
|
||||||
|
public class RoomDefinition(int id, RoomTag tag, string game)
|
||||||
{
|
{
|
||||||
[Key]
|
[Column(Order = 0)]
|
||||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
public int Id { get; } = id;
|
||||||
public int Id { get; private set; }
|
|
||||||
|
|
||||||
[Required]
|
[Column(Order = 1)]
|
||||||
public string Name { get; set; } = name;
|
public RoomTag Tag { get; } = tag;
|
||||||
|
|
||||||
|
[Column(Order = 2)]
|
||||||
|
public string Game { get; } = game;
|
||||||
|
|
||||||
|
public required string Name { get; set; }
|
||||||
|
|
||||||
|
public string Script { get; set; } = string.Empty;
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
namespace TextLore.Games.Roguelike.Models;
|
||||||
|
|
||||||
|
public enum RoomTag
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Start = 1,
|
||||||
|
End = 2,
|
||||||
|
Unique = 3
|
||||||
|
}
|
||||||
@@ -37,7 +37,7 @@ public partial class RoguelikePage
|
|||||||
{
|
{
|
||||||
if (firstRender)
|
if (firstRender)
|
||||||
{
|
{
|
||||||
await console.Execute(new GenerateLevelCommand(DatabaseContext.RoguelikeRooms, NavigationManager, OnLevelGenerated), Seed);
|
await console.Execute(new GenerateLevelCommand(DatabaseContext.Rooms, NavigationManager, OnLevelGenerated), Seed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+9
-11
@@ -28,17 +28,15 @@ GamesDatabaseContext databaseContext = serviceScope.ServiceProvider.GetRequiredS
|
|||||||
|
|
||||||
if (await databaseContext.Database.EnsureCreatedAsync())
|
if (await databaseContext.Database.EnsureCreatedAsync())
|
||||||
{
|
{
|
||||||
databaseContext.RoguelikeRooms.AddRange(
|
databaseContext.Rooms.AddRange(
|
||||||
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 1"),
|
new TextLore.Games.Roguelike.Models.RoomDefinition(1, TextLore.Games.Roguelike.Models.RoomTag.Start, "rogelike") { Name = "Start Room" },
|
||||||
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 2"),
|
new TextLore.Games.Roguelike.Models.RoomDefinition(1, TextLore.Games.Roguelike.Models.RoomTag.Unique, "rogelike") { Name = "Unique Room" },
|
||||||
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 3"),
|
new TextLore.Games.Roguelike.Models.RoomDefinition(2, TextLore.Games.Roguelike.Models.RoomTag.Unique, "rogelike") { Name = "Normal Room 1" },
|
||||||
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 4"),
|
new TextLore.Games.Roguelike.Models.RoomDefinition(3, TextLore.Games.Roguelike.Models.RoomTag.Unique, "rogelike") { Name = "Normal Room 2" },
|
||||||
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 5"),
|
new TextLore.Games.Roguelike.Models.RoomDefinition(4, TextLore.Games.Roguelike.Models.RoomTag.Unique, "rogelike") { Name = "Normal Room 3" },
|
||||||
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 6"),
|
new TextLore.Games.Roguelike.Models.RoomDefinition(5, TextLore.Games.Roguelike.Models.RoomTag.Unique, "rogelike") { Name = "Normal Room 4" },
|
||||||
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 7"),
|
new TextLore.Games.Roguelike.Models.RoomDefinition(6, TextLore.Games.Roguelike.Models.RoomTag.Unique, "rogelike") { Name = "Normal Room 5" },
|
||||||
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 8"),
|
new TextLore.Games.Roguelike.Models.RoomDefinition(1, TextLore.Games.Roguelike.Models.RoomTag.End, "rogelike") { Name = "End Room" }
|
||||||
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 9"),
|
|
||||||
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 10")
|
|
||||||
);
|
);
|
||||||
|
|
||||||
_ = await databaseContext.SaveChangesAsync();
|
_ = await databaseContext.SaveChangesAsync();
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user