Skip to content

Commit dfd4b92

Browse files
committed
Lua items.cpp: Simplify property bindings
Also improves string property handling.
1 parent 54e30ff commit dfd4b92

File tree

2 files changed

+68
-63
lines changed

2 files changed

+68
-63
lines changed

Source/lua/metadoc.hpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,30 +21,38 @@ inline std::string LuaDocstringKey(std::string_view key)
2121
template <typename U, typename T>
2222
void SetDocumented(sol::usertype<U> &table, std::string_view key, std::string_view signature, std::string_view doc, T &&value)
2323
{
24-
table[key] = std::forward<T>(value);
24+
table.set(key, std::forward<T>(value));
25+
// TODO: figure out a way to set signature and docstring.
26+
}
27+
28+
// This overload works around compiler issues on clang-15 with member field references.
29+
template <typename U, typename F>
30+
void SetDocumented(sol::usertype<U> &table, std::string_view key, std::string_view signature, std::string_view doc, F U::*&&value)
31+
{
32+
table.set(key, std::forward<F U::*>(value));
2533
// TODO: figure out a way to set signature and docstring.
2634
}
2735

2836
template <typename U, typename G, typename S>
2937
void SetDocumented(sol::usertype<U> &table, std::string_view key, std::string_view signature, std::string_view doc, G &&getter, S &&setter)
3038
{
31-
table[key] = sol::property(std::forward<G>(getter), std::forward<S>(setter));
39+
table.set(key, sol::property(std::forward<G>(getter), std::forward<S>(setter)));
3240
// TODO: figure out a way to set signature and docstring.
3341
}
3442

3543
template <typename T>
3644
void SetDocumented(sol::table &table, std::string_view key, std::string_view signature, std::string_view doc, T &&value)
3745
{
38-
table[key] = std::forward<T>(value);
39-
table[LuaSignatureKey(key)] = signature;
40-
table[LuaDocstringKey(key)] = doc;
46+
table.set(key, std::forward<T>(value));
47+
table.set(LuaSignatureKey(key), signature);
48+
table.set(LuaDocstringKey(key), doc);
4149
}
4250

4351
template <typename T>
4452
void SetWithSignature(sol::table &table, std::string_view key, std::string_view signature, T &&value)
4553
{
46-
table[key] = std::forward<T>(value);
47-
table[LuaSignatureKey(key)] = signature;
54+
table.set(key, std::forward<T>(value));
55+
table.set(LuaSignatureKey(key), signature);
4856
}
4957

5058
inline std::optional<std::string> GetSignature(const sol::table &table, std::string_view key)

Source/lua/modules/items.cpp

Lines changed: 53 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "items.h"
88
#include "lua/metadoc.hpp"
99
#include "player.h"
10+
#include "utils/utf8.hpp"
1011

1112
namespace devilution {
1213

@@ -18,75 +19,71 @@ void InitItemUserType(sol::state_view &lua)
1819
sol::usertype<Item> itemType = lua.new_usertype<Item>(sol::no_constructor);
1920

2021
// Member variables
21-
SetDocumented(itemType, "seed", "number", "Randomly generated identifier", [](const Item &i) { return i._iSeed; }, [](Item &i, unsigned int val) { i._iSeed = val; });
22-
SetDocumented(itemType, "createInfo", "number", "Creation flags", [](const Item &i) { return i._iCreateInfo; }, [](Item &i, unsigned int val) { i._iCreateInfo = val; });
22+
SetDocumented(itemType, "seed", "number", "Randomly generated identifier", &Item::_iSeed);
23+
SetDocumented(itemType, "createInfo", "number", "Creation flags", &Item::_iCreateInfo);
2324
SetDocumented(itemType, "type", "ItemType", "Item type", [](const Item &i) { return i._itype; }, [](Item &i, int val) { i._itype = static_cast<ItemType>(val); });
24-
SetDocumented(itemType, "animFlag", "boolean", "Animation flag", [](const Item &i) { return i._iAnimFlag; }, [](Item &i, bool val) { i._iAnimFlag = val; });
25-
SetDocumented(itemType, "position", "Point", "Item world position", [](const Item &i) { return i.position; }, [](Item &i, Point val) { i.position = val; });
25+
SetDocumented(itemType, "animFlag", "boolean", "Animation flag", &Item::_iAnimFlag);
26+
SetDocumented(itemType, "position", "Point", "Item world position", &Item::position);
2627
// TODO: Add AnimationInfo usertype
27-
// SetDocumented(itemType, "animInfo", "AnimationInfo", "Animation information", [](const Item &i) { return i.AnimInfo; }, [](Item &i, AnimationInfo val) { i.AnimInfo = val; });
28-
SetDocumented(itemType, "delFlag", "boolean", "Deletion flag", [](const Item &i) { return i._iDelFlag; }, [](Item &i, bool val) { i._iDelFlag = val; });
28+
// SetDocumented(itemType, "animInfo", "AnimationInfo", "Animation information", &Item::AnimInfo);
29+
SetDocumented(itemType, "delFlag", "boolean", "Deletion flag", &Item::_iDelFlag);
2930
SetDocumented(itemType, "selectionRegion", "number", "Selection region", [](const Item &i) { return static_cast<int>(i.selectionRegion); }, [](Item &i, int val) { i.selectionRegion = static_cast<SelectionRegion>(val); });
30-
SetDocumented(itemType, "postDraw", "boolean", "Post-draw flag", [](const Item &i) { return i._iPostDraw; }, [](Item &i, bool val) { i._iPostDraw = val; });
31-
SetDocumented(itemType, "identified", "boolean", "Identified flag", [](const Item &i) { return i._iIdentified; }, [](Item &i, bool val) { i._iIdentified = val; });
31+
SetDocumented(itemType, "postDraw", "boolean", "Post-draw flag", &Item::_iPostDraw);
32+
SetDocumented(itemType, "identified", "boolean", "Identified flag", &Item::_iIdentified);
3233
SetDocumented(itemType, "magical", "number", "Item quality", [](const Item &i) { return static_cast<int>(i._iMagical); }, [](Item &i, int val) { i._iMagical = static_cast<item_quality>(val); });
33-
SetDocumented(itemType, "name", "string", "Item name", [](const Item &i) { return std::string(i._iName); }, [](Item &i, const std::string &val) {
34-
std::strncpy(i._iName, val.c_str(), sizeof(i._iName));
35-
i._iName[sizeof(i._iName) - 1] = '\0'; });
36-
SetDocumented(itemType, "iName", "string", "Identified item name", [](const Item &i) { return std::string(i._iIName); }, [](Item &i, const std::string &val) {
37-
std::strncpy(i._iIName, val.c_str(), sizeof(i._iIName));
38-
i._iIName[sizeof(i._iIName) - 1] = '\0'; });
34+
SetDocumented(itemType, "name", "string", "Item name", [](const Item &i) { return std::string(i._iName); }, [](Item &i, const std::string &val) { CopyUtf8(i._iName, val, sizeof(i._iName)); });
35+
SetDocumented(itemType, "iName", "string", "Identified item name", [](const Item &i) { return std::string(i._iIName); }, [](Item &i, const std::string &val) { CopyUtf8(i._iIName, val, sizeof(i._iIName)); });
3936
SetDocumented(itemType, "loc", "ItemEquipType", "Equipment location", [](const Item &i) { return i._iLoc; }, [](Item &i, int val) { i._iLoc = static_cast<item_equip_type>(val); });
4037
SetDocumented(itemType, "class", "ItemClass", "Item class", [](const Item &i) { return i._iClass; }, [](Item &i, int val) { i._iClass = static_cast<item_class>(val); });
41-
SetDocumented(itemType, "curs", "number", "Cursor index", [](const Item &i) { return i._iCurs; }, [](Item &i, int val) { i._iCurs = val; });
42-
SetDocumented(itemType, "value", "number", "Item value", [](const Item &i) { return i._ivalue; }, [](Item &i, int val) { i._ivalue = val; });
43-
SetDocumented(itemType, "ivalue", "number", "Identified item value", [](const Item &i) { return i._iIvalue; }, [](Item &i, int val) { i._iIvalue = val; });
44-
SetDocumented(itemType, "minDam", "number", "Minimum damage", [](const Item &i) { return i._iMinDam; }, [](Item &i, int val) { i._iMinDam = val; });
45-
SetDocumented(itemType, "maxDam", "number", "Maximum damage", [](const Item &i) { return i._iMaxDam; }, [](Item &i, int val) { i._iMaxDam = val; });
46-
SetDocumented(itemType, "AC", "number", "Armor class", [](const Item &i) { return i._iAC; }, [](Item &i, int val) { i._iAC = val; });
38+
SetDocumented(itemType, "curs", "number", "Cursor index", &Item::_iCurs);
39+
SetDocumented(itemType, "value", "number", "Item value", &Item::_ivalue);
40+
SetDocumented(itemType, "ivalue", "number", "Identified item value", &Item::_iIvalue);
41+
SetDocumented(itemType, "minDam", "number", "Minimum damage", &Item::_iMinDam);
42+
SetDocumented(itemType, "maxDam", "number", "Maximum damage", &Item::_iMaxDam);
43+
SetDocumented(itemType, "AC", "number", "Armor class", &Item::_iAC);
4744
SetDocumented(itemType, "flags", "ItemSpecialEffect", "Special effect flags", [](const Item &i) { return static_cast<int>(i._iFlags); }, [](Item &i, int val) { i._iFlags = static_cast<ItemSpecialEffect>(val); });
4845
SetDocumented(itemType, "miscId", "ItemMiscID", "Miscellaneous ID", [](const Item &i) { return i._iMiscId; }, [](Item &i, int val) { i._iMiscId = static_cast<item_misc_id>(val); });
4946
SetDocumented(itemType, "spell", "SpellID", "Spell", [](const Item &i) { return i._iSpell; }, [](Item &i, int val) { i._iSpell = static_cast<SpellID>(val); });
5047
SetDocumented(itemType, "IDidx", "ItemIndex", "Base item index", [](const Item &i) { return i.IDidx; }, [](Item &i, int val) { i.IDidx = static_cast<_item_indexes>(val); });
51-
SetDocumented(itemType, "charges", "number", "Number of charges", [](const Item &i) { return i._iCharges; }, [](Item &i, int val) { i._iCharges = val; });
52-
SetDocumented(itemType, "maxCharges", "number", "Maximum charges", [](const Item &i) { return i._iMaxCharges; }, [](Item &i, int val) { i._iMaxCharges = val; });
53-
SetDocumented(itemType, "durability", "number", "Durability", [](const Item &i) { return i._iDurability; }, [](Item &i, int val) { i._iDurability = val; });
54-
SetDocumented(itemType, "maxDur", "number", "Maximum durability", [](const Item &i) { return i._iMaxDur; }, [](Item &i, int val) { i._iMaxDur = val; });
55-
SetDocumented(itemType, "PLDam", "number", "Damage % bonus", [](const Item &i) { return i._iPLDam; }, [](Item &i, int val) { i._iPLDam = val; });
56-
SetDocumented(itemType, "PLToHit", "number", "Chance to hit bonus", [](const Item &i) { return i._iPLToHit; }, [](Item &i, int val) { i._iPLToHit = val; });
57-
SetDocumented(itemType, "PLAC", "number", "Armor class % bonus", [](const Item &i) { return i._iPLAC; }, [](Item &i, int val) { i._iPLAC = val; });
58-
SetDocumented(itemType, "PLStr", "number", "Strength bonus", [](const Item &i) { return i._iPLStr; }, [](Item &i, int val) { i._iPLStr = val; });
59-
SetDocumented(itemType, "PLMag", "number", "Magic bonus", [](const Item &i) { return i._iPLMag; }, [](Item &i, int val) { i._iPLMag = val; });
60-
SetDocumented(itemType, "PLDex", "number", "Dexterity bonus", [](const Item &i) { return i._iPLDex; }, [](Item &i, int val) { i._iPLDex = val; });
61-
SetDocumented(itemType, "PLVit", "number", "Vitality bonus", [](const Item &i) { return i._iPLVit; }, [](Item &i, int val) { i._iPLVit = val; });
62-
SetDocumented(itemType, "PLFR", "number", "Fire resistance bonus", [](const Item &i) { return i._iPLFR; }, [](Item &i, int val) { i._iPLFR = val; });
63-
SetDocumented(itemType, "PLLR", "number", "Lightning resistance bonus", [](const Item &i) { return i._iPLLR; }, [](Item &i, int val) { i._iPLLR = val; });
64-
SetDocumented(itemType, "PLMR", "number", "Magic resistance bonus", [](const Item &i) { return i._iPLMR; }, [](Item &i, int val) { i._iPLMR = val; });
65-
SetDocumented(itemType, "PLMana", "number", "Mana bonus", [](const Item &i) { return i._iPLMana; }, [](Item &i, int val) { i._iPLMana = val; });
66-
SetDocumented(itemType, "PLHP", "number", "Life bonus", [](const Item &i) { return i._iPLHP; }, [](Item &i, int val) { i._iPLHP = val; });
67-
SetDocumented(itemType, "PLDamMod", "number", "Damage modifier bonus", [](const Item &i) { return i._iPLDamMod; }, [](Item &i, int val) { i._iPLDamMod = val; });
68-
SetDocumented(itemType, "PLGetHit", "number", "Damage from enemies bonus", [](const Item &i) { return i._iPLGetHit; }, [](Item &i, int val) { i._iPLGetHit = val; });
69-
SetDocumented(itemType, "PLLight", "number", "Light bonus", [](const Item &i) { return i._iPLLight; }, [](Item &i, int val) { i._iPLLight = val; });
70-
SetDocumented(itemType, "splLvlAdd", "number", "Spell level bonus", [](const Item &i) { return i._iSplLvlAdd; }, [](Item &i, int val) { i._iSplLvlAdd = val; });
71-
SetDocumented(itemType, "request", "boolean", "Request flag", [](const Item &i) { return i._iRequest; }, [](Item &i, bool val) { i._iRequest = val; });
72-
SetDocumented(itemType, "uid", "number", "Unique item ID", [](const Item &i) { return i._iUid; }, [](Item &i, int val) { i._iUid = val; });
73-
SetDocumented(itemType, "fMinDam", "number", "Fire minimum damage", [](const Item &i) { return i._iFMinDam; }, [](Item &i, int val) { i._iFMinDam = val; });
74-
SetDocumented(itemType, "fMaxDam", "number", "Fire maximum damage", [](const Item &i) { return i._iFMaxDam; }, [](Item &i, int val) { i._iFMaxDam = val; });
75-
SetDocumented(itemType, "lMinDam", "number", "Lightning minimum damage", [](const Item &i) { return i._iLMinDam; }, [](Item &i, int val) { i._iLMinDam = val; });
76-
SetDocumented(itemType, "lMaxDam", "number", "Lightning maximum damage", [](const Item &i) { return i._iLMaxDam; }, [](Item &i, int val) { i._iLMaxDam = val; });
77-
SetDocumented(itemType, "PLEnAc", "number", "Damage target AC bonus", [](const Item &i) { return i._iPLEnAc; }, [](Item &i, int val) { i._iPLEnAc = val; });
48+
SetDocumented(itemType, "charges", "number", "Number of charges", &Item::_iCharges);
49+
SetDocumented(itemType, "maxCharges", "number", "Maximum charges", &Item::_iMaxCharges);
50+
SetDocumented(itemType, "durability", "number", "Durability", &Item::_iDurability);
51+
SetDocumented(itemType, "maxDur", "number", "Maximum durability", &Item::_iMaxDur);
52+
SetDocumented(itemType, "PLDam", "number", "Damage % bonus", &Item::_iPLDam);
53+
SetDocumented(itemType, "PLToHit", "number", "Chance to hit bonus", &Item::_iPLToHit);
54+
SetDocumented(itemType, "PLAC", "number", "Armor class % bonus", &Item::_iPLAC);
55+
SetDocumented(itemType, "PLStr", "number", "Strength bonus", &Item::_iPLStr);
56+
SetDocumented(itemType, "PLMag", "number", "Magic bonus", &Item::_iPLMag);
57+
SetDocumented(itemType, "PLDex", "number", "Dexterity bonus", &Item::_iPLDex);
58+
SetDocumented(itemType, "PLVit", "number", "Vitality bonus", &Item::_iPLVit);
59+
SetDocumented(itemType, "PLFR", "number", "Fire resistance bonus", &Item::_iPLFR);
60+
SetDocumented(itemType, "PLLR", "number", "Lightning resistance bonus", &Item::_iPLLR);
61+
SetDocumented(itemType, "PLMR", "number", "Magic resistance bonus", &Item::_iPLMR);
62+
SetDocumented(itemType, "PLMana", "number", "Mana bonus", &Item::_iPLMana);
63+
SetDocumented(itemType, "PLHP", "number", "Life bonus", &Item::_iPLHP);
64+
SetDocumented(itemType, "PLDamMod", "number", "Damage modifier bonus", &Item::_iPLDamMod);
65+
SetDocumented(itemType, "PLGetHit", "number", "Damage from enemies bonus", &Item::_iPLGetHit);
66+
SetDocumented(itemType, "PLLight", "number", "Light bonus", &Item::_iPLLight);
67+
SetDocumented(itemType, "splLvlAdd", "number", "Spell level bonus", &Item::_iSplLvlAdd);
68+
SetDocumented(itemType, "request", "boolean", "Request flag", &Item::_iRequest);
69+
SetDocumented(itemType, "uid", "number", "Unique item ID", &Item::_iUid);
70+
SetDocumented(itemType, "fMinDam", "number", "Fire minimum damage", &Item::_iFMinDam);
71+
SetDocumented(itemType, "fMaxDam", "number", "Fire maximum damage", &Item::_iFMaxDam);
72+
SetDocumented(itemType, "lMinDam", "number", "Lightning minimum damage", &Item::_iLMinDam);
73+
SetDocumented(itemType, "lMaxDam", "number", "Lightning maximum damage", &Item::_iLMaxDam);
74+
SetDocumented(itemType, "PLEnAc", "number", "Damage target AC bonus", &Item::_iPLEnAc);
7875
SetDocumented(itemType, "prePower", "ItemEffectType", "Prefix power", [](const Item &i) { return i._iPrePower; }, [](Item &i, int val) { i._iPrePower = static_cast<item_effect_type>(val); });
7976
SetDocumented(itemType, "sufPower", "ItemEffectType", "Suffix power", [](const Item &i) { return i._iSufPower; }, [](Item &i, int val) { i._iSufPower = static_cast<item_effect_type>(val); });
80-
SetDocumented(itemType, "vAdd1", "number", "Value addition 1", [](const Item &i) { return i._iVAdd1; }, [](Item &i, int val) { i._iVAdd1 = val; });
81-
SetDocumented(itemType, "vMult1", "number", "Value multiplier 1", [](const Item &i) { return i._iVMult1; }, [](Item &i, int val) { i._iVMult1 = val; });
82-
SetDocumented(itemType, "vAdd2", "number", "Value addition 2", [](const Item &i) { return i._iVAdd2; }, [](Item &i, int val) { i._iVAdd2 = val; });
83-
SetDocumented(itemType, "vMult2", "number", "Value multiplier 2", [](const Item &i) { return i._iVMult2; }, [](Item &i, int val) { i._iVMult2 = val; });
84-
SetDocumented(itemType, "minStr", "number", "Minimum strength required", [](const Item &i) { return i._iMinStr; }, [](Item &i, int val) { i._iMinStr = val; });
85-
SetDocumented(itemType, "minMag", "number", "Minimum magic required", [](const Item &i) { return i._iMinMag; }, [](Item &i, int val) { i._iMinMag = val; });
86-
SetDocumented(itemType, "minDex", "number", "Minimum dexterity required", [](const Item &i) { return i._iMinDex; }, [](Item &i, int val) { i._iMinDex = val; });
87-
SetDocumented(itemType, "statFlag", "boolean", "Equippable flag", [](const Item &i) { return i._iStatFlag; }, [](Item &i, bool val) { i._iStatFlag = val; });
77+
SetDocumented(itemType, "vAdd1", "number", "Value addition 1", &Item::_iVAdd1);
78+
SetDocumented(itemType, "vMult1", "number", "Value multiplier 1", &Item::_iVMult1);
79+
SetDocumented(itemType, "vAdd2", "number", "Value addition 2", &Item::_iVAdd2);
80+
SetDocumented(itemType, "vMult2", "number", "Value multiplier 2", &Item::_iVMult2);
81+
SetDocumented(itemType, "minStr", "number", "Minimum strength required", &Item::_iMinStr);
82+
SetDocumented(itemType, "minMag", "number", "Minimum magic required", &Item::_iMinMag);
83+
SetDocumented(itemType, "minDex", "number", "Minimum dexterity required", &Item::_iMinDex);
84+
SetDocumented(itemType, "statFlag", "boolean", "Equippable flag", &Item::_iStatFlag);
8885
SetDocumented(itemType, "damAcFlags", "ItemSpecialEffectHf", "Secondary special effect flags", [](const Item &i) { return i._iDamAcFlags; }, [](Item &i, int val) { i._iDamAcFlags = static_cast<ItemSpecialEffectHf>(val); });
89-
SetDocumented(itemType, "buff", "number", "Secondary creation flags", [](const Item &i) { return i.dwBuff; }, [](Item &i, int val) { i.dwBuff = val; });
86+
SetDocumented(itemType, "buff", "number", "Secondary creation flags", &Item::dwBuff);
9087

9188
// Member functions
9289
SetDocumented(itemType, "pop", "() -> Item", "Clears this item and returns the old value", &Item::pop);

0 commit comments

Comments
 (0)