mirror of
https://github.com/Stone-Red-Code/TextLore.git
synced 2026-09-04 00:56:26 +02:00
Add basic room objects and inventory logic
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
using TextLore.Components.Pages.Games.Roguelike.Builders;
|
||||
using TextLore.Console;
|
||||
using TextLore.Shared.Commands;
|
||||
using TextLore.Shared.Logic;
|
||||
@@ -22,9 +23,11 @@ public partial class RoguelikePage
|
||||
[Parameter]
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -30,14 +30,14 @@ GamesDatabaseContext databaseContext = serviceScope.ServiceProvider.GetRequiredS
|
||||
if (await databaseContext.Database.EnsureCreatedAsync())
|
||||
{
|
||||
databaseContext.Rooms.AddRange(
|
||||
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" }
|
||||
new RoomDefinition(1, RoomTag.Start, "roguelike") { Name = "Start Room", Size = new(5, 5) },
|
||||
new RoomDefinition(1, RoomTag.Unique, "roguelike") { Name = "Unique Room", Size = new(30, 30) },
|
||||
new RoomDefinition(2, RoomTag.None, "roguelike") { Name = "Normal Room 1", Size = new(10, 10) },
|
||||
new RoomDefinition(3, RoomTag.None, "roguelike") { Name = "Normal Room 2", Size = new(10, 10) },
|
||||
new RoomDefinition(4, RoomTag.None, "roguelike") { Name = "Normal Room 3", Size = new(10, 10) },
|
||||
new RoomDefinition(5, RoomTag.None, "roguelike") { Name = "Normal Room 4", Size = new(10, 10) },
|
||||
new RoomDefinition(6, RoomTag.None, "roguelike") { Name = "Normal Room 5", Size = new(10, 10) },
|
||||
new RoomDefinition(1, RoomTag.End, "roguelike") { Name = "End Room", Size = new(10, 5) }
|
||||
);
|
||||
|
||||
_ = await databaseContext.SaveChangesAsync();
|
||||
|
||||
@@ -23,22 +23,95 @@ public partial class GameManager
|
||||
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)
|
||||
{
|
||||
scriptEngine.AddHostType(type.Name, type);
|
||||
}
|
||||
|
||||
foreach (object obj in objectsToAdd)
|
||||
{
|
||||
scriptEngine.AddHostObject(obj.GetType().Name, obj);
|
||||
}
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
PlayState.Player.Position = 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 void ExecuteMethod(string method, ConsoleWriter consoleWriter)
|
||||
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
|
||||
{
|
||||
_ = scriptEngine.Invoke(method, consoleWriter);
|
||||
return scriptEngine.Invoke(method, consoleWriter);
|
||||
}
|
||||
catch (ScriptEngineException ex)
|
||||
{
|
||||
@@ -48,9 +121,11 @@ public partial class GameManager
|
||||
{
|
||||
consoleWriter.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
private void SetScript(string script)
|
||||
protected void SetScript(string script)
|
||||
{
|
||||
scriptEngine.Execute(script);
|
||||
}
|
||||
|
||||
@@ -9,5 +9,5 @@ public class PlayState(Level level, Player player)
|
||||
|
||||
public Player Player { get; } = player;
|
||||
|
||||
public Room? CurrentRoom => Level.GetRoom(Player.Position);
|
||||
public Room? CurrentRoom => Level.GetRoom(Player.PositionInLevel);
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using TextLore.Shared.Logic;
|
||||
using TextLore.Shared.Models;
|
||||
|
||||
namespace TextLore.Shared.Models.Level;
|
||||
|
||||
@@ -12,6 +11,8 @@ public class Level(Size size, DeterministicRandom seed)
|
||||
|
||||
public DeterministicRandom Seed => seed;
|
||||
|
||||
public Room StartRoom => rooms.Values.First(r => r.Definition.Tag == RoomTag.Start);
|
||||
|
||||
public Room? GetRoom(Position 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);
|
||||
}
|
||||
|
||||
public void ClearRoom(Position point)
|
||||
public void RemoveRoom(Position point)
|
||||
{
|
||||
_ = rooms.Remove(point);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
private readonly Dictionary<Position, IRoomObject> objects = [];
|
||||
public Position Position => position;
|
||||
public List<Direction> DoorDirections { get; init; } = [Direction.Up, Direction.Down, Direction.Right, Direction.Left];
|
||||
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 Size Size { get; set; }
|
||||
|
||||
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,7 +4,9 @@ public class Player
|
||||
{
|
||||
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);
|
||||
}
|
||||
Reference in New Issue
Block a user