EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Quests::LUA (https://www.eqemulator.org/forums/forumdisplay.php?f=680)
-   -   lua_modules/items.lua enhanced (https://www.eqemulator.org/forums/showthread.php?t=39257)

iluvseq 01-21-2015 11:52 AM

lua_modules/items.lua enhanced
 
Below is a new items.lua for lua_modules.

This supports stacked items and quests that require multiples of the same item (stacked or unstacked). It changes the check_turn_in call syntax slightly to support this, but gives full support for clients handing in a mix of stacked and unstacked items and properly crediting the quest results.

Example code using this module:
Code:

function event_trade(e)
  local item_lib = require("items")
  local pfaction = e.other:GetFaction(e.self)

  while item_lib.check_turn_in(e.trade, {[13717] = 1}) do  -- Rat Head
    e.self:QuestSay(e.other, "Thank you for helping reduce the rat population!  Here is your reward...")
    if (pfaction < 5) then -- only give money to friendly folks
      e.other:GiveCash(math.random(10),math.random(2),0,0)
    end -- everyone gets faction hits and XP though
    e.other:Faction(1,1,0)
    e.other:Faction(2,-1,0)
    e.other:AddEXP(35)
  end

  item_lib.return_items(e.self, e.other, e.trade)
end

Code:

local items = {}

function items.check_turn_in(trade, trade_check)
  --create trade_return table == trade
  --shallow copy
  local trade_return = {};
  for key, value in pairs(trade) do
    trade_return[key] = value;
  end

  -- trade_check contains item_id => qty mapping
  -- for each item handed to us, check if it is in trade_check
  for i = 1, 4 do
    local inst = trade_return["item" .. i]  -- get an item instance that was handed to us
    if(inst.valid and trade_check[inst:GetID()] > 0) then  -- we have a valid item and it's ID is in the trade_check map
      if (inst:IsStackable()) then
        while (trade_check[inst:GetID()] > 0 and inst:GetCharges() >= trade_check[inst:GetID()]) do
          inst:SetCharges(inst:GetCharges() - 1) -- remove one item from the stack
          trade_check[inst:GetID()] = trade_check[inst:GetID()] - 1 -- decrement the count of required items in trade_check
        end
        if (inst:GetCharges() > 0) then -- still have items in the stack, return the remainder
          trade_return["item" .. i] = inst
        else
          trade_return["item" .. i] = ItemInst()  -- stack empty, return nothing
        end
      else
        trade_return["item" .. i] = ItemInst()  -- remove this item from our return queue
        trade_check[inst:GetID()] = trade_check[inst:GetID()] - 1 -- decrement the count of required items in trade_check
      end
    end
  end

  local items_left = 0;
  for key,value in pairs(trade_check) do
    if (key ~= "platinum" and key ~= "gold" and key ~= "silver" and key ~= "copper" and value > 0) then
      items_left = items_left + value
    end
  end
  if (items_left > 0) then return false end  -- we didn't find all of our items

  --convert our money into copper then check that we have enough then convert change back
  local trade_check_money = 0;
  local return_money = 0;

  if(trade_check["platinum"] ~= nil and trade_check["platinum"] ~= 0) then
    trade_check_money = trade_check_money + (trade_check["platinum"] * 1000);
  end

  if(trade_check["gold"] ~= nil and trade_check["gold"] ~= 0) then
    trade_check_money = trade_check_money + (trade_check["gold"] * 100);
  end

  if(trade_check["silver"] ~= nil and trade_check["silver"] ~= 0) then
    trade_check_money = trade_check_money + (trade_check["silver"] * 10);
  end

  if(trade_check["copper"] ~= nil and trade_check["copper"] ~= 0) then
    trade_check_money = trade_check_money + trade_check["copper"];
  end

  return_money = return_money + trade_return["platinum"] * 1000 + trade_return["gold"] * 100;
  return_money = return_money + trade_return["silver"] * 10 + trade_return["copper"];

  if(return_money < trade_check_money) then
    return false;
  else
    return_money = return_money - trade_check_money;
  end

  --replace trade with trade_return
  trade.item1 = trade_return.item1
  trade.item2 = trade_return.item2
  trade.item3 = trade_return.item3
  trade.item4 = trade_return.item4

  trade.platinum = math.floor(return_money / 1000)
  return_money = return_money - (trade.platinum * 1000)

  trade.gold = math.floor(return_money / 100)
  return_money = return_money - (trade.gold * 100)

  trade.silver = math.floor(return_money / 10)
  return_money = return_money - (trade.silver * 10)

  trade.copper = return_money
  return true
end

function items.return_items(npc, client, trade, text)
  text = text or true
  local returned = false
  for i = 1, 4 do
    local inst = trade["item" .. i]
    if(inst.valid) then
      if(eq.is_disc_tome(inst:GetID()) and npc:GetClass() > 19 and npc:GetClass() < 36) then
        if(client:GetClass() == npc:GetClass() - 19) then
          client:TrainDisc(inst:GetID())
        else
          npc:Say(string.format("You are not a member of my guild. I will not train you!"))
          client:PushItemOnCursor(inst)
          returned = true
        end
      else
        client:PushItemOnCursor(inst)
        if(text == true) then
          npc:Say(string.format("I have no need for this %s, you can have it back.", client:GetCleanName()))
        end
        returned = true
      end
    end
  end

  local money = false
  if(trade.platinum ~= 0) then
    returned = true
    money = true
  end

  if(trade.gold ~= 0) then
    returned = true
    money = true
  end

  if(trade.silver ~= 0) then
    returned = true
    money = true
  end

  if(trade.copper ~= 0) then
    returned = true
    money = true
  end

  if(money == true) then
    client:AddMoneyToPP(trade.copper, trade.silver, trade.gold, trade.platinum, true)
  end

  return returned
end

return items



All times are GMT -4. The time now is 05:56 PM.

Powered by vBulletin®, Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.