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;
}