diff --git a/Source/lua/autocomplete.cpp b/Source/lua/autocomplete.cpp index c369b244e..074efdbc3 100644 --- a/Source/lua/autocomplete.cpp +++ b/Source/lua/autocomplete.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -121,8 +122,36 @@ ValueInfo GetValueInfo(const sol::table &table, std::string_view key, const sol: return info; } +ValueInfo GetValueInfoForUserdata(const sol::userdata &obj, std::string_view key, const sol::object &value, std::optional memberType) +{ + ValueInfo info; + if (value.get_type() == sol::type::userdata) { + info.callable = false; + return info; + } + + if (std::optional signature = GetLuaUserdataSignature(obj, key); signature.has_value()) { + info.signature = *std::move(signature); + } + if (std::optional docstring = GetLuaUserdataDocstring(obj, key); docstring.has_value()) { + info.docstring = *std::move(docstring); + } + if (memberType.has_value()) { + info.callable = *memberType == LuaUserdataMemberType::MemberFunction; + } else { + info.callable = value.get_type() == sol::type::function; + } + return info; +} + +struct UserdataQuery { + const sol::userdata *obj; + bool colonAccess; +}; + void SuggestionsFromTable(const sol::table &table, std::string_view prefix, - size_t maxSuggestions, ankerl::unordered_dense::set &out) + size_t maxSuggestions, ankerl::unordered_dense::set &out, + std::optional userdataQuery = std::nullopt) { for (const auto &[key, value] : table) { if (key.get_type() == sol::type::string) { @@ -136,7 +165,20 @@ void SuggestionsFromTable(const sol::table &table, std::string_view prefix, || keyStr.find("☢") != std::string::npos || keyStr.find("🔩") != std::string::npos) continue; - ValueInfo info = GetValueInfo(table, keyStr, value); + ValueInfo info; + std::optional memberType; + if (userdataQuery.has_value()) { + memberType = GetLuaUserdataMemberType(*userdataQuery->obj, keyStr, value); + const bool requiresColonAccess = memberType.has_value() + ? *memberType == LuaUserdataMemberType::MemberFunction + : value.get_type() == sol::type::function; + if (userdataQuery->colonAccess != requiresColonAccess) { + continue; + } + info = GetValueInfoForUserdata(*userdataQuery->obj, keyStr, value, memberType); + } else { + info = GetValueInfo(table, keyStr, value); + } std::string completionText = keyStr.substr(prefix.size()); LuaAutocompleteSuggestion suggestion { std::move(keyStr), std::move(completionText) }; if (info.callable) { @@ -144,6 +186,9 @@ void SuggestionsFromTable(const sol::table &table, std::string_view prefix, suggestion.cursorAdjust = -1; } if (!info.signature.empty()) { + if (memberType.has_value() && memberType != LuaUserdataMemberType::MemberFunction) { + StrAppend(suggestion.displayText, ": "); + } StrAppend(suggestion.displayText, info.signature); } if (!info.docstring.empty()) { @@ -164,6 +209,15 @@ void SuggestionsFromTable(const sol::table &table, std::string_view prefix, } } +void SuggestionsFromUserdata(UserdataQuery query, std::string_view prefix, + size_t maxSuggestions, ankerl::unordered_dense::set &out) +{ + const auto &meta = query.obj->get>(sol::metatable_key); + if (meta.has_value() && meta->get_type() == sol::type::table) { + SuggestionsFromTable(meta->as(), prefix, maxSuggestions, out, query); + } +} + } // namespace void GetLuaAutocompleteSuggestions(std::string_view text, const sol::environment &lua, @@ -174,8 +228,9 @@ void GetLuaAutocompleteSuggestions(std::string_view text, const sol::environment std::string_view token = GetLastToken(text); const char prevChar = token.data() == text.data() ? '\0' : *(token.data() - 1); if (prevChar == '(' || prevChar == ',') return; - const size_t dotPos = token.rfind('.'); + const size_t dotPos = token.find_last_of(".:"); const std::string_view prefix = token.substr(dotPos + 1); + const char completionChar = dotPos != std::string_view::npos ? token[dotPos] : '\0'; token.remove_suffix(token.size() - (dotPos == std::string_view::npos ? 0 : dotPos)); ankerl::unordered_dense::set suggestions; @@ -192,13 +247,20 @@ void GetLuaAutocompleteSuggestions(std::string_view text, const sol::environment } } else { std::optional obj = lua; - for (const std::string_view part : SplitByChar(token, '.')) { - obj = obj->as().get>(part); - if (!obj.has_value() || obj->get_type() != sol::type::table) - return; + for (const std::string_view partDot : SplitByChar(token, '.')) { + for (const std::string_view part : SplitByChar(partDot, ':')) { + obj = obj->as().get>(part); + if (!obj.has_value() || !(obj->get_type() == sol::type::table || obj->get_type() == sol::type::userdata)) { + return; + } + } } if (obj->get_type() == sol::type::table) { addSuggestions(obj->as()); + } else if (obj->get_type() == sol::type::userdata) { + const sol::userdata &data = obj->as(); + SuggestionsFromUserdata(UserdataQuery { &data, completionChar == ':' }, + prefix, maxSuggestions, suggestions); } } diff --git a/Source/lua/metadoc.hpp b/Source/lua/metadoc.hpp index c3baf04bd..c7461245d 100644 --- a/Source/lua/metadoc.hpp +++ b/Source/lua/metadoc.hpp @@ -1,13 +1,23 @@ #pragma once -#include - +#include +#include +#include #include +#include + #include "utils/str_cat.hpp" namespace devilution { +enum class LuaUserdataMemberType : uint8_t { + ReadonlyProperty, + Property, + MemberFunction, + Constructor, +}; + inline std::string LuaSignatureKey(std::string_view key) { return StrCat("__sig_", key); @@ -18,33 +28,70 @@ inline std::string LuaDocstringKey(std::string_view key) return StrCat("__doc_", key); } +inline std::string LuaUserdataMemberTypeKey(std::string_view key) +{ + return StrCat("__udt_", key); +} + +namespace lua_metadoc_internal { +template +inline void SetUsertypeSignatureAndDocstring(sol::usertype &table, std::string_view key, const char *signature, const char *doc, LuaUserdataMemberType memberType) +{ + table.set(LuaSignatureKey(key), sol::var(signature)); + table.set(LuaDocstringKey(key), sol::var(doc)); + table.set(LuaUserdataMemberTypeKey(key), sol::var(static_cast(memberType))); +} +} // namespace lua_metadoc_internal + template -void SetDocumented(sol::usertype &table, std::string_view key, std::string_view signature, std::string_view doc, T &&value) +void LuaSetDocFn(sol::usertype &table, std::string_view key, const char *signature, const char *doc, T &&value) { - table[key] = std::forward(value); - // TODO: figure out a way to set signature and docstring. + table.set_function(key, std::forward(value)); + lua_metadoc_internal::SetUsertypeSignatureAndDocstring(table, key, signature, doc, LuaUserdataMemberType::MemberFunction); +} + +template +void LuaSetDocReadonlyProperty(sol::usertype &table, std::string_view key, const char *type, const char *doc, G &&getter) +{ + table.set(key, sol::readonly_property(std::forward(getter))); + lua_metadoc_internal::SetUsertypeSignatureAndDocstring(table, key, type, doc, LuaUserdataMemberType::ReadonlyProperty); } template -void SetDocumented(sol::usertype &table, std::string_view key, std::string_view signature, std::string_view doc, G &&getter, S &&setter) +void LuaSetDocProperty(sol::usertype &table, std::string_view key, const char *type, const char *doc, G &&getter, S &&setter) +{ + table.set(key, sol::property(std::forward(getter), std::forward(setter))); + lua_metadoc_internal::SetUsertypeSignatureAndDocstring(table, key, type, doc, LuaUserdataMemberType::Property); +} + +template +void LuaSetDocProperty(sol::usertype &table, std::string_view key, const char *type, const char *doc, F U::*&&value) +{ + table.set(key, value); + lua_metadoc_internal::SetUsertypeSignatureAndDocstring(table, key, type, doc, LuaUserdataMemberType::Property); +} + +template +void LuaSetDoc(sol::table &table, std::string_view key, const char *signature, const char *doc, T &&value) { - table[key] = sol::property(std::forward(getter), std::forward(setter)); - // TODO: figure out a way to set signature and docstring. + table.set(key, std::forward(value)); + table.set(LuaSignatureKey(key), signature); + table.set(LuaDocstringKey(key), doc); } template -void SetDocumented(sol::table &table, std::string_view key, std::string_view signature, std::string_view doc, T &&value) +void LuaSetDocFn(sol::table &table, std::string_view key, const char *signature, const char *doc, T &&value) { - table[key] = std::forward(value); - table[LuaSignatureKey(key)] = signature; - table[LuaDocstringKey(key)] = doc; + table.set_function(key, std::forward(value)); + table.set(LuaSignatureKey(key), signature); + table.set(LuaDocstringKey(key), doc); } template -void SetWithSignature(sol::table &table, std::string_view key, std::string_view signature, T &&value) +void LuaSetDocFn(sol::table &table, std::string_view key, std::string_view signature, T &&value) { - table[key] = std::forward(value); - table[LuaSignatureKey(key)] = signature; + table.set_function(key, std::forward(value)); + table.set(LuaSignatureKey(key), signature); } inline std::optional GetSignature(const sol::table &table, std::string_view key) @@ -57,4 +104,25 @@ inline std::optional GetDocstring(const sol::table &table, std::str return table.get>(LuaDocstringKey(key)); } +inline std::optional GetLuaUserdataSignature(const sol::userdata &obj, std::string_view key) +{ + return obj.get>(LuaSignatureKey(key)); +} + +inline std::optional GetLuaUserdataDocstring(const sol::userdata &obj, std::string_view key) +{ + return obj.get>(LuaDocstringKey(key)); +} + +inline std::optional GetLuaUserdataMemberType(const sol::userdata &obj, std::string_view key, const sol::object &value) +{ + std::optional result = obj.get>(LuaUserdataMemberTypeKey(key)); + if (!result.has_value()) { + if (value.get_type() == sol::type::userdata) return LuaUserdataMemberType::Property; + if (value.get_type() == sol::type::function && key == "new") return LuaUserdataMemberType::Constructor; + return std::nullopt; + } + return static_cast(*result); +} + } // namespace devilution diff --git a/Source/lua/modules/audio.cpp b/Source/lua/modules/audio.cpp index 8e486fcd5..f8ab0a7e2 100644 --- a/Source/lua/modules/audio.cpp +++ b/Source/lua/modules/audio.cpp @@ -19,10 +19,10 @@ bool IsValidSfx(int16_t psfx) sol::table LuaAudioModule(sol::state_view &lua) { sol::table table = lua.create_table(); - SetWithSignature(table, + LuaSetDocFn(table, "playSfx", "(id: number)", [](int16_t psfx) { if (IsValidSfx(psfx)) PlaySFX(static_cast(psfx)); }); - SetWithSignature(table, + LuaSetDocFn(table, "playSfxLoc", "(id: number, x: number, y: number)", [](int16_t psfx, int x, int y) { if (IsValidSfx(psfx)) PlaySfxLoc(static_cast(psfx), { x, y }); }); return table; diff --git a/Source/lua/modules/dev.cpp b/Source/lua/modules/dev.cpp index e3de74633..2778cdf1b 100644 --- a/Source/lua/modules/dev.cpp +++ b/Source/lua/modules/dev.cpp @@ -18,14 +18,14 @@ namespace devilution { sol::table LuaDevModule(sol::state_view &lua) { sol::table table = lua.create_table(); - SetDocumented(table, "display", "", "Debugging HUD and rendering commands.", LuaDevDisplayModule(lua)); - SetDocumented(table, "items", "", "Item-related commands.", LuaDevItemsModule(lua)); - SetDocumented(table, "level", "", "Level-related commands.", LuaDevLevelModule(lua)); - SetDocumented(table, "monsters", "", "Monster-related commands.", LuaDevMonstersModule(lua)); - SetDocumented(table, "player", "", "Player-related commands.", LuaDevPlayerModule(lua)); - SetDocumented(table, "quests", "", "Quest-related commands.", LuaDevQuestsModule(lua)); - SetDocumented(table, "search", "", "Search the map for monsters / items / objects.", LuaDevSearchModule(lua)); - SetDocumented(table, "towners", "", "Town NPC commands.", LuaDevTownersModule(lua)); + LuaSetDoc(table, "display", "", "Debugging HUD and rendering commands.", LuaDevDisplayModule(lua)); + LuaSetDoc(table, "items", "", "Item-related commands.", LuaDevItemsModule(lua)); + LuaSetDoc(table, "level", "", "Level-related commands.", LuaDevLevelModule(lua)); + LuaSetDoc(table, "monsters", "", "Monster-related commands.", LuaDevMonstersModule(lua)); + LuaSetDoc(table, "player", "", "Player-related commands.", LuaDevPlayerModule(lua)); + LuaSetDoc(table, "quests", "", "Quest-related commands.", LuaDevQuestsModule(lua)); + LuaSetDoc(table, "search", "", "Search the map for monsters / items / objects.", LuaDevSearchModule(lua)); + LuaSetDoc(table, "towners", "", "Town NPC commands.", LuaDevTownersModule(lua)); return table; } diff --git a/Source/lua/modules/dev/display.cpp b/Source/lua/modules/dev/display.cpp index 2e4f44f4a..c00f9965a 100644 --- a/Source/lua/modules/dev/display.cpp +++ b/Source/lua/modules/dev/display.cpp @@ -121,13 +121,13 @@ std::string DebugCmdToggleFPS(std::optional on) sol::table LuaDevDisplayModule(sol::state_view &lua) { sol::table table = lua.create_table(); - SetDocumented(table, "fps", "(name: string = nil)", "Toggle FPS display.", &DebugCmdToggleFPS); - SetDocumented(table, "fullbright", "(on: boolean = nil)", "Toggle light shading.", &DebugCmdFullbright); - SetDocumented(table, "grid", "(on: boolean = nil)", "Toggle showing the grid.", &DebugCmdShowGrid); - SetDocumented(table, "path", "(on: boolean = nil)", "Toggle path debug rendering.", &DebugCmdPath); - SetDocumented(table, "scrollView", "(on: boolean = nil)", "Toggle view scrolling via Shift+Mouse.", &DebugCmdScrollView); - SetDocumented(table, "tileData", "(name: string = nil)", "Toggle showing tile data.", &DebugCmdShowTileData); - SetDocumented(table, "vision", "(on: boolean = nil)", "Toggle vision debug rendering.", &DebugCmdVision); + LuaSetDocFn(table, "fps", "(name: string = nil)", "Toggle FPS display.", &DebugCmdToggleFPS); + LuaSetDocFn(table, "fullbright", "(on: boolean = nil)", "Toggle light shading.", &DebugCmdFullbright); + LuaSetDocFn(table, "grid", "(on: boolean = nil)", "Toggle showing the grid.", &DebugCmdShowGrid); + LuaSetDocFn(table, "path", "(on: boolean = nil)", "Toggle path debug rendering.", &DebugCmdPath); + LuaSetDocFn(table, "scrollView", "(on: boolean = nil)", "Toggle view scrolling via Shift+Mouse.", &DebugCmdScrollView); + LuaSetDocFn(table, "tileData", "(name: string = nil)", "Toggle showing tile data.", &DebugCmdShowTileData); + LuaSetDocFn(table, "vision", "(on: boolean = nil)", "Toggle vision debug rendering.", &DebugCmdVision); return table; } diff --git a/Source/lua/modules/dev/items.cpp b/Source/lua/modules/dev/items.cpp index da989c2cc..b5bc0e03d 100644 --- a/Source/lua/modules/dev/items.cpp +++ b/Source/lua/modules/dev/items.cpp @@ -194,9 +194,9 @@ std::string DebugSpawnUniqueItem(std::string itemName) sol::table LuaDevItemsModule(sol::state_view &lua) { sol::table table = lua.create_table(); - SetDocumented(table, "info", "()", "Show info of currently selected item.", &DebugCmdItemInfo); - SetDocumented(table, "spawn", "(name: string)", "Attempt to generate an item.", &DebugSpawnItem); - SetDocumented(table, "spawnUnique", "(name: string)", "Attempt to generate a unique item.", &DebugSpawnUniqueItem); + LuaSetDocFn(table, "info", "()", "Show info of currently selected item.", &DebugCmdItemInfo); + LuaSetDocFn(table, "spawn", "(name: string)", "Attempt to generate an item.", &DebugSpawnItem); + LuaSetDocFn(table, "spawnUnique", "(name: string)", "Attempt to generate a unique item.", &DebugSpawnUniqueItem); return table; } diff --git a/Source/lua/modules/dev/level.cpp b/Source/lua/modules/dev/level.cpp index 0a102a3a1..e75a34b2a 100644 --- a/Source/lua/modules/dev/level.cpp +++ b/Source/lua/modules/dev/level.cpp @@ -122,11 +122,11 @@ std::string DebugCmdLevelSeed(std::optional level) sol::table LuaDevLevelModule(sol::state_view &lua) { sol::table table = lua.create_table(); - SetDocumented(table, "exportDun", "()", "Save the current level as a dun-file.", &ExportDun); - SetDocumented(table, "map", "", "Automap-related commands.", LuaDevLevelMapModule(lua)); - SetDocumented(table, "reset", "(n: number, seed: number = nil)", "Resets specified level.", &DebugCmdResetLevel); - SetDocumented(table, "seed", "(level: number = nil)", "Get the seed of the current or given level.", &DebugCmdLevelSeed); - SetDocumented(table, "warp", "", "Warp to a level or a custom map.", LuaDevLevelWarpModule(lua)); + LuaSetDocFn(table, "exportDun", "()", "Save the current level as a dun-file.", &ExportDun); + LuaSetDocFn(table, "map", "", "Automap-related commands.", LuaDevLevelMapModule(lua)); + LuaSetDocFn(table, "reset", "(n: number, seed: number = nil)", "Resets specified level.", &DebugCmdResetLevel); + LuaSetDocFn(table, "seed", "(level: number = nil)", "Get the seed of the current or given level.", &DebugCmdLevelSeed); + LuaSetDocFn(table, "warp", "", "Warp to a level or a custom map.", LuaDevLevelWarpModule(lua)); return table; } diff --git a/Source/lua/modules/dev/level/map.cpp b/Source/lua/modules/dev/level/map.cpp index b1067fcad..f63b49a08 100644 --- a/Source/lua/modules/dev/level/map.cpp +++ b/Source/lua/modules/dev/level/map.cpp @@ -32,8 +32,8 @@ std::string DebugCmdMapHide() sol::table LuaDevLevelMapModule(sol::state_view &lua) { sol::table table = lua.create_table(); - SetDocumented(table, "hide", "()", "Hide the map.", &DebugCmdMapHide); - SetDocumented(table, "reveal", "()", "Reveal the map.", &DebugCmdMapReveal); + LuaSetDocFn(table, "hide", "()", "Hide the map.", &DebugCmdMapHide); + LuaSetDocFn(table, "reveal", "()", "Reveal the map.", &DebugCmdMapReveal); return table; } diff --git a/Source/lua/modules/dev/level/warp.cpp b/Source/lua/modules/dev/level/warp.cpp index 655a36289..0582db6cc 100644 --- a/Source/lua/modules/dev/level/warp.cpp +++ b/Source/lua/modules/dev/level/warp.cpp @@ -72,9 +72,9 @@ std::string DebugCmdWarpToCustomMap(std::string_view path, int dunType, int x, i sol::table LuaDevLevelWarpModule(sol::state_view &lua) { sol::table table = lua.create_table(); - SetDocumented(table, "dungeon", "(n: number)", "Go to dungeon level (0 for town).", &DebugCmdWarpToDungeonLevel); - SetDocumented(table, "map", "(path: string, dunType: number, x: number, y: number)", "Go to custom {path}.dun level", &DebugCmdWarpToCustomMap); - SetDocumented(table, "quest", "(n: number)", "Go to quest level.", &DebugCmdWarpToQuestLevel); + LuaSetDocFn(table, "dungeon", "(n: number)", "Go to dungeon level (0 for town).", &DebugCmdWarpToDungeonLevel); + LuaSetDocFn(table, "map", "(path: string, dunType: number, x: number, y: number)", "Go to custom {path}.dun level", &DebugCmdWarpToCustomMap); + LuaSetDocFn(table, "quest", "(n: number)", "Go to quest level.", &DebugCmdWarpToQuestLevel); return table; } diff --git a/Source/lua/modules/dev/monsters.cpp b/Source/lua/modules/dev/monsters.cpp index d9ee171fa..bb5a64a20 100644 --- a/Source/lua/modules/dev/monsters.cpp +++ b/Source/lua/modules/dev/monsters.cpp @@ -172,8 +172,8 @@ std::string DebugCmdSpawnMonster(std::string name, std::optional count sol::table LuaDevMonstersModule(sol::state_view &lua) { sol::table table = lua.create_table(); - SetDocumented(table, "spawn", "(name: string, count: number = 1)", "Spawn monster(s)", &DebugCmdSpawnMonster); - SetDocumented(table, "spawnUnique", "(name: string, count: number = 1)", "Spawn unique monster(s)", &DebugCmdSpawnUniqueMonster); + LuaSetDocFn(table, "spawn", "(name: string, count: number = 1)", "Spawn monster(s)", &DebugCmdSpawnMonster); + LuaSetDocFn(table, "spawnUnique", "(name: string, count: number = 1)", "Spawn unique monster(s)", &DebugCmdSpawnUniqueMonster); return table; } diff --git a/Source/lua/modules/dev/player.cpp b/Source/lua/modules/dev/player.cpp index 8bea5d50f..c019f2b01 100644 --- a/Source/lua/modules/dev/player.cpp +++ b/Source/lua/modules/dev/player.cpp @@ -81,11 +81,11 @@ std::string DebugSetPlayerTrn(std::string_view path) sol::table LuaDevPlayerTrnModule(sol::state_view &lua) { sol::table table = lua.create_table(); - SetDocumented(table, "mon", "(name: string)", "Set player TRN to monsters\\${name}.trn", + LuaSetDocFn(table, "mon", "(name: string)", "Set player TRN to monsters\\${name}.trn", [](std::string_view name) { return DebugSetPlayerTrn(StrCat("monsters\\", name, ".trn")); }); - SetDocumented(table, "plr", "(name: string)", "Set player TRN to plrgfx\\${name}.trn", + LuaSetDocFn(table, "plr", "(name: string)", "Set player TRN to plrgfx\\${name}.trn", [](std::string_view name) { return DebugSetPlayerTrn(StrCat("plrgfx\\", name, ".trn")); }); - SetDocumented(table, "clear", "()", "Unset player TRN", + LuaSetDocFn(table, "clear", "()", "Unset player TRN", []() { return DebugSetPlayerTrn(""); }); return table; } @@ -101,14 +101,14 @@ std::string DebugCmdInvisible(std::optional on) sol::table LuaDevPlayerModule(sol::state_view &lua) { sol::table table = lua.create_table(); - SetDocumented(table, "arrow", "(effect: 'normal'|'fire'|'lightning'|'explosion')", "Set arrow effect.", &DebugCmdArrow); - SetDocumented(table, "god", "(on: boolean = nil)", "Toggle god mode.", &DebugCmdGodMode); - SetDocumented(table, "gold", "", "Adjust player gold.", LuaDevPlayerGoldModule(lua)); - SetDocumented(table, "info", "(id: number = 0)", "Show player info.", &DebugCmdPlayerInfo); - SetDocumented(table, "spells", "", "Adjust player spells.", LuaDevPlayerSpellsModule(lua)); - SetDocumented(table, "stats", "", "Adjust player stats (Strength, HP, etc).", LuaDevPlayerStatsModule(lua)); - SetDocumented(table, "trn", "", "Set player TRN to '${name}.trn'", LuaDevPlayerTrnModule(lua)); - SetDocumented(table, "invisible", "(on: boolean = nil)", "Toggle invisibility.", &DebugCmdInvisible); + LuaSetDocFn(table, "arrow", "(effect: 'normal'|'fire'|'lightning'|'explosion')", "Set arrow effect.", &DebugCmdArrow); + LuaSetDocFn(table, "god", "(on: boolean = nil)", "Toggle god mode.", &DebugCmdGodMode); + LuaSetDoc(table, "gold", "", "Adjust player gold.", LuaDevPlayerGoldModule(lua)); + LuaSetDocFn(table, "info", "(id: number = 0)", "Show player info.", &DebugCmdPlayerInfo); + LuaSetDoc(table, "spells", "", "Adjust player spells.", LuaDevPlayerSpellsModule(lua)); + LuaSetDoc(table, "stats", "", "Adjust player stats (Strength, HP, etc).", LuaDevPlayerStatsModule(lua)); + LuaSetDoc(table, "trn", "", "Set player TRN to '${name}.trn'", LuaDevPlayerTrnModule(lua)); + LuaSetDocFn(table, "invisible", "(on: boolean = nil)", "Toggle invisibility.", &DebugCmdInvisible); return table; } diff --git a/Source/lua/modules/dev/player/gold.cpp b/Source/lua/modules/dev/player/gold.cpp index 679f2a047..c6a39e099 100644 --- a/Source/lua/modules/dev/player/gold.cpp +++ b/Source/lua/modules/dev/player/gold.cpp @@ -92,8 +92,8 @@ std::string DebugCmdTakeGoldCheat(std::optional amount) sol::table LuaDevPlayerGoldModule(sol::state_view &lua) { sol::table table = lua.create_table(); - SetDocumented(table, "give", "(amount: number = MAX)", "Gives the player gold.", &DebugCmdGiveGoldCheat); - SetDocumented(table, "take", "(amount: number = MAX)", "Takes the player's gold away.", &DebugCmdTakeGoldCheat); + LuaSetDocFn(table, "give", "(amount: number = MAX)", "Gives the player gold.", &DebugCmdGiveGoldCheat); + LuaSetDocFn(table, "take", "(amount: number = MAX)", "Takes the player's gold away.", &DebugCmdTakeGoldCheat); return table; } diff --git a/Source/lua/modules/dev/player/spells.cpp b/Source/lua/modules/dev/player/spells.cpp index c46700a88..ab7be2e4e 100644 --- a/Source/lua/modules/dev/player/spells.cpp +++ b/Source/lua/modules/dev/player/spells.cpp @@ -31,7 +31,7 @@ std::string DebugCmdSetSpellsLevel(uint8_t level) sol::table LuaDevPlayerSpellsModule(sol::state_view &lua) { sol::table table = lua.create_table(); - SetDocumented(table, "setLevel", "(level: number)", "Set spell level for all spells.", &DebugCmdSetSpellsLevel); + LuaSetDocFn(table, "setLevel", "(level: number)", "Set spell level for all spells.", &DebugCmdSetSpellsLevel); return table; } diff --git a/Source/lua/modules/dev/player/stats.cpp b/Source/lua/modules/dev/player/stats.cpp index daea36b8b..0451e520b 100644 --- a/Source/lua/modules/dev/player/stats.cpp +++ b/Source/lua/modules/dev/player/stats.cpp @@ -87,12 +87,12 @@ std::string DebugCmdChangeMana(int change) sol::table LuaDevPlayerStatsModule(sol::state_view &lua) { sol::table table = lua.create_table(); - SetDocumented(table, "adjustHealth", "(amount: number)", "Adjust HP (amount can be negative)", &DebugCmdChangeHealth); - SetDocumented(table, "adjustMana", "(amount: number)", "Adjust mana (amount can be negative)", &DebugCmdChangeMana); - SetDocumented(table, "levelUp", "(amount: number = 1)", "Level the player up.", &DebugCmdLevelUp); - SetDocumented(table, "rejuvenate", "()", "Refill health", &DebugCmdRefillHealthMana); - SetDocumented(table, "setAttrToMax", "()", "Set Str, Mag, Dex, and Vit to maximum.", &DebugCmdMaxStats); - SetDocumented(table, "setAttrToMin", "()", "Set Str, Mag, Dex, and Vit to minimum.", &DebugCmdMinStats); + LuaSetDocFn(table, "adjustHealth", "(amount: number)", "Adjust HP (amount can be negative)", &DebugCmdChangeHealth); + LuaSetDocFn(table, "adjustMana", "(amount: number)", "Adjust mana (amount can be negative)", &DebugCmdChangeMana); + LuaSetDocFn(table, "levelUp", "(amount: number = 1)", "Level the player up.", &DebugCmdLevelUp); + LuaSetDocFn(table, "rejuvenate", "()", "Refill health", &DebugCmdRefillHealthMana); + LuaSetDocFn(table, "setAttrToMax", "()", "Set Str, Mag, Dex, and Vit to maximum.", &DebugCmdMaxStats); + LuaSetDocFn(table, "setAttrToMin", "()", "Set Str, Mag, Dex, and Vit to minimum.", &DebugCmdMinStats); return table; } diff --git a/Source/lua/modules/dev/quests.cpp b/Source/lua/modules/dev/quests.cpp index b4b9148c9..4acef02d7 100644 --- a/Source/lua/modules/dev/quests.cpp +++ b/Source/lua/modules/dev/quests.cpp @@ -63,10 +63,10 @@ std::string DebugCmdQuestsInfo() sol::table LuaDevQuestsModule(sol::state_view &lua) { sol::table table = lua.create_table(); - SetDocumented(table, "activate", "(id: number)", "Activate the given quest.", &DebugCmdEnableQuest); - SetDocumented(table, "activateAll", "()", "Activate all available quests.", &DebugCmdEnableQuests); - SetDocumented(table, "all", "()", "Information on all available quest.", &DebugCmdQuestsInfo); - SetDocumented(table, "info", "(id: number)", "Information on the given quest.", &DebugCmdQuestInfo); + LuaSetDocFn(table, "activate", "(id: number)", "Activate the given quest.", &DebugCmdEnableQuest); + LuaSetDocFn(table, "activateAll", "()", "Activate all available quests.", &DebugCmdEnableQuests); + LuaSetDocFn(table, "all", "()", "Information on all available quest.", &DebugCmdQuestsInfo); + LuaSetDocFn(table, "info", "(id: number)", "Information on the given quest.", &DebugCmdQuestInfo); return table; } diff --git a/Source/lua/modules/dev/search.cpp b/Source/lua/modules/dev/search.cpp index 5718af215..851e2991d 100644 --- a/Source/lua/modules/dev/search.cpp +++ b/Source/lua/modules/dev/search.cpp @@ -45,10 +45,10 @@ std::string DebugCmdClearSearch() sol::table LuaDevSearchModule(sol::state_view &lua) { sol::table table = lua.create_table(); - SetDocumented(table, "clear", "()", "Clear search results from the map.", &DebugCmdClearSearch); - SetDocumented(table, "item", "(name: string)", "Search the map for an item.", &DebugCmdSearchItem); - SetDocumented(table, "monster", "(name: string)", "Search the map for a monster.", &DebugCmdSearchMonster); - SetDocumented(table, "object", "(name: string)", "Search the map for an object.", &DebugCmdSearchObject); + LuaSetDocFn(table, "clear", "()", "Clear search results from the map.", &DebugCmdClearSearch); + LuaSetDocFn(table, "item", "(name: string)", "Search the map for an item.", &DebugCmdSearchItem); + LuaSetDocFn(table, "monster", "(name: string)", "Search the map for a monster.", &DebugCmdSearchMonster); + LuaSetDocFn(table, "object", "(name: string)", "Search the map for an object.", &DebugCmdSearchObject); return table; } diff --git a/Source/lua/modules/dev/towners.cpp b/Source/lua/modules/dev/towners.cpp index 6895a9efb..f473262d1 100644 --- a/Source/lua/modules/dev/towners.cpp +++ b/Source/lua/modules/dev/towners.cpp @@ -99,8 +99,8 @@ std::string DebugCmdTalkToTowner(std::string_view name) sol::table LuaDevTownersModule(sol::state_view &lua) { sol::table table = lua.create_table(); - SetDocumented(table, "talk", "(name: string)", "Talk to towner.", &DebugCmdTalkToTowner); - SetDocumented(table, "visit", "(name: string)", "Teleport to towner.", &DebugCmdVisitTowner); + LuaSetDocFn(table, "talk", "(name: string)", "Talk to towner.", &DebugCmdTalkToTowner); + LuaSetDocFn(table, "visit", "(name: string)", "Teleport to towner.", &DebugCmdVisitTowner); return table; } diff --git a/Source/lua/modules/hellfire.cpp b/Source/lua/modules/hellfire.cpp index 20c64f5db..0b0452b0b 100644 --- a/Source/lua/modules/hellfire.cpp +++ b/Source/lua/modules/hellfire.cpp @@ -10,8 +10,8 @@ namespace devilution { sol::table LuaHellfireModule(sol::state_view &lua) { sol::table table = lua.create_table(); - SetWithSignature(table, "loadData", "()", []() { LoadHellfireArchives(); }); - SetWithSignature(table, "enable", "()", []() { gbIsHellfire = true; }); + LuaSetDocFn(table, "loadData", "()", LoadHellfireArchives); + LuaSetDocFn(table, "enable", "()", []() { gbIsHellfire = true; }); return table; } diff --git a/Source/lua/modules/i18n.cpp b/Source/lua/modules/i18n.cpp index c7d907578..9891e2091 100644 --- a/Source/lua/modules/i18n.cpp +++ b/Source/lua/modules/i18n.cpp @@ -13,17 +13,17 @@ namespace devilution { sol::table LuaI18nModule(sol::state_view &lua) { sol::table table = lua.create_table(); - SetDocumented(table, "language_code", "()", + LuaSetDocFn(table, "language_code", "()", "Returns the current language code", GetLanguageCode); - SetDocumented(table, "translate", "(text: string)", + LuaSetDocFn(table, "translate", "(text: string)", "Translates the given string", [](const char *key) { return LanguageTranslate(key); }); - SetDocumented(table, "plural_translate", "(singular: string, plural: string, count: integer)", + LuaSetDocFn(table, "plural_translate", "(singular: string, plural: string, count: integer)", "Returns a singular or plural translation for the given keys and count", [](const char *singular, std::string_view plural, int count) { return fmt::format(fmt::runtime(LanguagePluralTranslate(singular, plural, count)), count); }); - SetDocumented(table, "particular_translate", "(context: string, text: string)", + LuaSetDocFn(table, "particular_translate", "(context: string, text: string)", "Returns the translation for the given context identifier and key.", LanguageParticularTranslate); - SetDocumented(table, "is_small_font_tall", "()", + LuaSetDocFn(table, "is_small_font_tall", "()", "Whether the language's small font is tall (16px)", IsSmallFontTall); return table; } diff --git a/Source/lua/modules/items.cpp b/Source/lua/modules/items.cpp index 181838c16..a2e34acb4 100644 --- a/Source/lua/modules/items.cpp +++ b/Source/lua/modules/items.cpp @@ -1,12 +1,13 @@ #include "lua/modules/items.hpp" -#include +#include #include #include "items.h" #include "lua/metadoc.hpp" #include "player.h" +#include "utils/utf8.hpp" namespace devilution { @@ -18,98 +19,94 @@ void InitItemUserType(sol::state_view &lua) sol::usertype itemType = lua.new_usertype(sol::no_constructor); // Member variables - SetDocumented(itemType, "seed", "number", "Randomly generated identifier", [](const Item &i) { return i._iSeed; }, [](Item &i, unsigned int val) { i._iSeed = val; }); - SetDocumented(itemType, "createInfo", "number", "Creation flags", [](const Item &i) { return i._iCreateInfo; }, [](Item &i, unsigned int val) { i._iCreateInfo = val; }); - SetDocumented(itemType, "type", "ItemType", "Item type", [](const Item &i) { return i._itype; }, [](Item &i, int val) { i._itype = static_cast(val); }); - SetDocumented(itemType, "animFlag", "boolean", "Animation flag", [](const Item &i) { return i._iAnimFlag; }, [](Item &i, bool val) { i._iAnimFlag = val; }); - SetDocumented(itemType, "position", "Point", "Item world position", [](const Item &i) { return i.position; }, [](Item &i, Point val) { i.position = val; }); + LuaSetDocProperty(itemType, "seed", "number", "Randomly generated identifier", &Item::_iSeed); + LuaSetDocProperty(itemType, "createInfo", "number", "Creation flags", &Item::_iCreateInfo); + LuaSetDocProperty(itemType, "type", "ItemType", "Item type", &Item::_itype); + LuaSetDocProperty(itemType, "animFlag", "boolean", "Animation flag", &Item::_iAnimFlag); + LuaSetDocProperty(itemType, "position", "Point", "Item world position", &Item::position); // TODO: Add AnimationInfo usertype - // SetDocumented(itemType, "animInfo", "AnimationInfo", "Animation information", [](const Item &i) { return i.AnimInfo; }, [](Item &i, AnimationInfo val) { i.AnimInfo = val; }); - SetDocumented(itemType, "delFlag", "boolean", "Deletion flag", [](const Item &i) { return i._iDelFlag; }, [](Item &i, bool val) { i._iDelFlag = val; }); - SetDocumented(itemType, "selectionRegion", "number", "Selection region", [](const Item &i) { return static_cast(i.selectionRegion); }, [](Item &i, int val) { i.selectionRegion = static_cast(val); }); - SetDocumented(itemType, "postDraw", "boolean", "Post-draw flag", [](const Item &i) { return i._iPostDraw; }, [](Item &i, bool val) { i._iPostDraw = val; }); - SetDocumented(itemType, "identified", "boolean", "Identified flag", [](const Item &i) { return i._iIdentified; }, [](Item &i, bool val) { i._iIdentified = val; }); - SetDocumented(itemType, "magical", "number", "Item quality", [](const Item &i) { return static_cast(i._iMagical); }, [](Item &i, int val) { i._iMagical = static_cast(val); }); - SetDocumented(itemType, "name", "string", "Item name", [](const Item &i) { return std::string(i._iName); }, [](Item &i, const std::string &val) { - std::strncpy(i._iName, val.c_str(), sizeof(i._iName)); - i._iName[sizeof(i._iName) - 1] = '\0'; }); - SetDocumented(itemType, "iName", "string", "Identified item name", [](const Item &i) { return std::string(i._iIName); }, [](Item &i, const std::string &val) { - std::strncpy(i._iIName, val.c_str(), sizeof(i._iIName)); - i._iIName[sizeof(i._iIName) - 1] = '\0'; }); - SetDocumented(itemType, "loc", "ItemEquipType", "Equipment location", [](const Item &i) { return i._iLoc; }, [](Item &i, int val) { i._iLoc = static_cast(val); }); - SetDocumented(itemType, "class", "ItemClass", "Item class", [](const Item &i) { return i._iClass; }, [](Item &i, int val) { i._iClass = static_cast(val); }); - SetDocumented(itemType, "curs", "number", "Cursor index", [](const Item &i) { return i._iCurs; }, [](Item &i, int val) { i._iCurs = val; }); - SetDocumented(itemType, "value", "number", "Item value", [](const Item &i) { return i._ivalue; }, [](Item &i, int val) { i._ivalue = val; }); - SetDocumented(itemType, "ivalue", "number", "Identified item value", [](const Item &i) { return i._iIvalue; }, [](Item &i, int val) { i._iIvalue = val; }); - SetDocumented(itemType, "minDam", "number", "Minimum damage", [](const Item &i) { return i._iMinDam; }, [](Item &i, int val) { i._iMinDam = val; }); - SetDocumented(itemType, "maxDam", "number", "Maximum damage", [](const Item &i) { return i._iMaxDam; }, [](Item &i, int val) { i._iMaxDam = val; }); - SetDocumented(itemType, "AC", "number", "Armor class", [](const Item &i) { return i._iAC; }, [](Item &i, int val) { i._iAC = val; }); - SetDocumented(itemType, "flags", "ItemSpecialEffect", "Special effect flags", [](const Item &i) { return static_cast(i._iFlags); }, [](Item &i, int val) { i._iFlags = static_cast(val); }); - SetDocumented(itemType, "miscId", "ItemMiscID", "Miscellaneous ID", [](const Item &i) { return i._iMiscId; }, [](Item &i, int val) { i._iMiscId = static_cast(val); }); - SetDocumented(itemType, "spell", "SpellID", "Spell", [](const Item &i) { return i._iSpell; }, [](Item &i, int val) { i._iSpell = static_cast(val); }); - SetDocumented(itemType, "IDidx", "ItemIndex", "Base item index", [](const Item &i) { return i.IDidx; }, [](Item &i, int val) { i.IDidx = static_cast<_item_indexes>(val); }); - SetDocumented(itemType, "charges", "number", "Number of charges", [](const Item &i) { return i._iCharges; }, [](Item &i, int val) { i._iCharges = val; }); - SetDocumented(itemType, "maxCharges", "number", "Maximum charges", [](const Item &i) { return i._iMaxCharges; }, [](Item &i, int val) { i._iMaxCharges = val; }); - SetDocumented(itemType, "durability", "number", "Durability", [](const Item &i) { return i._iDurability; }, [](Item &i, int val) { i._iDurability = val; }); - SetDocumented(itemType, "maxDur", "number", "Maximum durability", [](const Item &i) { return i._iMaxDur; }, [](Item &i, int val) { i._iMaxDur = val; }); - SetDocumented(itemType, "PLDam", "number", "Damage % bonus", [](const Item &i) { return i._iPLDam; }, [](Item &i, int val) { i._iPLDam = val; }); - SetDocumented(itemType, "PLToHit", "number", "Chance to hit bonus", [](const Item &i) { return i._iPLToHit; }, [](Item &i, int val) { i._iPLToHit = val; }); - SetDocumented(itemType, "PLAC", "number", "Armor class % bonus", [](const Item &i) { return i._iPLAC; }, [](Item &i, int val) { i._iPLAC = val; }); - SetDocumented(itemType, "PLStr", "number", "Strength bonus", [](const Item &i) { return i._iPLStr; }, [](Item &i, int val) { i._iPLStr = val; }); - SetDocumented(itemType, "PLMag", "number", "Magic bonus", [](const Item &i) { return i._iPLMag; }, [](Item &i, int val) { i._iPLMag = val; }); - SetDocumented(itemType, "PLDex", "number", "Dexterity bonus", [](const Item &i) { return i._iPLDex; }, [](Item &i, int val) { i._iPLDex = val; }); - SetDocumented(itemType, "PLVit", "number", "Vitality bonus", [](const Item &i) { return i._iPLVit; }, [](Item &i, int val) { i._iPLVit = val; }); - SetDocumented(itemType, "PLFR", "number", "Fire resistance bonus", [](const Item &i) { return i._iPLFR; }, [](Item &i, int val) { i._iPLFR = val; }); - SetDocumented(itemType, "PLLR", "number", "Lightning resistance bonus", [](const Item &i) { return i._iPLLR; }, [](Item &i, int val) { i._iPLLR = val; }); - SetDocumented(itemType, "PLMR", "number", "Magic resistance bonus", [](const Item &i) { return i._iPLMR; }, [](Item &i, int val) { i._iPLMR = val; }); - SetDocumented(itemType, "PLMana", "number", "Mana bonus", [](const Item &i) { return i._iPLMana; }, [](Item &i, int val) { i._iPLMana = val; }); - SetDocumented(itemType, "PLHP", "number", "Life bonus", [](const Item &i) { return i._iPLHP; }, [](Item &i, int val) { i._iPLHP = val; }); - SetDocumented(itemType, "PLDamMod", "number", "Damage modifier bonus", [](const Item &i) { return i._iPLDamMod; }, [](Item &i, int val) { i._iPLDamMod = val; }); - SetDocumented(itemType, "PLGetHit", "number", "Damage from enemies bonus", [](const Item &i) { return i._iPLGetHit; }, [](Item &i, int val) { i._iPLGetHit = val; }); - SetDocumented(itemType, "PLLight", "number", "Light bonus", [](const Item &i) { return i._iPLLight; }, [](Item &i, int val) { i._iPLLight = val; }); - SetDocumented(itemType, "splLvlAdd", "number", "Spell level bonus", [](const Item &i) { return i._iSplLvlAdd; }, [](Item &i, int val) { i._iSplLvlAdd = val; }); - SetDocumented(itemType, "request", "boolean", "Request flag", [](const Item &i) { return i._iRequest; }, [](Item &i, bool val) { i._iRequest = val; }); - SetDocumented(itemType, "uid", "number", "Unique item ID", [](const Item &i) { return i._iUid; }, [](Item &i, int val) { i._iUid = val; }); - SetDocumented(itemType, "fMinDam", "number", "Fire minimum damage", [](const Item &i) { return i._iFMinDam; }, [](Item &i, int val) { i._iFMinDam = val; }); - SetDocumented(itemType, "fMaxDam", "number", "Fire maximum damage", [](const Item &i) { return i._iFMaxDam; }, [](Item &i, int val) { i._iFMaxDam = val; }); - SetDocumented(itemType, "lMinDam", "number", "Lightning minimum damage", [](const Item &i) { return i._iLMinDam; }, [](Item &i, int val) { i._iLMinDam = val; }); - SetDocumented(itemType, "lMaxDam", "number", "Lightning maximum damage", [](const Item &i) { return i._iLMaxDam; }, [](Item &i, int val) { i._iLMaxDam = val; }); - SetDocumented(itemType, "PLEnAc", "number", "Damage target AC bonus", [](const Item &i) { return i._iPLEnAc; }, [](Item &i, int val) { i._iPLEnAc = val; }); - SetDocumented(itemType, "prePower", "ItemEffectType", "Prefix power", [](const Item &i) { return i._iPrePower; }, [](Item &i, int val) { i._iPrePower = static_cast(val); }); - SetDocumented(itemType, "sufPower", "ItemEffectType", "Suffix power", [](const Item &i) { return i._iSufPower; }, [](Item &i, int val) { i._iSufPower = static_cast(val); }); - SetDocumented(itemType, "vAdd1", "number", "Value addition 1", [](const Item &i) { return i._iVAdd1; }, [](Item &i, int val) { i._iVAdd1 = val; }); - SetDocumented(itemType, "vMult1", "number", "Value multiplier 1", [](const Item &i) { return i._iVMult1; }, [](Item &i, int val) { i._iVMult1 = val; }); - SetDocumented(itemType, "vAdd2", "number", "Value addition 2", [](const Item &i) { return i._iVAdd2; }, [](Item &i, int val) { i._iVAdd2 = val; }); - SetDocumented(itemType, "vMult2", "number", "Value multiplier 2", [](const Item &i) { return i._iVMult2; }, [](Item &i, int val) { i._iVMult2 = val; }); - SetDocumented(itemType, "minStr", "number", "Minimum strength required", [](const Item &i) { return i._iMinStr; }, [](Item &i, int val) { i._iMinStr = val; }); - SetDocumented(itemType, "minMag", "number", "Minimum magic required", [](const Item &i) { return i._iMinMag; }, [](Item &i, int val) { i._iMinMag = val; }); - SetDocumented(itemType, "minDex", "number", "Minimum dexterity required", [](const Item &i) { return i._iMinDex; }, [](Item &i, int val) { i._iMinDex = val; }); - SetDocumented(itemType, "statFlag", "boolean", "Equippable flag", [](const Item &i) { return i._iStatFlag; }, [](Item &i, bool val) { i._iStatFlag = val; }); - SetDocumented(itemType, "damAcFlags", "ItemSpecialEffectHf", "Secondary special effect flags", [](const Item &i) { return i._iDamAcFlags; }, [](Item &i, int val) { i._iDamAcFlags = static_cast(val); }); - SetDocumented(itemType, "buff", "number", "Secondary creation flags", [](const Item &i) { return i.dwBuff; }, [](Item &i, int val) { i.dwBuff = val; }); + // LuaSetDocProperty(itemType, "animInfo", "AnimationInfo", "Animation information", &Item::AnimInfo); + LuaSetDocProperty(itemType, "delFlag", "boolean", "Deletion flag", &Item::_iDelFlag); + LuaSetDocProperty(itemType, "selectionRegion", "number", "Selection region", &Item::selectionRegion); + LuaSetDocProperty(itemType, "postDraw", "boolean", "Post-draw flag", &Item::_iPostDraw); + LuaSetDocProperty(itemType, "identified", "boolean", "Identified flag", &Item::_iIdentified); + LuaSetDocProperty(itemType, "magical", "number", "Item quality", &Item::_iMagical); + LuaSetDocProperty(itemType, "name", "string", "Item name", [](const Item &i) { return std::string_view(i._iName); }, [](Item &i, std::string_view val) { CopyUtf8(i._iName, val, sizeof(i._iName)); }); + LuaSetDocProperty(itemType, "iName", "string", "Identified item name", [](const Item &i) { return std::string_view(i._iIName); }, [](Item &i, std::string_view val) { CopyUtf8(i._iIName, val, sizeof(i._iIName)); }); + LuaSetDocProperty(itemType, "loc", "ItemEquipType", "Equipment location", &Item::_iLoc); + LuaSetDocProperty(itemType, "class", "ItemClass", "Item class", &Item::_iClass); + LuaSetDocProperty(itemType, "curs", "number", "Cursor index", &Item::_iCurs); + LuaSetDocProperty(itemType, "value", "number", "Item value", &Item::_ivalue); + LuaSetDocProperty(itemType, "ivalue", "number", "Identified item value", &Item::_iIvalue); + LuaSetDocProperty(itemType, "minDam", "number", "Minimum damage", &Item::_iMinDam); + LuaSetDocProperty(itemType, "maxDam", "number", "Maximum damage", &Item::_iMaxDam); + LuaSetDocProperty(itemType, "AC", "number", "Armor class", &Item::_iAC); + LuaSetDocProperty(itemType, "flags", "ItemSpecialEffect", "Special effect flags", &Item::_iFlags); + LuaSetDocProperty(itemType, "miscId", "ItemMiscID", "Miscellaneous ID", &Item::_iMiscId); + LuaSetDocProperty(itemType, "spell", "SpellID", "Spell", &Item::_iSpell); + LuaSetDocProperty(itemType, "IDidx", "ItemIndex", "Base item index", &Item::IDidx); + LuaSetDocProperty(itemType, "charges", "number", "Number of charges", &Item::_iCharges); + LuaSetDocProperty(itemType, "maxCharges", "number", "Maximum charges", &Item::_iMaxCharges); + LuaSetDocProperty(itemType, "durability", "number", "Durability", &Item::_iDurability); + LuaSetDocProperty(itemType, "maxDur", "number", "Maximum durability", &Item::_iMaxDur); + LuaSetDocProperty(itemType, "PLDam", "number", "Damage % bonus", &Item::_iPLDam); + LuaSetDocProperty(itemType, "PLToHit", "number", "Chance to hit bonus", &Item::_iPLToHit); + LuaSetDocProperty(itemType, "PLAC", "number", "Armor class % bonus", &Item::_iPLAC); + LuaSetDocProperty(itemType, "PLStr", "number", "Strength bonus", &Item::_iPLStr); + LuaSetDocProperty(itemType, "PLMag", "number", "Magic bonus", &Item::_iPLMag); + LuaSetDocProperty(itemType, "PLDex", "number", "Dexterity bonus", &Item::_iPLDex); + LuaSetDocProperty(itemType, "PLVit", "number", "Vitality bonus", &Item::_iPLVit); + LuaSetDocProperty(itemType, "PLFR", "number", "Fire resistance bonus", &Item::_iPLFR); + LuaSetDocProperty(itemType, "PLLR", "number", "Lightning resistance bonus", &Item::_iPLLR); + LuaSetDocProperty(itemType, "PLMR", "number", "Magic resistance bonus", &Item::_iPLMR); + LuaSetDocProperty(itemType, "PLMana", "number", "Mana bonus", &Item::_iPLMana); + LuaSetDocProperty(itemType, "PLHP", "number", "Life bonus", &Item::_iPLHP); + LuaSetDocProperty(itemType, "PLDamMod", "number", "Damage modifier bonus", &Item::_iPLDamMod); + LuaSetDocProperty(itemType, "PLGetHit", "number", "Damage from enemies bonus", &Item::_iPLGetHit); + LuaSetDocProperty(itemType, "PLLight", "number", "Light bonus", &Item::_iPLLight); + LuaSetDocProperty(itemType, "splLvlAdd", "number", "Spell level bonus", &Item::_iSplLvlAdd); + LuaSetDocProperty(itemType, "request", "boolean", "Request flag", &Item::_iRequest); + LuaSetDocProperty(itemType, "uid", "number", "Unique item ID", &Item::_iUid); + LuaSetDocProperty(itemType, "fMinDam", "number", "Fire minimum damage", &Item::_iFMinDam); + LuaSetDocProperty(itemType, "fMaxDam", "number", "Fire maximum damage", &Item::_iFMaxDam); + LuaSetDocProperty(itemType, "lMinDam", "number", "Lightning minimum damage", &Item::_iLMinDam); + LuaSetDocProperty(itemType, "lMaxDam", "number", "Lightning maximum damage", &Item::_iLMaxDam); + LuaSetDocProperty(itemType, "PLEnAc", "number", "Damage target AC bonus", &Item::_iPLEnAc); + LuaSetDocProperty(itemType, "prePower", "ItemEffectType", "Prefix power", &Item::_iPrePower); + LuaSetDocProperty(itemType, "sufPower", "ItemEffectType", "Suffix power", &Item::_iSufPower); + LuaSetDocProperty(itemType, "vAdd1", "number", "Value addition 1", &Item::_iVAdd1); + LuaSetDocProperty(itemType, "vMult1", "number", "Value multiplier 1", &Item::_iVMult1); + LuaSetDocProperty(itemType, "vAdd2", "number", "Value addition 2", &Item::_iVAdd2); + LuaSetDocProperty(itemType, "vMult2", "number", "Value multiplier 2", &Item::_iVMult2); + LuaSetDocProperty(itemType, "minStr", "number", "Minimum strength required", &Item::_iMinStr); + LuaSetDocProperty(itemType, "minMag", "number", "Minimum magic required", &Item::_iMinMag); + LuaSetDocProperty(itemType, "minDex", "number", "Minimum dexterity required", &Item::_iMinDex); + LuaSetDocProperty(itemType, "statFlag", "boolean", "Equippable flag", &Item::_iStatFlag); + LuaSetDocProperty(itemType, "damAcFlags", "ItemSpecialEffectHf", "Secondary special effect flags", &Item::_iDamAcFlags); + LuaSetDocProperty(itemType, "buff", "number", "Secondary creation flags", &Item::dwBuff); // Member functions - SetDocumented(itemType, "pop", "() -> Item", "Clears this item and returns the old value", &Item::pop); - SetDocumented(itemType, "clear", "() -> void", "Resets the item", &Item::clear); - SetDocumented(itemType, "isEmpty", "() -> boolean", "Checks whether this item is empty", &Item::isEmpty); - SetDocumented(itemType, "isEquipment", "() -> boolean", "Checks if item is equipment", &Item::isEquipment); - SetDocumented(itemType, "isWeapon", "() -> boolean", "Checks if item is a weapon", &Item::isWeapon); - SetDocumented(itemType, "isArmor", "() -> boolean", "Checks if item is armor", &Item::isArmor); - SetDocumented(itemType, "isGold", "() -> boolean", "Checks if item is gold", &Item::isGold); - SetDocumented(itemType, "isHelm", "() -> boolean", "Checks if item is a helm", &Item::isHelm); - SetDocumented(itemType, "isShield", "() -> boolean", "Checks if item is a shield", &Item::isShield); - SetDocumented(itemType, "isJewelry", "() -> boolean", "Checks if item is jewelry", &Item::isJewelry); - SetDocumented(itemType, "isScroll", "() -> boolean", "Checks if item is a scroll", &Item::isScroll); - SetDocumented(itemType, "isScrollOf", "(spell: SpellID) -> boolean", "Checks if item is a scroll of a given spell", &Item::isScrollOf); - SetDocumented(itemType, "isRune", "() -> boolean", "Checks if item is a rune", &Item::isRune); - SetDocumented(itemType, "isRuneOf", "(spell: SpellID) -> boolean", "Checks if item is a rune of a given spell", &Item::isRuneOf); - SetDocumented(itemType, "isUsable", "() -> boolean", "Checks if item is usable", &Item::isUsable); - SetDocumented(itemType, "keyAttributesMatch", "(seed: number, idx: number, createInfo: number) -> boolean", "Checks if key attributes match", &Item::keyAttributesMatch); - SetDocumented(itemType, "getTextColor", "() -> UiFlags", "Gets the text color", &Item::getTextColor); - SetDocumented(itemType, "getTextColorWithStatCheck", "() -> UiFlags", "Gets the text color with stat check", &Item::getTextColorWithStatCheck); - SetDocumented(itemType, "setNewAnimation", "(showAnimation: boolean) -> void", "Sets the new animation", &Item::setNewAnimation); - SetDocumented(itemType, "updateRequiredStatsCacheForPlayer", "(player: Player) -> void", "Updates the required stats cache", &Item::updateRequiredStatsCacheForPlayer); - SetDocumented(itemType, "getName", "() -> string", "Gets the translated item name", &Item::getName); + LuaSetDocFn(itemType, "pop", "() -> Item", "Clears this item and returns the old value", &Item::pop); + LuaSetDocFn(itemType, "clear", "() -> void", "Resets the item", &Item::clear); + LuaSetDocFn(itemType, "isEmpty", "() -> boolean", "Checks whether this item is empty", &Item::isEmpty); + LuaSetDocFn(itemType, "isEquipment", "() -> boolean", "Checks if item is equipment", &Item::isEquipment); + LuaSetDocFn(itemType, "isWeapon", "() -> boolean", "Checks if item is a weapon", &Item::isWeapon); + LuaSetDocFn(itemType, "isArmor", "() -> boolean", "Checks if item is armor", &Item::isArmor); + LuaSetDocFn(itemType, "isGold", "() -> boolean", "Checks if item is gold", &Item::isGold); + LuaSetDocFn(itemType, "isHelm", "() -> boolean", "Checks if item is a helm", &Item::isHelm); + LuaSetDocFn(itemType, "isShield", "() -> boolean", "Checks if item is a shield", &Item::isShield); + LuaSetDocFn(itemType, "isJewelry", "() -> boolean", "Checks if item is jewelry", &Item::isJewelry); + LuaSetDocFn(itemType, "isScroll", "() -> boolean", "Checks if item is a scroll", &Item::isScroll); + LuaSetDocFn(itemType, "isScrollOf", "(spell: SpellID) -> boolean", "Checks if item is a scroll of a given spell", &Item::isScrollOf); + LuaSetDocFn(itemType, "isRune", "() -> boolean", "Checks if item is a rune", &Item::isRune); + LuaSetDocFn(itemType, "isRuneOf", "(spell: SpellID) -> boolean", "Checks if item is a rune of a given spell", &Item::isRuneOf); + LuaSetDocFn(itemType, "isUsable", "() -> boolean", "Checks if item is usable", &Item::isUsable); + LuaSetDocFn(itemType, "keyAttributesMatch", "(seed: number, idx: number, createInfo: number) -> boolean", "Checks if key attributes match", &Item::keyAttributesMatch); + LuaSetDocFn(itemType, "getTextColor", "() -> UiFlags", "Gets the text color", &Item::getTextColor); + LuaSetDocFn(itemType, "getTextColorWithStatCheck", "() -> UiFlags", "Gets the text color with stat check", &Item::getTextColorWithStatCheck); + LuaSetDocFn(itemType, "setNewAnimation", "(showAnimation: boolean) -> void", "Sets the new animation", &Item::setNewAnimation); + LuaSetDocFn(itemType, "updateRequiredStatsCacheForPlayer", "(player: Player) -> void", "Updates the required stats cache", &Item::updateRequiredStatsCacheForPlayer); + LuaSetDocFn(itemType, "getName", "() -> string", "Gets the translated item name", &Item::getName); } void RegisterItemTypeEnum(sol::state_view &lua) diff --git a/Source/lua/modules/player.cpp b/Source/lua/modules/player.cpp index ad2b72d31..28a0e2cca 100644 --- a/Source/lua/modules/player.cpp +++ b/Source/lua/modules/player.cpp @@ -13,10 +13,10 @@ namespace { void InitPlayerUserType(sol::state_view &lua) { sol::usertype playerType = lua.new_usertype(sol::no_constructor); - SetDocumented(playerType, "name", "", + LuaSetDocReadonlyProperty(playerType, "name", "string", "Player's name (readonly)", - sol::readonly_property(&Player::name)); - SetDocumented(playerType, "addExperience", "(experience: integer, monsterLevel: integer = nil)", + &Player::name); + LuaSetDocFn(playerType, "addExperience", "(experience: integer, monsterLevel: integer = nil)", "Adds experience to this player based on the current game mode", [](Player &player, uint32_t experience, std::optional monsterLevel) { if (monsterLevel.has_value()) { @@ -25,9 +25,9 @@ void InitPlayerUserType(sol::state_view &lua) player.addExperience(experience); } }); - SetDocumented(playerType, "characterLevel", "", + LuaSetDocProperty(playerType, "characterLevel", "number", "Character level (writeable)", - sol::property(&Player::getCharacterLevel, &Player::setCharacterLevel)); + &Player::getCharacterLevel, &Player::setCharacterLevel); } } // namespace @@ -35,12 +35,12 @@ sol::table LuaPlayerModule(sol::state_view &lua) { InitPlayerUserType(lua); sol::table table = lua.create_table(); - SetDocumented(table, "self", "()", + LuaSetDocFn(table, "self", "()", "The current player", []() { return MyPlayer; }); - SetDocumented(table, "walk_to", "(x: integer, y: integer)", + LuaSetDocFn(table, "walk_to", "(x: integer, y: integer)", "Walk to the given coordinates", [](int x, int y) { NetSendCmdLoc(MyPlayerId, true, CMD_WALKXY, Point { x, y }); diff --git a/Source/lua/modules/render.cpp b/Source/lua/modules/render.cpp index cf618063f..99bd550fa 100644 --- a/Source/lua/modules/render.cpp +++ b/Source/lua/modules/render.cpp @@ -12,12 +12,12 @@ namespace devilution { sol::table LuaRenderModule(sol::state_view &lua) { sol::table table = lua.create_table(); - SetDocumented(table, "string", "(text: string, x: integer, y: integer)", + LuaSetDocFn(table, "string", "(text: string, x: integer, y: integer)", "Renders a string at the given coordinates", [](std::string_view text, int x, int y) { DrawString(GlobalBackBuffer(), text, { x, y }); }); - SetDocumented(table, "screen_width", "()", + LuaSetDocFn(table, "screen_width", "()", "Returns the screen width", []() { return gnScreenWidth; }); - SetDocumented(table, "screen_height", "()", + LuaSetDocFn(table, "screen_height", "()", "Returns the screen height", []() { return gnScreenHeight; }); return table; } diff --git a/Source/lua/modules/towners.cpp b/Source/lua/modules/towners.cpp index 48e55ade9..b04704b5d 100644 --- a/Source/lua/modules/towners.cpp +++ b/Source/lua/modules/towners.cpp @@ -31,7 +31,7 @@ const char *const TownerTableNames[NUM_TOWNER_TYPES] { void PopulateTownerTable(_talker_id townerId, sol::table &out) { - SetDocumented(out, "position", "()", + LuaSetDocFn(out, "position", "()", "Returns towner coordinates", [townerId]() -> std::optional> { const Towner *towner = GetTowner(townerId); @@ -47,7 +47,7 @@ sol::table LuaTownersModule(sol::state_view &lua) for (uint8_t townerId = TOWN_SMITH; townerId < NUM_TOWNER_TYPES; ++townerId) { sol::table townerTable = lua.create_table(); PopulateTownerTable(static_cast<_talker_id>(townerId), townerTable); - SetDocumented(table, TownerTableNames[townerId], /*signature=*/"", TownerLongNames[townerId], std::move(townerTable)); + LuaSetDoc(table, TownerTableNames[townerId], /*signature=*/"", TownerLongNames[townerId], std::move(townerTable)); } return table; }