diff --git a/src/common/buffer.h b/src/common/buffer.h
index e8541de..279901b 100644
--- a/src/common/buffer.h
+++ b/src/common/buffer.h
@@ -34,6 +34,16 @@
#define READ_PASCAL_STRING(b, var) var = b.read_pascal_string()
+#define READ_N_OBJECTS_WITH_LOAD(b, o) \
+ do \
+ { \
+ uint32_t n; \
+ READ(b, n); \
+ o.resize(n); \
+ for (auto &e : o) \
+ e.load(b); \
+ } while (0)
+
#define WRITE(b, var) b.write(&var)
std::string version();
diff --git a/src/common/common.natvis b/src/common/common.natvis
new file mode 100644
index 0000000..5185dd0
--- /dev/null
+++ b/src/common/common.natvis
@@ -0,0 +1,10 @@
+
+
+
+
+
+ {name1}
+
+
+
+
diff --git a/src/common/objects.h b/src/common/objects.h
index 5582486..c9344db 100644
--- a/src/common/objects.h
+++ b/src/common/objects.h
@@ -76,14 +76,14 @@ struct Segment
template
struct SegmentObjects : public Segment
{
- std::vector objects;
+ std::vector objects;
virtual void load(const buffer &b)
{
for (uint32_t i = 0; i < n_objects; i++)
{
- T* o = new T;
- o->load(b);
+ T o;
+ o.load(b);
objects.push_back(o);
}
}
@@ -91,6 +91,7 @@ struct SegmentObjects : public Segment
struct Common
{
+ // m_rotate_z[2].z - model scale on the map
vector4 m_rotate_z[3];
vector4 position;
diff --git a/src/common/types.cpp b/src/common/types.cpp
index 899ff1c..c41ee61 100644
--- a/src/common/types.cpp
+++ b/src/common/types.cpp
@@ -80,3 +80,24 @@ void water_group::load(const buffer &b)
segments.push_back(w);
}
}
+
+void Organization::load(const buffer &b)
+{
+ READ(b, unk0);
+ READ_STRING(b, name);
+ READ(b, count);
+ READ(b, trade_war);
+ READ(b, defence_attack);
+
+ // incorrect?
+ READ(b, configs[1].count_in_group);
+ READ(b, configs[2].count_in_group);
+ READ(b, configs[0].count_in_group);
+
+ READ(b, average_rating);
+ READ(b, is_free);
+ READ(b, is_foreign);
+ READ(b, unk1);
+ for (auto &c : configs)
+ c.load(b);
+}
diff --git a/src/common/types.h b/src/common/types.h
index 24e3093..e7fe8f1 100644
--- a/src/common/types.h
+++ b/src/common/types.h
@@ -155,13 +155,25 @@ struct water_group
struct Good
{
+ enum class TovType : uint32_t
+ {
+ RawMaterial,
+ Consumables,
+ SemiFinished,
+ };
+
std::string name;
char unk1[0x40];
float unk1_2 = 0;
- float price = 0;
+ float price = 0; // unk, quantity?
float unk2[10];
- float unk2_1[2];
- uint32_t unk2_2[2];
+ float buy_price; // initial
+ float sell_price; // initial
+ TovType type;
+ bool use_in_production;
+ bool unk3;
+ bool unk4;
+ bool unk5;
void load(const buffer &b)
{
@@ -175,8 +187,13 @@ struct Good
READ(b, unk2);
else
{
- READ(b, unk2_1);
- READ(b, unk2_2);
+ READ(b, buy_price);
+ READ(b, sell_price);
+ READ(b, type);
+ READ(b, use_in_production);
+ READ(b, unk3);
+ READ(b, unk4);
+ READ(b, unk5);
}
}
};
@@ -184,35 +201,27 @@ struct Good
struct BuildingGoods
{
std::string name;
- uint32_t n = 0;
std::vector goods;
void load(const buffer &b)
{
READ_STRING(b, name);
- READ(b, n);
-
- for (uint32_t i = 0; i < n; i++)
- {
- Good g;
- g.load(b);
- goods.push_back(g);
- }
+ READ_N_OBJECTS_WITH_LOAD(b, goods);
}
};
struct MapMusic
{
- std::string name1;
+ std::string mainTheme;
std::string name2;
- std::vector names1;
- std::vector names2;
+ std::vector fightThemes;
+ std::vector insertionThemes;
void load(const buffer &b)
{
- READ_STRING(b, name1);
+ READ_STRING(b, mainTheme);
READ_STRING(b, name2);
auto read_values = [&b](auto &v, auto &n)
@@ -223,21 +232,22 @@ struct MapMusic
uint32_t n1 = 0;
READ(b, n1);
- read_values(names1, n1);
+ read_values(fightThemes, n1);
uint32_t n2 = 0;
READ(b, n2);
- read_values(names2, n2);
+ read_values(insertionThemes, n2);
}
};
struct OrganizationConfig
{
- uint32_t n_configs = 0;
+ int count_in_group;
std::vector configs;
void load(const buffer &b)
{
+ uint32_t n_configs = 0;
READ(b, n_configs);
configs.resize(n_configs, std::string(0x20, 0));
for (uint32_t i = 0; i < n_configs; i++)
@@ -247,38 +257,19 @@ struct OrganizationConfig
struct Organization
{
- uint32_t unk0 = 0;
std::string name;
- char unk1[0xE0];
+ int count; // on map?
+ float trade_war;
+ float defence_attack;
+ float average_rating;
+ bool is_free;
+ bool is_foreign;
OrganizationConfig configs[3];
- void load(const buffer &b)
- {
- READ(b, unk0);
- READ_STRING(b, name);
- READ(b, unk1);
- for (auto &c : configs)
- c.load(b);
- }
-};
+ uint32_t unk0 = 0;
+ char unk1[0xE0 - 4-4-4-4*3-4-1-1];
-struct Organizations
-{
- std::vector organizations;
-
- void load(const buffer &b)
- {
- uint32_t len = 0;
- READ(b, len);
- uint32_t n = 0;
- READ(b, n);
- for (uint32_t i = 0; i < n; i++)
- {
- Organization s;
- s.load(b);
- organizations.push_back(s);
- }
- }
+ void load(const buffer &b);
};
struct OrganizationBase
@@ -295,23 +286,6 @@ struct OrganizationBase
}
};
-struct OrganizationBases
-{
- std::vector organizationBases;
-
- void load(const buffer &b)
- {
- uint32_t n = 0;
- READ(b, n);
- for (uint32_t i = 0; i < n; i++)
- {
- OrganizationBase s;
- s.load(b);
- organizationBases.push_back(s);
- }
- }
-};
-
struct ModificatorMask
{
enum class ItemType : uint8_t
diff --git a/src/mmo_extractor/mmo_extractor.cpp b/src/mmo_extractor/mmo_extractor.cpp
index ce1acbb..aef82db 100644
--- a/src/mmo_extractor/mmo_extractor.cpp
+++ b/src/mmo_extractor/mmo_extractor.cpp
@@ -53,12 +53,12 @@ struct mmo_storage
path name;
Objects objects;
MechGroups mechGroups;
- MapGoods mapGoods;
+ MapGoods mapGoods; // trading & production system
MapMusic mapMusic;
MapSounds mapSounds;
// aim2
- Organizations orgs;
- OrganizationBases orgsBases;
+ std::vector organizations;
+ std::vector organizationBases;
Prices prices;
uint32_t unk0 = 0;
@@ -75,8 +75,12 @@ struct mmo_storage
mapSounds.load(b);
if (gameType == GameType::Aim2)
{
- orgs.load(b);
- orgsBases.load(b);
+ uint32_t len = 0;
+ READ(b, len);
+
+ READ_N_OBJECTS_WITH_LOAD(b, organizations);
+ READ_N_OBJECTS_WITH_LOAD(b, organizationBases);
+
prices.load(b);
}
@@ -142,7 +146,7 @@ void write_mmo(Storage *storage, const mmo_storage &s)
std::set objs;
std::map bld_ids;
for (auto &object : segment->objects)
- objs.insert(object->name1);
+ objs.insert(object.name1);
for (auto &o : objs)
{
auto iter = std::find_if(storage->buildings.begin(), storage->buildings.end(), [&](const auto &p)
@@ -163,24 +167,19 @@ void write_mmo(Storage *storage, const mmo_storage &s)
for (auto &object : segment->objects)
{
// protect against nans
- object->m_rotate_z[2].z = ASSIGN(object->m_rotate_z[2].z, 1);
+ object.m_rotate_z[2].z = ASSIGN(object.m_rotate_z[2].z, 1);
MapBuilding mb;
- mb.text_id = object->name2;
- mb.building = storage->buildings[bld_ids[object->name1]];
+ mb.text_id = object.name2;
+ mb.building = storage->buildings[bld_ids[object.name1]];
mb.map = this_map;
- mb.x = ASSIGN(object->position.x, 0);
- mb.y = ASSIGN(object->position.y, 0);
- mb.z = ASSIGN(object->position.z, 0);
+ mb.x = ASSIGN(object.position.x, 0);
+ mb.y = ASSIGN(object.position.y, 0);
+ mb.z = ASSIGN(object.position.z, 0);
mb.roll = 0;
mb.pitch = 0;
- mb.yaw = calc_yaw(object->m_rotate_z);
- mb.scale = ASSIGN(object->m_rotate_z[2].z, 1);
- if (mb.scale != 1)
- {
- int a = 5;
- a++;
- }
+ mb.yaw = calc_yaw(object.m_rotate_z);
+ mb.scale = ASSIGN(object.m_rotate_z[2].z, 1);
auto i = find_if(storage->mapBuildings.begin(), storage->mapBuildings.end(), [&](const auto &p)
{
return *p.second == mb;
@@ -209,7 +208,7 @@ void write_mmo(Storage *storage, const mmo_storage &s)
std::set objs;
std::map bld_ids;
for (auto &object : segment->objects)
- objs.insert(object->name1);
+ objs.insert(object.name1);
for (auto &o : objs)
{
auto iter = find_if(storage->objects.begin(), storage->objects.end(), [&](const auto &p)
@@ -228,24 +227,19 @@ void write_mmo(Storage *storage, const mmo_storage &s)
for (auto &object : segment->objects)
{
// protect against nans
- object->m_rotate_z[2].z = ASSIGN(object->m_rotate_z[2].z, 1);
+ object.m_rotate_z[2].z = ASSIGN(object.m_rotate_z[2].z, 1);
polygon4::detail::MapObject mb;
- mb.text_id = object->name2;
+ mb.text_id = object.name2;
mb.map = this_map;
- mb.object = storage->objects[bld_ids[object->name1]];
- mb.x = ASSIGN(object->position.x, 0);
- mb.y = ASSIGN(object->position.y, 0);
- mb.z = ASSIGN(object->position.z, 0);
+ mb.object = storage->objects[bld_ids[object.name1]];
+ mb.x = ASSIGN(object.position.x, 0);
+ mb.y = ASSIGN(object.position.y, 0);
+ mb.z = ASSIGN(object.position.z, 0);
mb.roll = 0;
mb.pitch = 0;
- mb.yaw = calc_yaw(object->m_rotate_z);
- mb.scale = ASSIGN(object->m_rotate_z[2].z, 1);
- if (mb.scale != 1)
- {
- int a = 5;
- a++;
- }
+ mb.yaw = calc_yaw(object.m_rotate_z);
+ mb.scale = ASSIGN(object.m_rotate_z[2].z, 1);
auto i = find_if(storage->mapObjects.begin(), storage->mapObjects.end(), [&](const auto &p)
{
return *p.second == mb;
@@ -280,10 +274,6 @@ int main(int argc, char *argv[])
gameType = m2 ? GameType::Aim2 : GameType::Aim1;
- /*{
- std::cerr << parser;
- }*/
-
auto action = [&p](auto f)
{
if (fs::is_regular_file(p))
@@ -315,6 +305,10 @@ int main(int argc, char *argv[])
}
});
}
+ else if (db_path.empty())
+ {
+ action([](const path &, const auto &m) {});
+ }
else
{
auto storage = initStorage(db_path.u8string());
diff --git a/src/mpj_loader/mpj.cpp b/src/mpj_loader/mpj.cpp
index aef5c0f..c274b38 100644
--- a/src/mpj_loader/mpj.cpp
+++ b/src/mpj_loader/mpj.cpp
@@ -158,11 +158,8 @@ void map_music::load(const buffer &b)
void organizations::load(const buffer &b)
{
- READ(b, n);
- orgs.resize(n);
- for (auto &org : orgs)
- org.load(b);
- bases.load(b);
+ READ_N_OBJECTS_WITH_LOAD(b, orgs);
+ READ_N_OBJECTS_WITH_LOAD(b, organizationBases);
}
void gliders_n_goods::load(const buffer &b)
diff --git a/src/mpj_loader/mpj.h b/src/mpj_loader/mpj.h
index a3a5a4f..99e89a9 100644
--- a/src/mpj_loader/mpj.h
+++ b/src/mpj_loader/mpj.h
@@ -142,9 +142,8 @@ struct map_music : public segment
struct organizations : public segment
{
- uint32_t n;
std::vector orgs;
- OrganizationBases bases;
+ std::vector organizationBases;
virtual void load(const buffer &b) override;
};
diff --git a/sw.cpp b/sw.cpp
index d06c256..a5040d9 100644
--- a/sw.cpp
+++ b/sw.cpp
@@ -48,7 +48,7 @@ void build(Solution &s)
script2txt.CPPVersion = CPPLanguageStandard::CPP17;
script2txt.setRootDirectory("src/script2txt");
script2txt += "pub.lzwdgc.Polygon4.DataManager.schema-master"_dep;
- gen_flex_bison_pair(script2txt, "LALR1_CPP_VARIANT_PARSER", "script2txt");
+ gen_flex_bison_pair("org.sw.demo.lexxmark.winflexbison-master"_dep, script2txt, "LALR1_CPP_VARIANT_PARSER", "script2txt");
auto &model = tools.addStaticLibrary("model");
model.CPPVersion = CPPLanguageStandard::CPP17;