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["Глайдеры"]) {
|
||||
m2_gliders.erase(n);
|
||||
}
|
||||
for (auto &&[n, _] : m2_gliders) {
|
||||
mod.copy_glider_from_aim2(n);
|
||||
}
|
||||
//mod.copy_glider_from_aim2("GL_M4_S_FLASH");
|
||||
//m2_gliders.erase("GL_M4_S_FLASH");
|
||||
//for (auto &&[n, _] : m2_gliders) {
|
||||
// mod.copy_glider_from_aim2(n);
|
||||
//}
|
||||
std::string after;
|
||||
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["Оружие"]) {
|
||||
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.
|
||||
// TODO: check in debug why they crash
|
||||
mod.copy_weapon_from_aim2("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");
|
||||
after = mod.add_map_good("location1.mmo", "B_L1_BASE1", after, mmo_storage2::map_good("GUN_GRAVITON"));
|
||||
//mod.copy_weapon_from_aim2("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");
|
||||
//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.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
|
||||
// or maybe too many goods
|
||||
/*for (auto after = "EQP_POLYMER_ARMOR_S1"s; auto &&[n, _] : db["Оборудование"]) {
|
||||
|
|
|
|||
|
|
@ -473,6 +473,97 @@ struct mod_maker {
|
|||
// increase number of goods
|
||||
++*(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
|
||||
// handle the call instruction in 'dispatcher' symbol (naked) of your dll
|
||||
|
|
|
|||
Loading…
Reference in a new issue