From 15a769f6f006161a629c0df5da4ce59d08109590 Mon Sep 17 00:00:00 2001 From: Estebanfer Date: Fri, 6 Oct 2023 20:41:54 -0300 Subject: [PATCH 1/4] destroy_grid_entity function --- docs/game_data/spel2.lua | 5 +++++ docs/src/includes/_globals.md | 10 ++++++++++ src/game_api/layer.cpp | 32 ++++++++++++++++++++++++++++++++ src/game_api/layer.hpp | 2 ++ src/game_api/rpc.cpp | 9 +++++++++ src/game_api/rpc.hpp | 1 + src/game_api/script/lua_vm.cpp | 3 +++ 7 files changed, 62 insertions(+) diff --git a/docs/game_data/spel2.lua b/docs/game_data/spel2.lua index f9f06777c..630d603f4 100644 --- a/docs/game_data/spel2.lua +++ b/docs/game_data/spel2.lua @@ -464,6 +464,11 @@ function move_entity(uid, x, y, vx, vy, layer) end ---@param layer LAYER ---@return nil function move_grid_entity(uid, x, y, layer) end +---Destroy the grid entity, and its item entities, removing them from the grid without dropping particles or gold. +---Will also destroy monsters or items that are standing on a linked activefloor or chain, though excludes MASK.PLAYER to prevent crashes +---@param uid integer +---@return nil +function destroy_grid_entity(uid) end ---Make an ENT_TYPE.FLOOR_DOOR_EXIT go to world `w`, level `l`, theme `t` ---@param uid integer ---@param w integer diff --git a/docs/src/includes/_globals.md b/docs/src/includes/_globals.md index 01babc41e..37cbc536f 100644 --- a/docs/src/includes/_globals.md +++ b/docs/src/includes/_globals.md @@ -459,6 +459,16 @@ Change [ENT_TYPE](#ENT_TYPE)'s spawned when [Waddler](#Waddler) dies, by default Max 255 types. Use empty table as argument to reset to the game default +### destroy_grid_entity + + +> Search script examples for [destroy_grid_entity](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=destroy_grid_entity) + +#### nil destroy_grid_entity(int uid) + +Destroy the grid entity, and its item entities, removing them from the grid without dropping particles or gold. +Will also destroy monsters or items that are standing on a linked activefloor or chain, though excludes [MASK](#MASK).PLAYER to prevent crashes + ### drop diff --git a/src/game_api/layer.cpp b/src/game_api/layer.cpp index 68e52051d..4e9541b4a 100644 --- a/src/game_api/layer.cpp +++ b/src/game_api/layer.cpp @@ -215,3 +215,35 @@ void Layer::move_grid_entity(Entity* ent, uint32_t x, uint32_t y, Layer* dest_la } } } + +void Layer::destroy_grid_entity(Entity* ent) +{ + if (ent) + { + auto items = ent->items.entities(); + for (auto ptr = items.cend(); ptr != items.cbegin();) + { + ptr--; + Entity* item_ent = *ptr; + if (item_ent->type->search_flags & ~1) // if not player + { + destroy_grid_entity(item_ent); + } + } + + const auto pos = ent->position(); + const uint32_t current_grid_x = static_cast(std::round(pos.first)); + const uint32_t current_grid_y = static_cast(std::round(pos.second)); + if (current_grid_x < g_level_max_x && current_grid_y < g_level_max_y) + { + if (grid_entities[current_grid_y][current_grid_x] == ent) + { + grid_entities[current_grid_y][current_grid_x] = nullptr; + update_liquid_collision_at(pos.first, pos.second, false); + } + } + + ent->flags |= 1U << (29 - 1); // set DEAD flag to prevent certain stuff like gold nuggets drop or particles from entities such as spikes + ent->destroy(); + } +} diff --git a/src/game_api/layer.hpp b/src/game_api/layer.hpp index 8def12e0c..32dc5f40b 100644 --- a/src/game_api/layer.hpp +++ b/src/game_api/layer.hpp @@ -210,4 +210,6 @@ struct Layer void move_grid_entity(Entity* ent, float x, float y, Layer* dest_layer); void move_grid_entity(Entity* ent, uint32_t x, uint32_t y, Layer* dest_layer); + + void destroy_grid_entity(Entity* ent); }; diff --git a/src/game_api/rpc.cpp b/src/game_api/rpc.cpp index 0b53eda97..82b027738 100644 --- a/src/game_api/rpc.cpp +++ b/src/game_api/rpc.cpp @@ -1673,6 +1673,15 @@ void move_grid_entity(int32_t uid, float x, float y, LAYER layer) } } +void destroy_grid_entity(int32_t uid) +{ + if (auto entity = get_entity_ptr(uid)) + { + auto state = State::get(); + state.layer(entity->layer)->destroy_grid_entity(entity); + } +} + void add_item_to_shop(int32_t item_uid, int32_t shop_owner_uid) { Movable* item = get_entity_ptr(item_uid)->as(); diff --git a/src/game_api/rpc.hpp b/src/game_api/rpc.hpp index 2b6c155fa..b82693414 100644 --- a/src/game_api/rpc.hpp +++ b/src/game_api/rpc.hpp @@ -125,6 +125,7 @@ void change_waddler_drop(std::vector ent_types); void poison_entity(int32_t entity_uid); void modify_ankh_health_gain(uint8_t max_health, uint8_t beat_add_health); void move_grid_entity(int32_t uid, float x, float y, LAYER layer); +void destroy_grid_entity(int32_t uid); void add_item_to_shop(int32_t item_uid, int32_t shop_owner_uid); void change_poison_timer(int16_t frames); void set_adventure_seed(int64_t first, int64_t second); diff --git a/src/game_api/script/lua_vm.cpp b/src/game_api/script/lua_vm.cpp index a9f789d9b..e40164f63 100644 --- a/src/game_api/script/lua_vm.cpp +++ b/src/game_api/script/lua_vm.cpp @@ -966,6 +966,9 @@ end lua["move_entity"] = move_entity_abs; /// Teleport grid entity, the destination should be whole number, this ensures that the collisions will work properly lua["move_grid_entity"] = move_grid_entity; + /// Destroy the grid entity, and its item entities, removing them from the grid without dropping particles or gold. + /// Will also destroy monsters or items that are standing on a linked activefloor or chain, though excludes MASK.PLAYER to prevent crashes + lua["destroy_grid_entity"] = destroy_grid_entity; /// Make an ENT_TYPE.FLOOR_DOOR_EXIT go to world `w`, level `l`, theme `t` lua["set_door_target"] = set_door_target; /// Short for [set_door_target](#set_door_target). From 80cc987b721de45bbcc078566078fda571345ada Mon Sep 17 00:00:00 2001 From: Estebanfer Date: Sun, 8 Oct 2023 15:29:46 -0300 Subject: [PATCH 2/4] add destroy_grid_entity overload with position, detect player by ent->is_player() --- docs/game_data/spel2.lua | 7 +++++++ docs/src/includes/_globals.md | 2 ++ src/game_api/layer.cpp | 2 +- src/game_api/rpc.cpp | 11 +++++++++++ src/game_api/rpc.hpp | 1 + src/game_api/script/lua_vm.cpp | 4 +++- 6 files changed, 25 insertions(+), 2 deletions(-) diff --git a/docs/game_data/spel2.lua b/docs/game_data/spel2.lua index 630d603f4..7208b1954 100644 --- a/docs/game_data/spel2.lua +++ b/docs/game_data/spel2.lua @@ -469,6 +469,13 @@ function move_grid_entity(uid, x, y, layer) end ---@param uid integer ---@return nil function destroy_grid_entity(uid) end +---Destroy the grid entity, and its item entities, removing them from the grid without dropping particles or gold. +---Will also destroy monsters or items that are standing on a linked activefloor or chain, though excludes MASK.PLAYER to prevent crashes +---@param x number +---@param y number +---@param layer LAYER +---@return nil +function destroy_grid_entity(x, y, layer) end ---Make an ENT_TYPE.FLOOR_DOOR_EXIT go to world `w`, level `l`, theme `t` ---@param uid integer ---@param w integer diff --git a/docs/src/includes/_globals.md b/docs/src/includes/_globals.md index 37cbc536f..7fa5fe884 100644 --- a/docs/src/includes/_globals.md +++ b/docs/src/includes/_globals.md @@ -466,6 +466,8 @@ Use empty table as argument to reset to the game default #### nil destroy_grid_entity(int uid) +#### nil destroy_grid_entity(float x, float y, [LAYER](#LAYER) layer) + Destroy the grid entity, and its item entities, removing them from the grid without dropping particles or gold. Will also destroy monsters or items that are standing on a linked activefloor or chain, though excludes [MASK](#MASK).PLAYER to prevent crashes diff --git a/src/game_api/layer.cpp b/src/game_api/layer.cpp index 4e9541b4a..39a0ca999 100644 --- a/src/game_api/layer.cpp +++ b/src/game_api/layer.cpp @@ -225,7 +225,7 @@ void Layer::destroy_grid_entity(Entity* ent) { ptr--; Entity* item_ent = *ptr; - if (item_ent->type->search_flags & ~1) // if not player + if (!item_ent->is_player()) // if not player { destroy_grid_entity(item_ent); } diff --git a/src/game_api/rpc.cpp b/src/game_api/rpc.cpp index 82b027738..eaae42487 100644 --- a/src/game_api/rpc.cpp +++ b/src/game_api/rpc.cpp @@ -1682,6 +1682,17 @@ void destroy_grid_entity(int32_t uid) } } +void destroy_grid_entity(float x, float y, LAYER layer) +{ + 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)) + { + state.layer(entity->layer)->destroy_grid_entity(entity); + } +} + void add_item_to_shop(int32_t item_uid, int32_t shop_owner_uid) { Movable* item = get_entity_ptr(item_uid)->as(); diff --git a/src/game_api/rpc.hpp b/src/game_api/rpc.hpp index b82693414..5013d4cee 100644 --- a/src/game_api/rpc.hpp +++ b/src/game_api/rpc.hpp @@ -126,6 +126,7 @@ void poison_entity(int32_t entity_uid); void modify_ankh_health_gain(uint8_t max_health, uint8_t beat_add_health); void move_grid_entity(int32_t uid, float x, float y, LAYER layer); void destroy_grid_entity(int32_t uid); +void destroy_grid_entity(float x, float y, LAYER layer); void add_item_to_shop(int32_t item_uid, int32_t shop_owner_uid); void change_poison_timer(int16_t frames); void set_adventure_seed(int64_t first, int64_t second); diff --git a/src/game_api/script/lua_vm.cpp b/src/game_api/script/lua_vm.cpp index e40164f63..643093d5d 100644 --- a/src/game_api/script/lua_vm.cpp +++ b/src/game_api/script/lua_vm.cpp @@ -968,7 +968,9 @@ end lua["move_grid_entity"] = move_grid_entity; /// Destroy the grid entity, and its item entities, removing them from the grid without dropping particles or gold. /// Will also destroy monsters or items that are standing on a linked activefloor or chain, though excludes MASK.PLAYER to prevent crashes - lua["destroy_grid_entity"] = destroy_grid_entity; + lua["destroy_grid_entity"] = sol::overload( + static_cast(::destroy_grid_entity), + static_cast(::destroy_grid_entity)); /// Make an ENT_TYPE.FLOOR_DOOR_EXIT go to world `w`, level `l`, theme `t` lua["set_door_target"] = set_door_target; /// Short for [set_door_target](#set_door_target). From 99c8cb86cc1e445f91386e7ecaf7558a78865587 Mon Sep 17 00:00:00 2001 From: Estebanfer Date: Sun, 8 Oct 2023 15:32:44 -0300 Subject: [PATCH 3/4] format --- src/game_api/script/lua_vm.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game_api/script/lua_vm.cpp b/src/game_api/script/lua_vm.cpp index 643093d5d..dfc15b824 100644 --- a/src/game_api/script/lua_vm.cpp +++ b/src/game_api/script/lua_vm.cpp @@ -969,8 +969,8 @@ end /// Destroy the grid entity, and its item entities, removing them from the grid without dropping particles or gold. /// Will also destroy monsters or items that are standing on a linked activefloor or chain, though excludes MASK.PLAYER to prevent crashes lua["destroy_grid_entity"] = sol::overload( - static_cast(::destroy_grid_entity), - static_cast(::destroy_grid_entity)); + static_cast(::destroy_grid_entity), + static_cast(::destroy_grid_entity)); /// Make an ENT_TYPE.FLOOR_DOOR_EXIT go to world `w`, level `l`, theme `t` lua["set_door_target"] = set_door_target; /// Short for [set_door_target](#set_door_target). From 2e56a074f60a2b16855d381eef4d6aa75d22ebb0 Mon Sep 17 00:00:00 2001 From: Estebanfer Date: Sun, 8 Oct 2023 16:34:08 -0300 Subject: [PATCH 4/4] rename to destroy_grid --- docs/game_data/spel2.lua | 8 ++++---- docs/src/includes/_globals.md | 24 ++++++++++++------------ src/game_api/rpc.cpp | 4 ++-- src/game_api/rpc.hpp | 4 ++-- src/game_api/script/lua_vm.cpp | 9 +++++---- 5 files changed, 25 insertions(+), 24 deletions(-) diff --git a/docs/game_data/spel2.lua b/docs/game_data/spel2.lua index 7208b1954..9f0409a1e 100644 --- a/docs/game_data/spel2.lua +++ b/docs/game_data/spel2.lua @@ -464,18 +464,18 @@ function move_entity(uid, x, y, vx, vy, layer) end ---@param layer LAYER ---@return nil function move_grid_entity(uid, x, y, layer) end ----Destroy the grid entity, and its item entities, removing them from the grid without dropping particles or gold. +---Destroy the grid entity (by uid or position), and its item entities, removing them from the grid without dropping particles or gold. ---Will also destroy monsters or items that are standing on a linked activefloor or chain, though excludes MASK.PLAYER to prevent crashes ---@param uid integer ---@return nil -function destroy_grid_entity(uid) end ----Destroy the grid entity, and its item entities, removing them from the grid without dropping particles or gold. +function destroy_grid(uid) end +---Destroy the grid entity (by uid or position), and its item entities, removing them from the grid without dropping particles or gold. ---Will also destroy monsters or items that are standing on a linked activefloor or chain, though excludes MASK.PLAYER to prevent crashes ---@param x number ---@param y number ---@param layer LAYER ---@return nil -function destroy_grid_entity(x, y, layer) end +function destroy_grid(x, y, layer) end ---Make an ENT_TYPE.FLOOR_DOOR_EXIT go to world `w`, level `l`, theme `t` ---@param uid integer ---@param w integer diff --git a/docs/src/includes/_globals.md b/docs/src/includes/_globals.md index 7fa5fe884..fccf56f80 100644 --- a/docs/src/includes/_globals.md +++ b/docs/src/includes/_globals.md @@ -459,18 +459,6 @@ Change [ENT_TYPE](#ENT_TYPE)'s spawned when [Waddler](#Waddler) dies, by default Max 255 types. Use empty table as argument to reset to the game default -### destroy_grid_entity - - -> Search script examples for [destroy_grid_entity](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=destroy_grid_entity) - -#### nil destroy_grid_entity(int uid) - -#### nil destroy_grid_entity(float x, float y, [LAYER](#LAYER) layer) - -Destroy the grid entity, and its item entities, removing them from the grid without dropping particles or gold. -Will also destroy monsters or items that are standing on a linked activefloor or chain, though excludes [MASK](#MASK).PLAYER to prevent crashes - ### drop @@ -1216,6 +1204,18 @@ Depending on the image size, this can take a moment, preferably don't create the Create image from file, cropped to the geometry provided. Returns a tuple containing id, width and height. Depending on the image size, this can take a moment, preferably don't create them dynamically, rather create all you need in global scope so it will load them as soon as the game starts +### destroy_grid + + +> Search script examples for [destroy_grid](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=destroy_grid) + +#### nil destroy_grid(int uid) + +#### nil destroy_grid(float x, float y, [LAYER](#LAYER) layer) + +Destroy the grid entity (by uid or position), and its item entities, removing them from the grid without dropping particles or gold. +Will also destroy monsters or items that are standing on a linked activefloor or chain, though excludes [MASK](#MASK).PLAYER to prevent crashes + ### disable_floor_embeds diff --git a/src/game_api/rpc.cpp b/src/game_api/rpc.cpp index eaae42487..2442ce6b3 100644 --- a/src/game_api/rpc.cpp +++ b/src/game_api/rpc.cpp @@ -1673,7 +1673,7 @@ void move_grid_entity(int32_t uid, float x, float y, LAYER layer) } } -void destroy_grid_entity(int32_t uid) +void destroy_grid(int32_t uid) { if (auto entity = get_entity_ptr(uid)) { @@ -1682,7 +1682,7 @@ void destroy_grid_entity(int32_t uid) } } -void destroy_grid_entity(float x, float y, LAYER layer) +void destroy_grid(float x, float y, LAYER layer) { auto state = State::get(); uint8_t actual_layer = enum_to_layer(layer); diff --git a/src/game_api/rpc.hpp b/src/game_api/rpc.hpp index 5013d4cee..4c4c90d04 100644 --- a/src/game_api/rpc.hpp +++ b/src/game_api/rpc.hpp @@ -125,8 +125,8 @@ void change_waddler_drop(std::vector ent_types); void poison_entity(int32_t entity_uid); void modify_ankh_health_gain(uint8_t max_health, uint8_t beat_add_health); void move_grid_entity(int32_t uid, float x, float y, LAYER layer); -void destroy_grid_entity(int32_t uid); -void destroy_grid_entity(float x, float y, LAYER layer); +void destroy_grid(int32_t uid); +void destroy_grid(float x, float y, LAYER layer); void add_item_to_shop(int32_t item_uid, int32_t shop_owner_uid); void change_poison_timer(int16_t frames); void set_adventure_seed(int64_t first, int64_t second); diff --git a/src/game_api/script/lua_vm.cpp b/src/game_api/script/lua_vm.cpp index dfc15b824..73d6725c5 100644 --- a/src/game_api/script/lua_vm.cpp +++ b/src/game_api/script/lua_vm.cpp @@ -966,11 +966,12 @@ end lua["move_entity"] = move_entity_abs; /// Teleport grid entity, the destination should be whole number, this ensures that the collisions will work properly lua["move_grid_entity"] = move_grid_entity; - /// Destroy the grid entity, and its item entities, removing them from the grid without dropping particles or gold. + auto destroy_grid = sol::overload( + static_cast(::destroy_grid), + static_cast(::destroy_grid)); + /// Destroy the grid entity (by uid or position), and its item entities, removing them from the grid without dropping particles or gold. /// Will also destroy monsters or items that are standing on a linked activefloor or chain, though excludes MASK.PLAYER to prevent crashes - lua["destroy_grid_entity"] = sol::overload( - static_cast(::destroy_grid_entity), - static_cast(::destroy_grid_entity)); + lua["destroy_grid"] = destroy_grid; /// Make an ENT_TYPE.FLOOR_DOOR_EXIT go to world `w`, level `l`, theme `t` lua["set_door_target"] = set_door_target; /// Short for [set_door_target](#set_door_target).