-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMapSerializer.cs
More file actions
115 lines (94 loc) · 3.89 KB
/
Copy pathMapSerializer.cs
File metadata and controls
115 lines (94 loc) · 3.89 KB
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Serialization;
using MegaCrit.Sts2.Core.Map;
using MegaCrit.Sts2.Core.Runs;
namespace Sts2Agent;
public static class MapSerializer
{
private static readonly JsonSerializerOptions JsonOptions = new()
{
WriteIndented = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
public static string Serialize()
{
try
{
var runState = RunManager.Instance?.DebugOnlyGetState();
if (runState == null)
return JsonSerializer.Serialize(new { error = "No active run" }, JsonOptions);
var map = runState.Map;
if (map == null)
return JsonSerializer.Serialize(new { error = "No map available" }, JsonOptions);
var visited = new HashSet<(int row, int col)>(
runState.VisitedMapCoords.Select(c => (c.row, c.col)));
var currentCoord = runState.CurrentMapCoord;
var result = new Dictionary<string, object>
{
["act"] = runState.CurrentActIndex + 1,
["rows"] = map.GetRowCount(),
["cols"] = map.GetColumnCount()
};
if (currentCoord.HasValue)
result["currentCoord"] = new { row = currentCoord.Value.row, col = currentCoord.Value.col };
result["visitedCoords"] = runState.VisitedMapCoords
.Select(c => new { row = c.row, col = c.col })
.ToList();
// Boss node
var boss = map.BossMapPoint;
result["bossCoord"] = new { row = boss.coord.row, col = boss.coord.col };
if (map.SecondBossMapPoint != null)
{
var boss2 = map.SecondBossMapPoint;
result["secondBossCoord"] = new { row = boss2.coord.row, col = boss2.coord.col };
}
// Starting nodes (first row entry points)
result["startCoords"] = map.startMapPoints
.Select(p => new { row = p.coord.row, col = p.coord.col })
.ToList();
// Collect all points including special ones
var seen = new HashSet<(int row, int col)>();
var allPoints = new List<MapPoint>();
foreach (var point in map.GetAllMapPoints())
{
if (seen.Add((point.coord.row, point.coord.col)))
allPoints.Add(point);
}
// Include boss/starting points if not already yielded
foreach (var special in new[] { boss, map.SecondBossMapPoint, map.StartingMapPoint })
{
if (special != null && seen.Add((special.coord.row, special.coord.col)))
allPoints.Add(special);
}
var nodes = new List<object>();
foreach (var point in allPoints)
{
var node = new Dictionary<string, object>
{
["coord"] = new { row = point.coord.row, col = point.coord.col },
["type"] = point.PointType.ToString()
};
if (point.Children.Count > 0)
{
node["children"] = point.Children
.Select(c => new { row = c.coord.row, col = c.coord.col })
.ToList();
}
if (visited.Contains((point.coord.row, point.coord.col)))
node["visited"] = true;
nodes.Add(node);
}
result["nodes"] = nodes;
return JsonSerializer.Serialize(result, JsonOptions);
}
catch (Exception e)
{
return JsonSerializer.Serialize(new { error = e.Message }, JsonOptions);
}
}
}