File size: 2,795 Bytes
01fd682 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | using SilkroadBot.Domain.Enums;
namespace SilkroadBot.Domain.Models;
/// <summary>
/// Complete game state snapshot, thread-safe read model.
/// </summary>
public class GameState
{
private readonly object _lock = new();
public ConnectionState ConnectionState { get; set; } = ConnectionState.Disconnected;
public CharacterState Character { get; set; } = new();
public List<GameEntity> NearbyEntities { get; set; } = new();
public List<InventoryItem> Inventory { get; set; } = new();
public List<Skill> Skills { get; set; } = new();
public List<PartyMember> PartyMembers { get; set; } = new();
public List<string> Buffs { get; set; } = new();
public DateTime LastUpdate { get; set; } = DateTime.UtcNow;
/// <summary>
/// Returns a thread-safe snapshot of the current game state.
/// </summary>
public GameStateSnapshot GetSnapshot()
{
lock (_lock)
{
return new GameStateSnapshot
{
ConnectionState = ConnectionState,
CharacterName = Character.Name,
Level = Character.Level,
HP = Character.HP,
MaxHP = Character.MaxHP,
MP = Character.MP,
MaxMP = Character.MaxMP,
Position = Character.Position,
Gold = Character.Gold,
IsInCombat = Character.IsInCombat,
IsDead = Character.IsDead,
NearbyEntityCount = NearbyEntities.Count,
InventoryItemCount = Inventory.Count,
PartySize = PartyMembers.Count,
LastUpdate = LastUpdate
};
}
}
public void Update(Action<GameState> updater)
{
lock (_lock)
{
updater(this);
LastUpdate = DateTime.UtcNow;
}
}
}
/// <summary>
/// Immutable snapshot of game state for safe reading.
/// </summary>
public record GameStateSnapshot
{
public ConnectionState ConnectionState { get; init; }
public string CharacterName { get; init; } = string.Empty;
public int Level { get; init; }
public int HP { get; init; }
public int MaxHP { get; init; }
public int MP { get; init; }
public int MaxMP { get; init; }
public WorldPosition Position { get; init; }
public uint Gold { get; init; }
public bool IsInCombat { get; init; }
public bool IsDead { get; init; }
public int NearbyEntityCount { get; init; }
public int InventoryItemCount { get; init; }
public int PartySize { get; init; }
public DateTime LastUpdate { get; init; }
public double HPPercentage => MaxHP > 0 ? (double)HP / MaxHP * 100 : 0;
public double MPPercentage => MaxMP > 0 ? (double)MP / MaxMP * 100 : 0;
}
|