Add basic room objects and inventory logic

This commit is contained in:
Stone_Red
2024-02-07 21:50:28 +01:00
parent d160071e7c
commit 6cc7b05501
9 changed files with 150 additions and 36 deletions
@@ -1,5 +1,6 @@
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using TextLore.Components.Pages.Games.Roguelike.Builders;
using TextLore.Console; using TextLore.Console;
using TextLore.Shared.Commands; using TextLore.Shared.Commands;
using TextLore.Shared.Logic; using TextLore.Shared.Logic;
@@ -22,9 +23,11 @@ public partial class RoguelikePage
[Parameter] [Parameter]
public string Seed { get; set; } = string.Empty; public string Seed { get; set; } = string.Empty;
public async void OnLevelGenerated(Level level) public void OnLevelGenerated(Level level)
{ {
gameManager = new GameManager(level); gameManager = new GameManager(level, [typeof(EnemyBuilder)]);
gameManager.StartGame();
StateHasChanged(); StateHasChanged();
} }
+8 -8
View File
@@ -30,14 +30,14 @@ GamesDatabaseContext databaseContext = serviceScope.ServiceProvider.GetRequiredS
if (await databaseContext.Database.EnsureCreatedAsync()) if (await databaseContext.Database.EnsureCreatedAsync())
{ {
databaseContext.Rooms.AddRange( databaseContext.Rooms.AddRange(
new RoomDefinition(1, RoomTag.Start, "roguelike") { Name = "Start Room" }, new RoomDefinition(1, RoomTag.Start, "roguelike") { Name = "Start Room", Size = new(5, 5) },
new RoomDefinition(1, RoomTag.Unique, "roguelike") { Name = "Unique Room" }, new RoomDefinition(1, RoomTag.Unique, "roguelike") { Name = "Unique Room", Size = new(30, 30) },
new RoomDefinition(2, RoomTag.None, "roguelike") { Name = "Normal Room 1" }, new RoomDefinition(2, RoomTag.None, "roguelike") { Name = "Normal Room 1", Size = new(10, 10) },
new RoomDefinition(3, RoomTag.None, "roguelike") { Name = "Normal Room 2" }, new RoomDefinition(3, RoomTag.None, "roguelike") { Name = "Normal Room 2", Size = new(10, 10) },
new RoomDefinition(4, RoomTag.None, "roguelike") { Name = "Normal Room 3" }, new RoomDefinition(4, RoomTag.None, "roguelike") { Name = "Normal Room 3", Size = new(10, 10) },
new RoomDefinition(5, RoomTag.None, "roguelike") { Name = "Normal Room 4" }, new RoomDefinition(5, RoomTag.None, "roguelike") { Name = "Normal Room 4", Size = new(10, 10) },
new RoomDefinition(6, RoomTag.None, "roguelike") { Name = "Normal Room 5" }, new RoomDefinition(6, RoomTag.None, "roguelike") { Name = "Normal Room 5", Size = new(10, 10) },
new RoomDefinition(1, RoomTag.End, "roguelike") { Name = "End Room" } new RoomDefinition(1, RoomTag.End, "roguelike") { Name = "End Room", Size = new(10, 5) }
); );
_ = await databaseContext.SaveChangesAsync(); _ = await databaseContext.SaveChangesAsync();
+83 -8
View File
@@ -23,22 +23,95 @@ public partial class GameManager
scriptEngine.AddHostObject("context", currentScriptContext); scriptEngine.AddHostObject("context", currentScriptContext);
} }
public void MovePlayer(Direction direction) public GameManager(Level level, IEnumerable<Type> typesToAdd, IEnumerable<object> objectsToAdd) : this(level)
{ {
Position newPosition = PlayState.Player.Position + direction; foreach (Type type in typesToAdd)
if (PlayState.Level.IsPositionInBounds(newPosition))
{ {
PlayState.Player.Position = newPosition; scriptEngine.AddHostType(type.Name, type);
}
SetScript(PlayState.CurrentRoom?.Definition.Script ?? string.Empty); foreach (object obj in objectsToAdd)
{
scriptEngine.AddHostObject(obj.GetType().Name, obj);
} }
} }
public void ExecuteMethod(string method, ConsoleWriter consoleWriter) public GameManager(Level level, IEnumerable<Type> typesToAdd) : this(level)
{ {
foreach (Type type in typesToAdd)
{
scriptEngine.AddHostType(type.Name, type);
}
}
public GameManager(Level level, IEnumerable<object> objectsToAdd) : this(level)
{
foreach (object obj in objectsToAdd)
{
scriptEngine.AddHostObject(obj.GetType().Name, obj);
}
}
public virtual void StartGame()
{
SetPlayerPositionInLevel(PlayState.Level.StartRoom.Position);
Size currentRoomSize = PlayState.CurrentRoom!.Definition.Size;
SetPlayerPositionInRoom(new(currentRoomSize.Width / 2, currentRoomSize.Height / 2));
}
public void MovePlayerInLevel(Direction direction)
{
Position newPosition = PlayState.Player.PositionInLevel + direction;
if (PlayState.Level.IsPositionInBounds(newPosition))
{
SetPlayerPositionInLevel(newPosition);
}
}
public void MovePlayerInRoom(Direction direction)
{
Position newPosition = PlayState.Player.PositionInLevel + direction;
if (PlayState.CurrentRoom?.IsPositionInBounds(newPosition) == true)
{
SetPlayerPositionInRoom(newPosition);
}
}
public virtual void SetPlayerPositionInLevel(Position position)
{
PlayState.Player.PositionInLevel = position;
SetScript(PlayState.CurrentRoom?.Definition.Script ?? string.Empty);
_ = ExecuteMethod("onPlayerEnterRoom");
}
public virtual void SetPlayerPositionInRoom(Position position)
{
PlayState.Player.PositionInLevel = position;
_ = ExecuteMethod("onPlayerMove");
}
public void Update()
{
_ = ExecuteMethod("onUpdate");
}
protected T? ExecuteMethod<T>(string method, ConsoleWriter? consoleWriter = null) where T : class
{
return ExecuteMethod(method, consoleWriter) as T;
}
protected object? ExecuteMethod(string method, ConsoleWriter? consoleWriter = null)
{
consoleWriter ??= new ConsoleWriter();
try try
{ {
_ = scriptEngine.Invoke(method, consoleWriter); return scriptEngine.Invoke(method, consoleWriter);
} }
catch (ScriptEngineException ex) catch (ScriptEngineException ex)
{ {
@@ -48,9 +121,11 @@ public partial class GameManager
{ {
consoleWriter.WriteLine(ex.Message); consoleWriter.WriteLine(ex.Message);
} }
return default;
} }
private void SetScript(string script) protected void SetScript(string script)
{ {
scriptEngine.Execute(script); scriptEngine.Execute(script);
} }
+1 -1
View File
@@ -9,5 +9,5 @@ public class PlayState(Level level, Player player)
public Player Player { get; } = player; public Player Player { get; } = player;
public Room? CurrentRoom => Level.GetRoom(Player.Position); public Room? CurrentRoom => Level.GetRoom(Player.PositionInLevel);
} }
+3 -2
View File
@@ -1,5 +1,4 @@
using TextLore.Shared.Logic; using TextLore.Shared.Logic;
using TextLore.Shared.Models;
namespace TextLore.Shared.Models.Level; namespace TextLore.Shared.Models.Level;
@@ -12,6 +11,8 @@ public class Level(Size size, DeterministicRandom seed)
public DeterministicRandom Seed => seed; public DeterministicRandom Seed => seed;
public Room StartRoom => rooms.Values.First(r => r.Definition.Tag == RoomTag.Start);
public Room? GetRoom(Position point) public Room? GetRoom(Position point)
{ {
return rooms.GetValueOrDefault(point); return rooms.GetValueOrDefault(point);
@@ -64,7 +65,7 @@ public class Level(Size size, DeterministicRandom seed)
return rooms.Values.Any(r => r.Definition.Id == definition.Id); return rooms.Values.Any(r => r.Definition.Id == definition.Id);
} }
public void ClearRoom(Position point) public void RemoveRoom(Position point)
{ {
_ = rooms.Remove(point); _ = rooms.Remove(point);
} }
+44 -3
View File
@@ -1,10 +1,51 @@
using TextLore.Shared.Models; namespace TextLore.Shared.Models.Level;
namespace TextLore.Shared.Models.Level;
public class Room(Position position, RoomDefinition roomDefinition) public class Room(Position position, RoomDefinition roomDefinition)
{ {
private readonly Dictionary<Position, IRoomObject> objects = [];
public Position Position => position; public Position Position => position;
public List<Direction> DoorDirections { get; init; } = [Direction.Up, Direction.Down, Direction.Right, Direction.Left]; public List<Direction> DoorDirections { get; init; } = [Direction.Up, Direction.Down, Direction.Right, Direction.Left];
public RoomDefinition Definition => roomDefinition; public RoomDefinition Definition => roomDefinition;
public IRoomObject? GetObject(Position point)
{
return objects.GetValueOrDefault(point);
}
public IReadOnlyDictionary<Position, IRoomObject> GetRooms()
{
return objects;
}
public bool AddObject(Position point, IRoomObject roomObject)
{
if (!IsPositionInBounds(point))
{
return false;
}
objects[point] = roomObject;
return true;
}
public bool IsPositionInBounds(Position point)
{
return point.X >= 0 && point.X < roomDefinition.Size.Width && point.Y >= 0 && point.Y < roomDefinition.Size.Height;
}
public bool ObjectExists(Position point)
{
return objects.ContainsKey(point);
}
public void RemoveObject(Position point)
{
_ = objects.Remove(point);
}
public void ClearObjects()
{
objects.Clear();
}
} }
@@ -18,5 +18,7 @@ public class RoomDefinition(int id, RoomTag tag, string game)
public required string Name { get; set; } public required string Name { get; set; }
public required Size Size { get; set; }
public string Script { get; set; } = string.Empty; public string Script { get; set; } = string.Empty;
} }
@@ -1,10 +0,0 @@
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;
}
+4 -2
View File
@@ -4,7 +4,9 @@ public class Player
{ {
public int Health { get; set; } = 100; public int Health { get; set; } = 100;
public List<InventoryItem> Inventory { get; } = []; public List<IInventoryItem> Inventory { get; } = [];
public Position Position { get; set; } = new Position(0, 0); public Position PositionInLevel { get; set; } = new Position(0, 0);
public Position PositionInRoom { get; set; } = new Position(0, 0);
} }