diff --git a/docs/examples/RenderInfo.md b/docs/examples/RenderInfo.md new file mode 100644 index 000000000..1b4d40b8a --- /dev/null +++ b/docs/examples/RenderInfo.md @@ -0,0 +1,11 @@ +> For using a custom normal map: + +```lua +set_post_entity_spawn(function(ent) + -- Doesn't really make sense with this texture, you can use your custom normal texture id here + ent.rendering_info:set_normal_map_texture(TEXTURE.DATA_TEXTURES_FLOORSTYLED_GOLD_NORMAL_0) + ent.rendering_info.shader = 30 -- Make sure to set the shader to one that uses normal map +end, SPAWN_TYPE.LEVEL_GEN, MASK.FLOOR, ENT_TYPE.FLOORSTYLED_MINEWOOD) +``` + +> Note: if using set_texture_num, make sure to have used set_second_texture/set_third_texture before, since not doing so can lead to crashes diff --git a/docs/game_data/spel2.lua b/docs/game_data/spel2.lua index 8bbb52b05..bf911e699 100644 --- a/docs/game_data/spel2.lua +++ b/docs/game_data/spel2.lua @@ -2165,7 +2165,14 @@ function PRNG:random(min, max) end ---@field tileh number ---@field facing_left boolean ---@field render_inactive boolean + ---@field texture_num integer ---@field get_entity fun(self): class Entity + ---@field set_normal_map_texture fun(self, texture_id: TEXTURE): boolean @Sets second_texture to the texture specified, then sets third_texture to SHINE_0 and texture_num to 3. You still have to change shader to 30 to render with normal map (same as COG normal maps) + ---@field get_second_texture TEXTURE? + ---@field get_third_texture TEXTURE? + ---@field set_second_texture fun(self, texture_id: TEXTURE): boolean + ---@field set_third_texture fun(self, texture_id: TEXTURE): boolean + ---@field set_texture_num fun(self, texture_id: integer): boolean @Set the number of textures that may be used, need to have them set before for it to work ---@field set_pre_virtual fun(self, entry: RENDER_INFO_OVERRIDE, fun: function): CallbackId @Hooks before the virtual function at index `entry`. ---@field set_post_virtual fun(self, entry: RENDER_INFO_OVERRIDE, fun: function): CallbackId @Hooks after the virtual function at index `entry`. ---@field clear_virtual fun(self, callback_id: CallbackId): nil @Clears the hook given by `callback_id`, alternatively use `clear_callback()` inside the hook. diff --git a/docs/parse_source.py b/docs/parse_source.py index 58ff32320..8f00d989e 100644 --- a/docs/parse_source.py +++ b/docs/parse_source.py @@ -714,7 +714,7 @@ def run_parse(): ) else: m_return_type = re.search( - r"->(\w+){", var[1] + r"->([:<>\w]+){", var[1] ) # Use var[1] instead of cpp because it could be replaced on the sol::property stuff if m_return_type: sig = f"{m_return_type[1]} {var_name}" diff --git a/src/game_api/render_api.cpp b/src/game_api/render_api.cpp index 69ec9b4fd..4fc8134fb 100644 --- a/src/game_api/render_api.cpp +++ b/src/game_api/render_api.cpp @@ -664,6 +664,49 @@ uint32_t RenderInfo::get_aux_id() const return get_entity()->uid; } +bool RenderInfo::set_second_texture(TEXTURE texture_id) +{ + if (auto* new_texture = ::get_texture(texture_id)) + { + second_texture_name = new_texture->name; + return true; + } + return false; +} + +bool RenderInfo::set_third_texture(TEXTURE texture_id) +{ + if (auto* new_texture = ::get_texture(texture_id)) + { + third_texture_name = new_texture->name; + return true; + } + return false; +} + +bool RenderInfo::set_texture_num(uint32_t num) +{ + // Prevent some crashes + if ((num >= 2 && !second_texture_name) || (num >= 3 && !third_texture_name) || num >= 4) + { + return false; + } + texture_num = num; + return true; +} + +bool RenderInfo::set_normal_map_texture(TEXTURE texture_id) +{ + if (set_second_texture(texture_id)) + { + constexpr uint32_t SHINE_TEXTURE = 400; + third_texture_name = ::get_texture(SHINE_TEXTURE)->name; + texture_num = 3; + return true; + } + return false; +} + void TextureRenderingInfo::set_destination(const AABB& bbox) { auto w = bbox.width(); diff --git a/src/game_api/render_api.hpp b/src/game_api/render_api.hpp index b0675b6bf..8cb9152ee 100644 --- a/src/game_api/render_api.hpp +++ b/src/game_api/render_api.hpp @@ -303,16 +303,13 @@ struct RenderInfo Texture* texture; const char** texture_name; - size_t unknown39; - size_t unknown40; - size_t unknown41; + const char** second_texture_name; // Normal map texture on COG entities (shader 30), shine texture on ice entities. May not have a correct value on entities that don't use it + const char** third_texture_name; // Shine texture on COG entities (shader 30). May not have a correct value on entities that don't use it + size_t unknown41; // fourth texture?? seems to be somehow used if changing the texture_num to 4 size_t unknown42; size_t unknown43; size_t unknown44; - bool render_as_non_liquid; // for liquids, forced to false, for non-liquids: sprite goes crazy when moving about - uint8_t unknown47; - uint8_t unknown48; - uint8_t unknown49; + uint32_t texture_num; // liquids use 0, most sprite entities use 1, ice uses 2, COG entities use 3 uint32_t unknown50; size_t entity_offset; // the offset of the associated entity in memory, starting from the memory segment that State resides in bool flip_horizontal; // facing left @@ -339,6 +336,13 @@ struct RenderInfo // for supporting HookableVTable uint32_t get_aux_id() const; + + bool set_second_texture(TEXTURE texture_id); + bool set_third_texture(TEXTURE texture_id); + /// Set the number of textures that may be used, need to have them set before for it to work + bool set_texture_num(uint32_t texture_id); + /// Sets second_texture to the texture specified, then sets third_texture to SHINE_0 and texture_num to 3. You still have to change shader to 30 to render with normal map (same as COG normal maps) + bool set_normal_map_texture(TEXTURE texture_id); }; void init_render_api_hooks(); diff --git a/src/game_api/script/usertypes/entity_lua.cpp b/src/game_api/script/usertypes/entity_lua.cpp index db99f6f9a..717ea407b 100644 --- a/src/game_api/script/usertypes/entity_lua.cpp +++ b/src/game_api/script/usertypes/entity_lua.cpp @@ -137,8 +137,36 @@ void register_usertypes(sol::state& lua) &RenderInfo::flip_horizontal, "render_inactive", &RenderInfo::render_inactive, + "texture_num", + sol::readonly(&RenderInfo::texture_num), "get_entity", - &RenderInfo::get_entity); + &RenderInfo::get_entity, + "set_normal_map_texture", + &RenderInfo::set_normal_map_texture, + "get_second_texture", + [](const RenderInfo& ri) -> std::optional + { + if (!ri.second_texture_name || ri.texture_num < 2) + { + return std::nullopt; + } + return ::get_texture(std::string_view(*ri.second_texture_name)) /**/; + }, + "get_third_texture", + [](const RenderInfo& ri) -> std::optional + { + if (!ri.third_texture_name || ri.texture_num < 3) + { + return std::nullopt; + } + return ::get_texture(std::string_view(*ri.third_texture_name)) /**/; + }, + "set_second_texture", + &RenderInfo::set_second_texture, + "set_third_texture", + &RenderInfo::set_third_texture, + "set_texture_num", + &RenderInfo::set_texture_num); auto get_overlay = [&lua](Entity& entity) {