Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Random stuff, again #349

Merged
merged 33 commits into from
Nov 2, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
d991bc9
one pattern less
Mr-Auto Oct 20, 2023
6c1673c
4 pattern less
Mr-Auto Oct 20, 2023
5cfba4a
another one
Mr-Auto Oct 20, 2023
9438478
just rename
Mr-Auto Oct 20, 2023
4b92f05
Merge remote-tracking branch 'origin/main' into stuff
Mr-Auto Oct 21, 2023
704d9b9
make it big letters
Mr-Auto Oct 21, 2023
ff9b1da
screen level thing
Mr-Auto Oct 21, 2023
56e3813
super small optimisation in `get_entities_by`
Mr-Auto Oct 21, 2023
8432219
comment out unused stuff
Mr-Auto Oct 21, 2023
31c9628
fix some super rare bug
Mr-Auto Oct 21, 2023
b256fda
if layer() and layer_local() do the same thing, just use one, so ever…
Mr-Auto Oct 21, 2023
e649a77
use advantages of map and initializer list for `worn_backitem` functi…
Mr-Auto Oct 21, 2023
f6ab87e
one more pattern gone
Mr-Auto Oct 21, 2023
7c357f2
add `set_camera_layer_control_enabled`
Mr-Auto Oct 22, 2023
7965a6f
this idea is as dead as it can be
Mr-Auto Oct 22, 2023
824380a
use local, why not
Mr-Auto Oct 22, 2023
cf4745e
move illumination to separate file, expose the full version of the fu…
Mr-Auto Oct 28, 2023
a01e9f4
Merge remote-tracking branch 'origin/main' into stuff
Mr-Auto Oct 28, 2023
837cd4a
fix and update doc
Mr-Auto Oct 28, 2023
b64d34c
some more doc stuff
Mr-Auto Oct 28, 2023
1c425b4
game api stuff
Mr-Auto Oct 29, 2023
de66eaa
fix example
Mr-Auto Oct 29, 2023
33b6df2
why this is fine locally but not on remote?
Mr-Auto Oct 29, 2023
78546ae
bring back zoom hack
Mr-Auto Oct 29, 2023
b8ad3f0
fix ui flags
Mr-Auto Oct 30, 2023
91c3c2e
improve flags in UI
Mr-Auto Oct 31, 2023
be56a7d
small random stuff
Mr-Auto Oct 31, 2023
4c5c4f6
add more `:set()` functions, unless there is some lua alternative?
Mr-Auto Nov 1, 2023
4881181
wtf
Mr-Auto Nov 1, 2023
5b317b8
some non important changes
Mr-Auto Nov 1, 2023
c99216a
particle stuff, move the particle functions from rpc, expose some mor…
Mr-Auto Nov 1, 2023
07e37a3
update doc
Mr-Auto Nov 1, 2023
4efa404
write our some more obvious stuff
Mr-Auto Nov 2, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 21 additions & 68 deletions src/game_api/level_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -848,65 +848,6 @@ void level_gen(LevelGenSystem* level_gen_sys, float param_2, size_t param_3)
g_levels_to_load.clear();
}

using TransGenFun = void(ThemeInfo*);
TransGenFun* g_trans_gen_trampoline{nullptr};
TransGenFun* g_trans_gen2_trampoline{nullptr};
using TransGenFun3 = void(size_t, size_t, ThemeInfo*);
TransGenFun3* g_trans_gen3_trampoline{nullptr};
using TransGenFun4 = void(size_t, size_t, size_t, size_t, size_t, size_t);
TransGenFun4* g_trans_gen4_trampoline{nullptr};
// generic transition hook
void trans_gen(ThemeInfo* theme)
{
push_spawn_type_flags(SPAWN_TYPE_LEVEL_GEN_GENERAL);
OnScopeExit pop{[]
{ pop_spawn_type_flags(SPAWN_TYPE_LEVEL_GEN_GENERAL); }};

if (pre_level_generation())
return;
g_trans_gen_trampoline(theme);
post_level_generation();
}
// cosmic transition hook
void trans_gen2(ThemeInfo* theme)
{
push_spawn_type_flags(SPAWN_TYPE_LEVEL_GEN_GENERAL);
OnScopeExit pop{[]
{ pop_spawn_type_flags(SPAWN_TYPE_LEVEL_GEN_GENERAL); }};

if (pre_level_generation())
return;
g_trans_gen2_trampoline(theme);
post_level_generation();
}
// cog-duat transition hook
void trans_gen3(size_t a, size_t b, ThemeInfo* theme)
{
push_spawn_type_flags(SPAWN_TYPE_LEVEL_GEN_GENERAL);
OnScopeExit pop{[]
{ pop_spawn_type_flags(SPAWN_TYPE_LEVEL_GEN_GENERAL); }};

auto state = State::get().ptr();
// trampoline will call the generic trans_gen if not going to duat
if (state->theme_next == 12 && pre_level_generation())
return;
g_trans_gen3_trampoline(a, b, theme);
if (state->theme_next == 12)
post_level_generation();
}
// olmecship transition hook
void trans_gen4(size_t a, size_t b, size_t c, size_t d, size_t e, size_t f)
{
push_spawn_type_flags(SPAWN_TYPE_LEVEL_GEN_GENERAL);
OnScopeExit pop{[]
{ pop_spawn_type_flags(SPAWN_TYPE_LEVEL_GEN_GENERAL); }};

if (pre_level_generation())
return;
g_trans_gen4_trampoline(a, b, c, d, e, f);
post_level_generation();
}

using LoadScreenFun = void(StateMemory*, size_t, size_t);
LoadScreenFun* g_load_screen_trampoline{nullptr};
void load_screen(StateMemory* state, size_t param_2, size_t param_3)
Expand Down Expand Up @@ -1560,10 +1501,6 @@ void LevelGenData::init()
g_load_screen_trampoline = (LoadScreenFun*)get_address("load_screen_func"sv);
g_unload_layer_trampoline = (UnloadLayerFun*)get_address("unload_layer"sv);
g_init_layer_trampoline = (InitLayerFun*)get_address("init_layer"sv);
g_trans_gen_trampoline = (TransGenFun*)get_address("spawn_transition"sv);
g_trans_gen2_trampoline = (TransGenFun*)get_address("spawn_transition_cosmic"sv);
g_trans_gen3_trampoline = (TransGenFun3*)get_address("spawn_transition_duat"sv);
g_trans_gen4_trampoline = (TransGenFun4*)get_address("spawn_transition_olmecship"sv);

DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
Expand All @@ -1581,15 +1518,11 @@ void LevelGenData::init()
DetourAttach((void**)&g_load_screen_trampoline, load_screen);
DetourAttach((void**)&g_unload_layer_trampoline, unload_layer);
DetourAttach((void**)&g_init_layer_trampoline, load_layer);
DetourAttach((void**)&g_trans_gen_trampoline, trans_gen);
DetourAttach((void**)&g_trans_gen2_trampoline, trans_gen2);
DetourAttach((void**)&g_trans_gen3_trampoline, trans_gen3);
DetourAttach((void**)&g_trans_gen4_trampoline, trans_gen4);

const LONG error = DetourTransactionCommit();
if (error != NO_ERROR)
{
DEBUG("Failed hooking HandleTileCode: {}\n", error);
DEBUG("Failed hooking LevelGenData stuff: {}\n", error);
}
}

Expand Down Expand Up @@ -1880,6 +1813,26 @@ uint32_t ThemeInfo::get_aux_id()
void LevelGenSystem::init()
{
data->init();

for (auto theme : themes)
{
if (theme == theme_arena) // no reason to?
continue;

hook_vtable<void(ThemeInfo*), 0x15>( // spawn_transition
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So why does this work but not the thing in hook_themes?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And even more curious why the other hooks there do work but not this...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to check but can't setup any debugging or export .pdb file (to use symbols in x64dbg) for release.
Was thinking maybe it's a thread issue, but changing ptr to ptr_main in get_entities doesn't solve this
So until you get to ask @Malacath-92 about this it remains mystery

theme,
[](ThemeInfo* th, void (*original)(ThemeInfo*))
{
push_spawn_type_flags(SPAWN_TYPE_LEVEL_GEN_GENERAL);
OnScopeExit pop{[]
{ pop_spawn_type_flags(SPAWN_TYPE_LEVEL_GEN_GENERAL); }};

if (pre_level_generation())
return;
original(th);
post_level_generation();
});
}
}

void LevelGenSystem::populate_level_hook(ThemeInfo* self, uint64_t param_2, uint64_t param_3, uint64_t param_4, PopulateLevelFun* original)
Expand Down
22 changes: 10 additions & 12 deletions src/game_api/rpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "memory.hpp" // for write_mem_prot, write_mem_recoverable
#include "movable.hpp" // for Movable
#include "particles.hpp" // for ParticleEmitterInfo
#include "screen.hpp" //
#include "search.hpp" // for get_address, find_inst
#include "state.hpp" // for State, get_state_ptr, enum_to_layer
#include "state_structs.hpp" // for ShopRestrictedItem, Illumination
Expand Down Expand Up @@ -1510,11 +1511,10 @@ void game_log(std::string message)
game_log_fun(log_stream, message.c_str(), nullptr, LogLevel::Info);
}

void call_death_screen()
void load_death_screen()
{
using DeathScreen = void();
static auto death_screen = (DeathScreen*)get_address("death_screen");
death_screen();
auto state = State::get().ptr();
state->screen_death->init();
}

void save_progress()
Expand Down Expand Up @@ -1938,18 +1938,16 @@ void create_level()
create_layer(1);
}

void set_death_enabled(bool enable)
void set_level_logic_enabled(bool enable)
{
static size_t offset = 0;
if (offset == 0)
{
offset = get_address("dead_players");
}
auto state = State::get().ptr();
static size_t offset = get_virtual_function_address(state->screen_level, 1);

if (offset != 0)
{
if (!enable)
write_mem_recoverable("death_disable", offset, "\xC3\x90"sv, true);
write_mem_recoverable("set_level_logic_enabled", offset, "\xC3\x90"sv, true);
else
recover_mem("death_disable");
recover_mem("set_level_logic_enabled");
}
}
4 changes: 2 additions & 2 deletions src/game_api/rpc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ void update_liquid_collision_at(float x, float y, bool add);
bool disable_floor_embeds(bool disable);
void set_cursepot_ghost_enabled(bool enable);
void game_log(std::string message);
void call_death_screen();
void load_death_screen();
void save_progress();
void set_level_string(std::u16string_view text);
void set_ending_unlock(ENT_TYPE type);
Expand All @@ -138,4 +138,4 @@ void destroy_layer(uint8_t layer);
void destroy_level();
void create_layer(uint8_t layer);
void create_level();
void set_death_enabled(bool enable);
void set_level_logic_enabled(bool enable);
4 changes: 2 additions & 2 deletions src/game_api/script/lua_vm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1923,7 +1923,7 @@ end
lua["log_print"] = game_log;

/// Immediately ends the run with the death screen, also calls the [save_progress](#save_progress)
lua["load_death_screen"] = call_death_screen;
lua["load_death_screen"] = load_death_screen;

/// Saves the game to savegame.sav, unless game saves are blocked in the settings. Also runs the ON.SAVE callback. Fails and returns false, if you're trying to save too often (2s).
lua["save_progress"] = []() -> bool
Expand Down Expand Up @@ -2155,7 +2155,7 @@ end
lua["create_layer"] = create_layer;

/// Setting to false disables all player logic in SCREEN.LEVEL, mainly the death screen from popping up if all players are dead or missing, but also shop camera zoom and some other small things.
lua["set_level_logic_enabled"] = set_death_enabled;
lua["set_level_logic_enabled"] = set_level_logic_enabled;

/// Converts INPUTS to (x, y, BUTTON)
lua["inputs_to_buttons"] = [](INPUTS inputs) -> std::tuple<float, float, BUTTON>
Expand Down
53 changes: 2 additions & 51 deletions src/game_api/search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1264,6 +1264,7 @@ std::unordered_map<std::string_view, AddressRule> g_address_rules{
"show_journal"sv,
// aka render_journal / open journal chapter
// Break on GameManager.journal_ui.state, open the journal
// Or go to state->death screen, to first virtul function, the second call in that virtual is the function
PatternCommandBuffer{}
.find_inst("88 5F 04 80 FB 0B 0F"_gh)
.at_exe()
Expand Down Expand Up @@ -1878,16 +1879,7 @@ std::unordered_map<std::string_view, AddressRule> g_address_rules{
.function_start(),
},
{
// Set write bp on write_to_file, take a death in game, return from write_to_file, then from the next function as well
// you should be now in the death_screen function, the first call is also the save_progress function
"death_screen"sv,
PatternCommandBuffer{}
.find_inst("4D 0F 44 C1 49 8B 88 F0 12 00 00"_gh)
.at_exe()
.function_start(),
},
{
// see death_screen
// go to state->death screen, to first virtual, this is the first call in that virtual
"save_progress"sv,
PatternCommandBuffer{}
.find_inst("48 8B 90 F0 12 00 00 8B 5A 28"_gh)
Expand Down Expand Up @@ -2068,47 +2060,6 @@ std::unordered_map<std::string_view, AddressRule> g_address_rules{
.function_start(),
//.from_exe_base(0x228b58f0),
},
{
"dead_players"sv,
// I guess it writes 14 to screen_next before the death screen pops up. Apparently it's a SCREEN_LEVEL virtual too.
PatternCommandBuffer{}
.find_inst("4c 8b b8 e8 12 00 00 48 8b 80 f0 12 00 00"_gh)
.at_exe()
.function_start(),
//.from_exe_base(0x22c061d0),
},
{
"spawn_transition"sv,
// These functions are hooked separately cause hooking the vtable just didn't work right for POST_LEVEL_GENERATION
PatternCommandBuffer{}
.get_virtual_function_address(VTABLE_OFFSET::THEME_DWELLING, VIRT_FUNC::THEME_SPAWN_TRANSITION)
.at_exe(),
//.from_exe_base(0x22afe5c0),
},
{
"spawn_transition_cosmic"sv,
// These functions are hooked separately cause hooking the vtable just didn't work right for POST_LEVEL_GENERATION
PatternCommandBuffer{}
.get_virtual_function_address(VTABLE_OFFSET::THEME_COSMICOCEAN, VIRT_FUNC::THEME_SPAWN_TRANSITION)
.at_exe(),
//.from_exe_base(0x22b373b0),
},
{
"spawn_transition_duat"sv,
// These functions are hooked separately cause hooking the vtable just didn't work right for POST_LEVEL_GENERATION
PatternCommandBuffer{}
.get_virtual_function_address(VTABLE_OFFSET::THEME_CITY_OF_GOLD, VIRT_FUNC::THEME_SPAWN_TRANSITION)
.at_exe(),
//.from_exe_base(0x22b34940),
},
{
"spawn_transition_olmecship"sv,
// These functions are hooked separately cause hooking the vtable just didn't work right for POST_LEVEL_GENERATION
PatternCommandBuffer{}
.get_virtual_function_address(VTABLE_OFFSET::THEME_BASECAMP, VIRT_FUNC::THEME_SPAWN_TRANSITION)
.at_exe(),
//.from_exe_base(0x22b2d350),
},
};
std::unordered_map<std::string_view, size_t> g_cached_addresses;

Expand Down
2 changes: 1 addition & 1 deletion src/game_api/state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ State& State::get()
}
auto addr_location = get_address("state_location");
STATE = State{addr_location};
get_is_init() = true;

if (get_do_hooks())
{
Expand Down Expand Up @@ -310,7 +311,6 @@ State& State::get()
DEBUG("Not applying patches, someone has already done it");
}
}
get_is_init() = true;
}
return STATE;
}
Expand Down
6 changes: 6 additions & 0 deletions src/game_api/virtual_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,9 @@ size_t get_virtual_function_address(VTABLE_OFFSET table_entry, uint32_t function
size_t* func_address = reinterpret_cast<size_t*>(first_table_entry + ((static_cast<size_t>(table_entry) + function_index) * sizeof(size_t)));
return *func_address - mem.exe_ptr;
}

size_t get_virtual_function_address(void* object, uint32_t function_index)
{
auto v_table = *static_cast<size_t**>(object);
return *(v_table + function_index);
}
1 change: 1 addition & 0 deletions src/game_api/virtual_table.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -990,3 +990,4 @@ enum class VTABLE_OFFSET
};

size_t get_virtual_function_address(VTABLE_OFFSET table_entry, uint32_t function_index);
size_t get_virtual_function_address(void* object, uint32_t function_index);
4 changes: 2 additions & 2 deletions src/injected/ui_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ void UI::godmode_companions(bool g)
}
void UI::death_enabled(bool g)
{
set_death_enabled(g);
set_level_logic_enabled(g);
}
std::pair<float, float> UI::click_position(float x, float y)
{
Expand Down Expand Up @@ -767,5 +767,5 @@ std::pair<float, float> UI::spawn_position()

void UI::load_death_screen()
{
call_death_screen();
::load_death_screen();
}
Loading