From 584cfc97067fbe0564f27839fde70c8bc272e532 Mon Sep 17 00:00:00 2001 From: Mr-Auto <36127424+Mr-Auto@users.noreply.github.com> Date: Sun, 26 Nov 2023 12:02:38 +0100 Subject: [PATCH 01/12] expose `special_sound` in Player --- docs/game_data/spel2.lua | 1 + docs/src/includes/_types.md | 1 + src/game_api/entities_chars.hpp | 4 ++-- src/game_api/script/usertypes/entities_chars_lua.cpp | 2 ++ 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/game_data/spel2.lua b/docs/game_data/spel2.lua index b78b353b4..729e31320 100644 --- a/docs/game_data/spel2.lua +++ b/docs/game_data/spel2.lua @@ -2742,6 +2742,7 @@ function Movable:generic_update_world(move, sprint_factor, disable_gravity, on_r ---@field ai Ai ---@field input PlayerSlot ---@field basecamp_button_entity Entity @Used in base camp to talk with the NPC's + ---@field special_sound SoundMeta @For Lise System walking and looking up sounds ---@field jump_lock_timer integer @Increases when holding jump button in the air, set to max while jumping. If this isn't 0, a jump will only be
registered if the jump button was not held on the previous frame. ---@field coyote_timer integer @can jump while airborne if greater than 0 ---@field swim_timer integer @Timer between strokes when holding jump button in water. diff --git a/docs/src/includes/_types.md b/docs/src/includes/_types.md index 4efc355f4..56987dda6 100644 --- a/docs/src/includes/_types.md +++ b/docs/src/includes/_types.md @@ -5312,6 +5312,7 @@ int | [linked_companion_child](https://github.com/spelunky-fyi/overlunky/search? [Ai](#Ai) | [ai](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=ai) | [PlayerSlot](#PlayerSlot) | [input](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=input) | [Entity](#Entity) | [basecamp_button_entity](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=basecamp_button_entity) | Used in base camp to talk with the [NPC](#NPC)'s +[SoundMeta](#SoundMeta) | [special_sound](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=special_sound) | For Lise System walking and looking up sounds int | [jump_lock_timer](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=jump_lock_timer) | Increases when holding jump button in the air, set to max while jumping. If this isn't 0, a jump will only be
registered if the jump button was not held on the previous frame. int | [coyote_timer](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=coyote_timer) | can jump while airborne if greater than 0 int | [swim_timer](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=swim_timer) | Timer between strokes when holding jump button in water. diff --git a/src/game_api/entities_chars.hpp b/src/game_api/entities_chars.hpp index 863161149..ef4f182e4 100644 --- a/src/game_api/entities_chars.hpp +++ b/src/game_api/entities_chars.hpp @@ -102,8 +102,8 @@ class Player : public PowerupCapable PlayerSlot* input_ptr; /// Used in base camp to talk with the NPC's Entity* basecamp_button_entity; - int32_t i168; - int32_t i16c; + /// For Lise System walking and looking up sounds + SoundMeta* special_sound; float y_pos; // not sure why, seams to be the same as abs_y /// Increases when holding jump button in the air, set to max while jumping. If this isn't 0, a jump will only be /// registered if the jump button was not held on the previous frame. diff --git a/src/game_api/script/usertypes/entities_chars_lua.cpp b/src/game_api/script/usertypes/entities_chars_lua.cpp index d708773cb..cbc810894 100644 --- a/src/game_api/script/usertypes/entities_chars_lua.cpp +++ b/src/game_api/script/usertypes/entities_chars_lua.cpp @@ -13,6 +13,7 @@ #include "entity.hpp" // for Entity #include "illumination.hpp" // IWYU pragma: keep #include "items.hpp" // for Inventory, Inventory::acquired_powerups +#include "sound_manager.hpp" // IWYU pragma: keep #include "state_structs.hpp" // IWYU pragma: keep class Movable; @@ -114,6 +115,7 @@ void register_usertypes(sol::state& lua) player_type["ai"] = &Player::ai; player_type["input"] = &Player::input_ptr; player_type["basecamp_button_entity"] = &Player::basecamp_button_entity; + player_type["special_sound"] = &Player::special_sound; player_type["jump_lock_timer"] = &Player::jump_lock_timer; player_type["coyote_timer"] = &Player::coyote_timer; player_type["swim_timer"] = &Player::swim_timer; From 91edfcc9f14bc16007fa7c9754c2ea885f8d5c18 Mon Sep 17 00:00:00 2001 From: Mr-Auto <36127424+Mr-Auto@users.noreply.github.com> Date: Tue, 28 Nov 2023 19:17:02 +0100 Subject: [PATCH 02/12] safety, avoiding pointless constructions --- src/game_api/bucket.hpp | 5 +++++ src/game_api/entities_floors.cpp | 6 +++--- src/game_api/entity.cpp | 10 +++++----- src/game_api/entity_lookup.cpp | 10 +++++----- src/game_api/layer.cpp | 2 +- src/game_api/level_api.cpp | 6 ++---- src/game_api/rpc.cpp | 22 +++++++++++----------- src/game_api/script/lua_vm.cpp | 2 +- src/game_api/spawn_api.cpp | 4 ++-- src/game_api/state.cpp | 11 ++++++----- src/game_api/state.hpp | 16 +++++++++++++--- src/injected/ui_util.cpp | 2 +- 12 files changed, 55 insertions(+), 41 deletions(-) diff --git a/src/game_api/bucket.hpp b/src/game_api/bucket.hpp index 697a745ff..9df101be3 100644 --- a/src/game_api/bucket.hpp +++ b/src/game_api/bucket.hpp @@ -64,4 +64,9 @@ class Bucket std::pair adventure_seed{0, 0}; // Used by memory for recoverable memory interoperability std::unordered_map original_memory; + + private: + Bucket() = default; + Bucket(const Bucket&) = delete; + Bucket& operator=(const Bucket&) = delete; }; diff --git a/src/game_api/entities_floors.cpp b/src/game_api/entities_floors.cpp index 4d8cd54a6..ef00ed7a0 100644 --- a/src/game_api/entities_floors.cpp +++ b/src/game_api/entities_floors.cpp @@ -88,7 +88,7 @@ void Floor::fix_decorations(bool fix_also_neighbors, bool fix_styled_floor) Floor* neighbours[4]{}; bool neighbours_same[4]{}; - auto state = State::get(); + auto& state = State::get(); auto layer_ptr = state.layer(layer); for (size_t i = 0; i < 4; i++) @@ -188,7 +188,7 @@ void Floor::add_decoration(FLOOR_SIDE side) return; } - auto state = State::get(); + auto& state = State::get(); auto layer_ptr = state.layer(layer); add_decoration_opt(side, decoration_entity_type, layer_ptr); } @@ -735,7 +735,7 @@ void Door::unlock(bool unlock) static const ENT_TYPE eggchild_room_door = to_id("ENT_TYPE_FLOOR_DOOR_MOAI_STATUE"); static const ENT_TYPE EW_door = to_id("ENT_TYPE_FLOOR_DOOR_EGGPLANT_WORLD"); const auto ent_type = this->type->id; - auto state = State::get(); + auto& state = State::get(); if (ent_type == locked_door || ent_type == locked_door + 1) // plus one for DOOR_LOCKED_PEN { diff --git a/src/game_api/entity.cpp b/src/game_api/entity.cpp index d5785a814..5183811e0 100644 --- a/src/game_api/entity.cpp +++ b/src/game_api/entity.cpp @@ -54,7 +54,7 @@ void Entity::teleport(float dx, float dy, bool s, float vx, float vy, bool snap) { // screen coordinates -1..1 // log::debug!("Teleporting to screen {}, {}", x, y); - auto state = State::get(); + auto& state = State::get(); auto [x_pos, y_pos] = state.click_position(dx, dy); if (snap && abs(vx) + abs(vy) <= 0.04f) { @@ -96,7 +96,7 @@ void Entity::set_layer(LAYER layer_to) if (layer == dest_layer) return; - auto state = State::get(); + auto& state = State::get(); if (this != this->topmost_mount()) this->topmost_mount()->set_layer(layer_to); @@ -125,7 +125,7 @@ void Entity::remove() { if (layer != 2) { - auto state = State::get(); + auto& state = State::get(); auto ptr_from = state.ptr()->layers[layer]; if ((this->type->search_flags & 1) == 0 || ((Player*)this)->ai != 0) { @@ -373,7 +373,7 @@ std::span Entity::get_items() Entity* get_entity_ptr(uint32_t uid) { - auto state = State::get(); + auto& state = State::get(); auto p = state.find(uid); if (IsBadWritePtr(p, 0x178)) return nullptr; @@ -382,7 +382,7 @@ Entity* get_entity_ptr(uint32_t uid) Entity* get_entity_ptr_local(uint32_t uid) { - auto state = State::get(); + auto& state = State::get(); auto p = state.find_local(uid); if (IsBadWritePtr(p, 0x178)) return nullptr; diff --git a/src/game_api/entity_lookup.cpp b/src/game_api/entity_lookup.cpp index 3e9b609fb..b64572a9f 100644 --- a/src/game_api/entity_lookup.cpp +++ b/src/game_api/entity_lookup.cpp @@ -43,7 +43,7 @@ std::vector get_proper_types(std::vector ent_types) int32_t get_grid_entity_at(float x, float y, LAYER layer) { - auto state = State::get(); + auto& state = State::get(); uint8_t actual_layer = enum_to_layer(layer); if (Entity* ent = state.layer(actual_layer)->get_grid_entity_at(x, y)) @@ -169,8 +169,8 @@ std::vector get_entities_by(ENT_TYPE entity_type, uint32_t mask, LAYER std::vector get_entities_at(std::vector entity_types, uint32_t mask, float x, float y, LAYER layer, float radius) { - // TODO: use entitie regions? - auto state = State::get(); + // TODO: use entity regions? + auto& state = State::get(); std::vector found; const std::vector proper_types = get_proper_types(std::move(entity_types)); auto push_entities_at = [&x, &y, &radius, &proper_types, &found](const EntityList& entities) @@ -204,8 +204,8 @@ std::vector get_entities_at(ENT_TYPE entity_type, uint32_t mask, float std::vector get_entities_overlapping_hitbox(std::vector entity_types, uint32_t mask, AABB hitbox, LAYER layer) { - // TODO: use entitie regions? - auto state = State::get(); + // TODO: use entity regions? + auto& state = State::get(); std::vector result; const std::vector proper_types = get_proper_types(std::move(entity_types)); if (layer == LAYER::BOTH) diff --git a/src/game_api/layer.cpp b/src/game_api/layer.cpp index a6aed792c..0a2bd6f9f 100644 --- a/src/game_api/layer.cpp +++ b/src/game_api/layer.cpp @@ -31,7 +31,7 @@ Entity* Layer::spawn_entity(ENT_TYPE id, float x, float y, bool screen, float vx } else if (screen) { - auto state = State::get(); + auto& state = State::get(); std::tie(x, y) = state.click_position(x, y); min_speed_check = 0.04f; if (snap && abs(vx) + abs(vy) <= min_speed_check) diff --git a/src/game_api/level_api.cpp b/src/game_api/level_api.cpp index fef3ebdee..f354739b9 100644 --- a/src/game_api/level_api.cpp +++ b/src/game_api/level_api.cpp @@ -1887,8 +1887,7 @@ std::pair LevelGenSystem::get_room_pos(uint32_t x, uint32_t y) } std::optional LevelGenSystem::get_room_template(uint32_t x, uint32_t y, uint8_t l) { - auto state = State::get(); - auto* state_ptr = state.ptr_local(); + auto* state_ptr = State::get().ptr_local(); if (x < 0 || y < 0 || x >= state_ptr->w || y >= state_ptr->h) return std::nullopt; @@ -1904,8 +1903,7 @@ std::optional LevelGenSystem::get_room_template(uint32_t x, uint32_t y } bool LevelGenSystem::set_room_template(uint32_t x, uint32_t y, int l, uint16_t room_template) { - auto state = State::get(); - auto* state_ptr = state.ptr_local(); + auto* state_ptr = State::get().ptr_local(); if (x < 0 || y < 0 || x >= state_ptr->w || y >= state_ptr->h) return false; diff --git a/src/game_api/rpc.cpp b/src/game_api/rpc.cpp index 242217594..f82ae6901 100644 --- a/src/game_api/rpc.cpp +++ b/src/game_api/rpc.cpp @@ -236,13 +236,13 @@ int get_entity_ai_state(uint32_t uid) uint32_t get_level_flags() { - auto state = State::get(); + auto& state = State::get(); return state.flags(); } void set_level_flags(uint32_t flags) { - auto state = State::get(); + auto& state = State::get(); state.set_flags(flags); } @@ -391,12 +391,12 @@ void unlock_door_at(float x, float y) uint32_t get_frame_count_main() { - auto state = State::get(); + auto& state = State::get(); return state.get_frame_count_main(); } uint32_t get_frame_count() { - auto state = State::get(); + auto& state = State::get(); return state.get_frame_count(); } @@ -447,19 +447,19 @@ void flip_entity(uint32_t uid) void set_camera_position(float cx, float cy) { - auto state = State::get(); + auto& state = State::get(); state.set_camera_position(cx, cy); } void warp(uint8_t world, uint8_t level, uint8_t theme) { - auto state = State::get(); + auto& state = State::get(); state.warp(world, level, theme); } void set_seed(uint32_t seed) { - auto state = State::get(); + auto& state = State::get(); state.set_seed(seed); } @@ -562,7 +562,7 @@ void set_blood_multiplication(uint32_t /*default_multiplier*/, uint32_t vladscap std::vector read_prng() { - auto state = State::get(); + auto& state = State::get(); return state.read_prng(); } @@ -1209,7 +1209,7 @@ void move_grid_entity(int32_t uid, float x, float y, LAYER layer) { if (auto entity = get_entity_ptr(uid)) { - auto state = State::get(); + auto& state = State::get(); std::pair offset; const auto actual_layer = enum_to_layer(layer, offset); state.layer(entity->layer)->move_grid_entity(entity, offset.first + x, offset.first + y, state.layer(actual_layer)); @@ -1222,14 +1222,14 @@ void destroy_grid(int32_t uid) { if (auto entity = get_entity_ptr(uid)) { - auto state = State::get(); + auto& state = State::get(); state.layer(entity->layer)->destroy_grid_entity(entity); } } void destroy_grid(float x, float y, LAYER layer) { - auto state = State::get(); + auto& state = State::get(); uint8_t actual_layer = enum_to_layer(layer); if (Entity* entity = state.layer(actual_layer)->get_grid_entity_at(x, y)) diff --git a/src/game_api/script/lua_vm.cpp b/src/game_api/script/lua_vm.cpp index fc0056045..aad5133e0 100644 --- a/src/game_api/script/lua_vm.cpp +++ b/src/game_api/script/lua_vm.cpp @@ -977,7 +977,7 @@ end /// I suggest `state.pause == 2`, but that won't run any callback, `state.pause == 16` will do the same but [set_global_interval](#set_global_interval) will still work lua["pause"] = [](bool p) { - auto state = State::get(); + auto& state = State::get(); if (p) state.set_pause(0x20); else diff --git a/src/game_api/spawn_api.cpp b/src/game_api/spawn_api.cpp index 4024ce175..18d1f3a7c 100644 --- a/src/game_api/spawn_api.cpp +++ b/src/game_api/spawn_api.cpp @@ -214,7 +214,7 @@ int32_t spawn_entity_over(ENT_TYPE entity_type, uint32_t over_uid, float x, floa OnScopeExit pop{[] { pop_spawn_type_flags(SPAWN_TYPE_SCRIPT); }}; - auto state = State::get(); + auto& state = State::get(); Entity* overlay = get_entity_ptr(over_uid); if (overlay == nullptr) return -1; @@ -243,7 +243,7 @@ void spawn_backdoor_abs(float x, float y) OnScopeExit pop{[] { pop_spawn_type_flags(SPAWN_TYPE_SCRIPT); }}; - auto state = State::get(); + auto& state = State::get(); DEBUG("Spawning backdoor on {}, {}", x, y); Layer* front_layer = state.layer(0); Layer* back_layer = state.layer(1); diff --git a/src/game_api/state.cpp b/src/game_api/state.cpp index 62f14958d..ab47b4452 100644 --- a/src/game_api/state.cpp +++ b/src/game_api/state.cpp @@ -275,15 +275,16 @@ void State::post_init() State& State::get() { - static State STATE; + static State STATE{0x4A0}; if (!get_is_init()) { if (get_write_load_opt()) { do_write_load_opt(); } - auto addr_location = get_address("state_location"); - STATE = State{addr_location}; + if (auto addr_location = get_address("state_location"); addr_location != 0) + STATE.location = addr_location; + get_is_init() = true; if (get_do_hooks()) @@ -420,7 +421,7 @@ void State::zoom_reset() game_api->set_zoom(std::nullopt, 13.5f); } -void StateMemory::force_current_theme(uint32_t t) +void StateMemory::force_current_theme(THEME t) { if (t > 0 && t < 19) { @@ -697,7 +698,7 @@ using OnGameLoop = void(void* a, float b, void* c); OnGameLoop* g_game_loop_trampoline{nullptr}; void GameLoop(void* a, float b, void* c) { - auto state = State::get(); + auto& state = State::get(); if (global_frame_count < state.get_frame_count_main()) global_frame_count = state.get_frame_count_main(); else diff --git a/src/game_api/state.hpp b/src/game_api/state.hpp index 22b701081..fdc2e2744 100644 --- a/src/game_api/state.hpp +++ b/src/game_api/state.hpp @@ -302,7 +302,7 @@ struct StateMemory uint32_t unknown44; // probably padding /// This function should only be used in a very specific circumstance (forcing the exiting theme when manually transitioning). Will crash the game if used inappropriately! - void force_current_theme(uint32_t t); + void force_current_theme(THEME t); /// Returns animation_frame of the correct ushabti uint16_t get_correct_ushabti(); @@ -314,8 +314,6 @@ StateMemory* get_state_ptr(); struct State { - size_t location; - static void set_do_hooks(bool do_hooks); static void set_write_load_opt(bool allow); @@ -331,6 +329,10 @@ struct State StateMemory* ptr() const; StateMemory* ptr_local() const; + // TODO: rest of the functions should probably be just static or moved out of here as they don't need State + // they have to assume to use public/local ptr in which case they probably should be moved to StateMemory + // also because we really only use this struct to get to the StateMemory, make ptr functions static and simply make them call the get() + // use only if you only want the layer, otherwise use `ptr()->layers` Layer* layer(uint8_t index) const { @@ -376,6 +378,14 @@ struct State void set_seed(uint32_t seed); SaveData* savedata(); LiquidPhysicsEngine* get_correct_liquid_engine(ENT_TYPE liquid_type); + + private: + State(size_t addr) + : location(addr){}; + + size_t location; + State(const State&) = delete; + State& operator=(const State&) = delete; }; void init_state_update_hook(); void init_process_input_hook(); diff --git a/src/injected/ui_util.cpp b/src/injected/ui_util.cpp index b448ffa5e..afc4fd01d 100644 --- a/src/injected/ui_util.cpp +++ b/src/injected/ui_util.cpp @@ -111,7 +111,7 @@ float UI::screen_distance(float x) } Entity* UI::get_entity_at(float x, float y, bool s, float radius, uint32_t mask) { - auto state = State::get(); + auto& state = State::get(); static const auto masks_order = { 0x1, // Player From d91180303400d59a616ac00b057208751404a92b Mon Sep 17 00:00:00 2001 From: Mr-Auto <36127424+Mr-Auto@users.noreply.github.com> Date: Tue, 28 Nov 2023 20:35:31 +0100 Subject: [PATCH 03/12] fix get_entity using main --- src/game_api/entity.cpp | 16 +-- src/game_api/entity.hpp | 2 +- src/game_api/script/lua_backend.cpp | 145 +++++++++++++++------------- src/injected/ui.cpp | 102 +++++++++---------- src/injected/ui_util.cpp | 36 +++---- 5 files changed, 157 insertions(+), 144 deletions(-) diff --git a/src/game_api/entity.cpp b/src/game_api/entity.cpp index 5183811e0..890dbe629 100644 --- a/src/game_api/entity.cpp +++ b/src/game_api/entity.cpp @@ -176,7 +176,7 @@ std::pair Entity::position_self() const void Entity::remove_item(uint32_t item_uid) { - auto entity = get_entity_ptr(item_uid); + auto entity = get_entity_ptr_local(item_uid); if (entity) remove_item_ptr(entity); } @@ -213,7 +213,7 @@ bool Movable::damage(uint32_t damage_dealer_uid, int8_t damage_amount, uint16_t return; }*/ - auto dealer = get_entity_ptr(damage_dealer_uid); + auto dealer = get_entity_ptr_local(damage_dealer_uid); /* but it can be nil? if (dealer == nullptr) { @@ -241,7 +241,7 @@ bool Movable::is_button_released(BUTTON button) std::tuple get_position(uint32_t uid) { - Entity* ent = get_entity_ptr(uid); + Entity* ent = get_entity_ptr_local(uid); if (ent) return std::make_tuple(ent->position().first, ent->position().second, ent->layer); @@ -250,7 +250,7 @@ std::tuple get_position(uint32_t uid) std::tuple get_render_position(uint32_t uid) { - Entity* ent = get_entity_ptr(uid); + Entity* ent = get_entity_ptr_local(uid); if (ent) { if (ent->rendering_info != nullptr && !ent->rendering_info->render_inactive) @@ -263,7 +263,7 @@ std::tuple get_render_position(uint32_t uid) std::tuple get_velocity(uint32_t uid) { - if (Entity* ent = get_entity_ptr(uid)) + if (Entity* ent = get_entity_ptr_local(uid)) { float vx{0.0f}; float vy{0.0f}; @@ -292,7 +292,7 @@ std::tuple get_velocity(uint32_t uid) AABB get_hitbox(uint32_t uid, bool use_render_pos) { - if (Entity* ent = get_entity_ptr(uid)) + if (Entity* ent = get_entity_ptr_local(uid)) { auto [x, y, l] = (use_render_pos ? get_render_position : get_position)(uid); return AABB{ @@ -371,7 +371,7 @@ std::span Entity::get_items() return {}; } -Entity* get_entity_ptr(uint32_t uid) +Entity* get_entity_ptr_main(uint32_t uid) { auto& state = State::get(); auto p = state.find(uid); @@ -518,7 +518,7 @@ bool recursive(Entity* ent, std::optional mask, std::vector auto currend_uid = true_type->tail_bg_uid; for (int idx = 0; idx < 8; ++idx) { - auto tail_ent = get_entity_ptr(currend_uid + idx); + auto tail_ent = get_entity_ptr_local(currend_uid + idx); if (tail_ent != nullptr && (tail_ent->type->id == jellys_tails[0] || tail_ent->type->id == jellys_tails[1])) // only kill the tail { recursive(tail_ent, mask, ent_types, rec_mode, func); diff --git a/src/game_api/entity.hpp b/src/game_api/entity.hpp index 312db1810..2435cb97f 100644 --- a/src/game_api/entity.hpp +++ b/src/game_api/entity.hpp @@ -313,5 +313,5 @@ std::tuple get_velocity(uint32_t uid); AABB get_hitbox(uint32_t uid, bool use_render_pos); struct EntityFactory* entity_factory(); +Entity* get_entity_ptr_main(uint32_t uid); Entity* get_entity_ptr(uint32_t uid); -Entity* get_entity_ptr_local(uint32_t uid); diff --git a/src/game_api/script/lua_backend.cpp b/src/game_api/script/lua_backend.cpp index ad56a7181..33d51704a 100644 --- a/src/game_api/script/lua_backend.cpp +++ b/src/game_api/script/lua_backend.cpp @@ -14,7 +14,6 @@ #include "constants.hpp" // for no_return_str #include "entities_chars.hpp" // for Player #include "entity.hpp" // for Entity, get_entity_ptr -#include "entity_lookup.hpp" // #include "handle_lua_function.hpp" // for handle_function #include "items.hpp" // for Inventory #include "level_api.hpp" // for LevelGenData, LevelGenSy... @@ -832,55 +831,62 @@ bool LuaBackend::pre_load_screen() if ((ON)state_ptr->screen == ON::LEVEL && (ON)state_ptr->screen_next != ON::DEATH && (state_ptr->quest_flags & 1) == 0) { - for (auto uid : get_entities_by_mask(1)) + for (auto layer : State::get().ptr()->layers) { - auto ent = get_entity_ptr(uid)->as(); - int slot = ent->inventory_ptr->player_slot; - if (slot == -1 && ent->linked_companion_parent == -1) + auto it = layer->entities_by_mask.find(1); + if (it == layer->entities_by_mask.end()) continue; - if (slot == -1 && ent->linked_companion_parent != -1) + + for (auto entity : it->second.entities()) { - Player* parent = ent; - while (true) + auto ent = entity->as(); + int slot = ent->inventory_ptr->player_slot; + if (slot == -1 && ent->linked_companion_parent == -1) + continue; + if (slot == -1 && ent->linked_companion_parent != -1) { - parent = get_entity_ptr(parent->linked_companion_parent)->as(); - slot++; - if (parent->linked_companion_parent == -1) + Player* parent = ent; + while (true) { - slot += (parent->inventory_ptr->player_slot + 1) * 100; - break; + parent = get_entity_ptr(parent->linked_companion_parent)->as(); + slot++; + if (parent->linked_companion_parent == -1) + { + slot += (parent->inventory_ptr->player_slot + 1) * 100; + break; + } } } - } - if (slot < 0) - continue; - bool should_save = false; - SavedUserData saved; - if (user_datas.contains(ent->uid)) - { - saved.self = get_user_data(ent->uid); - should_save = true; - } - if (ent->holding_uid != -1 and user_datas.contains(ent->holding_uid)) - { - saved.held = get_user_data(ent->holding_uid); - should_save = true; - } - if (ent->overlay && (ent->overlay->type->search_flags & 2) > 0 && user_datas.contains(ent->overlay->uid)) - { - saved.mount = get_user_data(ent->overlay->uid); - should_save = true; - } - for (auto& [type, powerup] : ent->powerups) - { - if (user_datas.contains(powerup->uid)) + if (slot < 0) + continue; + bool should_save = false; + SavedUserData saved; + if (user_datas.contains(ent->uid)) + { + saved.self = get_user_data(ent->uid); + should_save = true; + } + if (ent->holding_uid != -1 and user_datas.contains(ent->holding_uid)) + { + saved.held = get_user_data(ent->holding_uid); + should_save = true; + } + if (ent->overlay && (ent->overlay->type->search_flags & 2) > 0 && user_datas.contains(ent->overlay->uid)) { - saved.powerups[type] = get_user_data(powerup->uid); + saved.mount = get_user_data(ent->overlay->uid); should_save = true; } + for (auto& [type, powerup] : ent->powerups) + { + if (user_datas.contains(powerup->uid)) + { + saved.powerups[type] = get_user_data(powerup->uid); + should_save = true; + } + } + if (should_save) + saved_user_datas[slot] = saved; } - if (should_save) - saved_user_datas[slot] = saved; } } @@ -969,40 +975,47 @@ void LuaBackend::post_room_generation() void LuaBackend::load_user_data() { - for (auto uid : get_entities_by_mask(1)) + for (auto layer : State::get().ptr()->layers) { - auto ent = get_entity_ptr(uid)->as(); - int slot = ent->inventory_ptr->player_slot; - if (slot == -1 && ent->linked_companion_parent == -1) + auto it = layer->entities_by_mask.find(1); + if (it == layer->entities_by_mask.end()) continue; - if (slot == -1 && ent->linked_companion_parent != -1) + + for (auto entity : it->second.entities()) { - Player* parent = ent; - while (true) + auto ent = entity->as(); + int slot = ent->inventory_ptr->player_slot; + if (slot == -1 && ent->linked_companion_parent == -1) + continue; + if (slot == -1 && ent->linked_companion_parent != -1) { - parent = get_entity_ptr(parent->linked_companion_parent)->as(); - slot++; - if (parent->linked_companion_parent == -1) + Player* parent = ent; + while (true) { - slot += (parent->inventory_ptr->player_slot + 1) * 100; - break; + parent = get_entity_ptr(parent->linked_companion_parent)->as(); + slot++; + if (parent->linked_companion_parent == -1) + { + slot += (parent->inventory_ptr->player_slot + 1) * 100; + break; + } } } - } - if (slot < 0) - continue; - if (saved_user_datas.contains(slot)) - { - if (saved_user_datas[slot].self.has_value()) - set_user_data(*ent, saved_user_datas[slot].self.value()); - if (ent->holding_uid != -1 && saved_user_datas[slot].held.has_value()) - set_user_data(ent->holding_uid, saved_user_datas[slot].held.value()); - if (ent->overlay && (ent->overlay->type->search_flags & 2) > 0 && saved_user_datas[slot].mount.has_value()) - set_user_data(ent->overlay->uid, saved_user_datas[slot].mount.value()); - for (auto& [type, powerup] : ent->powerups) + if (slot < 0) + continue; + if (saved_user_datas.contains(slot)) { - if (saved_user_datas[slot].powerups.contains(type)) - set_user_data(powerup->uid, saved_user_datas[slot].powerups[type]); + if (saved_user_datas[slot].self.has_value()) + set_user_data(*ent, saved_user_datas[slot].self.value()); + if (ent->holding_uid != -1 && saved_user_datas[slot].held.has_value()) + set_user_data(ent->holding_uid, saved_user_datas[slot].held.value()); + if (ent->overlay && (ent->overlay->type->search_flags & 2) > 0 && saved_user_datas[slot].mount.has_value()) + set_user_data(ent->overlay->uid, saved_user_datas[slot].mount.value()); + for (auto& [type, powerup] : ent->powerups) + { + if (saved_user_datas[slot].powerups.contains(type)) + set_user_data(powerup->uid, saved_user_datas[slot].powerups[type]); + } } } } @@ -1204,7 +1217,7 @@ Entity* LuaBackend::pre_entity_spawn(std::uint32_t entity_type, float x, float y if (auto spawn_replacement = handle_function(this, callback.func, entity_type, x, y, layer, overlay, spawn_type_flags)) { clear_current_callback(); - return get_entity_ptr(spawn_replacement.value()); + return get_entity_ptr(spawn_replacement.value()); // TODO: this assumes that the entity is valid, which will crash if it's not } clear_current_callback(); } diff --git a/src/injected/ui.cpp b/src/injected/ui.cpp index dc1534235..68a38f646 100644 --- a/src/injected/ui.cpp +++ b/src/injected/ui.cpp @@ -1419,7 +1419,7 @@ int32_t spawn_entityitem(EntityItem to_spawn, bool s, bool set_last = true) auto old_block_id = UI::get_grid_entity_at(cpos.first, cpos.second, LAYER::PLAYER); if (old_block_id != -1) { - auto old_block = get_entity_ptr(old_block_id); + auto old_block = get_entity_ptr_main(old_block_id); if (old_block) smart_delete(old_block); @@ -1434,12 +1434,12 @@ int32_t spawn_entityitem(EntityItem to_spawn, bool s, bool set_last = true) int spawned = UI::spawn_entity(to_spawn.id, g_x, g_y, s, g_vx, g_vy, snap); if (to_spawn.name.find("ENT_TYPE_MOUNT") != std::string::npos) { - auto mount = get_entity_ptr(spawned)->as(); + auto mount = get_entity_ptr_main(spawned)->as(); mount->tame(true); } if (to_spawn.name.find("ENT_TYPE_FLOOR") != std::string::npos && options["spawn_floor_decorated"]) { - if (Floor* floor = get_entity_ptr(spawned)->as()) + if (Floor* floor = get_entity_ptr_main(spawned)->as()) { if (flip && (to_spawn.name.find("ARROW_TRAP") != std::string::npos || to_spawn.name.find("LASER_TRAP") != std::string::npos || to_spawn.name.find("HORIZONTAL") != std::string::npos)) { @@ -1463,13 +1463,13 @@ int32_t spawn_entityitem(EntityItem to_spawn, bool s, bool set_last = true) } if (flip) { - auto ent = get_entity_ptr(spawned); + auto ent = get_entity_ptr_main(spawned); if (ent) ent->flags |= (1U << 16); } if (to_spawn.id == also_snap[0]) { - auto ent = get_entity_ptr(spawned)->as(); + auto ent = get_entity_ptr_main(spawned)->as(); ent->door_type = to_id("ENT_TYPE_FLOOR_DOOR_LAYER"); ent->platform_type = to_id("ENT_TYPE_FLOOR_DOOR_PLATFORM"); } @@ -1529,7 +1529,7 @@ void spawn_kit(Kit* kit) if (spawned == -1) continue; - auto spawned_ent = get_entity_ptr(spawned)->as(); + auto spawned_ent = get_entity_ptr_main(spawned)->as(); if (std::find(std::begin(wearable), std::end(wearable), id) != std::end(wearable) && g_players.at(0)->worn_backitem() == -1) { @@ -1537,7 +1537,7 @@ void spawn_kit(Kit* kit) } else if (item.name.find("MOUNT_") != std::string::npos) { - auto spawned_mount = get_entity_ptr(spawned)->as(); + auto spawned_mount = get_entity_ptr_main(spawned)->as(); spawned_mount->tame(true); if (!g_players.at(0)->overlay) { @@ -1601,9 +1601,9 @@ void spawn_entity_over() return; } - if (g_over_id == -1 || !get_entity_ptr(g_over_id)) + if (g_over_id == -1 || !get_entity_ptr_main(g_over_id)) return; - auto overlay = get_entity_ptr(g_over_id); + auto overlay = get_entity_ptr_main(g_over_id); if (item.name.find("ENT_TYPE_ITEM_POWERUP") != std::string::npos) { @@ -1613,7 +1613,7 @@ void spawn_entity_over() else if (item.name.find("ENT_TYPE_ITEM") != std::string::npos && overlay->type->search_flags & 0x100) { int spawned = UI::spawn_entity_over(item.id, g_over_id, g_dx, g_dy); - auto ent = get_entity_ptr(spawned); + auto ent = get_entity_ptr_main(spawned); if (g_dx == 0 && g_dy == 0) { ent->set_draw_depth(9); @@ -1639,7 +1639,7 @@ void spawn_entity_over() { auto mount = overlay->as(); int spawned = UI::spawn_entity(item.id, g_x, g_y, true, g_vx, g_vy, false); - auto rider = get_entity_ptr(spawned)->as(); + auto rider = get_entity_ptr_main(spawned)->as(); mount->carry(rider); rider->move_state = 0; if (!lock_entity) @@ -1689,7 +1689,7 @@ bool update_entity() return false; if (g_last_id > -1) { - g_entity = get_entity_ptr(g_last_id); + g_entity = get_entity_ptr_main(g_last_id); if (!g_entity) return false; @@ -2065,7 +2065,7 @@ void clear_void() { for (auto uid : UI::get_entities_by({}, 1422, LAYER::FRONT)) { - auto ent = get_entity_ptr(uid); + auto ent = get_entity_ptr_main(uid); auto [x, y] = ent->position(); if (x > 2.5f && y < 122.5f && x < g_state->w * 10.0f + 2.5f && y > 122.5f - g_state->h * 8.0f) UI::safe_destroy(ent); @@ -2095,7 +2095,7 @@ void load_void(std::string data) if (e.id <= 915) { auto uid = UI::spawn_grid(e.id, (float)e.x, (float)e.y, 0); - auto ent = get_entity_ptr(uid); + auto ent = get_entity_ptr_main(uid); if (ent->type->search_flags & 0x100) { fix_decorations_at((float)e.x, (float)e.y, LAYER::FRONT); @@ -2160,7 +2160,7 @@ std::string serialize_void() uids = UI::get_entities_by({}, export_mask, LAYER::FRONT); for (auto uid : uids) { - auto ent = get_entity_ptr(uid); + auto ent = get_entity_ptr_main(uid); if (!ent || !(ent->type->search_flags & export_mask)) continue; auto [x, y] = ent->position(); @@ -2341,7 +2341,7 @@ void warp_next_level(size_t num) for (auto doorid : UI::get_entities_by({(ENT_TYPE)CUSTOM_TYPE::EXITDOOR}, 0x100, LAYER::BOTH)) { - ExitDoor* doorent = get_entity_ptr(doorid)->as(); + ExitDoor* doorent = get_entity_ptr_main(doorid)->as(); if (!doorent->special_door) continue; targets.emplace_back(doorent->world, doorent->level, doorent->theme); @@ -3490,7 +3490,7 @@ bool process_keys(UINT nCode, WPARAM wParam, [[maybe_unused]] LPARAM lParam) } else if (pressed("destroy_grabbed", wParam)) { - auto selected = get_entity_ptr(g_last_id); + auto selected = get_entity_ptr_main(g_last_id); if (selected) smart_delete(selected, true); if (!lock_entity) @@ -3500,7 +3500,7 @@ bool process_keys(UINT nCode, WPARAM wParam, [[maybe_unused]] LPARAM lParam) { for (auto selected_uid : g_selected_ids) { - auto ent = get_entity_ptr(selected_uid); + auto ent = get_entity_ptr_main(selected_uid); if (ent) smart_delete(ent, false); } @@ -3867,7 +3867,7 @@ void render_narnia() for (auto doorid : UI::get_entities_by({(ENT_TYPE)CUSTOM_TYPE::EXITDOOR}, 0x100, LAYER::BOTH)) { - ExitDoor* target = get_entity_ptr(doorid)->as(); + ExitDoor* target = get_entity_ptr_main(doorid)->as(); if (!target->special_door) continue; std::string buf = fmt::format("{}-{} {}", target->world, target->level, theme_name(target->theme)); @@ -4347,7 +4347,7 @@ void erase_entities() auto box = AABB{ax, ay, ax, ay}; for (auto erase_uid : UI::get_entities_overlapping(mask, box.extrude(0.1f), (LAYER)g_state->camera_layer)) { - auto erase = get_entity_ptr(erase_uid); + auto erase = get_entity_ptr_main(erase_uid); if (erase) smart_delete(erase); } @@ -4638,7 +4638,7 @@ std::string entity_tooltip(Entity* hovered) if (hovered->type->search_flags & 15 && hovered->as()->last_owner_uid > -1) { auto ent = hovered->as(); - auto owner = get_entity_ptr(ent->last_owner_uid); + auto owner = get_entity_ptr_main(ent->last_owner_uid); if (owner) coords += fmt::format("\nOWNER: {}, {} ({:.2f}, {:.2f})", owner->uid, entity_names[owner->type->id], owner->abs_x == -FLT_MAX ? owner->x : owner->abs_x, owner->abs_y == -FLT_MAX ? owner->y : owner->abs_y); } @@ -4995,7 +4995,7 @@ void render_clickhandler() static const auto olmec = to_id("ENT_TYPE_ACTIVEFLOOR_OLMEC"); for (auto entity : UI::get_entities_by({}, g_hitbox_mask, (LAYER)(peek_layer ? g_state->camera_layer ^ 1 : g_state->camera_layer))) { - auto ent = get_entity_ptr(entity); + auto ent = get_entity_ptr_main(entity); if (!ent) continue; @@ -5049,17 +5049,17 @@ void render_clickhandler() }; for (auto entity : UI::get_entities_by(additional_fixed_entities, 0x180, (LAYER)(peek_layer ? g_state->camera_layer ^ 1 : g_state->camera_layer))) // FLOOR | ACTIVEFLOOR { - auto ent = get_entity_ptr(entity); + auto ent = get_entity_ptr_main(entity); render_hitbox(ent, false, ImColor(0, 255, 255, 150)); } for (auto entity : UI::get_entities_by({(ENT_TYPE)CUSTOM_TYPE::TRIGGER}, 0x1000, (LAYER)(peek_layer ? g_state->camera_layer ^ 1 : g_state->camera_layer))) // LOGICAL { - auto ent = get_entity_ptr(entity); + auto ent = get_entity_ptr_main(entity); render_hitbox(ent, false, ImColor(255, 0, 0, 150)); } for (auto entity : UI::get_entities_by({to_id("ENT_TYPE_LOGICAL_DOOR")}, 0x1000, (LAYER)(peek_layer ? g_state->camera_layer ^ 1 : g_state->camera_layer))) // DOOR { - auto ent = get_entity_ptr(entity); + auto ent = get_entity_ptr_main(entity); render_hitbox(ent, false, ImColor(255, 180, 45, 150), false, true); } @@ -5120,7 +5120,7 @@ void render_clickhandler() } for (auto entity : g_selected_ids) { - auto ent = get_entity_ptr(entity); + auto ent = get_entity_ptr_main(entity); if (ent) { if (ent->layer == (peek_layer ? g_state->camera_layer ^ 1 : g_state->camera_layer)) @@ -5414,7 +5414,7 @@ void render_clickhandler() throw_held = true; } set_pos(startpos); - auto held = get_entity_ptr(g_held_id); + auto held = get_entity_ptr_main(g_held_id); if (held && held->is_movable()) { UI::move_entity(g_held_id, g_x, g_y, true, 0, 0, false); @@ -6177,7 +6177,7 @@ void render_options() void render_debug() { ImGui::PushItemWidth(-ImGui::GetWindowWidth() * 0.5f); - const auto selected_entity = get_entity_ptr(g_last_id); + const auto selected_entity = get_entity_ptr_main(g_last_id); size_t entity_addr = reinterpret_cast(selected_entity); size_t state_addr = reinterpret_cast(g_state); size_t save_addr = reinterpret_cast(g_save); @@ -7120,7 +7120,7 @@ void render_entity_finder() { g_selected_ids.erase(std::remove_if(g_selected_ids.begin(), g_selected_ids.end(), [&](uint32_t filter_uid) { - auto ent = get_entity_ptr(filter_uid); + auto ent = get_entity_ptr_main(filter_uid); if (!ent) return true; return ent->type->id != search_entity_type; }), @@ -7130,7 +7130,7 @@ void render_entity_finder() { g_selected_ids.erase(std::remove_if(g_selected_ids.begin(), g_selected_ids.end(), [&](uint32_t filter_uid) { - auto ent = get_entity_ptr(filter_uid); + auto ent = get_entity_ptr_main(filter_uid); if (!ent) return true; return (ent->type->search_flags & search_entity_mask) == 0; }), @@ -7139,7 +7139,7 @@ void render_entity_finder() { g_selected_ids.erase(std::remove_if(g_selected_ids.begin(), g_selected_ids.end(), [&](uint32_t filter_uid) { - auto ent = get_entity_ptr(filter_uid); + auto ent = get_entity_ptr_main(filter_uid); if (!ent) return true; return ent->layer != enum_to_layer((LAYER)search_entity_layer); }), @@ -7151,7 +7151,7 @@ void render_entity_finder() { g_selected_ids.erase(std::remove_if(g_selected_ids.begin(), g_selected_ids.end(), [&](uint32_t filter_uid) { - auto ent = get_entity_ptr(filter_uid); + auto ent = get_entity_ptr_main(filter_uid); if (!ent) return true; return (ent->flags & search_entity_flags) != search_entity_flags; }), @@ -7161,7 +7161,7 @@ void render_entity_finder() { g_selected_ids.erase(std::remove_if(g_selected_ids.begin(), g_selected_ids.end(), [&](uint32_t filter_uid) { - auto ent = get_entity_ptr(filter_uid); + auto ent = get_entity_ptr_main(filter_uid); if (!ent) return true; return (ent->flags & search_entity_not_flags) != 0; }), @@ -7171,7 +7171,7 @@ void render_entity_finder() { g_selected_ids.erase(std::remove_if(g_selected_ids.begin(), g_selected_ids.end(), [&](uint32_t filter_uid) { - auto ent = get_entity_ptr(filter_uid); + auto ent = get_entity_ptr_main(filter_uid); if (!ent) return true; return (ent->more_flags & search_entity_more_flags) != search_entity_more_flags; }), @@ -7181,7 +7181,7 @@ void render_entity_finder() { g_selected_ids.erase(std::remove_if(g_selected_ids.begin(), g_selected_ids.end(), [&](uint32_t filter_uid) { - auto ent = get_entity_ptr(filter_uid); + auto ent = get_entity_ptr_main(filter_uid); if (!ent) return true; return (ent->more_flags & search_entity_not_more_flags) != 0; }), @@ -7191,7 +7191,7 @@ void render_entity_finder() { g_selected_ids.erase(std::remove_if(g_selected_ids.begin(), g_selected_ids.end(), [&](uint32_t filter_uid) { - auto ent = get_entity_ptr(filter_uid); + auto ent = get_entity_ptr_main(filter_uid); if (!ent) return true; return (ent->type->properties_flags & search_entity_properties_flags) != search_entity_properties_flags; }), @@ -7201,7 +7201,7 @@ void render_entity_finder() { g_selected_ids.erase(std::remove_if(g_selected_ids.begin(), g_selected_ids.end(), [&](uint32_t filter_uid) { - auto ent = get_entity_ptr(filter_uid); + auto ent = get_entity_ptr_main(filter_uid); if (!ent) return true; return (ent->type->properties_flags & search_entity_not_properties_flags) != 0; }), @@ -7211,7 +7211,7 @@ void render_entity_finder() { g_selected_ids.erase(std::remove_if(g_selected_ids.begin(), g_selected_ids.end(), [&](uint32_t filter_uid) { - auto ent = get_entity_ptr(filter_uid); + auto ent = get_entity_ptr_main(filter_uid); if (!ent) return true; return !StrStrIA(entity_names[ent->type->id].c_str(), search_entity_name.c_str()); }), @@ -7221,7 +7221,7 @@ void render_entity_finder() { g_selected_ids.erase(std::remove_if(g_selected_ids.begin(), g_selected_ids.end(), [&](uint32_t filter_uid) { - auto ent = get_entity_ptr(filter_uid); + auto ent = get_entity_ptr_main(filter_uid); if (!ent) return true; return ent->draw_depth < search_entity_depth[0] || ent->draw_depth > search_entity_depth[1]; }), @@ -7255,7 +7255,7 @@ void render_entity_finder() { for (auto selected_uid : g_selected_ids) { - auto ent = get_entity_ptr(selected_uid); + auto ent = get_entity_ptr_main(selected_uid); if (ent) smart_delete(ent, false); } @@ -7266,7 +7266,7 @@ void render_entity_finder() { for (auto selected_uid : g_selected_ids) { - auto ent = get_entity_ptr(selected_uid); + auto ent = get_entity_ptr_main(selected_uid); if (ent) ent->kill(true, nullptr); } @@ -7277,7 +7277,7 @@ void render_entity_finder() { for (auto selected_uid : g_selected_ids) { - auto ent = get_entity_ptr(selected_uid); + auto ent = get_entity_ptr_main(selected_uid); if (ent) ent->destroy(); } @@ -7293,7 +7293,7 @@ void render_entity_finder() void render_entity_props(int uid, bool detached = false) { - auto entity = get_entity_ptr(uid); + auto entity = get_entity_ptr_main(uid); ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.5f); if (!detached) { @@ -7468,7 +7468,7 @@ void render_entity_props(int uid, bool detached = false) ImGui::SameLine(); if (ImGui::Button("Drop##DropHolding")) { - auto holding = get_entity_ptr(movable->holding_uid); + auto holding = get_entity_ptr_main(movable->holding_uid); if (holding) movable->drop(holding); else @@ -8044,12 +8044,12 @@ void render_texture_viewer() } if (texture_viewer.uid != g_last_id) { - Entity* ent = get_entity_ptr(g_last_id); + Entity* ent = get_entity_ptr_main(g_last_id); if (ent) texture_viewer.id = ent->get_texture(); texture_viewer.uid = g_last_id; } - Entity* ent = get_entity_ptr(texture_viewer.uid); + Entity* ent = get_entity_ptr_main(texture_viewer.uid); auto pos = ImGui::GetWindowPos(); auto size = ImGui::GetWindowSize(); @@ -8584,7 +8584,7 @@ void render_game_props() } for (auto uid : UI::get_entities_by({to_id("ENT_TYPE_ITEM_PLAYERGHOST")}, 0x8, LAYER::BOTH)) { - auto ghost = get_entity_ptr(uid)->as(); + auto ghost = get_entity_ptr_main(uid)->as(); if (ghost->player_inputs && ghost->player_inputs->player_slot == i && g_state->items->player_count < i + 1) ghost->destroy(); } @@ -8602,7 +8602,7 @@ void render_game_props() g_state->items->player_inventories[i].health = 4; auto uid = g_state->next_entity_uid; UI::spawn_player(i); - auto player = get_entity_ptr(uid)->as(); + auto player = get_entity_ptr_main(uid)->as(); player->set_position(spawn_x, spawn_y); } } @@ -8742,7 +8742,7 @@ void render_game_props() { continue; } - auto ai_entity = get_entity_ptr(ai_target.ai_uid); + auto ai_entity = get_entity_ptr_main(ai_target.ai_uid); auto target = ai_target.target_uid; if (ai_entity == nullptr || (ai_entity->type->search_flags & 1) != 1) { @@ -8758,7 +8758,7 @@ void render_game_props() } else { - auto target_entity = get_entity_ptr(target); + auto target_entity = get_entity_ptr_main(target); if (target_entity != nullptr) { ImGui::Text("%s", entity_names[target_entity->type->id].c_str()); @@ -9773,7 +9773,7 @@ void update_bucket() if (g_bucket->overlunky->set_selected_uid.has_value()) { g_last_id = g_bucket->overlunky->set_selected_uid.value(); - g_entity = get_entity_ptr(g_last_id); + g_entity = get_entity_ptr_main(g_last_id); g_bucket->overlunky->set_selected_uid = std::nullopt; } if (g_bucket->overlunky->set_selected_uids.has_value()) diff --git a/src/injected/ui_util.cpp b/src/injected/ui_util.cpp index afc4fd01d..abf0978b1 100644 --- a/src/injected/ui_util.cpp +++ b/src/injected/ui_util.cpp @@ -12,7 +12,7 @@ #include "entities_floors.hpp" // for Floor, Floor::(anonymous), FLOO... #include "entities_items.hpp" // for Torch #include "entities_mounts.hpp" // for Mount -#include "entity.hpp" // for to_id, Entity, get_entity_ptr +#include "entity.hpp" // for to_id, Entity, get_entity_ptr_main #include "entity_lookup.hpp" // #include "game_api.hpp" // #include "game_manager.hpp" // for get_game_manager, GameManager @@ -176,7 +176,7 @@ Entity* UI::get_entity_at(float x, float y, bool s, float radius, uint32_t mask) } void UI::move_entity(uint32_t uid, float x, float y, bool s, float vx, float vy, bool snap) { - auto ent = get_entity_ptr(uid); + auto ent = get_entity_ptr_main(uid); if (ent) ent->teleport(x, y, s, vx, vy, snap); } @@ -255,7 +255,7 @@ float UI::get_spark_distance(SparkTrap* ent) const static auto offset = get_address("sparktrap_angle_increment") + 4; if (memory_read(offset - 1) == 0x89) // check if sparktraps_hack is active { - auto spark = get_entity_ptr(ent->spark_uid)->as(); + auto spark = get_entity_ptr_main(ent->spark_uid)->as(); return spark->distance; } auto parameters = get_sparktraps_parameters_ptr(); @@ -307,7 +307,7 @@ std::vector UI::get_entities_by(std::vector entity_types, ui int32_t UI::spawn_companion(ENT_TYPE compatnion_type, float x, float y, LAYER l, float vx, float vy) { auto uid = ::spawn_companion(compatnion_type, x, y, (LAYER)enum_to_layer(l)); - auto ent = get_entity_ptr(uid)->as(); + auto ent = get_entity_ptr_main(uid)->as(); ent->velocityx = vx; ent->velocityy = vy; return uid; @@ -354,7 +354,7 @@ int32_t UI::destroy_entity_items(Entity* ent) int32_t last_uid = *it; while (it != items.rend()) { - auto item = get_entity_ptr(*it); + auto item = get_entity_ptr_main(*it); UI::destroy_entity_items(item); UI::safe_destroy(item, false, false); it++; @@ -370,7 +370,7 @@ bool UI::destroy_entity_item_type(Entity* ent, ENT_TYPE type) std::vector::reverse_iterator it = items.rbegin(); while (it != items.rend()) { - auto item = get_entity_ptr(*it); + auto item = get_entity_ptr_main(*it); if (item && item->type->id == type) { UI::destroy_entity_items(item); @@ -409,7 +409,7 @@ void UI::update_floor_at(float x, float y, LAYER l) auto uid = get_grid_entity_at(x, y, l); if (uid == -1) return; - auto ent = get_entity_ptr(uid); + auto ent = get_entity_ptr_main(uid); if ((ent->type->search_flags & 0x100) == 0 || !test_flag(ent->flags, 3)) return; auto floor = ent->as(); @@ -418,7 +418,7 @@ void UI::update_floor_at(float x, float y, LAYER l) { for (auto item : entity_get_items_by(floor->uid, 0, 0x8)) { - auto embed = get_entity_ptr(item); + auto embed = get_entity_ptr_main(item); clr_flag(embed->flags, 1); } } @@ -433,7 +433,7 @@ void UI::update_floor_at(float x, float y, LAYER l) { for (int i = 0; i < 4; ++i) { - auto deco_ent = get_entity_ptr(floor->decos[i]); + auto deco_ent = get_entity_ptr_main(floor->decos[i]); if (deco_ent) deco_ent->destroy(); floor->decos[i] = -1; @@ -441,13 +441,13 @@ void UI::update_floor_at(float x, float y, LAYER l) } for (auto deco : entity_get_items_by(floor->uid, destroy_deco, 0x200)) { - auto deco_ent = get_entity_ptr(deco); + auto deco_ent = get_entity_ptr_main(deco); if (deco_ent) deco_ent->destroy(); } for (auto deco : get_entities_at(destroy_deco, 0, x, y, l, 0.5f)) { - auto deco_ent = get_entity_ptr(deco); + auto deco_ent = get_entity_ptr_main(deco); if (deco_ent) deco_ent->destroy(); } @@ -504,7 +504,7 @@ void UI::cleanup_at(float x, float y, LAYER l, ENT_TYPE type) for (auto bg : get_entities_at(cleanup_ents, 0, x, y, l, 0.1f)) { - auto bg_ent = get_entity_ptr(bg); + auto bg_ent = get_entity_ptr_main(bg); if (bg_ent) bg_ent->destroy(); } @@ -519,7 +519,7 @@ void UI::cleanup_at(float x, float y, LAYER l, ENT_TYPE type) return; for (auto bg : bgs) { - auto ent = get_entity_ptr(bg); + auto ent = get_entity_ptr_main(bg); ent->destroy(); } } @@ -532,12 +532,12 @@ void UI::cleanup_at(float x, float y, LAYER l, ENT_TYPE type) auto door_parts = get_entities_at(door_crap, 0, x, y, l, 0.5f); for (auto part : door_parts) { - auto ent = get_entity_ptr(part); + auto ent = get_entity_ptr_main(part); ent->destroy(); } for (auto uid : get_entities_at(door_platform, 0x100, x, y - 1.0f, l, 0.5f)) { - auto ent = get_entity_ptr(uid); + auto ent = get_entity_ptr_main(uid); ent->destroy(); } } @@ -636,7 +636,7 @@ void UI::safe_destroy(Entity* ent, bool unsafe, bool recurse) // stupid tail is not attached to jelly, but it should always be here for (int tail_uid = last_item + 8; tail_uid > last_item; --tail_uid) { - auto tail = get_entity_ptr(tail_uid); + auto tail = get_entity_ptr_main(tail_uid); if (tail) tail->destroy(); } @@ -650,7 +650,7 @@ void UI::safe_destroy(Entity* ent, bool unsafe, bool recurse) while (true) { uid--; - find_jelly = get_entity_ptr(uid); + find_jelly = get_entity_ptr_main(uid); if (find_jelly && in_array(find_jelly->type->id, jellys)) { safe_destroy(find_jelly); @@ -754,7 +754,7 @@ void UI::save_progress() int32_t UI::spawn_playerghost(ENT_TYPE char_type, float x, float y, LAYER layer, float vx, float vy) { auto uid = ::spawn_playerghost(char_type, x, y, (LAYER)enum_to_layer(layer)); - auto ent = get_entity_ptr(uid)->as(); + auto ent = get_entity_ptr_main(uid)->as(); ent->velocityx = vx; ent->velocityy = vy; return uid; From da89e23b20da55e23075b409247f1eea2a7ba92f Mon Sep 17 00:00:00 2001 From: Mr-Auto <36127424+Mr-Auto@users.noreply.github.com> Date: Tue, 28 Nov 2023 20:37:17 +0100 Subject: [PATCH 04/12] formatting --- src/game_api/script/lua_backend.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game_api/script/lua_backend.cpp b/src/game_api/script/lua_backend.cpp index 33d51704a..c4eae6933 100644 --- a/src/game_api/script/lua_backend.cpp +++ b/src/game_api/script/lua_backend.cpp @@ -848,7 +848,7 @@ bool LuaBackend::pre_load_screen() Player* parent = ent; while (true) { - parent = get_entity_ptr(parent->linked_companion_parent)->as(); + parent = get_entity_ptr(parent->linked_companion_parent)->as(); slot++; if (parent->linked_companion_parent == -1) { @@ -992,7 +992,7 @@ void LuaBackend::load_user_data() Player* parent = ent; while (true) { - parent = get_entity_ptr(parent->linked_companion_parent)->as(); + parent = get_entity_ptr(parent->linked_companion_parent)->as(); slot++; if (parent->linked_companion_parent == -1) { From b44b9f35867896ae70dd2228214a9b267569ad79 Mon Sep 17 00:00:00 2001 From: Mr-Auto <36127424+Mr-Auto@users.noreply.github.com> Date: Tue, 28 Nov 2023 20:45:41 +0100 Subject: [PATCH 05/12] and i missed this for some reason --- src/game_api/entity.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/game_api/entity.cpp b/src/game_api/entity.cpp index 890dbe629..98517a1cd 100644 --- a/src/game_api/entity.cpp +++ b/src/game_api/entity.cpp @@ -176,7 +176,7 @@ std::pair Entity::position_self() const void Entity::remove_item(uint32_t item_uid) { - auto entity = get_entity_ptr_local(item_uid); + auto entity = get_entity_ptr(item_uid); if (entity) remove_item_ptr(entity); } @@ -213,7 +213,7 @@ bool Movable::damage(uint32_t damage_dealer_uid, int8_t damage_amount, uint16_t return; }*/ - auto dealer = get_entity_ptr_local(damage_dealer_uid); + auto dealer = get_entity_ptr(damage_dealer_uid); /* but it can be nil? if (dealer == nullptr) { @@ -241,7 +241,7 @@ bool Movable::is_button_released(BUTTON button) std::tuple get_position(uint32_t uid) { - Entity* ent = get_entity_ptr_local(uid); + Entity* ent = get_entity_ptr(uid); if (ent) return std::make_tuple(ent->position().first, ent->position().second, ent->layer); @@ -250,7 +250,7 @@ std::tuple get_position(uint32_t uid) std::tuple get_render_position(uint32_t uid) { - Entity* ent = get_entity_ptr_local(uid); + Entity* ent = get_entity_ptr(uid); if (ent) { if (ent->rendering_info != nullptr && !ent->rendering_info->render_inactive) @@ -263,7 +263,7 @@ std::tuple get_render_position(uint32_t uid) std::tuple get_velocity(uint32_t uid) { - if (Entity* ent = get_entity_ptr_local(uid)) + if (Entity* ent = get_entity_ptr(uid)) { float vx{0.0f}; float vy{0.0f}; @@ -292,7 +292,7 @@ std::tuple get_velocity(uint32_t uid) AABB get_hitbox(uint32_t uid, bool use_render_pos) { - if (Entity* ent = get_entity_ptr_local(uid)) + if (Entity* ent = get_entity_ptr(uid)) { auto [x, y, l] = (use_render_pos ? get_render_position : get_position)(uid); return AABB{ @@ -380,7 +380,7 @@ Entity* get_entity_ptr_main(uint32_t uid) return p; } -Entity* get_entity_ptr_local(uint32_t uid) +Entity* get_entity_ptr(uint32_t uid) { auto& state = State::get(); auto p = state.find_local(uid); @@ -518,7 +518,7 @@ bool recursive(Entity* ent, std::optional mask, std::vector auto currend_uid = true_type->tail_bg_uid; for (int idx = 0; idx < 8; ++idx) { - auto tail_ent = get_entity_ptr_local(currend_uid + idx); + auto tail_ent = get_entity_ptr(currend_uid + idx); if (tail_ent != nullptr && (tail_ent->type->id == jellys_tails[0] || tail_ent->type->id == jellys_tails[1])) // only kill the tail { recursive(tail_ent, mask, ent_types, rec_mode, func); From 19d0bf65aed5d2e715b31df131a2919f60d7a037 Mon Sep 17 00:00:00 2001 From: Mr-Auto <36127424+Mr-Auto@users.noreply.github.com> Date: Tue, 28 Nov 2023 22:03:18 +0100 Subject: [PATCH 06/12] all local unless you need specifically need main --- src/game_api/entity.cpp | 16 ++---- src/game_api/entity.hpp | 1 - src/game_api/state.cpp | 10 +--- src/game_api/state.hpp | 3 +- src/injected/ui.cpp | 102 +++++++++++++++++++-------------------- src/injected/ui_util.cpp | 36 +++++++------- 6 files changed, 74 insertions(+), 94 deletions(-) diff --git a/src/game_api/entity.cpp b/src/game_api/entity.cpp index 98517a1cd..aabc5d828 100644 --- a/src/game_api/entity.cpp +++ b/src/game_api/entity.cpp @@ -371,21 +371,11 @@ std::span Entity::get_items() return {}; } -Entity* get_entity_ptr_main(uint32_t uid) -{ - auto& state = State::get(); - auto p = state.find(uid); - if (IsBadWritePtr(p, 0x178)) - return nullptr; - return p; -} - Entity* get_entity_ptr(uint32_t uid) { - auto& state = State::get(); - auto p = state.find_local(uid); - if (IsBadWritePtr(p, 0x178)) - return nullptr; + auto p = State::find(State::get().ptr(), uid); + // if (IsBadWritePtr(p, 0x178)) + // return nullptr; return p; } diff --git a/src/game_api/entity.hpp b/src/game_api/entity.hpp index 2435cb97f..8ee242530 100644 --- a/src/game_api/entity.hpp +++ b/src/game_api/entity.hpp @@ -313,5 +313,4 @@ std::tuple get_velocity(uint32_t uid); AABB get_hitbox(uint32_t uid, bool use_render_pos); struct EntityFactory* entity_factory(); -Entity* get_entity_ptr_main(uint32_t uid); Entity* get_entity_ptr(uint32_t uid); diff --git a/src/game_api/state.cpp b/src/game_api/state.cpp index ab47b4452..1ad68ee0b 100644 --- a/src/game_api/state.cpp +++ b/src/game_api/state.cpp @@ -547,7 +547,7 @@ uint32_t lowbias32_r(uint32_t x) x ^= x >> 16; return x; } -Entity* find(StateMemory* state, uint32_t uid) +Entity* State::find(StateMemory* state, uint32_t uid) { // Ported from MauveAlert's python code in the CAT tracker @@ -581,14 +581,6 @@ Entity* find(StateMemory* state, uint32_t uid) cur_index = (cur_index + (uint32_t)1) & mask; } } -Entity* State::find(uint32_t uid) -{ - return ::find(ptr(), uid); -} -Entity* State::find_local(uint32_t uid) -{ - return ::find(ptr_local(), uid); -} LiquidPhysicsEngine* State::get_correct_liquid_engine(ENT_TYPE liquid_type) { diff --git a/src/game_api/state.hpp b/src/game_api/state.hpp index fdc2e2744..e4a4c9b0d 100644 --- a/src/game_api/state.hpp +++ b/src/game_api/state.hpp @@ -369,8 +369,7 @@ struct State std::vector read_prng() const; - Entity* find(uint32_t uid); - Entity* find_local(uint32_t uid); + static Entity* find(StateMemory* state, uint32_t uid); static std::pair get_camera_position(); void set_camera_position(float cx, float cy); diff --git a/src/injected/ui.cpp b/src/injected/ui.cpp index 68a38f646..dc1534235 100644 --- a/src/injected/ui.cpp +++ b/src/injected/ui.cpp @@ -1419,7 +1419,7 @@ int32_t spawn_entityitem(EntityItem to_spawn, bool s, bool set_last = true) auto old_block_id = UI::get_grid_entity_at(cpos.first, cpos.second, LAYER::PLAYER); if (old_block_id != -1) { - auto old_block = get_entity_ptr_main(old_block_id); + auto old_block = get_entity_ptr(old_block_id); if (old_block) smart_delete(old_block); @@ -1434,12 +1434,12 @@ int32_t spawn_entityitem(EntityItem to_spawn, bool s, bool set_last = true) int spawned = UI::spawn_entity(to_spawn.id, g_x, g_y, s, g_vx, g_vy, snap); if (to_spawn.name.find("ENT_TYPE_MOUNT") != std::string::npos) { - auto mount = get_entity_ptr_main(spawned)->as(); + auto mount = get_entity_ptr(spawned)->as(); mount->tame(true); } if (to_spawn.name.find("ENT_TYPE_FLOOR") != std::string::npos && options["spawn_floor_decorated"]) { - if (Floor* floor = get_entity_ptr_main(spawned)->as()) + if (Floor* floor = get_entity_ptr(spawned)->as()) { if (flip && (to_spawn.name.find("ARROW_TRAP") != std::string::npos || to_spawn.name.find("LASER_TRAP") != std::string::npos || to_spawn.name.find("HORIZONTAL") != std::string::npos)) { @@ -1463,13 +1463,13 @@ int32_t spawn_entityitem(EntityItem to_spawn, bool s, bool set_last = true) } if (flip) { - auto ent = get_entity_ptr_main(spawned); + auto ent = get_entity_ptr(spawned); if (ent) ent->flags |= (1U << 16); } if (to_spawn.id == also_snap[0]) { - auto ent = get_entity_ptr_main(spawned)->as(); + auto ent = get_entity_ptr(spawned)->as(); ent->door_type = to_id("ENT_TYPE_FLOOR_DOOR_LAYER"); ent->platform_type = to_id("ENT_TYPE_FLOOR_DOOR_PLATFORM"); } @@ -1529,7 +1529,7 @@ void spawn_kit(Kit* kit) if (spawned == -1) continue; - auto spawned_ent = get_entity_ptr_main(spawned)->as(); + auto spawned_ent = get_entity_ptr(spawned)->as(); if (std::find(std::begin(wearable), std::end(wearable), id) != std::end(wearable) && g_players.at(0)->worn_backitem() == -1) { @@ -1537,7 +1537,7 @@ void spawn_kit(Kit* kit) } else if (item.name.find("MOUNT_") != std::string::npos) { - auto spawned_mount = get_entity_ptr_main(spawned)->as(); + auto spawned_mount = get_entity_ptr(spawned)->as(); spawned_mount->tame(true); if (!g_players.at(0)->overlay) { @@ -1601,9 +1601,9 @@ void spawn_entity_over() return; } - if (g_over_id == -1 || !get_entity_ptr_main(g_over_id)) + if (g_over_id == -1 || !get_entity_ptr(g_over_id)) return; - auto overlay = get_entity_ptr_main(g_over_id); + auto overlay = get_entity_ptr(g_over_id); if (item.name.find("ENT_TYPE_ITEM_POWERUP") != std::string::npos) { @@ -1613,7 +1613,7 @@ void spawn_entity_over() else if (item.name.find("ENT_TYPE_ITEM") != std::string::npos && overlay->type->search_flags & 0x100) { int spawned = UI::spawn_entity_over(item.id, g_over_id, g_dx, g_dy); - auto ent = get_entity_ptr_main(spawned); + auto ent = get_entity_ptr(spawned); if (g_dx == 0 && g_dy == 0) { ent->set_draw_depth(9); @@ -1639,7 +1639,7 @@ void spawn_entity_over() { auto mount = overlay->as(); int spawned = UI::spawn_entity(item.id, g_x, g_y, true, g_vx, g_vy, false); - auto rider = get_entity_ptr_main(spawned)->as(); + auto rider = get_entity_ptr(spawned)->as(); mount->carry(rider); rider->move_state = 0; if (!lock_entity) @@ -1689,7 +1689,7 @@ bool update_entity() return false; if (g_last_id > -1) { - g_entity = get_entity_ptr_main(g_last_id); + g_entity = get_entity_ptr(g_last_id); if (!g_entity) return false; @@ -2065,7 +2065,7 @@ void clear_void() { for (auto uid : UI::get_entities_by({}, 1422, LAYER::FRONT)) { - auto ent = get_entity_ptr_main(uid); + auto ent = get_entity_ptr(uid); auto [x, y] = ent->position(); if (x > 2.5f && y < 122.5f && x < g_state->w * 10.0f + 2.5f && y > 122.5f - g_state->h * 8.0f) UI::safe_destroy(ent); @@ -2095,7 +2095,7 @@ void load_void(std::string data) if (e.id <= 915) { auto uid = UI::spawn_grid(e.id, (float)e.x, (float)e.y, 0); - auto ent = get_entity_ptr_main(uid); + auto ent = get_entity_ptr(uid); if (ent->type->search_flags & 0x100) { fix_decorations_at((float)e.x, (float)e.y, LAYER::FRONT); @@ -2160,7 +2160,7 @@ std::string serialize_void() uids = UI::get_entities_by({}, export_mask, LAYER::FRONT); for (auto uid : uids) { - auto ent = get_entity_ptr_main(uid); + auto ent = get_entity_ptr(uid); if (!ent || !(ent->type->search_flags & export_mask)) continue; auto [x, y] = ent->position(); @@ -2341,7 +2341,7 @@ void warp_next_level(size_t num) for (auto doorid : UI::get_entities_by({(ENT_TYPE)CUSTOM_TYPE::EXITDOOR}, 0x100, LAYER::BOTH)) { - ExitDoor* doorent = get_entity_ptr_main(doorid)->as(); + ExitDoor* doorent = get_entity_ptr(doorid)->as(); if (!doorent->special_door) continue; targets.emplace_back(doorent->world, doorent->level, doorent->theme); @@ -3490,7 +3490,7 @@ bool process_keys(UINT nCode, WPARAM wParam, [[maybe_unused]] LPARAM lParam) } else if (pressed("destroy_grabbed", wParam)) { - auto selected = get_entity_ptr_main(g_last_id); + auto selected = get_entity_ptr(g_last_id); if (selected) smart_delete(selected, true); if (!lock_entity) @@ -3500,7 +3500,7 @@ bool process_keys(UINT nCode, WPARAM wParam, [[maybe_unused]] LPARAM lParam) { for (auto selected_uid : g_selected_ids) { - auto ent = get_entity_ptr_main(selected_uid); + auto ent = get_entity_ptr(selected_uid); if (ent) smart_delete(ent, false); } @@ -3867,7 +3867,7 @@ void render_narnia() for (auto doorid : UI::get_entities_by({(ENT_TYPE)CUSTOM_TYPE::EXITDOOR}, 0x100, LAYER::BOTH)) { - ExitDoor* target = get_entity_ptr_main(doorid)->as(); + ExitDoor* target = get_entity_ptr(doorid)->as(); if (!target->special_door) continue; std::string buf = fmt::format("{}-{} {}", target->world, target->level, theme_name(target->theme)); @@ -4347,7 +4347,7 @@ void erase_entities() auto box = AABB{ax, ay, ax, ay}; for (auto erase_uid : UI::get_entities_overlapping(mask, box.extrude(0.1f), (LAYER)g_state->camera_layer)) { - auto erase = get_entity_ptr_main(erase_uid); + auto erase = get_entity_ptr(erase_uid); if (erase) smart_delete(erase); } @@ -4638,7 +4638,7 @@ std::string entity_tooltip(Entity* hovered) if (hovered->type->search_flags & 15 && hovered->as()->last_owner_uid > -1) { auto ent = hovered->as(); - auto owner = get_entity_ptr_main(ent->last_owner_uid); + auto owner = get_entity_ptr(ent->last_owner_uid); if (owner) coords += fmt::format("\nOWNER: {}, {} ({:.2f}, {:.2f})", owner->uid, entity_names[owner->type->id], owner->abs_x == -FLT_MAX ? owner->x : owner->abs_x, owner->abs_y == -FLT_MAX ? owner->y : owner->abs_y); } @@ -4995,7 +4995,7 @@ void render_clickhandler() static const auto olmec = to_id("ENT_TYPE_ACTIVEFLOOR_OLMEC"); for (auto entity : UI::get_entities_by({}, g_hitbox_mask, (LAYER)(peek_layer ? g_state->camera_layer ^ 1 : g_state->camera_layer))) { - auto ent = get_entity_ptr_main(entity); + auto ent = get_entity_ptr(entity); if (!ent) continue; @@ -5049,17 +5049,17 @@ void render_clickhandler() }; for (auto entity : UI::get_entities_by(additional_fixed_entities, 0x180, (LAYER)(peek_layer ? g_state->camera_layer ^ 1 : g_state->camera_layer))) // FLOOR | ACTIVEFLOOR { - auto ent = get_entity_ptr_main(entity); + auto ent = get_entity_ptr(entity); render_hitbox(ent, false, ImColor(0, 255, 255, 150)); } for (auto entity : UI::get_entities_by({(ENT_TYPE)CUSTOM_TYPE::TRIGGER}, 0x1000, (LAYER)(peek_layer ? g_state->camera_layer ^ 1 : g_state->camera_layer))) // LOGICAL { - auto ent = get_entity_ptr_main(entity); + auto ent = get_entity_ptr(entity); render_hitbox(ent, false, ImColor(255, 0, 0, 150)); } for (auto entity : UI::get_entities_by({to_id("ENT_TYPE_LOGICAL_DOOR")}, 0x1000, (LAYER)(peek_layer ? g_state->camera_layer ^ 1 : g_state->camera_layer))) // DOOR { - auto ent = get_entity_ptr_main(entity); + auto ent = get_entity_ptr(entity); render_hitbox(ent, false, ImColor(255, 180, 45, 150), false, true); } @@ -5120,7 +5120,7 @@ void render_clickhandler() } for (auto entity : g_selected_ids) { - auto ent = get_entity_ptr_main(entity); + auto ent = get_entity_ptr(entity); if (ent) { if (ent->layer == (peek_layer ? g_state->camera_layer ^ 1 : g_state->camera_layer)) @@ -5414,7 +5414,7 @@ void render_clickhandler() throw_held = true; } set_pos(startpos); - auto held = get_entity_ptr_main(g_held_id); + auto held = get_entity_ptr(g_held_id); if (held && held->is_movable()) { UI::move_entity(g_held_id, g_x, g_y, true, 0, 0, false); @@ -6177,7 +6177,7 @@ void render_options() void render_debug() { ImGui::PushItemWidth(-ImGui::GetWindowWidth() * 0.5f); - const auto selected_entity = get_entity_ptr_main(g_last_id); + const auto selected_entity = get_entity_ptr(g_last_id); size_t entity_addr = reinterpret_cast(selected_entity); size_t state_addr = reinterpret_cast(g_state); size_t save_addr = reinterpret_cast(g_save); @@ -7120,7 +7120,7 @@ void render_entity_finder() { g_selected_ids.erase(std::remove_if(g_selected_ids.begin(), g_selected_ids.end(), [&](uint32_t filter_uid) { - auto ent = get_entity_ptr_main(filter_uid); + auto ent = get_entity_ptr(filter_uid); if (!ent) return true; return ent->type->id != search_entity_type; }), @@ -7130,7 +7130,7 @@ void render_entity_finder() { g_selected_ids.erase(std::remove_if(g_selected_ids.begin(), g_selected_ids.end(), [&](uint32_t filter_uid) { - auto ent = get_entity_ptr_main(filter_uid); + auto ent = get_entity_ptr(filter_uid); if (!ent) return true; return (ent->type->search_flags & search_entity_mask) == 0; }), @@ -7139,7 +7139,7 @@ void render_entity_finder() { g_selected_ids.erase(std::remove_if(g_selected_ids.begin(), g_selected_ids.end(), [&](uint32_t filter_uid) { - auto ent = get_entity_ptr_main(filter_uid); + auto ent = get_entity_ptr(filter_uid); if (!ent) return true; return ent->layer != enum_to_layer((LAYER)search_entity_layer); }), @@ -7151,7 +7151,7 @@ void render_entity_finder() { g_selected_ids.erase(std::remove_if(g_selected_ids.begin(), g_selected_ids.end(), [&](uint32_t filter_uid) { - auto ent = get_entity_ptr_main(filter_uid); + auto ent = get_entity_ptr(filter_uid); if (!ent) return true; return (ent->flags & search_entity_flags) != search_entity_flags; }), @@ -7161,7 +7161,7 @@ void render_entity_finder() { g_selected_ids.erase(std::remove_if(g_selected_ids.begin(), g_selected_ids.end(), [&](uint32_t filter_uid) { - auto ent = get_entity_ptr_main(filter_uid); + auto ent = get_entity_ptr(filter_uid); if (!ent) return true; return (ent->flags & search_entity_not_flags) != 0; }), @@ -7171,7 +7171,7 @@ void render_entity_finder() { g_selected_ids.erase(std::remove_if(g_selected_ids.begin(), g_selected_ids.end(), [&](uint32_t filter_uid) { - auto ent = get_entity_ptr_main(filter_uid); + auto ent = get_entity_ptr(filter_uid); if (!ent) return true; return (ent->more_flags & search_entity_more_flags) != search_entity_more_flags; }), @@ -7181,7 +7181,7 @@ void render_entity_finder() { g_selected_ids.erase(std::remove_if(g_selected_ids.begin(), g_selected_ids.end(), [&](uint32_t filter_uid) { - auto ent = get_entity_ptr_main(filter_uid); + auto ent = get_entity_ptr(filter_uid); if (!ent) return true; return (ent->more_flags & search_entity_not_more_flags) != 0; }), @@ -7191,7 +7191,7 @@ void render_entity_finder() { g_selected_ids.erase(std::remove_if(g_selected_ids.begin(), g_selected_ids.end(), [&](uint32_t filter_uid) { - auto ent = get_entity_ptr_main(filter_uid); + auto ent = get_entity_ptr(filter_uid); if (!ent) return true; return (ent->type->properties_flags & search_entity_properties_flags) != search_entity_properties_flags; }), @@ -7201,7 +7201,7 @@ void render_entity_finder() { g_selected_ids.erase(std::remove_if(g_selected_ids.begin(), g_selected_ids.end(), [&](uint32_t filter_uid) { - auto ent = get_entity_ptr_main(filter_uid); + auto ent = get_entity_ptr(filter_uid); if (!ent) return true; return (ent->type->properties_flags & search_entity_not_properties_flags) != 0; }), @@ -7211,7 +7211,7 @@ void render_entity_finder() { g_selected_ids.erase(std::remove_if(g_selected_ids.begin(), g_selected_ids.end(), [&](uint32_t filter_uid) { - auto ent = get_entity_ptr_main(filter_uid); + auto ent = get_entity_ptr(filter_uid); if (!ent) return true; return !StrStrIA(entity_names[ent->type->id].c_str(), search_entity_name.c_str()); }), @@ -7221,7 +7221,7 @@ void render_entity_finder() { g_selected_ids.erase(std::remove_if(g_selected_ids.begin(), g_selected_ids.end(), [&](uint32_t filter_uid) { - auto ent = get_entity_ptr_main(filter_uid); + auto ent = get_entity_ptr(filter_uid); if (!ent) return true; return ent->draw_depth < search_entity_depth[0] || ent->draw_depth > search_entity_depth[1]; }), @@ -7255,7 +7255,7 @@ void render_entity_finder() { for (auto selected_uid : g_selected_ids) { - auto ent = get_entity_ptr_main(selected_uid); + auto ent = get_entity_ptr(selected_uid); if (ent) smart_delete(ent, false); } @@ -7266,7 +7266,7 @@ void render_entity_finder() { for (auto selected_uid : g_selected_ids) { - auto ent = get_entity_ptr_main(selected_uid); + auto ent = get_entity_ptr(selected_uid); if (ent) ent->kill(true, nullptr); } @@ -7277,7 +7277,7 @@ void render_entity_finder() { for (auto selected_uid : g_selected_ids) { - auto ent = get_entity_ptr_main(selected_uid); + auto ent = get_entity_ptr(selected_uid); if (ent) ent->destroy(); } @@ -7293,7 +7293,7 @@ void render_entity_finder() void render_entity_props(int uid, bool detached = false) { - auto entity = get_entity_ptr_main(uid); + auto entity = get_entity_ptr(uid); ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.5f); if (!detached) { @@ -7468,7 +7468,7 @@ void render_entity_props(int uid, bool detached = false) ImGui::SameLine(); if (ImGui::Button("Drop##DropHolding")) { - auto holding = get_entity_ptr_main(movable->holding_uid); + auto holding = get_entity_ptr(movable->holding_uid); if (holding) movable->drop(holding); else @@ -8044,12 +8044,12 @@ void render_texture_viewer() } if (texture_viewer.uid != g_last_id) { - Entity* ent = get_entity_ptr_main(g_last_id); + Entity* ent = get_entity_ptr(g_last_id); if (ent) texture_viewer.id = ent->get_texture(); texture_viewer.uid = g_last_id; } - Entity* ent = get_entity_ptr_main(texture_viewer.uid); + Entity* ent = get_entity_ptr(texture_viewer.uid); auto pos = ImGui::GetWindowPos(); auto size = ImGui::GetWindowSize(); @@ -8584,7 +8584,7 @@ void render_game_props() } for (auto uid : UI::get_entities_by({to_id("ENT_TYPE_ITEM_PLAYERGHOST")}, 0x8, LAYER::BOTH)) { - auto ghost = get_entity_ptr_main(uid)->as(); + auto ghost = get_entity_ptr(uid)->as(); if (ghost->player_inputs && ghost->player_inputs->player_slot == i && g_state->items->player_count < i + 1) ghost->destroy(); } @@ -8602,7 +8602,7 @@ void render_game_props() g_state->items->player_inventories[i].health = 4; auto uid = g_state->next_entity_uid; UI::spawn_player(i); - auto player = get_entity_ptr_main(uid)->as(); + auto player = get_entity_ptr(uid)->as(); player->set_position(spawn_x, spawn_y); } } @@ -8742,7 +8742,7 @@ void render_game_props() { continue; } - auto ai_entity = get_entity_ptr_main(ai_target.ai_uid); + auto ai_entity = get_entity_ptr(ai_target.ai_uid); auto target = ai_target.target_uid; if (ai_entity == nullptr || (ai_entity->type->search_flags & 1) != 1) { @@ -8758,7 +8758,7 @@ void render_game_props() } else { - auto target_entity = get_entity_ptr_main(target); + auto target_entity = get_entity_ptr(target); if (target_entity != nullptr) { ImGui::Text("%s", entity_names[target_entity->type->id].c_str()); @@ -9773,7 +9773,7 @@ void update_bucket() if (g_bucket->overlunky->set_selected_uid.has_value()) { g_last_id = g_bucket->overlunky->set_selected_uid.value(); - g_entity = get_entity_ptr_main(g_last_id); + g_entity = get_entity_ptr(g_last_id); g_bucket->overlunky->set_selected_uid = std::nullopt; } if (g_bucket->overlunky->set_selected_uids.has_value()) diff --git a/src/injected/ui_util.cpp b/src/injected/ui_util.cpp index abf0978b1..afc4fd01d 100644 --- a/src/injected/ui_util.cpp +++ b/src/injected/ui_util.cpp @@ -12,7 +12,7 @@ #include "entities_floors.hpp" // for Floor, Floor::(anonymous), FLOO... #include "entities_items.hpp" // for Torch #include "entities_mounts.hpp" // for Mount -#include "entity.hpp" // for to_id, Entity, get_entity_ptr_main +#include "entity.hpp" // for to_id, Entity, get_entity_ptr #include "entity_lookup.hpp" // #include "game_api.hpp" // #include "game_manager.hpp" // for get_game_manager, GameManager @@ -176,7 +176,7 @@ Entity* UI::get_entity_at(float x, float y, bool s, float radius, uint32_t mask) } void UI::move_entity(uint32_t uid, float x, float y, bool s, float vx, float vy, bool snap) { - auto ent = get_entity_ptr_main(uid); + auto ent = get_entity_ptr(uid); if (ent) ent->teleport(x, y, s, vx, vy, snap); } @@ -255,7 +255,7 @@ float UI::get_spark_distance(SparkTrap* ent) const static auto offset = get_address("sparktrap_angle_increment") + 4; if (memory_read(offset - 1) == 0x89) // check if sparktraps_hack is active { - auto spark = get_entity_ptr_main(ent->spark_uid)->as(); + auto spark = get_entity_ptr(ent->spark_uid)->as(); return spark->distance; } auto parameters = get_sparktraps_parameters_ptr(); @@ -307,7 +307,7 @@ std::vector UI::get_entities_by(std::vector entity_types, ui int32_t UI::spawn_companion(ENT_TYPE compatnion_type, float x, float y, LAYER l, float vx, float vy) { auto uid = ::spawn_companion(compatnion_type, x, y, (LAYER)enum_to_layer(l)); - auto ent = get_entity_ptr_main(uid)->as(); + auto ent = get_entity_ptr(uid)->as(); ent->velocityx = vx; ent->velocityy = vy; return uid; @@ -354,7 +354,7 @@ int32_t UI::destroy_entity_items(Entity* ent) int32_t last_uid = *it; while (it != items.rend()) { - auto item = get_entity_ptr_main(*it); + auto item = get_entity_ptr(*it); UI::destroy_entity_items(item); UI::safe_destroy(item, false, false); it++; @@ -370,7 +370,7 @@ bool UI::destroy_entity_item_type(Entity* ent, ENT_TYPE type) std::vector::reverse_iterator it = items.rbegin(); while (it != items.rend()) { - auto item = get_entity_ptr_main(*it); + auto item = get_entity_ptr(*it); if (item && item->type->id == type) { UI::destroy_entity_items(item); @@ -409,7 +409,7 @@ void UI::update_floor_at(float x, float y, LAYER l) auto uid = get_grid_entity_at(x, y, l); if (uid == -1) return; - auto ent = get_entity_ptr_main(uid); + auto ent = get_entity_ptr(uid); if ((ent->type->search_flags & 0x100) == 0 || !test_flag(ent->flags, 3)) return; auto floor = ent->as(); @@ -418,7 +418,7 @@ void UI::update_floor_at(float x, float y, LAYER l) { for (auto item : entity_get_items_by(floor->uid, 0, 0x8)) { - auto embed = get_entity_ptr_main(item); + auto embed = get_entity_ptr(item); clr_flag(embed->flags, 1); } } @@ -433,7 +433,7 @@ void UI::update_floor_at(float x, float y, LAYER l) { for (int i = 0; i < 4; ++i) { - auto deco_ent = get_entity_ptr_main(floor->decos[i]); + auto deco_ent = get_entity_ptr(floor->decos[i]); if (deco_ent) deco_ent->destroy(); floor->decos[i] = -1; @@ -441,13 +441,13 @@ void UI::update_floor_at(float x, float y, LAYER l) } for (auto deco : entity_get_items_by(floor->uid, destroy_deco, 0x200)) { - auto deco_ent = get_entity_ptr_main(deco); + auto deco_ent = get_entity_ptr(deco); if (deco_ent) deco_ent->destroy(); } for (auto deco : get_entities_at(destroy_deco, 0, x, y, l, 0.5f)) { - auto deco_ent = get_entity_ptr_main(deco); + auto deco_ent = get_entity_ptr(deco); if (deco_ent) deco_ent->destroy(); } @@ -504,7 +504,7 @@ void UI::cleanup_at(float x, float y, LAYER l, ENT_TYPE type) for (auto bg : get_entities_at(cleanup_ents, 0, x, y, l, 0.1f)) { - auto bg_ent = get_entity_ptr_main(bg); + auto bg_ent = get_entity_ptr(bg); if (bg_ent) bg_ent->destroy(); } @@ -519,7 +519,7 @@ void UI::cleanup_at(float x, float y, LAYER l, ENT_TYPE type) return; for (auto bg : bgs) { - auto ent = get_entity_ptr_main(bg); + auto ent = get_entity_ptr(bg); ent->destroy(); } } @@ -532,12 +532,12 @@ void UI::cleanup_at(float x, float y, LAYER l, ENT_TYPE type) auto door_parts = get_entities_at(door_crap, 0, x, y, l, 0.5f); for (auto part : door_parts) { - auto ent = get_entity_ptr_main(part); + auto ent = get_entity_ptr(part); ent->destroy(); } for (auto uid : get_entities_at(door_platform, 0x100, x, y - 1.0f, l, 0.5f)) { - auto ent = get_entity_ptr_main(uid); + auto ent = get_entity_ptr(uid); ent->destroy(); } } @@ -636,7 +636,7 @@ void UI::safe_destroy(Entity* ent, bool unsafe, bool recurse) // stupid tail is not attached to jelly, but it should always be here for (int tail_uid = last_item + 8; tail_uid > last_item; --tail_uid) { - auto tail = get_entity_ptr_main(tail_uid); + auto tail = get_entity_ptr(tail_uid); if (tail) tail->destroy(); } @@ -650,7 +650,7 @@ void UI::safe_destroy(Entity* ent, bool unsafe, bool recurse) while (true) { uid--; - find_jelly = get_entity_ptr_main(uid); + find_jelly = get_entity_ptr(uid); if (find_jelly && in_array(find_jelly->type->id, jellys)) { safe_destroy(find_jelly); @@ -754,7 +754,7 @@ void UI::save_progress() int32_t UI::spawn_playerghost(ENT_TYPE char_type, float x, float y, LAYER layer, float vx, float vy) { auto uid = ::spawn_playerghost(char_type, x, y, (LAYER)enum_to_layer(layer)); - auto ent = get_entity_ptr_main(uid)->as(); + auto ent = get_entity_ptr(uid)->as(); ent->velocityx = vx; ent->velocityy = vy; return uid; From 93ee4455d02e87e5fb232f5f29372a62c9cdfc5e Mon Sep 17 00:00:00 2001 From: Mr-Auto <36127424+Mr-Auto@users.noreply.github.com> Date: Tue, 28 Nov 2023 22:07:57 +0100 Subject: [PATCH 07/12] doc, comment --- docs/game_data/spel2.lua | 2 +- docs/src/includes/_types.md | 2 +- src/game_api/state.hpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/game_data/spel2.lua b/docs/game_data/spel2.lua index 729e31320..54692577f 100644 --- a/docs/game_data/spel2.lua +++ b/docs/game_data/spel2.lua @@ -2063,7 +2063,7 @@ do ---@field theme_next THEME @Next THEME number, used when loading a new level or transition ---@field theme_start THEME @THEME to start new runs in ---@field current_theme ThemeInfo @Points to the current ThemeInfo - ---@field force_current_theme fun(self, t: integer): nil @This function should only be used in a very specific circumstance (forcing the exiting theme when manually transitioning). Will crash the game if used inappropriately! + ---@field force_current_theme fun(self, t: THEME): nil @This function should only be used in a very specific circumstance (forcing the exiting theme when manually transitioning). Will crash the game if used inappropriately! ---@field shoppie_aggro integer @Current shoppie aggro ---@field shoppie_aggro_next integer @Shoppie aggro to use in the next level ---@field outposts_spawned integer diff --git a/docs/src/includes/_types.md b/docs/src/includes/_types.md index 56987dda6..b30083f1d 100644 --- a/docs/src/includes/_types.md +++ b/docs/src/includes/_types.md @@ -2926,7 +2926,7 @@ int | [level_start](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=lev [THEME](#THEME) | [theme_next](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=theme_next) | Next [THEME](#THEME) number, used when loading a new level or transition [THEME](#THEME) | [theme_start](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=theme_start) | [THEME](#THEME) to start new runs in [ThemeInfo](#ThemeInfo) | [current_theme](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=current_theme) | Points to the current [ThemeInfo](#ThemeInfo) -nil | [force_current_theme(int t)](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=force_current_theme) | This function should only be used in a very specific circumstance (forcing the exiting theme when manually transitioning). Will crash the game if used inappropriately! +nil | [force_current_theme(THEME t)](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=force_current_theme) | This function should only be used in a very specific circumstance (forcing the exiting theme when manually transitioning). Will crash the game if used inappropriately! int | [shoppie_aggro](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=shoppie_aggro) | Current shoppie aggro int | [shoppie_aggro_next](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=shoppie_aggro_next) | Shoppie aggro to use in the next level int | [outposts_spawned](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=outposts_spawned) | diff --git a/src/game_api/state.hpp b/src/game_api/state.hpp index e4a4c9b0d..fc051c6bf 100644 --- a/src/game_api/state.hpp +++ b/src/game_api/state.hpp @@ -330,7 +330,7 @@ struct State StateMemory* ptr_local() const; // TODO: rest of the functions should probably be just static or moved out of here as they don't need State - // they have to assume to use public/local ptr in which case they probably should be moved to StateMemory + // they have to assume to use main/local ptr in which case they probably should be moved to StateMemory to be more clear // also because we really only use this struct to get to the StateMemory, make ptr functions static and simply make them call the get() // use only if you only want the layer, otherwise use `ptr()->layers` From 46687c945e1659761cbebd243142445845725669 Mon Sep 17 00:00:00 2001 From: Mr-Auto <36127424+Mr-Auto@users.noreply.github.com> Date: Sat, 2 Dec 2023 13:44:36 +0100 Subject: [PATCH 08/12] that's no padding --- src/game_api/level_api.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/game_api/level_api.hpp b/src/game_api/level_api.hpp index 32fd2e363..f85562239 100644 --- a/src/game_api/level_api.hpp +++ b/src/game_api/level_api.hpp @@ -142,7 +142,7 @@ struct LevelGenData uint32_t machine_rewardroom_chance; uint32_t max_liquid_particles; uint32_t flagged_liquid_rooms; - uint32_t unknown_config; + uint32_t unknown_config; // }; }; @@ -151,7 +151,8 @@ struct LevelGenData game_unordered_map room_templates; game_unordered_map room_template_datas; - std::byte padding1[0x6b8]; + std::array unknown; // index is tile code id from TileCodeDef + // uint32_t padding; std::array set_room_datas; game_unordered_map monster_chances; From ce764135867b058ab2bac9d14722a7020b3fc87e Mon Sep 17 00:00:00 2001 From: Mr-Auto <36127424+Mr-Auto@users.noreply.github.com> Date: Sat, 2 Dec 2023 15:32:59 +0100 Subject: [PATCH 09/12] `player_id` -> `player_slot` --- docs/game_data/spel2.lua | 2 +- docs/src/includes/_types.md | 2 +- src/game_api/script/usertypes/player_lua.cpp | 26 +++++++++----------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/docs/game_data/spel2.lua b/docs/game_data/spel2.lua index 54692577f..18b219f45 100644 --- a/docs/game_data/spel2.lua +++ b/docs/game_data/spel2.lua @@ -4904,7 +4904,7 @@ function CustomSound:play(paused, sound_type) end ---@field buttons INPUTS ---@field input_mapping_keyboard InputMapping ---@field input_mapping_controller InputMapping - ---@field player_id integer + ---@field player_slot integer ---@field is_participating boolean ---@class InputMapping diff --git a/docs/src/includes/_types.md b/docs/src/includes/_types.md index b30083f1d..92d5682c7 100644 --- a/docs/src/includes/_types.md +++ b/docs/src/includes/_types.md @@ -2862,7 +2862,7 @@ Type | Name | Description [INPUTS](#INPUTS) | [buttons](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=buttons) | [InputMapping](#InputMapping) | [input_mapping_keyboard](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=input_mapping_keyboard) | [InputMapping](#InputMapping) | [input_mapping_controller](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=input_mapping_controller) | -int | [player_id](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=player_id) | +int | [player_slot](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=player_slot) | bool | [is_participating](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=is_participating) | ### PlayerSlotSettings diff --git a/src/game_api/script/usertypes/player_lua.cpp b/src/game_api/script/usertypes/player_lua.cpp index ef11f6746..0e7b77b6c 100644 --- a/src/game_api/script/usertypes/player_lua.cpp +++ b/src/game_api/script/usertypes/player_lua.cpp @@ -26,20 +26,18 @@ void register_usertypes(sol::state& lua) sol::readonly(&PlayerSlotSettings::auto_run_enabled), "controller_right_stick", sol::readonly(&PlayerSlotSettings::controller_right_stick)); - lua.new_usertype( - "PlayerSlot", - "buttons_gameplay", - &PlayerSlot::buttons_gameplay, - "buttons", - &PlayerSlot::buttons, - "input_mapping_keyboard", - sol::readonly(&PlayerSlot::input_mapping_keyboard), - "input_mapping_controller", - sol::readonly(&PlayerSlot::input_mapping_controller), - "player_id", - sol::readonly(&PlayerSlot::player_slot), - "is_participating", - sol::readonly(&PlayerSlot::is_participating)); + + auto playerslot_type = lua.new_usertype("PlayerSlot"); + playerslot_type["buttons_gameplay"] = &PlayerSlot::buttons_gameplay; + playerslot_type["buttons"] = &PlayerSlot::buttons; + playerslot_type["input_mapping_keyboard"] = sol::readonly(&PlayerSlot::input_mapping_keyboard); + playerslot_type["input_mapping_controller"] = sol::readonly(&PlayerSlot::input_mapping_controller); + /// NoDoc + playerslot_type["player_id"] = sol::readonly(&PlayerSlot::player_slot); + playerslot_type["player_slot"] = sol::property([](PlayerSlot& p) + { return p.player_slot < 0 ? p.player_slot : p.player_slot + 1; }); + playerslot_type["is_participating"] = sol::readonly(&PlayerSlot::is_participating); + /// Used in PlayerSlot lua.new_usertype( "InputMapping", From 0c751c22e17ef49e73206933a3a0c589b535ab70 Mon Sep 17 00:00:00 2001 From: Mr-Auto <36127424+Mr-Auto@users.noreply.github.com> Date: Sun, 3 Dec 2023 23:34:15 +0100 Subject: [PATCH 10/12] add missing PURCHASABLE custom type --- src/game_api/custom_types.cpp | 59 +++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/src/game_api/custom_types.cpp b/src/game_api/custom_types.cpp index d698fd2ff..0e428e0db 100644 --- a/src/game_api/custom_types.cpp +++ b/src/game_api/custom_types.cpp @@ -343,6 +343,7 @@ const std::vector> custom_type_names = {CUSTOM_TYPE::YELLOWCAPE, "YELLOWCAPE"}, {CUSTOM_TYPE::YETIKING, "YETIKING"}, {CUSTOM_TYPE::YETIQUEEN, "YETIQUEEN"}, + {CUSTOM_TYPE::PURCHASABLE, "PURCHASABLE"}, }; template @@ -1564,6 +1565,64 @@ std::span get_custom_entity_types(CUSTOM_TYPE type) return make_custom_entity_type_list("ENT_TYPE_MONS_YETIKING"); case CUSTOM_TYPE::YETIQUEEN: return make_custom_entity_type_list("ENT_TYPE_MONS_YETIQUEEN"); + case CUSTOM_TYPE::PURCHASABLE: + return make_custom_entity_type_list( + "ENT_TYPE_ITEM_WOODEN_ARROW", + "ENT_TYPE_ITEM_ROCK", + "ENT_TYPE_ITEM_METAL_ARROW", + "ENT_TYPE_ITEM_LIGHT_ARROW", + "ENT_TYPE_ITEM_PRESENT", + "ENT_TYPE_ITEM_GHIST_PRESENT", + "ENT_TYPE_ITEM_POT", + "ENT_TYPE_ITEM_SKULL", + "ENT_TYPE_ITEM_PICKUP_TORNJOURNALPAGE", + "ENT_TYPE_ITEM_PICKUP_JOURNAL", + "ENT_TYPE_ITEM_PICKUP_ROPE", + "ENT_TYPE_ITEM_PICKUP_ROPEPILE", + "ENT_TYPE_ITEM_PICKUP_BOMBBAG", + "ENT_TYPE_ITEM_PICKUP_BOMBBOX", + "ENT_TYPE_ITEM_PICKUP_ROYALJELLY", + "ENT_TYPE_ITEM_PICKUP_COOKEDTURKEY", + "ENT_TYPE_ITEM_PICKUP_GIANTFOOD", + "ENT_TYPE_ITEM_PICKUP_ELIXIR", + "ENT_TYPE_ITEM_PICKUP_CLOVER", + "ENT_TYPE_ITEM_PICKUP_SEEDEDRUNSUNLOCKER", + "ENT_TYPE_ITEM_PICKUP_SPECTACLES", + "ENT_TYPE_ITEM_PICKUP_CLIMBINGGLOVES", + "ENT_TYPE_ITEM_PICKUP_PITCHERSMITT", + "ENT_TYPE_ITEM_PICKUP_SPRINGSHOES", + "ENT_TYPE_ITEM_PICKUP_SPIKESHOES", + "ENT_TYPE_ITEM_PICKUP_PASTE", + "ENT_TYPE_ITEM_PICKUP_COMPASS", + "ENT_TYPE_ITEM_PICKUP_SPECIALCOMPASS", + "ENT_TYPE_ITEM_PICKUP_PARACHUTE", + "ENT_TYPE_ITEM_PICKUP_UDJATEYE", + "ENT_TYPE_ITEM_PICKUP_KAPALA", + "ENT_TYPE_ITEM_PICKUP_HEDJET", + "ENT_TYPE_ITEM_PICKUP_CROWN", + "ENT_TYPE_ITEM_PICKUP_EGGPLANTCROWN", + "ENT_TYPE_ITEM_PICKUP_TRUECROWN", + "ENT_TYPE_ITEM_PICKUP_ANKH", + "ENT_TYPE_ITEM_PICKUP_TABLETOFDESTINY", + "ENT_TYPE_ITEM_PICKUP_SKELETON_KEY", + "ENT_TYPE_ITEM_PURCHASABLE_CAPE", + "ENT_TYPE_ITEM_PURCHASABLE_JETPACK", + "ENT_TYPE_ITEM_PURCHASABLE_TELEPORTER_BACKPACK", + "ENT_TYPE_ITEM_PURCHASABLE_HOVERPACK", + "ENT_TYPE_ITEM_PURCHASABLE_POWERPACK", + "ENT_TYPE_ITEM_WEBGUN", + "ENT_TYPE_ITEM_SHOTGUN", + "ENT_TYPE_ITEM_FREEZERAY", + "ENT_TYPE_ITEM_CAMERA", + "ENT_TYPE_ITEM_TELEPORTER", + "ENT_TYPE_ITEM_MATTOCK", + "ENT_TYPE_ITEM_BOOMERANG", + "ENT_TYPE_ITEM_MACHETE", + "ENT_TYPE_ITEM_PLASMACANNON", + "ENT_TYPE_ITEM_SCEPTER", + "ENT_TYPE_ITEM_CLONEGUN", + "ENT_TYPE_ITEM_WOODEN_SHIELD", + "ENT_TYPE_ITEM_METAL_SHIELD"); default: { auto it = user_custom_types.find(type); From 6d114bcdf59a7f08af7551f38254b933e14f3507 Mon Sep 17 00:00:00 2001 From: Mr-Auto <36127424+Mr-Auto@users.noreply.github.com> Date: Sun, 3 Dec 2023 23:42:47 +0100 Subject: [PATCH 11/12] forgot to push .hpp with the enum updated --- src/game_api/custom_types.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/game_api/custom_types.hpp b/src/game_api/custom_types.hpp index 683fdd5da..cafca0744 100644 --- a/src/game_api/custom_types.hpp +++ b/src/game_api/custom_types.hpp @@ -7,6 +7,7 @@ #include "aliases.hpp" // for ENT_TYPE +// New types need to be added to the enum, plus the custom_type_names vector and then finally in the get_custom_entity_types function enum class CUSTOM_TYPE : uint32_t { ACIDBUBBLE = 1000, // to be sure that's it's bigger than ENT_TYPE_LIQUID_COARSE_LAVA @@ -343,6 +344,7 @@ enum class CUSTOM_TYPE : uint32_t YELLOWCAPE, YETIKING, YETIQUEEN, + PURCHASABLE, }; constexpr CUSTOM_TYPE custom_type_max = CUSTOM_TYPE::YETIQUEEN; From c6bb76140f6b9e470bb65d5d8a2c46bc0e576e67 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 5 Dec 2023 21:26:45 +0000 Subject: [PATCH 12/12] update slate[no ci] --- docs/index.html | 9 +++++++-- docs/light.html | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/docs/index.html b/docs/index.html index fc55cccaa..7fa4306e3 100644 --- a/docs/index.html +++ b/docs/index.html @@ -16451,7 +16451,7 @@

PlayerSlot

int -player_id +player_slot @@ -16681,7 +16681,7 @@

StateMemory

nil -force_current_theme(int t) +force_current_theme(THEME t) This function should only be used in a very specific circumstance (forcing the exiting theme when manually transitioning). Will crash the game if used inappropriately! @@ -23531,6 +23531,11 @@

Player

Used in base camp to talk with the NPC's +SoundMeta +special_sound +For Lise System walking and looking up sounds + + int jump_lock_timer Increases when holding jump button in the air, set to max while jumping. If this isn't 0, a jump will only be
registered if the jump button was not held on the previous frame. diff --git a/docs/light.html b/docs/light.html index c07a53053..3be655666 100644 --- a/docs/light.html +++ b/docs/light.html @@ -16451,7 +16451,7 @@

PlayerSlot

int -player_id +player_slot @@ -16681,7 +16681,7 @@

StateMemory

nil -force_current_theme(int t) +force_current_theme(THEME t) This function should only be used in a very specific circumstance (forcing the exiting theme when manually transitioning). Will crash the game if used inappropriately! @@ -23531,6 +23531,11 @@

Player

Used in base camp to talk with the NPC's +SoundMeta +special_sound +For Lise System walking and looking up sounds + + int jump_lock_timer Increases when holding jump button in the air, set to max while jumping. If this isn't 0, a jump will only be
registered if the jump button was not held on the previous frame.