Skip to content

Commit

Permalink
add rising speed for Hundun
Browse files Browse the repository at this point in the history
  • Loading branch information
Mr-Auto committed Sep 25, 2023
1 parent 3a5f7bf commit a07921d
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 14 deletions.
4 changes: 4 additions & 0 deletions src/game_api/entities_monsters.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,10 @@ class Hundun : public Monster
/// This is custom variable, you need [activate_hundun_hack](#activate_hundun_hack) to use it
float y_limit;
/// This is custom variable, you need [activate_hundun_hack](#activate_hundun_hack) to use it
float rising_speed_x;
/// This is custom variable, you need [activate_hundun_hack](#activate_hundun_hack) to use it
float rising_speed_y;
/// This is custom variable, you need [activate_hundun_hack](#activate_hundun_hack) to use it
float bird_head_spawn_y;
/// This is custom variable, you need [activate_hundun_hack](#activate_hundun_hack) to use it
float snake_head_spawn_y;
Expand Down
55 changes: 42 additions & 13 deletions src/game_api/rpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1946,8 +1946,8 @@ void activate_hundun_hack(bool activate)
* Pointer to Hundun entity is stored in r13 register. which means we need 8 bytes for ucomiss instruction
* but we have 7 available, that's why we jump out to new code with the instruction and back
*/
static size_t offsets[4]; // y_limit, y_limit, bird_head, sneak_head
static char new_code[2][7];
static size_t offsets[6]; // y_limit, y_limit, bird_head, sneak_head, speed, speed
static char new_code[3][8];

if (offsets[0] == 0)
{
Expand All @@ -1966,52 +1966,81 @@ void activate_hundun_hack(bool activate)
}
offsets[1] += 8; // pattern size

offsets[2] = find_inst(memory.exe(), "\xF3\x41\x0F\x58\x45\x7C"sv, offsets[0], offsets[1], "");
offsets[2] = find_inst(memory.exe(), "\xF3\x41\x0F\x58\x45\x7C"sv, offsets[0], offsets[1], "activate_hundun_hack");
if (offsets[2] == 0)
{
offsets[0] = 0;
return;
}
offsets[2] += 6; // pattern size

offsets[3] = find_inst(memory.exe(), "\xF3\x41\x0F\x58\x45\x7C"sv, offsets[2], offsets[1], "");
offsets[3] = find_inst(memory.exe(), "\xF3\x41\x0F\x58\x45\x7C"sv, offsets[2], offsets[1], "activate_hundun_hack");
if (offsets[3] == 0)
{
offsets[0] = 0;
return;
}
offsets[3] += 6; // pattern size

offsets[4] = find_inst(memory.exe(), "\x83\x7A\x0C\x0E"sv, offsets[1], offsets[1] + 0xC0, "activate_hundun_hack");
if (offsets[4] == 0)
{
offsets[0] = 0;
return;
}
offsets[4] += 6; // pattern size plus jump

offsets[5] = find_inst(memory.exe(), "\xF3\x41\x0F"sv, offsets[4], offsets[4] + 0x58, "activate_hundun_hack");
if (offsets[5] == 0)
{
offsets[0] = 0;
return;
}
offsets[5] += 9; // instruction size (din't include the whole thing in pattern, very short distance)

offsets[0] = memory.at_exe(offsets[0]);
offsets[1] = memory.at_exe(offsets[1]);
offsets[2] = memory.at_exe(offsets[2]);
offsets[3] = memory.at_exe(offsets[3]);
offsets[4] = memory.at_exe(offsets[4]);
offsets[5] = memory.at_exe(offsets[5]);

char old_code[2][7];
char old_code[3][7];

std::memcpy(old_code[0], (void*)offsets[0], 7);
std::memcpy(old_code[1], (void*)offsets[1], 7);
std::memcpy(old_code[2], (void*)offsets[5], 8);

const std::string_view patch_code{"\x41\x0F\x2E\xBD\x64\x01\x00\x00"sv}; // ucomiss xmm7,DWORD PTR [r13+0x164]
const std::string_view patch_code{"\x41\x0F\x2E\xBD\x64\x01\x00\x00"sv}; // ucomiss xmm7,DWORD PTR [r13+0x164]
const std::string_view speed_patch{"\xF3\x41\x0F\x58\x85\x68\x01\x00\x00"sv}; // addss xmm0,DWORD PTR [r13+0x168]

patch_and_redirect(offsets[0], 7, patch_code, true);
patch_and_redirect(offsets[1], 7, patch_code, true);
patch_and_redirect(offsets[5], 8, speed_patch, true); // always one byte short :(

std::memcpy(new_code[0], (void*)offsets[0], 7);
std::memcpy(new_code[1], (void*)offsets[1], 7);
std::memcpy(new_code[2], (void*)offsets[5], 8);

// writing back the old code so we can just use write_mem_recoverable for going from vanilla to the patch
write_mem_prot(offsets[0], std::string_view{&old_code[0][0], &old_code[0][7]}, true);
write_mem_prot(offsets[1], std::string_view{&old_code[1][0], &old_code[1][7]}, true);
write_mem_prot(offsets[5], std::string_view{&old_code[2][0], &old_code[2][8]}, true);
}

if (activate)
{
write_mem_recoverable("activate_hundun_hack", offsets[0], std::string_view{&new_code[0][0], &new_code[0][7]}, true);
write_mem_recoverable("activate_hundun_hack", offsets[1], std::string_view{&new_code[1][0], &new_code[1][7]}, true);
static const std::string_view speed_code{"\x49\x8D\x95\x68\x01\x00\x00"sv // lea rdx,[r13+0x168]
"\x66\x2E\x0F\x1F\x84\x00\x00\x00\x00\x00\x90\x90\x90"sv}; // spoiled with space, all nop

write_mem_recoverable("activate_hundun_hack", offsets[0], std::string_view{&new_code[0][0], &new_code[0][7]}, true); // limit
write_mem_recoverable("activate_hundun_hack", offsets[1], std::string_view{&new_code[1][0], &new_code[1][7]}, true); // limit
write_mem_recoverable("activate_hundun_hack", offsets[5], std::string_view{&new_code[2][0], &new_code[2][8]}, true); // speed for adding to the y_limit

write_mem_recoverable("activate_hundun_hack", offsets[4], speed_code, true); // speed (for adding to the x position)

write_mem_recoverable("activate_hundun_hack", offsets[2], "\x0F\x2E\xB8\x68\x01\x00\x00"sv, true); // ucomiss xmm7,DWORD PTR [rax+0x168]
write_mem_recoverable("activate_hundun_hack", offsets[3], "\x0F\x2E\xB8\x6C\x01\x00\x00"sv, true); // ucomiss xmm7,DWORD PTR [rax+0x16C]
write_mem_recoverable("activate_hundun_hack", offsets[2], "\x0F\x2E\xB8\x70\x01\x00\x00"sv, true); // ucomiss xmm7,DWORD PTR [rax+0x170] // bird_head
write_mem_recoverable("activate_hundun_hack", offsets[3], "\x0F\x2E\xB8\x74\x01\x00\x00"sv, true); // ucomiss xmm7,DWORD PTR [rax+0x174] // snake head
}
else
recover_mem("activate_hundun_hack");
Expand All @@ -2027,7 +2056,7 @@ void set_boss_door_control_enabled(bool enable)
if (offsets[0] == 0)
return;
// find tiamat door control (the same pattern)
offsets[1] = find_inst(memory.exe(), "\x4A\x8B\xB4\xC8\x80\xF4\x00\x00", offsets[0] - memory.exe_ptr + 0x777, std::nullopt, "set_boss_door_control_enabled");
offsets[1] = find_inst(memory.exe(), "\x4A\x8B\xB4\xC8\x80\xF4\x00\x00"sv, offsets[0] - memory.exe_ptr + 0x777, std::nullopt, "set_boss_door_control_enabled");
if (offsets[1] == 0)
{
offsets[0] = 0;
Expand All @@ -2037,8 +2066,8 @@ void set_boss_door_control_enabled(bool enable)
}
if (!enable)
{
write_mem_recoverable("set_boss_door_control_enabled", offsets[0], "\xC3\x90", true);
write_mem_recoverable("set_boss_door_control_enabled", offsets[1], "\xC3\x90", true);
write_mem_recoverable("set_boss_door_control_enabled", offsets[0], "\xC3\x90"sv, true);
write_mem_recoverable("set_boss_door_control_enabled", offsets[1], "\xC3\x90"sv, true);
}
else
recover_mem("set_boss_door_control_enabled");
Expand Down
2 changes: 1 addition & 1 deletion src/game_api/script/lua_vm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2032,7 +2032,7 @@ end

/// Activate custom variables for y coordinate limit for hundun and spawn of it's heads
/// note: because those variables are custom and game does not initiate them, you need to do it yourself for each Hundun entity, recommending `set_post_entity_spawn`
/// default game value is: y_limit = 98.5, bird_head_spawn_y = 55, snake_head_spawn_y = 71
/// default game value are: y_limit = 98.5, rising_speed_x = 0, rising_speed_y = 0.0125, bird_head_spawn_y = 55, snake_head_spawn_y = 71
lua["activate_hundun_hack"] = activate_hundun_hack;

/// Allows you to disable the control over the door for Hundun and Tiamat
Expand Down
4 changes: 4 additions & 0 deletions src/game_api/script/usertypes/entities_monsters_lua.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1106,6 +1106,10 @@ void register_usertypes(sol::state& lua)
&Hundun::hundun_flags,
"y_limit",
&Hundun::y_limit,
"rising_speed_x",
&Hundun::rising_speed_x,
"rising_speed_y",
&Hundun::rising_speed_y,
"bird_head_spawn_y",
&Hundun::bird_head_spawn_y,
"snake_head_spawn_y",
Expand Down

0 comments on commit a07921d

Please sign in to comment.