Skip to content

Commit a728c79

Browse files
committed
Added map option for Definite Edition
1 parent c44a634 commit a728c79

File tree

3 files changed

+182
-1
lines changed

3 files changed

+182
-1
lines changed

XbTool/XbTool/Options.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public enum Task
4141
GenerateSite,
4242
ExportQuests,
4343
ReplaceArchive,
44-
SdPrintTest
44+
SdPrintTest,
45+
GiveMaps
4546
}
4647
}

XbTool/XbTool/Tasks.cs

+15
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ internal static void RunTask(Options options)
9393
case Task.SdPrintTest:
9494
SdPrintTest(options);
9595
break;
96+
case Task.GiveMaps:
97+
GiveMaps(options);
98+
break;
9699
default:
97100
throw new ArgumentOutOfRangeException();
98101
}
@@ -460,5 +463,17 @@ private static void SdPrintTest(Options options)
460463
var localFs = new LocalFileSystem("output");
461464
fs.CopyFileSystem(localFs, options.Progress);
462465
}
466+
467+
private static void GiveMaps(Options options)
468+
{
469+
if (options.Input == null) throw new NullReferenceException("No input file was specified.");
470+
if (options.BdatDir == null) throw new NullReferenceException("No bdat dir was specified.");
471+
if (options.Output == null) throw new NullReferenceException("No output dir was specified.");
472+
if (options.Game != Game.XB1DE) throw new NotImplementedException("Xb Definitive Edition only.");
473+
if (!Directory.Exists(options.Input)) throw new DirectoryNotFoundException($"{options.Input} is not a valid directory.");
474+
475+
BdatStringCollection tables = GetBdatStringCollection(options);
476+
Xbde.Maps.ReadMap(tables, options);
477+
}
463478
}
464479
}

XbTool/XbTool/Xbde/Maps.cs

+165
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Drawing;
4+
using System.IO;
5+
using System.Linq;
6+
using System.Text;
7+
using System.Threading.Tasks;
8+
using XbTool.BdatString;
9+
using XbTool.Common.Textures;
10+
using XbTool.Types;
11+
using XbTool.Xb2.Textures;
12+
13+
namespace XbTool.Xbde
14+
{
15+
public static class Maps
16+
{
17+
public static void ReadMap(BdatStringCollection bdats, Options options)
18+
{
19+
var bdatMiniMapLists = bdats.Tables.Where(x => x.Key.Contains("minimaplist")).Select(x => x.Value).ToList();
20+
var bdatMaps = bdats.Tables["FLD_maplist"];
21+
22+
foreach (var map in bdatMaps.Items)
23+
{
24+
string index = map.Values["resource"].Value.ToString().Substring(2);
25+
if (index != "2501" && index != "2601") continue;
26+
var minimap = bdatMiniMapLists.FirstOrDefault(x => x.Name.Contains(index));
27+
if (minimap == null) continue;
28+
29+
int.TryParse(map["minimap_lt_x"].Value.ToString(), out int minX);
30+
int.TryParse(map["minimap_lt_z"].Value.ToString(), out int minZ);
31+
int.TryParse(map["minimap_rb_x"].Value.ToString(), out int maxX);
32+
int.TryParse(map["minimap_rb_z"].Value.ToString(), out int maxZ);
33+
34+
Rectangle mapBounds = new Rectangle(minX, minZ, maxX - minX, maxZ - minZ);
35+
36+
// var landmarks = bdatLandmarks.Items.Where(x => x["mapID"].Reference == map).ToList();
37+
if (!bdats.Tables.ContainsKey("Litemlist" + index)) continue;
38+
var collectables = bdats.Tables["Litemlist" + index]?.Items?.Where(x => CheckDrop(x, options.Filter));
39+
//var fb = bdats.Tables["poplist" + index]?.Items?.Where(x => x["NAMED_FLG"].DisplayString != "0" && x["ene1Per"].DisplayString == "100");
40+
//var um = bdats.Tables["poplist" + index]?.Items?.Where(x => x["NAMED_FLG"].DisplayString != "0" && x["ene1Per"].DisplayString == "30");
41+
var etherMine = bdats.Tables["gemMineList2501"].Items.Where(x => x.Id == 102 || x.Id == 120 || x.Id == 122 || x.Id == 126 || x.Id == 127 || x.Id == 128 || x.Id == 124 || x.Id == 103);
42+
var um = bdats.Tables["poplist" + index]?.Items?.Where(x => x["NAMED_FLG"].DisplayString != "0");
43+
var landmarks = bdats.Tables["landmarklist"].Items.Where(x => x["mapID"].Reference == map && (x["category"].DisplayString == "0" || x["category"].DisplayString == "1")).ToList();
44+
// if (!collectables.Any()) continue;
45+
46+
int ground = int.MinValue;
47+
foreach (var floor in minimap.Items)
48+
{
49+
int.TryParse(floor["height"].Value.ToString(), out int ceiling);
50+
51+
var map_file_name = floor["mapimg"].Reference["filename"].Value.ToString();
52+
if (floor["mapimg1"].Reference != null)
53+
map_file_name = floor["mapimg1"].Reference["filename"].Value.ToString();
54+
if (floor["mapimg2"].Reference != null)
55+
map_file_name = floor["mapimg2"].Reference["filename"].Value.ToString();
56+
57+
var map_file = Path.Combine(Path.Combine(options.Input, "image"), map_file_name + ".wilay");
58+
byte[] file = File.ReadAllBytes(map_file);
59+
var wilay = new WilayRead(file);
60+
LahdTexture texture = wilay.Textures[0];
61+
Bitmap bitmap = texture.ToBitmap();
62+
63+
var brush1 = new SolidBrush(System.Drawing.Color.Red);
64+
var brush2 = new SolidBrush(System.Drawing.Color.Yellow);
65+
var brush3 = new SolidBrush(System.Drawing.Color.Blue);
66+
var outerBrush = new SolidBrush(System.Drawing.Color.Black);
67+
Pen pen = new Pen(outerBrush, 2);
68+
69+
using (Graphics graphics = Graphics.FromImage(bitmap))
70+
{
71+
// Landmarks
72+
//graphics.MarkItems(landmarks, innerBrush, pen, mapBounds, bitmap.Size, ground, ceiling);
73+
74+
// Collectables
75+
// graphics.MarkItems(collectables.ToList(), brush1, pen, mapBounds, bitmap.Size, ground, ceiling);
76+
77+
// Enemies
78+
// graphics.MarkItems(fb.ToList(), brush2, pen, mapBounds, bitmap.Size, ground, ceiling);
79+
// graphics.MarkItems(um.ToList(), brush1, pen, mapBounds, bitmap.Size, ground, ceiling);
80+
// graphics.MarkItems(landmarks.ToList(), brush3, pen, mapBounds, bitmap.Size, ground, ceiling);
81+
82+
83+
graphics.MarkItems(etherMine.ToList(), brush1, pen, mapBounds, bitmap.Size, ground, ceiling);
84+
85+
86+
87+
}
88+
byte[] png = bitmap.ToPng();
89+
File.WriteAllBytes(Path.Combine(options.Output, $"png/{map["name"].DisplayString} - f{floor["floorname"].Value.ToString()}.png"), png);
90+
91+
Console.WriteLine("");
92+
ground = ceiling;
93+
}
94+
}
95+
}
96+
97+
private static bool CheckDrop(BdatStringItem x, string filter)
98+
{
99+
for (int i = 1; i <= 8; i++)
100+
{
101+
int.TryParse(x[$"itm{i}Per"].DisplayString, out int percent);
102+
if (x[$"itm{i}ID"].DisplayString == filter && percent == 15)
103+
return true;
104+
}
105+
return false;
106+
}
107+
108+
public static void MarkItems(this Graphics g, List<BdatStringItem> items, Brush brush, Pen pen, Rectangle bounds, Size size, int ground, int ceiling)
109+
{
110+
foreach (var item in items)
111+
{
112+
int.TryParse(item["posX"].Value.ToString(), out int x_coord);
113+
int.TryParse(item["posY"].Value.ToString(), out int y);
114+
int.TryParse(item["posZ"].Value.ToString(), out int z_coord);
115+
// if (y < ground || y > ceiling) continue;
116+
117+
float x = (float)(x_coord / 10000 - bounds.Left) / bounds.Width * size.Width;
118+
float z = (float)(z_coord / 10000 - bounds.Top) / bounds.Height * size.Height;
119+
120+
g.FillCircle(brush, x, z, 16);
121+
g.DrawCircle(pen, x, z, 16);
122+
}
123+
124+
}
125+
126+
public static void FillCircle(this Graphics g, Brush brush,
127+
float centerX, float centerY, float radius)
128+
{
129+
g.FillEllipse(brush, centerX - radius, centerY - radius,
130+
radius + radius, radius + radius);
131+
}
132+
133+
public static void DrawRect(this Graphics g, Pen pen,
134+
float centerX, float centerY, float scaleX, float scaleY)
135+
{
136+
g.DrawRectangle(pen, centerX - scaleX / 2, centerY - scaleY / 2, scaleX, scaleY);
137+
}
138+
139+
public static void DrawEllipse(this Graphics g, Pen pen,
140+
float centerX, float centerY, float scaleX, float scaleY)
141+
{
142+
g.DrawEllipse(pen, centerX - scaleX / 2, centerY - scaleY / 2, scaleX, scaleY);
143+
}
144+
145+
public static void FillEllipse(this Graphics g, Brush brush,
146+
float centerX, float centerY, float scaleX, float scaleY)
147+
{
148+
g.FillEllipse(brush, centerX - scaleX / 2, centerY - scaleY / 2, scaleX, scaleY);
149+
}
150+
151+
public static void FillRect(this Graphics g, Brush brush,
152+
float centerX, float centerY, float scaleX, float scaleY)
153+
{
154+
g.FillRectangle(brush, centerX - scaleX / 2, centerY - scaleY / 2, scaleX, scaleY);
155+
}
156+
157+
public static void DrawCircle(this Graphics g, Pen pen,
158+
float centerX, float centerY, float radius)
159+
{
160+
g.DrawEllipse(pen, centerX - radius, centerY - radius,
161+
radius + radius, radius + radius);
162+
}
163+
}
164+
165+
}

0 commit comments

Comments
 (0)