mirror of
https://github.com/Stone-Red-Code/TextLore.git
synced 2026-09-04 09:06:35 +02:00
Make room system generic
This commit is contained in:
+4
-2
@@ -302,8 +302,6 @@ node_modules/
|
||||
*.dsp
|
||||
|
||||
# Visual Studio 6 technical files
|
||||
*.ncb
|
||||
*.aps
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
@@ -396,3 +394,7 @@ FodyWeavers.xsd
|
||||
|
||||
# JetBrains Rider
|
||||
*.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 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);
|
||||
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));
|
||||
|
||||
Room startRoom = new Room(startRoomPosition, startRoomDefinition);
|
||||
|
||||
level.AddRoom(startRoom);
|
||||
_ = level.AddRoom(startRoom);
|
||||
generationQueue.Enqueue(startRoom);
|
||||
|
||||
while (generationQueue.Count > 0)
|
||||
@@ -43,11 +43,11 @@ public class LevelGenerator(DeterministicRandom seed, IQueryable<RoomDefinition>
|
||||
|
||||
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."));
|
||||
|
||||
level.AddRoom(newRoom);
|
||||
_ = level.AddRoom(newRoom);
|
||||
generationQueue.Enqueue(newRoom);
|
||||
}
|
||||
}
|
||||
@@ -74,7 +74,7 @@ public class LevelGenerator(DeterministicRandom seed, IQueryable<RoomDefinition>
|
||||
return level;
|
||||
}
|
||||
|
||||
private async Task<RoomDefinition?> GetRandomRoomDefinition()
|
||||
private async Task<RoomDefinition?> GetRandomRoomDefinition(Level level)
|
||||
{
|
||||
RoomDefinition? room = null;
|
||||
int randomRoomIndex = seed.Next();
|
||||
@@ -87,6 +87,11 @@ public class LevelGenerator(DeterministicRandom seed, IQueryable<RoomDefinition>
|
||||
{
|
||||
room = await rooms.FirstOrDefaultAsync(x => x.Id == randomRoomIndex);
|
||||
|
||||
if (room?.Tag == RoomTag.Unique && level.RoomExists(room))
|
||||
{
|
||||
room = null;
|
||||
}
|
||||
|
||||
if (room is not null)
|
||||
{
|
||||
break;
|
||||
|
||||
@@ -22,14 +22,26 @@ public class Level(Size size, DeterministicRandom seed)
|
||||
return rooms;
|
||||
}
|
||||
|
||||
public void AddRoom(Room room)
|
||||
public bool AddRoom(Room 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;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsPositionInBounds(Position point)
|
||||
@@ -47,6 +59,11 @@ public class Level(Size size, DeterministicRandom seed)
|
||||
return rooms.ContainsKey(point);
|
||||
}
|
||||
|
||||
public bool RoomExists(RoomDefinition definition)
|
||||
{
|
||||
return rooms.Values.Any(r => r.Definition.Id == definition.Id);
|
||||
}
|
||||
|
||||
public void ClearRoom(Position point)
|
||||
{
|
||||
_ = rooms.Remove(point);
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
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]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public int Id { get; private set; }
|
||||
[Column(Order = 0)]
|
||||
public int Id { get; } = id;
|
||||
|
||||
[Required]
|
||||
public string Name { get; set; } = name;
|
||||
[Column(Order = 1)]
|
||||
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)
|
||||
{
|
||||
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())
|
||||
{
|
||||
databaseContext.RoguelikeRooms.AddRange(
|
||||
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 1"),
|
||||
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 2"),
|
||||
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 3"),
|
||||
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 4"),
|
||||
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 5"),
|
||||
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 6"),
|
||||
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 7"),
|
||||
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 8"),
|
||||
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 9"),
|
||||
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 10")
|
||||
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.Unique, "rogelike") { Name = "Normal Room 1" },
|
||||
new TextLore.Games.Roguelike.Models.RoomDefinition(3, TextLore.Games.Roguelike.Models.RoomTag.Unique, "rogelike") { Name = "Normal Room 2" },
|
||||
new TextLore.Games.Roguelike.Models.RoomDefinition(4, TextLore.Games.Roguelike.Models.RoomTag.Unique, "rogelike") { Name = "Normal Room 3" },
|
||||
new TextLore.Games.Roguelike.Models.RoomDefinition(5, TextLore.Games.Roguelike.Models.RoomTag.Unique, "rogelike") { Name = "Normal Room 4" },
|
||||
new TextLore.Games.Roguelike.Models.RoomDefinition(6, TextLore.Games.Roguelike.Models.RoomTag.Unique, "rogelike") { Name = "Normal Room 5" },
|
||||
new TextLore.Games.Roguelike.Models.RoomDefinition(1, TextLore.Games.Roguelike.Models.RoomTag.End, "rogelike") { Name = "End Room" }
|
||||
);
|
||||
|
||||
_ = await databaseContext.SaveChangesAsync();
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user