Skip to content

Commit f6bc7cb

Browse files
committed
gimmicks: use bdatstringcollection instead of serialized bdatcollection
gimmicks: save reference of associated bdat item to gimmick
1 parent cb5c907 commit f6bc7cb

File tree

7 files changed

+100
-30
lines changed

7 files changed

+100
-30
lines changed

XbTool/XbTool/Gimmick/Lvb.cs

+4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Collections.Generic;
22
using System.Text;
33
using XbTool.Common;
4+
using XbTool.BdatString;
45

56
namespace XbTool.Gimmick
67
{
@@ -177,8 +178,11 @@ public class InfoEntry
177178
public Transform Xfrm;
178179
public string Name;
179180
public string GmkType;
181+
public string Key;
180182
public int Id;
181183
public int IdInFile;
184+
public MapAreaInfo ParentArea;
185+
public BdatStringItem BdatItem;
182186

183187
public InfoEntry(DataBuffer data)
184188
{

XbTool/XbTool/Gimmick/MapInfo.cs

+5-1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public MapInfo(DataBuffer data)
3737
area.LowerBound = new Point3(xLo, yLo, zLo);
3838
area.UpperBound = new Point3(xHi, yHi, zHi);
3939
area.Size = new Point3(xHi - xLo, yHi - yLo, zHi - zLo);
40+
area.ParentMap = this;
4041
data.Position = start + 72;
4142
Areas[i] = area;
4243

@@ -67,7 +68,7 @@ public MapAreaInfo GetContainingArea(Point3 point)
6768
public static Dictionary<string, MapInfo> ReadAll(IFileSystem fs)
6869
{
6970
var infos = new Dictionary<string, MapInfo>();
70-
IEnumerable<string> filenames = fs.EnumerateEntries("/menu/minimap", "*.mi", SearchOptions.Default).Where(x=>x.Type == DirectoryEntryType.File).Select(x => x.FullPath);
71+
IEnumerable<string> filenames = fs.EnumerateEntries("/menu/minimap", "*.mi", SearchOptions.RecurseSubdirectories).Select(x => x.FullPath);
7172

7273
foreach (string filename in filenames)
7374
{
@@ -98,6 +99,7 @@ public static Dictionary<string, MapInfo> ReadAll(IFileSystem fs)
9899
[DebuggerDisplay("{" + nameof(DisplayName) + ", nq}")]
99100
public class MapAreaInfo
100101
{
102+
public MapInfo ParentMap { get; set; }
101103
public MapSegmentInfo SegmentInfo { get; set; }
102104
public string Name { get; set; }
103105
public string DisplayName { get; set; }
@@ -122,6 +124,8 @@ public void AddGimmick(InfoEntry gimmick, string type)
122124
Gimmicks.Add(type, new List<InfoEntry>());
123125
}
124126

127+
gimmick.ParentArea = this;
128+
gimmick.Key = type;
125129
Gimmicks[type].Add(gimmick);
126130
}
127131

XbTool/XbTool/Gimmick/ReadGmk.cs

+34-24
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,32 @@
55
using LibHac.Fs;
66
using LibHac.FsSystem;
77
using XbTool.Bdat;
8+
using XbTool.BdatString;
89
using XbTool.Common;
910
using XbTool.Types;
1011

1112
namespace XbTool.Gimmick
1213
{
1314
public static class ReadGmk
1415
{
15-
public static MapInfo[] ReadAll(IFileSystem fs, BdatCollection tables, IProgressReport progress = null)
16+
public static MapInfo[] ReadAll(IFileSystem fs, BdatStringCollection tables, IProgressReport progress = null)
1617
{
1718
progress?.LogMessage("Reading map info and gimmick sets");
1819
Dictionary<string, MapInfo> maps = MapInfo.ReadAll(fs);
1920

20-
BdatTable<FLD_maplist> mapList = tables.FLD_maplist;
21-
BdatTable<MNU_MapInfo> areaList = tables.MNU_MapInfo;
21+
BdatStringItem[] mapList = tables.Tables["FLD_maplist"].Items;
22+
BdatStringItem[] areaList = tables.Tables["MNU_MapInfo"].Items;
2223

2324
foreach (MapInfo mapInfo in maps.Values)
2425
{
25-
FLD_maplist map = mapList.FirstOrDefault(x => x.resource == mapInfo.Name && x._nameID != null);
26+
BdatStringItem map = mapList.FirstOrDefault(x => x["resource"].DisplayString == mapInfo.Name && x["nameID"].DisplayString != null);
2627
if (map == null) continue;
27-
if (map._nameID != null) mapInfo.DisplayName = map._nameID.name;
28+
mapInfo.DisplayName = map["nameID"].DisplayString;
2829

2930
foreach (MapAreaInfo areaInfo in mapInfo.Areas)
3031
{
31-
MNU_MapInfo area = areaList.FirstOrDefault(x =>
32-
x.level_name == areaInfo.Name || x.level_name2 == areaInfo.Name);
32+
BdatStringItem area = areaList.FirstOrDefault(x =>
33+
x["level_name"].DisplayString == areaInfo.Name || x["level_name2"].DisplayString == areaInfo.Name);
3334
if (area == null)
3435
{
3536
progress?.LogMessage($"Found area {areaInfo.Name} that is not in the BDAT tables");
@@ -40,24 +41,24 @@ public static MapInfo[] ReadAll(IFileSystem fs, BdatCollection tables, IProgress
4041
// These 2 maps are always the same except one has a small addition or removal.
4142
// We want the map with the most objects on it, so we use the second map for
4243
// Gormott (ma05a), and the first map for everywhere else.
43-
if (!string.IsNullOrWhiteSpace(area.level_name2)
44-
&& area.level_name == areaInfo.Name
44+
if (!string.IsNullOrWhiteSpace(area["level_name2"].DisplayString)
45+
&& area["level_name"].DisplayString == areaInfo.Name
4546
&& mapInfo.Name == "ma05a")
4647
{
4748
areaInfo.Priority = int.MaxValue;
4849
}
49-
else if (!string.IsNullOrWhiteSpace(area.level_name2)
50-
&& area.level_name2 == areaInfo.Name
50+
else if (!string.IsNullOrWhiteSpace(area["level_name2"].DisplayString)
51+
&& area["level_name2"].DisplayString == areaInfo.Name
5152
&& mapInfo.Name != "ma05a")
5253
{
5354
areaInfo.Priority = int.MaxValue;
5455
}
5556
else
5657
{
57-
areaInfo.Priority = area.level_priority;
58+
areaInfo.Priority = int.Parse(area["level_priority"].ValueString);
5859
}
5960

60-
if (area._disp_name?.name != null) areaInfo.DisplayName = area._disp_name.name;
61+
if (area["disp_name"].DisplayString != null) areaInfo.DisplayName = area["disp_name"].DisplayString;
6162
}
6263

6364
Dictionary<string, Lvb> gimmickSet = ReadGimmickSet(fs, tables, map.Id);
@@ -67,31 +68,40 @@ public static MapInfo[] ReadAll(IFileSystem fs, BdatCollection tables, IProgress
6768
return maps.Values.ToArray();
6869
}
6970

70-
public static Dictionary<string, Lvb> ReadGimmickSet(IFileSystem fs, BdatCollection tables, int mapId)
71+
public static Dictionary<string, Lvb> ReadGimmickSet(IFileSystem fs, BdatStringCollection tables, int mapId)
7172
{
72-
RSC_GmkSetList setBdat = tables.RSC_GmkSetList.First(x => x.mapId == mapId);
73+
BdatStringItem setBdat = tables.Tables["RSC_GmkSetList"].Items.First(x => int.Parse(x["mapId"].ValueString) == mapId);
74+
IEnumerable<string> fields = setBdat.Values.Keys.Where(x => !x.Contains("_bdat"));
7375
Dictionary<string, FieldInfo> fieldsDict = setBdat.GetType().GetFields().ToDictionary(x => x.Name, x => x);
74-
IEnumerable<FieldInfo> fields = fieldsDict.Values.Where(x => x.FieldType == typeof(string) && !x.Name.Contains("_bdat"));
7576
var gimmicks = new Dictionary<string, Lvb>();
7677

77-
foreach (FieldInfo field in fields)
78+
foreach (string field in fields)
7879
{
79-
string value = (string)field.GetValue(setBdat);
80+
string value = setBdat[field].DisplayString;
8081
if (value == null) continue;
8182
string filename = $"/gmk/{value}.lvb";
8283
if (!fs.FileExists(filename)) continue;
8384

8485
byte[] file = fs.ReadFile(filename);
85-
var lvb = new Lvb(new DataBuffer(file, Game.XB2, 0)) { Filename = field.Name };
86+
var lvb = new Lvb(new DataBuffer(file, Game.XB2, 0)) { Filename = field };
8687

87-
string bdatField = field.Name + "_bdat";
88-
if (fieldsDict.ContainsKey(bdatField))
88+
string bdatField = field + "_bdat";
89+
if (setBdat.Values.ContainsKey(bdatField))
8990
{
90-
string bdatName = (string)fieldsDict[bdatField].GetValue(setBdat);
91-
if (!string.IsNullOrWhiteSpace(bdatName)) lvb.BdatName = bdatName;
91+
string bdatName = setBdat[bdatField].DisplayString;
92+
if (!string.IsNullOrWhiteSpace(bdatName))
93+
{
94+
lvb.BdatName = bdatName;
95+
foreach (var gmk in lvb.Info)
96+
{
97+
gmk.BdatItem = tables[lvb.BdatName].Items.FirstOrDefault(itm => itm["name"].DisplayString == gmk.Name);
98+
if (gmk.BdatItem != null)
99+
gmk.BdatItem.Gmk = gmk;
100+
}
101+
}
92102
}
93103

94-
gimmicks.Add(field.Name, lvb);
104+
gimmicks.Add(field, lvb);
95105
}
96106

97107
return gimmicks;

XbTool/XbTool/Tasks.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ private static void ReadGimmick(Options options)
384384

385385
var xb2Fs = new Xb2FileSystem(options.SdPath);
386386

387-
BdatCollection tables = GetBdatCollection(xb2Fs, false);
387+
BdatStringCollection tables = GetBdatStringCollection(options);
388388

389389
MapInfo[] gimmicks = ReadGmk.ReadAll(xb2Fs, tables);
390390
ExportMap.ExportCsv(gimmicks, options.Output);
@@ -507,7 +507,7 @@ private static void GiveMaps(Options options)
507507
//gmks = salvage.SelectMany(x => x.ReferencedBy).Where(x => x.Table.Name == "FLD_SalvageTable").SelectMany(x => x.ReferencedBy).Where(x => x.Table.Filename == "common_gmk").Select(x=>x.Gmk);
508508
//gmks = tables["ma15a_FLD_NpcPop"].Items.Where(x => x.Id == 15178 || x.Id == 15179 || x.Id == 15180).Select(x=>x.Gmk);
509509
Directory.CreateDirectory(options.Output);
510-
ExportMap.Export(xb2Fs, gmks.ToList(), $"{options.Output}/{options.Input}");
510+
Maps.Export(xb2Fs, gmks.ToList(), $"{options.Output}/{options.Input}");
511511
}
512512
else
513513
{

XbTool/XbTool/Website/Generate.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public static void GenerateBdatHtml(IFileSystem fs, string outDir, IProgressRepo
5454
}
5555

5656
string gmkDir = Path.Combine(outDir, GmkDir);
57-
MapInfo[] gimmicks = ReadGmk.ReadAll(fs, tables, progress);
57+
MapInfo[] gimmicks = ReadGmk.ReadAll(fs, tablesStr, progress);
5858
progress.LogMessage("Writing map info and gimmick data");
5959
ExportMap.ExportCsv(gimmicks, gmkDir);
6060
}

XbTool/XbTool/Xb2/GameData/Maps.cs

+52
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,58 @@ public static void Export(IFileSystem fs, MapInfo[] gimmicks, BdatStringItem gim
8282
}
8383
}
8484
}
85+
public static void Export(IFileSystem fs, List<InfoEntry> gmks, string outDir)
86+
{
87+
//Directory.CreateDirectory(outDir);
88+
Dictionary<MapAreaInfo, List<InfoEntry>> gmkDict = new Dictionary<MapAreaInfo, List<InfoEntry>>();
89+
90+
foreach (var gmk in gmks)
91+
{
92+
if (gmk == null || gmk.ParentArea == null)
93+
continue;
94+
if (!gmkDict.ContainsKey(gmk.ParentArea))
95+
gmkDict[gmk.ParentArea] = new List<InfoEntry> { gmk };
96+
else
97+
gmkDict[gmk.ParentArea].Add(gmk);
98+
}
99+
100+
101+
foreach (KeyValuePair<MapAreaInfo, List<InfoEntry>> pair in gmkDict)
102+
{
103+
var gmkList = pair.Value;
104+
MapAreaInfo area = pair.Key;
105+
MapInfo map = area.ParentMap;
106+
107+
float scale = 1;
108+
string texPath = $"/menu/image/{area.Name}_map.wilay";
109+
byte[] texBytes = fs.ReadFile(texPath);
110+
var wilay = new WilayRead(texBytes);
111+
LahdTexture texture = wilay.Textures[0];
112+
Bitmap bitmapBase = texture.ToBitmap();
113+
bitmapBase = ResizeImage(bitmapBase, (int)(bitmapBase.Width * scale), (int)(bitmapBase.Height * scale));
114+
115+
var outerBrush = new SolidBrush(System.Drawing.Color.Black);
116+
//var backing = new SolidBrush(System.Drawing.Color.White);
117+
var innerBrush = new SolidBrush(System.Drawing.Color.GreenYellow);
118+
var pen = new Pen(outerBrush, 1 * scale);
119+
120+
bitmapBase.RotateFlip(RotateFlipType.Rotate180FlipNone);
121+
var bitmap = (Bitmap)bitmapBase.Clone();
122+
123+
using (Graphics graphics = Graphics.FromImage(bitmap))
124+
{
125+
foreach (var gmk in pair.Value)
126+
{
127+
Point2 point = area.Get2DPosition(gmk.Xfrm.Position);
128+
graphics.FillCircle(innerBrush, point.X * scale, point.Y * scale, 8 * scale);
129+
graphics.DrawCircle(pen, point.X * scale, point.Y * scale, 8 * scale);
130+
}
131+
}
132+
byte[] png = bitmap.ToPng();
133+
134+
File.WriteAllBytes(outDir + $"{map.DisplayName}-{area.DisplayName}.png", png);
135+
}
136+
}
85137
public static Bitmap ResizeImage(Image image, int width, int height)
86138
{
87139
var destRect = new Rectangle(0, 0, width, height);

XbTool/XbTool/Xb2/GameData/Quest.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public void OutputQuest(IFileSystem fs, string outDir, IEnumerable<string> scrip
8181

8282
if (StartGimmick != null)
8383
{
84-
ExportMap.Export(fs, new List<InfoEntry> { StartGimmick }, Path.Combine(outDir, $"{QuestName}/Start-"));
84+
Maps.Export(fs, new List<InfoEntry> { StartGimmick }, Path.Combine(outDir, $"{QuestName}/Start-"));
8585
}
8686

8787
int i = 1;
@@ -90,7 +90,7 @@ public void OutputQuest(IFileSystem fs, string outDir, IEnumerable<string> scrip
9090
int j = 1;
9191
foreach (var gmkSet in task.GetTaskGimmicks())
9292
{
93-
ExportMap.Export(fs, gmkSet.Where(x=>x.Gmk != null).Select(x=>x.Gmk).ToList(), Path.Combine(outDir, $"{QuestName}/Task{i}-{j++}-"));
93+
Maps.Export(fs, gmkSet.Where(x=>x.Gmk != null).Select(x=>x.Gmk).ToList(), Path.Combine(outDir, $"{QuestName}/Task{i}-{j++}-"));
9494
}
9595
i++;
9696
}

0 commit comments

Comments
 (0)