Active+ Member ScriptMan 1530 Posted February 9 Active+ Member Share Posted February 9 (edited) Hello! Today I found that in lua the modification of item.set_socket(0, value) does not work. Fixed: int item_set_socket(lua_State* L) { CQuestManager& q = CQuestManager::instance(); if (q.GetCurrentItem() && lua_isnumber(L, 1) && lua_isnumber(L, 2)) { int idx = (int)lua_tonumber(L, 1); int value = (int)lua_tonumber(L, 2); if (idx >= 0 && idx < ITEM_SOCKET_MAX_NUM) q.GetCurrentItem()->SetSocket(idx, value); } return 0; } Original: int item_set_socket(lua_State* L) { CQuestManager& q = CQuestManager::instance(); if (&q == NULL) return 0; LPITEM item = q.GetCurrentItem(); if (item == NULL) return 0; if (item && lua_isnumber(L, 1) && lua_isnumber(L, 2)) { int idx = (int) lua_tonumber(L, 1); int value = (int) lua_tonumber(L, 2); if (idx == NULL) return 0; if (value == NULL) return 0; if (idx >=0 && idx < ITEM_SOCKET_MAX_NUM) item->SetSocket(idx, value); } return 0; } Explanation: If the socket index is 0, it returns and does not run the code... fck logic. if (idx == NULL) return 0; Edited February 9 by speze012 3 1 Link to comment Share on other sites More sharing options...
Forum Moderator Gurgarath 2513 Posted February 10 Forum Moderator Share Posted February 10 (edited) Hello, thanks for the tutorial, but I would still advise you to keep the nullptr checks for relevant parts. I don't think it will go null, but you never know until it gets null. int item_set_socket(lua_State* L) { CQuestManager& q = CQuestManager::instance(); LPITEM item = q.GetCurrentItem(); if (item == NULL) return 0; if (item && lua_isnumber(L, 1) && lua_isnumber(L, 2)) { int idx = (int) lua_tonumber(L, 1); int value = (int) lua_tonumber(L, 2); if (idx >=0 && idx < ITEM_SOCKET_MAX_NUM) item->SetSocket(idx, value); } return 0; } Edited February 10 by Gurgarath 2 Gurgarath coming soon Link to comment Share on other sites More sharing options...
Premium WeedHex 635 Posted February 10 Premium Share Posted February 10 (edited) It was blocking also Set Value to 0. if (value == NULL) return 0; My version: int item_set_socket(lua_State* L) { LPITEM item = CQuestManager::instance().GetCurrentItem(); if (!item) return 0; if (lua_isnumber(L, 1) && lua_isnumber(L, 2)) { const auto idx = static_cast<int>(lua_tonumber(L, 1)); if (idx < 0 || idx >= ITEM_SOCKET_MAX_NUM) return 0; // Value can be 0 or negative. const auto value = static_cast<int>(lua_tonumber(L, 2)); item->SetSocket(idx, value); } else sys_err("Passing bad argument from LUA."); return 0; } Edited February 10 by WeedHex 1 2 Link to comment Share on other sites More sharing options...
Premium Syreldar 1875 Posted February 19 Premium Share Posted February 19 (edited) define WEAPON_SHOP_DEALER 9001 define ARMOUR_SHOP_DEALER 9002 define TINCTURE_VNUM 71047 define SOCKETS_MAX_NUM 3 quest tincture_stone_add begin state start begin function GetItemSlotsNum() -- end -- function function BuildStoneListForItemType(item_type) -- end -- function function GetStoneFamily(stone_vnum) -- end -- function function IsStoneFamilySocketed(stone_vnum) -- end -- function function BuildAvailableStoneListForItemType(item_type) -- end -- function when WEAPON_SHOP_DEALER.take or ARMOUR_SHOP_DEALER.take begin local npc_vnum = npc.get_race(); say_title(string.format("%s:[ENTER]", mob_name(npc_vnum))) local item_type = item.get_type(); if (npc_vnum == WEAPON_SHOP_DEALER and item_type ~= ITEM_TYPES.WEAPON) then say_reward("I only accept weapons.[ENTER]") return; elseif (npc_vnum == ARMOUR_SHOP_DEALER and item_type ~= ITEM_TYPES.ARMOR) then say_reward("I only accept armors.[ENTER]") return; end -- if/elseif local item_sub_type = item.get_sub_type(); local invalid_weapon_subtypes = { ITEM_SUB_TYPES.WEAPONS.ARROW, ITEM_SUB_TYPES.WEAPONS.MOUNT_SPEAR, ITEM_SUB_TYPES.WEAPONS.QUIVER }; if (npc_vnum == WEAPON_SHOP_DEALER and table_is_in(invalid_weapon_subtypes, item_sub_type)) then say_reward("I only accept valid weapons.[ENTER]") return; elseif (npc_vnum == ARMOUR_SHOP_DEALER and item_sub_type ~= ITEM_SUB_TYPES.ARMORS.BODY) then say_reward("I only accept valid armors.[ENTER]") return; end -- if/elseif if (pc.count_item(TINCTURE_VNUM) == 0) then say_reward("You require:") say_item_vnum(TINCTURE_VNUM); return; end -- if local slots_num = tincture_stone_add.GetItemSlotsNum(); if (slots_num == 0) then say_reward("This item can't be socketed.[ENTER]") return; end -- if say(string.format("This item has %d possible slot%s.[ENTER]", slots_num, (slots_num > 1 and "s" or ""))) local available_socket_ids, socket_vnum = {}, -1; for socket_id = 0, slots_num-1 do socket_vnum = item.get_socket(socket_id); if (socket_vnum > 1) then color_say("lightgreen", string.format("Slot n.%d: %s;", socket_id + 1, item_name(socket_vnum))) else say_reward(string.format("Slot n.%d: No stone;", socket_id + 1)) table.insert(available_socket_ids, socket_id); end -- if/else end -- for if (table.getn(available_socket_ids) == 0) then say_reward("[ENTER]There's already a stone in every available socket.[ENTER]") return; end -- if local available_stones_vnums = tincture_stone_add.BuildAvailableStoneListForItemType(item_type); if (table.getn(available_stones_vnums) == 0) then say_reward("[ENTER]You don't have any stone I can socket in.[ENTER]") return; end -- if say("[ENTER]Which stone do you want to add?") local available_stones_names = {}; table.foreach(available_stones_vnums, function(_, stone_vnum) table.insert(available_stones_names, item_name(stone_vnum)); end -- function ); table.insert(available_stones_names, "Abort"); -- Window length management local available_stones_num = table.getn(available_stones_names); if (available_stones_num > 3) then say_size(350, 300 + 27 * math.min(5, available_stones_num - SOCKETS_MAX_NUM)) else say("") end -- if/else local selected_stone = select_table(available_stones_names); if (selected_stone == table.getn(available_stones_names)) then return; end -- if pc.remove_item(TINCTURE_VNUM, 1); local selected_stone_vnum = available_stones_vnums[selected_stone]; pc.remove_item(selected_stone_vnum, 1); item.set_socket(available_socket_ids[1], selected_stone_vnum); end -- when end -- state end -- quest This is an old quest I wrote. In order for the logic to work, the socket of index 0 must work.. and it does even on traditional kraizy files. Are you sure this error is a thing? I'm pretty sure (although I didn't check) that some official quests also use that very same instruction. Edited February 19 by Syreldar 1 1 "Nothing's free in this life. Ignorant people have an obligation to make up for their ignorance by paying those who help them. Either you got the brains or cash, if you lack both you're useless." Syreldar Link to comment Share on other sites More sharing options...
Forum Moderator Gurgarath 2513 Posted February 19 Forum Moderator Share Posted February 19 Well, well, well. Syreldar is absolutely right and we should have checked. On the original mainline and novaline, the "Original" function is your "Fixed" function. Your "Original" is a completely custom function that of course doesn't work because of NULL checks on integers. I thought it was an original shenanigans as it wouldn't be unlikely, but no. By default, everyone has a working function, this tutorial is by essence not necessary. What sources do you use though? Gurgarath coming soon Link to comment Share on other sites More sharing options...
Recommended Posts