This commit is contained in:
lzwdgc 2024-06-03 15:35:15 +03:00
parent 400e66d4a1
commit 06b39b9881
3 changed files with 177 additions and 19 deletions

View file

@ -207,6 +207,7 @@ int main(int argc, char *argv[]) {
// patch note dev: give powerful glider based on FLASH
db["Глайдеры"]["GL_M4_S_TEST"] = db["Глайдеры"]["GL_M4_S_FIRST2"];
db["Глайдеры"]["GL_M4_S_TEST"]["MAXWEIGHT"] = 1'000'000.f;
db["Глайдеры"]["GL_M4_S_TEST"]["ROTATESPEED"] = 75.f;
db["Конфигурации"]["CFG_STARTUP"]["GLIDER"] = "GL_M4_S_TEST";
// patch note dev: give powerful reactor
add_test_eqp("REACTOR", "EQP_GLUON_REACTOR_S1", 9'000'000.f);
@ -226,6 +227,11 @@ int main(int argc, char *argv[]) {
db["Оружие"]["GUN_IMPULSE_MEGALAZER_TEST"]["DAMAGE"] = 40000.f;
db["Оружие"]["GUN_IMPULSE_MEGALAZER_TEST"]["STANDARD"] = 1;
db["Конфигурации"]["CFG_STARTUP"]["HEAVYGUN1"] = "GUN_IMPULSE_MEGALAZER_TEST";
//
db["Конфигурации"]["CFG_STARTUP"]["EQP_ANALYZER"] = 1;
db["Конфигурации"]["CFG_STARTUP"]["EQP_QUANTUM_TRANSLATOR"] = 1;
db["Конфигурации"]["CFG_STARTUP"]["EQP_INVISIBILITY_SHIELD"] = 1;
db["Конфигурации"]["CFG_STARTUP"]["EQP_UNIVERSAL_SHIELD"] = 1;
// end of db changes in dev mode
// patch note dev: allow to buy GL_S3_PS_FINDER1 without pre-quest
mod.add_map_good("location6.mmo", "B_L6_IK_FINDER", "GL_S3_PS_FINDER1", mmo_storage2::map_good("GL_S3_PS_FINDER1"));
@ -262,19 +268,39 @@ int main(int argc, char *argv[]) {
//
mod.clone_mechmind_group("location1.mmo", "MINVACH-6", "MINVACH-666");
mod.update_mechmind_group_configurations("location1.mmo", "MINVACH-666",
"CFG_INVADER_1",
"CFG_INVADER_1",
"CFG_INVADER_1",
"CFG_INVADER_1",
"CFG_INVADER_1",
"CFG_INVADER_1",
"CFG_INVADER_1",
"CFG_INVADER_1",
"CFG_INVADER_1",
"CFG_INVADER_1"
);
mod.set_mechmind_organization("location1.mmo", "MINVACH-666", "ORG_PLAYER");
auto cfg = "CFG_TEST";
db["Конфигурации"][cfg] = db["Конфигурации"]["CFG_STARTUP"];
db["Конфигурации"][cfg]["ENGINE"] = "EQP_VACUUM_DRIVE_S4";
auto make = [&](auto name, int road) {
mod.clone_mechmind_group("location1.mmo", "MINVACH-6", name);
mod.update_mechmind_group_configurations("location1.mmo", name, cfg);
mod.set_mechmind_group_type("location1.mmo", name, 1, road);
};
for (int i = 0; i < 20; ++i) {
make(std::format("MINVACH-6{}", i), 1000 / 20 * i + 20);
}
/*mod.update_mechmind_group_configurations("location1.mmo", "MINVACH-666",
cfg,
cfg,
cfg,
cfg,
cfg,
cfg,
cfg,
cfg,
cfg,
cfg
);*/
//mod.set_mechmind_group_organization("location1.mmo", "MINVACH-666", "ORG_PLAYER");
//mod.set_mechmind_group_type("location1.mmo", "MINVACH-666", 1);
/*mod.hide_mechmind_group("location1.mmo", "MINVACH-666");
mod.delete_mechmind_group("location1.mmo", "MINVACH-6");
for (auto &&[n,_] : mod.get_mmo_storage("location1.mmo").mechs) {
if (n != "SHUN-2") {
mod.delete_mechmind_group("location1.mmo", n);
}
}*/
// does not work, crashes. Maybe different item size
// or maybe too many goods
@ -313,10 +339,10 @@ int main(int argc, char *argv[]) {
//_ADDOBJECT(GUN_RAILGUN)
//_ADDOBJECT(GUN_IMPULSE_MEGALAZER)
_ADDOBJECT(EQP_ANALYZER)
_ADDOBJECT(EQP_QUANTUM_TRANSLATOR)
_ADDOBJECT(EQP_INVISIBILITY_SHIELD)
_ADDOBJECT(EQP_UNIVERSAL_SHIELD)
//_ADDOBJECT(EQP_ANALYZER)
//_ADDOBJECT(EQP_QUANTUM_TRANSLATOR)
//_ADDOBJECT(EQP_INVISIBILITY_SHIELD)
//_ADDOBJECT(EQP_UNIVERSAL_SHIELD)
_ADDRATING(300000000)
_ADDBALANCE(30000000)
@ -346,6 +372,11 @@ int main(int argc, char *argv[]) {
//_INFO(SECTOR9_TEST)
//_INFO(SECTOR10_TEST)
)");
//mod.copy_sector_from_aim1(2, 2);
//quest["ru_RU"]["INFORMATION"]["SECTOR2_TEST"]["NAME"] = "test";
//quest["ru_RU"]["INFORMATION"]["SECTOR2_TEST"]["TEXT"] = "<link: войти 2=LINKJUMPTO location2.mmp>";
//mod.copy_sector_from_aim1(1, 1);
//mod.copy_sector_from_aim1(2, 2);
/*mod.copy_sector_from_aim1(1, 3);
mod.copy_sector_from_aim1(1);
mod.copy_sector_from_aim1(2);

View file

@ -475,7 +475,52 @@ struct mod_maker {
// increase number of goods
++*(uint32_t *)(f.p + it->second.offset);
}
auto get_mmo_storage(path mmo_fn) {
auto fn = find_real_filename(mmo_fn);
mmo_storage2 m{fn};
m.load();
return m;
}
void hide_mechmind_group(path mmo_fn, const std::string &name) {
log("hiding mechmind group {} in loc {}", name, mmo_fn.string());
auto fn = find_real_filename(mmo_fn);
files_to_pak.insert(fn);
mmo_storage2 m{fn};
m.load();
auto it = m.mechs.find(name);
if (it == m.mechs.end()) {
throw std::runtime_error{"no such mechmind or group: " + name};
}
primitives::templates2::mmap_file<uint8_t> f{fn, primitives::templates2::mmap_file<uint8_t>::rw{}};
auto n = *(uint32_t*)(f.p + it->second.n_mechs_offset);
auto &hidden = *(uint8_t*)(f.p + it->second.mechs_offset + n * 0x20);
hidden = 1;
}
void delete_mechmind_group(path mmo_fn, const std::string &name) {
log("deleting mechmind group {} in loc {}", name, mmo_fn.string());
auto fn = find_real_filename(mmo_fn);
files_to_pak.insert(fn);
mmo_storage2 m{fn};
m.load();
auto it = m.mechs.find(name);
if (it == m.mechs.end()) {
throw std::runtime_error{"no such mechmind or group: " + name};
}
primitives::templates2::mmap_file<uint8_t> f{fn, primitives::templates2::mmap_file<uint8_t>::rw{}};
auto &n = *(uint32_t*)(f.p + m.n_mech_groups_offset);
--n;
f.close();
bin_patcher::erase(fn, it->second.offset, it->second.size);
}
void clone_mechmind_group(path mmo_fn, const std::string &name, const std::string &newname) {
log("cloninig mechmind group {} in loc {}, new name {}", name, mmo_fn.string(), newname);
auto fn = find_real_filename(mmo_fn);
files_to_pak.insert(fn);
@ -498,6 +543,12 @@ struct mod_maker {
bin_patcher::insert(fn, m.mech_groups_offset, data);
}
bool set_mechmind_organization(path mmo_fn, const std::string &name, const std::string &orgname) {
// deprecated, for api stability
return set_mechmind_group_organization(mmo_fn, name, orgname);
}
bool set_mechmind_group_organization(path mmo_fn, const std::string &name, const std::string &orgname) {
log("setting mechmind group {} organization {} in loc {}", name, orgname, mmo_fn.string());
auto fn = find_real_filename(mmo_fn);
files_to_pak.insert(fn);
@ -515,7 +566,32 @@ struct mod_maker {
memcpy(f.p + it->second.name_offset + 0x20, orgname.data(), orgname.size() + 1);
return true;
}
void set_mechmind_group_type(path mmo_fn, const std::string &name, int newtype, int new_road_id = 100) {
log("setting mechmind group {} in loc {} to {}", name, mmo_fn.string(), newtype);
auto fn = find_real_filename(mmo_fn);
files_to_pak.insert(fn);
mmo_storage2 m{fn};
m.load();
auto it = m.mechs.find(name);
if (it == m.mechs.end()) {
throw std::runtime_error{"no such mechmind or group: " + name};
}
primitives::templates2::mmap_file<uint8_t> f{fn, primitives::templates2::mmap_file<uint8_t>::rw{}};
auto &type = *(uint32_t*)(f.p + it->second.offset + 0x20 + 0x20);
type = newtype;
auto &road_id = *(uint32_t*)(f.p + it->second.post_comment_offset);
road_id = new_road_id;
if (newtype == 1) {
auto &unk = *(float*)(f.p + it->second.post_comment_offset + 4);
unk = 0;
}
}
bool rename_mechmind_group(path mmo_fn, const std::string &name, const std::string &newname) {
log("renaming mechmind group {} in loc {} to {}", name, mmo_fn.string(), newname);
auto fn = find_real_filename(mmo_fn);
files_to_pak.insert(fn);
@ -534,6 +610,14 @@ struct mod_maker {
return true;
}
void update_mechmind_group_configurations(path mmo_fn, const std::string &name, auto &&cfg, auto &&...cfgs) {
std::string format;
auto addname = [&](const std::string &cfg) {
format += cfg + ",";
};
addname(cfg);
(addname(cfgs),...);
log("updating mechmind group {} configurations in loc {} to {}", name, mmo_fn.string(), format);
auto fn = find_real_filename(mmo_fn);
files_to_pak.insert(fn);
@ -818,8 +902,11 @@ struct mod_maker {
auto mmp = find_real_filename(from + ".mmp");
auto mmo = find_real_filename(from + ".mmo");
auto mmm = find_real_filename(from + ".mmm");
if (mmp != get_mod_dir() / (to + ".mmp"))
fs::copy_file(mmp, get_mod_dir() / (to + ".mmp"), fs::copy_options::update_existing);
if (mmo != get_mod_dir() / (to + ".mmo"))
fs::copy_file(mmo, get_mod_dir() / (to + ".mmo"), fs::copy_options::update_existing);
if (mmm != get_mod_dir() / (to + ".mmm"))
fs::copy_file(mmm, get_mod_dir() / (to + ".mmm"), fs::copy_options::update_existing);
files_to_pak.insert(get_mod_dir() / (to + ".mmp"));
files_to_pak.insert(get_mod_dir() / (to + ".mmo"));

View file

@ -62,6 +62,7 @@ struct mmo_storage2 {
uint32_t name_offset;
uint32_t n_mechs_offset;
uint32_t mechs_offset;
uint32_t post_comment_offset;
uint32_t offset;
uint32_t size;
};
@ -105,6 +106,7 @@ struct mmo_storage2 {
m.comment = o.comment;
m.name_offset = (uint8_t*)o.name - f.p;
m.n_mechs_offset = (uint8_t*)&o.n_mechs - f.p;
m.post_comment_offset = (uint8_t*)s.p - f.p;
if (strcmp(o.name, "MINVACH-6") == 0) {
int a = 5;
@ -114,16 +116,46 @@ struct mmo_storage2 {
int a = 5;
a++;
}
if (strcmp(o.name, "ETRANNA-1") == 0) {
int a = 5;
a++;
}
if (strcmp(o.name, "SHUN-2") == 0) {
int a = 5;
a++;
}
// mech are spawned on random path when leaving the base
// probably far from player
//
// 0 = stationary
// 0 = CGuardMechGroup?
// 1 = roaming between bases (and trading?)
// 1 = CTransMechGroup!
// 2 = patrol? or roaming and killing?
// 2 = CHunterMechGroup!
// 3 = ? free mechs? spawn pos? flag? free roaming? always 0 except single ORG_FREE mob in location5
// 3 = CPeopleMechGroup
// 4 = ? platforms? spawn pos? probably only single appearence in the game - location2 GL_PLATFORM
// 4 = CGuardMechGroup?
switch (o.type) {
case 0: // alive
case 1: {
{
uint32_t sector_id = s; // road id? or map sector id
float height = s; // height?
int a = 5;
a++;
} break;
case 1: {
uint32_t road_id = s; // road id? or map sector id
float unused_guessed = s; // height?
int a = 5;
a++;
} break;
// patrol? because transes have type '1'
// and seems pathes are generated ingame between bases
case 2: {
std::vector<uint32_t> t; // current path?
uint32_t len = s;
@ -132,9 +164,17 @@ struct mmo_storage2 {
} break;
case 3: // 3 = free mechanoids only?
{
// dead in other mech id?
// object id? base id?
uint32_t t = s; // other mech id?
if (t != 0) {
int a = 5;
a++;
}
int a = 5;
a++;
} break;
case 4: {
// dead in other mech id?
// object id? base id?