Helliot1
Owner of Empire Online
- Joined
- Jul 26, 2017
- Messages
- 315
- Solutions
- 1
- Reaction score
- 58
Can someone explain to me what's going on and how can i fix it?
I am editing my NPC module, removing some functions and adding others. And when I sell an item, I get this error.
ERROR: protected lua call failed: LUA ERROR:
/game_npctrade/npctrade.lua:219: attempt to index local 'item' (a nil value) stack traceback:
[C]: in function '__index'
/game_npctrade/npctrade.lua:219: in function 'getItemPrice'
/game_npctrade/npctrade.lua:525: in function 'checkMoney'
/game_npctrade/npctrade.lua:344: in function 'refreshPlayerGoods'
/game_npctrade/npctrade.lua:399: in function </game_npctrade/npctrade.lua:386>
npctrade.lua
I am editing my NPC module, removing some functions and adding others. And when I sell an item, I get this error.
ERROR: protected lua call failed: LUA ERROR:
/game_npctrade/npctrade.lua:219: attempt to index local 'item' (a nil value) stack traceback:
[C]: in function '__index'
/game_npctrade/npctrade.lua:219: in function 'getItemPrice'
/game_npctrade/npctrade.lua:525: in function 'checkMoney'
/game_npctrade/npctrade.lua:344: in function 'refreshPlayerGoods'
/game_npctrade/npctrade.lua:399: in function </game_npctrade/npctrade.lua:386>
npctrade.lua
Lua:
BUY = 1
SELL = 2
CURRENCY = 'gold'
CURRENCY_DECIMAL = false
WEIGHT_UNIT = 'oz'
LAST_INVENTORY = 10
npcWindow = nil
tradeWindow = nil
itemsPanel = nil
radioTabs = nil
radioItems = nil
--setupPanel = nil
quantity = nil
quantityScroll = nil
--nameLabel = nil
--priceLabel = nil
--moneyLabel = nil
tradeButton = nil
buyTab = nil
sellTab = nil
initialized = false
totalPrice = nil
priceLabel = nil
textUm = nil
textDois = nil
textTres = nil
playerFreeCapacity = 0
playerMoney = 0
tradeItems = {}
playerItems = {}
selectedItem = nil
cancelNextRelease = nil
function init()
npcWindow = g_ui.displayUI('npctrade')
npcWindow:setVisible(false)
tradeWindow = g_ui.displayUI('trade')
tradeWindow:setVisible(false)
itemsPanel = npcWindow:recursiveGetChildById('itemsPanel')
--setupPanel = npcWindow:recursiveGetChildById('setupPanel')
quantityScroll = tradeWindow:getChildById('quantityScroll')
--nameLabel = setupPanel:getChildById('name')
--priceLabel = setupPanel:getChildById('price')
--moneyLabel = setupPanel:getChildById('money')
tradeButton = npcWindow:recursiveGetChildById('tradeButton')
list = npcWindow:getChildById('list')
iconItem = tradeWindow:getChildById('iconItem')
totalPrice = tradeWindow:recursiveGetChildById('totalPriceText')
priceLabel = tradeWindow:recursiveGetChildById('price')
textUm = tradeWindow:recursiveGetChildById('textUm')
textDois = tradeWindow:recursiveGetChildById('textDois')
textTres = tradeWindow:recursiveGetChildById('textTres')
buyTab = npcWindow:getChildById('buyTab')
sellTab = npcWindow:getChildById('sellTab')
radioTabs = UIRadioGroup.create()
radioTabs:addWidget(buyTab)
radioTabs:addWidget(sellTab)
radioTabs:selectWidget(buyTab)
radioTabs.onSelectionChange = onTradeTypeChange
cancelNextRelease = false
if g_game.isOnline() then
playerFreeCapacity = g_game.getLocalPlayer():getFreeCapacity()
end
connect(g_game, { onGameEnd = hide,
onOpenNpcTrade = onOpenNpcTrade,
onCloseNpcTrade = onCloseNpcTrade,
onPlayerGoods = onPlayerGoods } )
connect(LocalPlayer, { onFreeCapacityChange = onFreeCapacityChange,
onInventoryChange = onInventoryChange } )
initialized = true
end
function terminate()
initialized = false
npcWindow:destroy()
disconnect(g_game, { onGameEnd = hide,
onOpenNpcTrade = onOpenNpcTrade,
onCloseNpcTrade = onCloseNpcTrade,
onPlayerGoods = onPlayerGoods } )
disconnect(LocalPlayer, { onFreeCapacityChange = onFreeCapacityChange,
onInventoryChange = onInventoryChange } )
end
function show()
if g_game.isOnline() then
if #tradeItems[BUY] > 0 then
radioTabs:selectWidget(buyTab)
else
radioTabs:selectWidget(sellTab)
end
npcWindow:show()
npcWindow:raise()
npcWindow:focus()
end
end
function hide()
npcWindow:hide()
end
function onItemBoxChecked(widget)
if widget:isChecked() then
local item = widget.item
selectedItem = item
refreshItem(item)
tradeButton:enable()
if getCurrentTradeType() == SELL then
quantityScroll:setValue(quantityScroll:getMaximum())
end
end
end
function onQuantityValueChange(quantity)
if selectedItem then
--priceLabel:setText(formatCurrency(getItemPrice(selectedItem)))
end
checkMoney()
end
function onTradeTypeChange(radioTabs, selected, deselected)
tradeButton:setText(selected:getText())
selected:setOn(true)
deselected:setOn(false)
refreshTradeItems()
refreshPlayerGoods()
end
function onTradeClick()
tradeWindow:show()
tradeWindow:focus()
iconItem:setItem(selectedItem.ptr)
iconItem.onMouseRelease = itemPopup
checkText()
end
function itemPopup(self, mousePosition, mouseButton)
if cancelNextRelease then
cancelNextRelease = false
return false
end
if mouseButton == MouseRightButton then
local menu = g_ui.createWidget('PopupMenu')
menu:setGameMenu(true)
menu:addOption(tr('Look'), function() return g_game.inspectNpcTrade(self:getItem()) end)
menu:display(mousePosition)
return true
elseif ((g_mouse.isPressed(MouseLeftButton) and mouseButton == MouseRightButton)
or (g_mouse.isPressed(MouseRightButton) and mouseButton == MouseLeftButton)) then
cancelNextRelease = true
g_game.inspectNpcTrade(self:getItem())
return true
end
return false
end
function setCurrency(currency, decimal)
CURRENCY = currency
CURRENCY_DECIMAL = decimal
end
function clearSelectedItem()
--nameLabel:clearText()
--priceLabel:clearText()
tradeButton:disable()
quantityScroll:setMinimum(0)
quantityScroll:setMaximum(0)
if selectedItem then
radioItems:selectWidget(nil)
selectedItem = nil
end
end
function getCurrentTradeType()
if tradeButton:getText() == tr('Buy') then
list:setText('Choose an item from the list to buy from the NPC.')
return BUY
else
list:setText('Choose an item from the list to sell it to the NPC.')
return SELL
end
end
function getItemPrice(item, single)
local amount = 1
local single = single or false
if not single then
amount = quantityScroll:getValue()
end
if getCurrentTradeType() == BUY then
if item.ptr:isStackable() then
return item.price*amount + 20
else
return item.price*amount + math.ceil(amount/20)*20
end
end
return item.price*amount
end
function getSellQuantity(item)
if not item or not playerItems[item:getId()] then return 0 end
local removeAmount = 0
local localPlayer = g_game.getLocalPlayer()
for i=1,LAST_INVENTORY do
local inventoryItem = localPlayer:getInventoryItem(i)
if inventoryItem and inventoryItem:getId() == item:getId() then
removeAmount = removeAmount + inventoryItem:getCount()
end
end
return playerItems[item:getId()] - removeAmount
end
function canTradeItem(item)
if getCurrentTradeType() == BUY then
return playerMoney >= getItemPrice(item, true)
else
return getSellQuantity(item.ptr) > 0
end
end
function refreshItem(item)
--nameLabel:setText(item.name)
--priceLabel:setText(formatCurrency(getItemPrice(item)))
if getCurrentTradeType() == BUY then
local capacityMaxCount = math.floor(playerFreeCapacity / item.weight)
local priceMaxCount = math.floor(playerMoney / getItemPrice(item, true))
local finalCount = math.max(0, math.min(getMaxAmount(), math.min(priceMaxCount, capacityMaxCount)))
quantityScroll:setMinimum(1)
quantityScroll:setMaximum(finalCount)
else
quantityScroll:setMinimum(1)
quantityScroll:setMaximum(math.max(0, math.min(getMaxAmount(), getSellQuantity(item.ptr))))
end
--setupPanel:enable()
end
function refreshTradeItems()
local layout = itemsPanel:getLayout()
layout:disableUpdates()
clearSelectedItem()
--setupPanel:disable()
itemsPanel:destroyChildren()
if radioItems then
radioItems:destroy()
end
radioItems = UIRadioGroup.create()
local currentTradeItems = tradeItems[getCurrentTradeType()]
for key,item in pairs(currentTradeItems) do
local itemBox = g_ui.createWidget('NPCItemBox', itemsPanel)
itemBox.item = item
itemBox.itemName = itemName
itemBox.itemPrice = itemPrice
local name = item.name
text = name
nameItemDescricao = text
local itemName = itemBox:getChildById('itemName')
itemName:setText(text)
local price = formatCurrency(item.price)
text = price
priceItemDescricao = text
local itemPrice = itemBox:getChildById('itemPrice')
itemPrice:setText(text)
local itemWidget = itemBox:getChildById('item')
itemWidget:setItem(item.ptr)
itemWidget.onMouseRelease = itemPopup
radioItems:addWidget(itemBox)
end
layout:enableUpdates()
layout:update()
end
function refreshPlayerGoods()
if not initialized then return end
checkSellAllTooltip()
--moneyLabel:setText(formatCurrency(playerMoney))
local currentTradeType = getCurrentTradeType()
local foundSelectedItem = false
local items = itemsPanel:getChildCount()
for i=1,items do
local itemWidget = itemsPanel:getChildByIndex(i)
local item = itemWidget.item
local canTrade = canTradeItem(item)
itemWidget:setOn(canTrade)
itemWidget:setEnabled(canTrade)
if selectedItem == item and itemWidget:isEnabled() and itemWidget:isVisible() then
foundSelectedItem = true
end
end
if not foundSelectedItem then
clearSelectedItem()
end
if selectedItem then
refreshItem(selectedItem)
end
if tradeWindow:isVisible() then
checkMoney()
checkText()
end
end
function onOpenNpcTrade(items)
tradeItems[BUY] = {}
tradeItems[SELL] = {}
for key,item in pairs(items) do
if item[4] > 0 then
local newItem = {}
newItem.ptr = item[1]
newItem.name = item[2]
newItem.weight = item[3] / 100
newItem.price = item[4]
table.insert(tradeItems[BUY], newItem)
end
if item[5] > 0 then
local newItem = {}
newItem.ptr = item[1]
newItem.name = item[2]
newItem.weight = item[3] / 100
newItem.price = item[5]
table.insert(tradeItems[SELL], newItem)
end
end
refreshTradeItems()
addEvent(show) -- player goods has not been parsed yet
end
function closeNpcTrade()
g_game.closeNpcTrade()
hide()
end
function onCloseNpcTrade()
hide()
end
function onPlayerGoods(money, items)
playerMoney = money
playerItems = {}
for key,item in pairs(items) do
local id = item[1]:getId()
if not playerItems[id] then
playerItems[id] = item[2]
else
playerItems[id] = playerItems[id] + item[2]
end
end
refreshPlayerGoods()
end
function onFreeCapacityChange(localPlayer, freeCapacity, oldFreeCapacity)
playerFreeCapacity = freeCapacity
if npcWindow:isVisible() then
refreshPlayerGoods()
end
end
function onInventoryChange(inventory, item, oldItem)
refreshPlayerGoods()
end
function getTradeItemData(id, type)
if table.empty(tradeItems[type]) then
return false
end
if type then
for key,item in pairs(tradeItems[type]) do
if item.ptr and item.ptr:getId() == id then
return item
end
end
else
for _,items in pairs(tradeItems) do
for key,item in pairs(items) do
if item.ptr and item.ptr:getId() == id then
return item
end
end
end
end
return false
end
function checkSellAllTooltip()
local total = 0
local info = ''
local first = true
for key, amount in pairs(playerItems) do
local data = getTradeItemData(key, SELL)
if data then
amount = getSellQuantity(data.ptr)
if amount > 0 then
if data and amount > 0 then
info = info..(not first and "\n" or "")..
amount.." "..
data.name.." ("..
data.price*amount.." gold)"
total = total+(data.price*amount)
if first then first = false end
end
end
end
end
end
function formatCurrency(amount)
if CURRENCY_DECIMAL then
return string.format("%.02f", amount/100.0) .. ' ' .. CURRENCY
else
return amount .. ' ' .. CURRENCY
end
end
function getMaxAmount()
if getCurrentTradeType() == SELL and g_game.getFeature(GameDoubleShopSellAmount) then
return 10000
end
return 100
end
function sellAll()
for itemid,item in pairs(playerItems) do
local item = Item.create(itemid)
local amount = getSellQuantity(item)
if amount > 0 then
g_game.sellItem(item, amount)
end
end
end
function checkText()
if tradeWindow:isVisible() then
-- TEXTO 1° LINHA
if getCurrentTradeType() == BUY then
itemDescricaoUm = 'You are buying ' .. nameItemDescricao .. ' for ' .. priceItemDescricao .. ' each.'
else
itemDescricaoUm = 'You are selling ' .. nameItemDescricao .. ' for ' .. priceItemDescricao .. ' each.'
end
textUm:setText(itemDescricaoUm)
-- TEXTO 2° LINHA
itemDescricaoDois = 'You are carrying ' .. playerMoney .. ' gold with you.'
textDois:setText(itemDescricaoDois)
-- TEXTO 3º LINHA
if getCurrentTradeType() == BUY then
itemPriceDescricao = getItemPrice(selectedItem, true)
if playerMoney > itemPriceDescricao then
quantidade = playerMoney / itemPriceDescricao
itemDescricaoTres = 'That means you can buy ' .. quantidade .. ' of them.'
textTres:setText(itemDescricaoTres)
else
itemDescricaoTres = 'You can not afford to buy this item.'
textTres:setText(itemDescricaoTres)
end
else
itemDescricaoTres = ''
textTres:setText(itemDescricaoTres)
end
end
end
function checkMoney()
if tradeWindow:isVisible() then
itemPriceDescricao = getItemPrice(selectedItem, true)
if playerMoney > itemPriceDescricao then
totalPrice:setColor("#c8c8c8")
priceLabel:setColor("#c8c8c8")
else
totalPrice:setColor("red")
priceLabel:setColor("red")
end
end
end
function onTradeConfirm()
if getCurrentTradeType() == BUY then
g_game.buyItem(selectedItem.ptr, quantityScroll:getValue())
else
g_game.sellItem(selectedItem.ptr, quantityScroll:getValue())
end
end
function onTradeCancel()
tradeWindow:hide()
end
Last edited: