mirror of
https://github.com/aimrebirth/tools.git
synced 2026-04-14 17:33:25 +00:00
[mod] New APIs: clone_mechmind_group(), rename_mechmind_group(), update_mechmind_group_configurations(), set_mechmind_organization().
This commit is contained in:
parent
5ac5d05083
commit
152b935b25
2 changed files with 118 additions and 9 deletions
|
|
@ -238,26 +238,44 @@ int main(int argc, char *argv[]) {
|
||||||
for (auto &&[n,_] : db["Глайдеры"]) {
|
for (auto &&[n,_] : db["Глайдеры"]) {
|
||||||
m2_gliders.erase(n);
|
m2_gliders.erase(n);
|
||||||
}
|
}
|
||||||
for (auto &&[n, _] : m2_gliders) {
|
//mod.copy_glider_from_aim2("GL_M4_S_FLASH");
|
||||||
mod.copy_glider_from_aim2(n);
|
//m2_gliders.erase("GL_M4_S_FLASH");
|
||||||
}
|
//for (auto &&[n, _] : m2_gliders) {
|
||||||
|
// mod.copy_glider_from_aim2(n);
|
||||||
|
//}
|
||||||
std::string after;
|
std::string after;
|
||||||
for (after = "GL_M1_A_ATTACKER"s; auto &&[n, _] : db["Глайдеры"]) {
|
for (after = "GL_M1_A_ATTACKER"s; auto &&[n, _] : db["Глайдеры"]) {
|
||||||
after = mod.add_map_good("location1.mmo", "B_L1_BASE1", after, mmo_storage2::map_good(n));
|
//after = mod.add_map_good("location1.mmo", "B_L1_BASE1", after, mmo_storage2::map_good(n));
|
||||||
}
|
}
|
||||||
for (after = "GUN_RAY_LAZER"s; auto &&[n, _] : db["Оружие"]) {
|
for (after = "GUN_RAY_LAZER"s; auto &&[n, _] : db["Оружие"]) {
|
||||||
after = mod.add_map_good("location1.mmo", "B_L1_BASE1", after, mmo_storage2::map_good(n));
|
//after = mod.add_map_good("location1.mmo", "B_L1_BASE1", after, mmo_storage2::map_good(n));
|
||||||
}
|
}
|
||||||
// patch note dev: copy GUN_DRAINER and GUN_GRAVITON from AIM2. They crash frequently while in F2 mode. Some does not have fx.
|
// patch note dev: copy GUN_DRAINER and GUN_GRAVITON from AIM2. They crash frequently while in F2 mode. Some does not have fx.
|
||||||
// TODO: check in debug why they crash
|
// TODO: check in debug why they crash
|
||||||
mod.copy_weapon_from_aim2("GUN_DRAINER");
|
//mod.copy_weapon_from_aim2("GUN_DRAINER");
|
||||||
after = mod.add_map_good("location1.mmo", "B_L1_BASE1", after, mmo_storage2::map_good("GUN_DRAINER"));
|
//after = mod.add_map_good("location1.mmo", "B_L1_BASE1", after, mmo_storage2::map_good("GUN_DRAINER"));
|
||||||
mod.copy_weapon_from_aim2("GUN_GRAVITON");
|
//mod.copy_weapon_from_aim2("GUN_GRAVITON");
|
||||||
after = mod.add_map_good("location1.mmo", "B_L1_BASE1", after, mmo_storage2::map_good("GUN_GRAVITON"));
|
//after = mod.add_map_good("location1.mmo", "B_L1_BASE1", after, mmo_storage2::map_good("GUN_GRAVITON"));
|
||||||
|
|
||||||
//
|
//
|
||||||
mod.replace("under.scr", "_ADDSENSOR(T_L4_BASE_2)", "_ADDSENSOR(T_L4_BASE_2 )\n_MARK(T_L4_BASE_2)");
|
mod.replace("under.scr", "_ADDSENSOR(T_L4_BASE_2)", "_ADDSENSOR(T_L4_BASE_2 )\n_MARK(T_L4_BASE_2)");
|
||||||
|
|
||||||
|
//
|
||||||
|
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");
|
||||||
|
|
||||||
// does not work, crashes. Maybe different item size
|
// does not work, crashes. Maybe different item size
|
||||||
// or maybe too many goods
|
// or maybe too many goods
|
||||||
/*for (auto after = "EQP_POLYMER_ARMOR_S1"s; auto &&[n, _] : db["Оборудование"]) {
|
/*for (auto after = "EQP_POLYMER_ARMOR_S1"s; auto &&[n, _] : db["Оборудование"]) {
|
||||||
|
|
|
||||||
|
|
@ -473,6 +473,97 @@ struct mod_maker {
|
||||||
// increase number of goods
|
// increase number of goods
|
||||||
++*(uint32_t *)(f.p + it->second.offset);
|
++*(uint32_t *)(f.p + it->second.offset);
|
||||||
}
|
}
|
||||||
|
void clone_mechmind_group(path mmo_fn, const std::string &name, const std::string &newname) {
|
||||||
|
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};
|
||||||
|
}
|
||||||
|
if (newname.size() > 0x20-1) {
|
||||||
|
throw std::runtime_error{"too long name: " + newname};
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
std::string data{f.p + it->second.offset, f.p + it->second.offset + it->second.size};
|
||||||
|
strcpy(data.data(), newname.data());
|
||||||
|
f.close();
|
||||||
|
bin_patcher::insert(fn, m.mech_groups_offset, data);
|
||||||
|
}
|
||||||
|
bool set_mechmind_organization(path mmo_fn, const std::string &name, const std::string &orgname) {
|
||||||
|
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};
|
||||||
|
}
|
||||||
|
if (orgname.size() > 0x20-1) {
|
||||||
|
throw std::runtime_error{"too long organization name: " + orgname};
|
||||||
|
}
|
||||||
|
primitives::templates2::mmap_file<uint8_t> f{fn, primitives::templates2::mmap_file<uint8_t>::rw{}};
|
||||||
|
memcpy(f.p + it->second.name_offset + 0x20, orgname.data(), orgname.size() + 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool rename_mechmind_group(path mmo_fn, const std::string &name, const std::string &newname) {
|
||||||
|
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()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (newname.size() > 0x20-1) {
|
||||||
|
throw std::runtime_error{"too long name: " + newname};
|
||||||
|
}
|
||||||
|
primitives::templates2::mmap_file<uint8_t> f{fn, primitives::templates2::mmap_file<uint8_t>::rw{}};
|
||||||
|
memcpy(f.p + it->second.name_offset, newname.data(), newname.size() + 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void update_mechmind_group_configurations(path mmo_fn, const std::string &name, auto &&cfg, auto &&...cfgs) {
|
||||||
|
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};
|
||||||
|
}
|
||||||
|
auto new_n = 1 + sizeof...(cfgs);
|
||||||
|
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 oldn = n;
|
||||||
|
n = new_n;
|
||||||
|
f.close();
|
||||||
|
|
||||||
|
bin_patcher::erase(fn, it->second.mechs_offset, oldn * 0x20);
|
||||||
|
std::string newcfgs;
|
||||||
|
newcfgs.resize(0x20 * new_n);
|
||||||
|
auto p = newcfgs.data();
|
||||||
|
auto add = [&](const std::string &cfg) {
|
||||||
|
if (cfg.size() > 0x20-1) {
|
||||||
|
throw std::runtime_error{"too long config name: " + cfg};
|
||||||
|
}
|
||||||
|
strcpy(p, cfg.data());
|
||||||
|
p += 0x20;
|
||||||
|
};
|
||||||
|
add(cfg);
|
||||||
|
(add(cfgs),...);
|
||||||
|
bin_patcher::insert(fn, it->second.mechs_offset, newcfgs);
|
||||||
|
}
|
||||||
|
|
||||||
// all you need is to provide injection address (virtual) with size
|
// all you need is to provide injection address (virtual) with size
|
||||||
// handle the call instruction in 'dispatcher' symbol (naked) of your dll
|
// handle the call instruction in 'dispatcher' symbol (naked) of your dll
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue