--==<< Rock5's mail related functions >>==-- --==<< By Rock5 Version 1.90 b3 >>==-- --==<< >>==-- --==<< Requirements: modified Ultimate Mail Mod addon >>==-- --==<< ingamefunction addon installed >>==-- --==<< mailbox to already be open >>==-- --==<< >>==-- --==<< www.solarstrike.net/phpBB3/viewtopic.php?p=12952 >>==-- local UMM_FromSlot = 61 -- Default 61, first slot local UMM_ToSlot = 240 -- Default 240, last slot of bag 6 local use1UseMailbox local recipientMailFullString local stsnd = os.clock() -- "Mail recipient does not exist!" Warning message local function getRecipientDoisNotExistString() if not recipientDoisNotExistString then recipientDoisNotExistString = getTEXT("SYS_SENDMAIL_TARGET_ERROR") end return recipientDoisNotExistString end -- "Recipient's mailbox is full!" Warning message local function getMailboxFullString() if not recipientMailFullString then recipientMailFullString = getTEXT("SYS_SENDMAIL_TARGET_MAILFULL") end return recipientMailFullString end -- "You still cannot do this!" Warning message local function getCanotDoItString() if not mailsenderCanotDoItString then mailsenderCanotDoItString = getTEXT("SYS_CANOT_DO_IT") end return mailsenderCanotDoItString end -- taggedCount local function taggedCount() return RoMCode([[a=0 for k,v in pairs(UMMMailManager.Mails) do if v.WasRead then a=a+1 end end ]]) end -- returnMailCount local function returnMailCount() return RoMCode([[a=0 for k,v in pairs(UMMMailManager.Mails) do if v.Tagged then a=a+1 end end ]]) end -- UMM_SetSlotRange function UMM_SetSlotRange(_from, _to) ------------------------------- -- Sets the range of slots to send from (61-240) -- Error checks if type(_from) ~= "number" or type(_to) ~= "number" or _from > _to or _from < 61 or _to > 240 then error("Invalid arguments used in UMM_SetSlotRange(_from, _to). Valid values are from 61 to 240.") end UMM_FromSlot = _from UMM_ToSlot = _to end -- UMM_SetOneUseMailboxRelog function UMM_SetOneUseMailboxRelog(boolean) ------------------------------- -- Enables relogging after reaching the sending limit when using single-use convenient mailboxes. if type(boolean) == "boolean" then use1UseMailbox = boolean end end -- markToSend local function markToSend(_slotnumber) local item = inventory.BagSlot[_slotnumber + 60] item:update() if item.Empty then return end local bagid = math.floor((_slotnumber-1)/30+1) local slotid = _slotnumber - (bagid * 30 - 30) RoMCode("UMMMassSendItemsSlotTemplate_OnClick(_G['UMMFrameTab3BagsBag"..bagid.."Slot"..slotid.."'])") end -- openTab local function openTab(_tab) if _tab == 1 then RoMCode("UMMFrameTab1:Show()") yrest(50) RoMCode("UMMFrameTab2:Hide()") yrest(50) RoMCode("UMMFrameTab3:Hide()") yrest(50) RoMCode("UMMFrameTab1Viewer:Hide()") yrest(50) elseif _tab == 2 then RoMCode("UMMFrameTab1:Hide()") yrest(50) RoMCode("UMMFrameTab2:Show()") yrest(50) RoMCode("UMMFrameTab3:Hide()") yrest(50) elseif _tab == 3 then RoMCode("SetSendMailMoney(0, 0)") yrest(50) -- fix wrong gold send error RoMCode("UMMFrameTab1:Hide()") yrest(50) RoMCode("UMMFrameTab2:Hide()") yrest(50) RoMCode("UMMFrameTab3:Show()") yrest(50) end yrest(1000) end -- findMailbox function findMailbox() -- List of mailboxes and floating mail icon Id. local MailboxExceptions = { 110538, 110694, 110771, 110793, 112113, 112778, 113043, 113112, 113136, 113525, 114779, 117407, 118670, 118688, 119274, 122097, 123006, 123117, GetIdName(110538), -- Mailbox Name. GetIdName(122097), -- Hyern Mailbox. GetIdName(123006), -- Muckgale Mailbox. 123117, -- Hortek Mailbox (no name so use id). 110986, -- Mailbox icon Id. }; -- Check for a physical mailbox local mailboxicon = player:findNearestNameOrId(MailboxExceptions) -- Mailbox exceptions and Mail icon. if mailboxicon and distance(mailboxicon.X, mailboxicon.Z, player.X, player.Z) < 100 then if mailboxicon.Id == 110986 then -- Find mailbox near icon -- Search for mailbox under icon local closestObject = nil; local obj = nil; local objectList = CObjectList(); objectList:update(); for i = 0,objectList:size() do obj = objectList:getObject(i); if obj ~= nil and obj.Type == PT_NPC and obj.Id ~= 110986 then local dist = distance(mailboxicon.X, mailboxicon.Z, obj.X, obj.Z); if( closestObject ~= nil ) then if dist < distance(mailboxicon.X, mailboxicon.Z, closestObject.X, closestObject.Z) then -- this node is closer closestObject = obj; end elseif dist < 5 then closestObject = obj; end end end mailboxicon = closestObject end return "mailbox", mailboxicon end -- check for rented mailbox local rented = tonumber(RoMScript("TimeLet_GetLetTime(\"MailLet\")")) if rented and rented > 1 then return "rented mailbox" end -- Check for convenient mailbox local convmailbox = (inventory:findItem(208792) or inventory:findItem(201136)) if convmailbox then if convmailbox.Id == 208792 then return "7 day convenient mailbox", convmailbox else return "1 use convenient mailbox", convmailbox end end end -- tryRelog local function tryRelog() printf("\n") -- Find mailbox local mailtype, mailbox = findMailbox() -- If mailbox not found if not mailtype or (use1UseMailbox ~= true and mailtype == "1 use convenient mailbox") then cprintf(cli.yellow,"Mailing delayed. No mailbox found. Sending stopped.\n") return false end if getLastWarning(getCanotDoItString(),30) then -- if "You still cannot do this!" Warning message if not ChangeCharRestart then cprintf(cli.yellow,"Mailing delayed. Userfunction LoginNextChar not installed. Cannot send. Sending stopped.\n") return false end cprintf(cli.green,"Mailing delayed. Restarting before continuing.\n") ChangeCharRestart("current") else cprintf(cli.green,"Mailing delayed. Reloging before continuing.\n") repeat RoMCode("MailFrame:Hide()") until not RoMScript("MailFrame:IsVisible()") RoMCode("ChangeChar(CHARACTER_SELECT.selectedIndex)") waitForLoadingScreen() end rest(3000) player:update() return openMailbox() end --== Primary functions ==-- -- openMailbox function openMailbox() -- Check if already open if RoMScript("UMMFrame:IsVisible()") then return true else -- In case of bug after changing character RoMScript("OpenMail();CloseMail();CloseBank();") end -- Find mailbox local mailtype, mailbox = findMailbox() -- If mailbox not found if not mailtype then cprintf(cli.yellow,"Was unable to open mailbox. No mailbox, rented mailbox or convenient mailbox found\n") return false end -- Check mailbox type and open accordingly if mailtype == "mailbox" then player:target_NPC(mailbox.Id) yrest(2000) if RoMScript("SpeakFrame:IsVisible()") then RoMCode("ChoiceOption(1)") end elseif mailtype == "rented mailbox" then RoMCode("OpenMail()") elseif mailtype == "7 day convenient mailbox" or mailtype == "1 use convenient mailbox" then mailbox:use() end -- See if it opened successfully yrest(1000) if not RoMScript("MailFrame:IsVisible()") then cprintf(cli.yellow,"Attempt to open "..mailtype.." failed.\n") return false else -- Wait while loading mail repeat local Loading = RoMScript("string.find(UMMFrameTab1InfoLabel:GetText(),UMM_INBOX_LOADING,1,true)") yrest(50) until not Loading yrest(100) stsnd = os.clock() return true end end -- UMM_CountMail function UMM_CountMail(_type) ------------------------------- -- returns the count of mails of type _type -- Check type to count local itemName = false if _type == nil or _type:lower() == "everything" then _type = "everything" elseif _type:lower() == "money" then _type = "AttachedMoney" elseif _type:lower() == "diamonds" then _type = "AttachedDiamonds" elseif _type:lower() == "items" then _type = "AttachedItems" else itemName = true end -- Count if _type == "everything" then -- Count every mail return RoMScript("(#UMMMailManager.Mails)") elseif itemName then -- Count items by name match if( bot.ClientLanguage == "RU" ) then _type = utf82oem_russian(_type); end return RoMCode([[a=0 for k,v in pairs(UMMMailManager.Mails) do if string.find(v.Subject,"]].. _type ..[[") then a=a+1 end end]]) else -- Count item type; items, money or diamonds return RoMCode([[a=0 for k,v in pairs(UMMMailManager.Mails) do a=a+v.]].. _type ..[[ end]]) end end -- UMM_TakeMail function UMM_TakeMail(_type) ------------------------------- -- Takes all mail in the inbox of type "_type". -- Possible choices are "everything"(default), "items", "money", "diamonds" -- or the name of the items you wish to take. -- Error checks if not openMailbox() then return false, "Mailbox did not open" end -- Open correct tab openTab(1) -- Check if there is mail local InboxCount repeat InboxCount = UMM_CountMail(_type) until InboxCount ~= nil if InboxCount == 0 then -- no mail printf("No mail to take.\n") return true end -- Select option if _type specified if _type == nil or _type:lower() == "everything" then RoMCode("UMMFrameTab1Tools:SetOption(1)") elseif _type:lower() == "items" then -- All items RoMCode("UMMFrameTab1Tools:SetOption(2)") elseif _type:lower() == "money" then -- All money RoMCode("UMMFrameTab1Tools:SetOption(3)") elseif _type:lower() == "diamonds" then -- All diamonds RoMCode("UMMFrameTab1Tools:SetOption(4)") else -- All matching name items RoMCode([[for k,v in pairs(UMMMailManager.Mails) do if string.find(v.Subject,"]].. _type ..[[") then UMMMailManager:Tag(k) end end UMMFrameTab1TOC:RefreshTOC()]]) end -- Taking mail local starttimer = os.clock() repeat RoMCode("UMMFrameTab1Tools:ButtonClick('take');"); yrest(1000) until RoMScript("UMMMailManager.priv_AutoRunning") == true or RoMScript("UMMMailManager.MailCount") == 0 or os.clock() - starttimer > 5 local lastInboxCount = taggedCount() repeat yrest(5000) InboxCount = taggedCount() if InboxCount == lastInboxCount then -- Stuck RoMCode("HideUIPanel(MailFrame)") break end lastInboxCount = InboxCount until RoMScript("UMMMailManager.priv_AutoRunning") == nil if InboxCount > 0 and inventory:itemTotalCount(0) == 0 then printf("Inventory is full.\n") else printf("Mail taken.\n") end inventory:update() return true end -- UMM_DeleteEmptyMail function UMM_DeleteEmptyMail() ----------------------------------- -- Selects then deletes empty mail. -- Error checks if not openMailbox() then return false, "Mailbox did not open" end -- Open correct tab openTab(1) -- Click 'Empty' and then 'Delete' buttons RoMCode([[UMMFrameTab1Tools:ButtonClick("tagempty") if UMMFrameTab1ToolsButtonDelete:IsEnable() then UMMFrameTab1Tools:ButtonClick("delete") end]]) repeat yrest(2000) until RoMScript("UMMMailManager.priv_AutoRunning") == nil end -- UMM_ReturnMail function UMM_ReturnMail(_type, _senders) ------------------------------- -- Return all mail in the inbox of type "_type". -- Possible choices type, are "everything"(default), "items", "money", "diamonds" -- or the name of the items you wish to return. -- Possible choices senders, are "everything"(default), "chars", "friend", "guildis", -- "other", "empty" -- or the name of sender the items you wish to return. -- Error checks if not openMailbox() then return false, "Mailbox did not open" end -- Open correct tab openTab(1) -- Check if there is mail local InboxCount _type = _type or "everything" repeat InboxCount = UMM_CountMail(_type) until InboxCount ~= nil if InboxCount == 0 then -- no mail printf("No mail type: ".._type.." to return.\n") return true end -- Select option if _senders specified _senders = _senders or "everything" printf("Retun mail type: ".._type..", to senders: ".._senders..".\n") if _senders == nil or _senders:lower() == "everything" then RoMCode([[for k,v in pairs(UMMMailManager.Mails) do UMMMailManager:Tag(k) end UMMFrameTab1TOC:RefreshTOC()]]) elseif _senders:lower() == "chars" then -- All you chars RoMCode("UMMFrameTab1Tools:ButtonClick('tagchars');") elseif _senders:lower() == "friend" then -- All you friend RoMCode("UMMFrameTab1Tools:ButtonClick('tagfriends');") elseif _senders:lower() == "guildis" then -- All you guildis RoMCode("UMMFrameTab1Tools:ButtonClick('tagguildies');") elseif _senders:lower() == "other" then -- All other RoMCode("UMMFrameTab1Tools:ButtonClick('tagother');") elseif _senders:lower() == "empty" then -- All empty RoMCode("UMMFrameTab1Tools:ButtonClick('tagother');") elseif type(_senders) == "string" then -- All matching items by sender name RoMCode([[for k,v in pairs(UMMMailManager.Mails) do if string.find(v.Author,"]].. _senders ..[[") then UMMMailManager:Tag(k) end end UMMFrameTab1TOC:RefreshTOC()]]); end -- Select option if _type specified wich can be reply if _type == nil or _type:lower() == "everything" then -- do nufing elseif _type:lower() == "items" then -- All items RoMCode([[for k,v in pairs(UMMMailManager.Mails) do if v.Tagged and 1 > v.AttachedItems then UMMMailManager:UnTag(k) end end UMMFrameTab1TOC:RefreshTOC()]]); elseif _type:lower() == "money" then -- All money RoMCode([[for k,v in pairs(UMMMailManager.Mails) do if v.Tagged and 1 > v.AttachedMoney then UMMMailManager:UnTag(k) end end UMMFrameTab1TOC:RefreshTOC()]]); elseif _type:lower() == "diamonds" then -- All diamonds RoMCode([[for k,v in pairs(UMMMailManager.Mails) do if v.Tagged and 1 > v.AttachedDiamonds then UMMMailManager:UnTag(k) end end UMMFrameTab1TOC:RefreshTOC()]]); else -- All matching name items RoMCode([[for k,v in pairs(UMMMailManager.Mails) do if v.Tagged and not string.find(v.Subject,"]].. _type ..[[") then UMMMailManager:UnTag(k) end end UMMFrameTab1TOC:RefreshTOC()]]); end -- Skip any mails with C.O.D. amounds --RoMCode([[for k,v in pairs(UMMMailManager.Mails) do --if v.CODAmount == 0 then UMMMailManager:UnTag(k) end end --UMMFrameTab1TOC:RefreshTOC()]]) -- Return mail if returnMailCount() > 0 then local starttimer = os.clock() repeat RoMCode("UMMFrameTab1Tools:ButtonClick('return');"); yrest(1000) until RoMScript("UMMMailManager.priv_AutoRunning") == true or returnMailCount() == 0 or RoMScript("UMMMailManager.MailCount") == 0 or os.clock() - starttimer > 5 local lastInboxCount = taggedCount() repeat yrest(5000) InboxCount = taggedCount() if InboxCount == lastInboxCount then -- Stuck RoMCode("HideUIPanel(MailFrame)") break end lastInboxCount = InboxCount until RoMScript("UMMMailManager.priv_AutoRunning") == nil end if InboxCount > 0 and inventory:itemTotalCount(0) == 0 then printf("Inventory of sender is full.\n") else printf("Mail returned.\n") end inventory:update() return true end -- UMM_SendMoney function UMM_SendMoney(_recipient, _amount) ------------------------------------- -- Sends amount of gold to recipient. -- Error checks if not openMailbox() then return false, "Mailbox did not open" end repeat Copper = RoMScript("GetPlayerMoney('copper')") until Copper ~= nil if _recipient == nil or _amount == nil then error("You must specify a recipient and amount of gold to send when using UMM_SendMoney()") elseif type(_amount) ~= "number" and string.lower(_amount) ~= "all" then error("Argument #2 to UMM_SendMoney(): Expected type 'number' or text value 'all'.") end if string.lower(_amount) == "all" or _amount > Copper then _amount = Copper end printf("Sending money to ".._recipient.."... ") -- Open correct tab openTab(2) -- Enter recipients name RoMCode("UMMFrameTab2ComposerHeaderAuthor:SetText('".._recipient.."');") -- Set money RoMCode("UMMFrameTab2ComposerFooterMoney:SetText(".._amount..");") -- Sending RoMCode("UMMFrameTab2Composer:Send()") printf("Money sent.\n") return true end -- UMM_SendAdvanced function UMM_SendAdvanced(_recipient, _itemTable, _quality, _reqLevel, _worth, _objType, _statNo, _dura, _amount, _stackSize, _fusedTier, _statsList) ---------------------------------- -- Sends if all search terms match local debugfilter = false inventory:update() local function passesFilter(_slotitem) -- Empty, rented, Bound? if not _slotitem.Available or _slotitem.Empty then return false end if debugfilter then printf("\n%16s slot%3d ",string.sub(_slotitem.Name,1,15),_slotitem.SlotNumber) end if not bitAnd(_slotitem.BoundStatus, 1) then if debugfilter then printf("Bound") end return false end -- Check name or id if _itemTable ~= nil then local match = false for __, nam in pairs(_itemTable) do if string.find(string.lower(_slotitem.Name),string.lower(nam)) or (_slotitem.Id == tonumber(nam)) then match = true break end end if match == false then if debugfilter then printf("No item name match") end return false end end -- Check Quality if _quality ~= nil and _slotitem.Quality < _quality then if debugfilter then printf("Quality too low") end return false end -- Check RequiredLvl if _reqLevel ~= nil and _slotitem.RequiredLvl < _reqLevel then if debugfilter then printf("Level too low") end return false end -- Check Worth if _worth ~= nil and _slotitem.Worth < _worth then if debugfilter then printf("Worth too low") end return false end -- Check ObjType if _objType ~= nil then local match = false for __, typ in pairs(_objType) do if _slotitem:isType(typ) then match = true break end end if match == false then if debugfilter then printf("No item type match") end return false end end -- Check StatNo if _statNo ~= nil then -- Not Clean? if _statNo == 0 and #_slotitem.Stats ~= 0 then -- not clean return false end -- Clean but not weapon or armor if _statNo == 0 and not (_slotitem.ObjType == 0 or _slotitem.ObjType == 1) then return false end -- Enough stats if _statNo > 0 and #_slotitem.Stats < _statNo then -- not enough stats return false end end -- Check Dura if _dura ~= nil and (_slotitem.MaxDurability or _slotitem.Durability) < _dura then return false end -- Check Stacksize if _stackSize ~= nil then -- Full stack? if string.lower(_stackSize) == "max" and _slotitem.ItemCount ~= _slotitem.MaxStack then return false end -- Not big enough stack if type(_stackSize) == "number" and _slotitem.ItemCount < _stackSize then return false end end -- Check fused tier. That is what tier level mana stone the item would make. if _fusedTier ~= nil then -- Only weapons and armor can be fused if not (_slotitem.ObjType == 0 or _slotitem.ObjType == 1) then return false end -- If weapon, can't be projectile if _slotitem.ObjType == 0 and _slotitem.ObjSubType == 6 then return false end -- If weapon, can't be arrows if _slotitem.ObjType == 0 and _slotitem.ObjSubType == 5 and _slotitem.ObjSubSubType == 2 then return false end -- Calculate item level including quality local level = _slotitem.RequiredLvl if _slotitem.Quality > 0 then level = level + 2 end if _slotitem.Quality > 1 then level = level + (_slotitem.Quality - 1) * 4 end -- Calculate tier level local tier = 1 if level >= 20 and level <= 39 then tier = 2 elseif level >= 40 and level <= 59 then tier = 3 elseif level >= 60 and level <= 79 then tier = 4 elseif level >= 80 and level <= 99 then tier = 5 end if tier < _fusedTier then return false end end -- Searches for 1 or more stats in _slotitem.Stats list -- All must be found to return true local function hasStat(stats) if type(stats) == "table" then for _,stat in pairs(stats) do if not hasStat(stat) then -- A stat is missing so return false return false end end -- All stats exist so return true return true else for _, itemstat in pairs(_slotitem.Stats) do if type(stats) == "number" then if itemstat.Id == stats and itemstat.Name == getTEXT("Sys"..stats.."_name") then -- The stat exists so return true return true end elseif itemstat.Id == stats or itemstat.Name == stats then -- The stat exists so return true return true end end -- The stat doesn't exist so return false return false end end -- Check and find stats if _statsList ~= nil and #_statsList > 0 then -- First check enough stats if _statNo used if _statNo ~= nil and #_slotitem.Stats ~= _statNo then return false end if type(_statsList[1]) ~= "table" then -- Only 1 table of stats -- Chack if not have all stats if not hasStat(_statsList) then return false end -- Check if wrong number of stats if _statNo == nil and #_statsList ~= #_slotitem.Stats then return false end else -- Table of tables of stats. -- Need to match 1 set local matched = false for j, value in pairs(_statsList) do if hasStat(value) then -- Has all stats but do the number of stats match if _statNo ~= nil and #value ~= #_slotitem.Stats then return false else matched = true break end end end -- If no set of stats match then return false if not matched then return false end end end if debugfilter then printf("Sent") end return true end -- Error checks if not openMailbox() then return false, "Mailbox did not open" end if _recipient == nil then error("You must specify a recipient to use UMM_SendAdvanced()") elseif _itemTable ~= nil and type(_itemTable) ~= "table" and type(_itemTable) ~= "number" and type(_itemTable) ~= "string" then error("Argument #2 to UMM_SendAdvanced(): Expected type 'table' or 'string' or 'number', got '" .. type(_itemTable) .. "'") elseif _quality ~= nil and type(_quality) ~= "number" then error("Argument #3 to UMM_SendAdvanced(): Expected type 'number', got '" .. type(_quality) .. "'") elseif _reqLevel ~= nil and type(_reqLevel) ~= "number" then error("Argument #4 to UMM_SendAdvanced(): Expected type 'number', got '" .. type(_reqLevel) .. "'") elseif _worth ~= nil and type( _worth) ~= "number" then error("Argument #5 to UMM_SendAdvanced(): Expected type 'number', got '" .. type(_worth) .. "'") elseif _objType ~= nil and type(_objType) ~= "string" and type(_objType) ~= "table" then error("Argument #6 to UMM_SendAdvanced(): Expected type 'string' or 'table', got '" .. type(_objType) .. "'") elseif _statNo ~= nil and type(_statNo) ~= "number" then error("Argument #7 to UMM_SendAdvanced(): Expected type 'number', got '" .. type(_statNo) .. "'") elseif _dura ~= nil and type(_dura) ~= "number" then error("Argument #8 to UMM_SendAdvanced(): Expected type 'number', got '" .. type(_dura) .. "'") elseif _amount ~= nil and type(_amount) ~= "number" then error("Argument #9 to UMM_SendAdvanced(): Expected type 'number', got '" .. type(_amount) .. "'") elseif _stackSize ~= nil and type(_stackSize) ~= "number" and string.lower(_stackSize) ~= "max" then error("Argument #10 to UMM_SendAdvanced(): Expected type 'number' or string 'max', got '" .. type(_stackSize) .. "'") elseif _fusedTier ~= nil and type(_fusedTier) ~= "number" then error("Argument #11 to UMM_SendAdvanced(): Expected type 'number', got '" .. type(_fusedTier) .. "'") elseif _statsList ~= nil and type(_statsList) ~= "table" and type(_statsList) ~= "string" and type(_statsList) ~= "number" then error("Argument #12 to UMM_SendAdvanced(): Expected type 'table' or 'string' or 'number', got '" .. type(_statsList) .. "'") end -- place item in table if not already if type(_itemTable) == "number" or type(_itemTable) == "string" then _itemTable = {_itemTable} end -- place item type in table if not already if type(_objType) == "string" then _objType = {_objType} end -- place stats in table if not already if type(_statsList) == "number" or type(_statsList) == "string" then _statsList = {_statsList} end -- Make table of items to send local counter = 0 local sendlist = {} local itemlinks = {} for item = UMM_FromSlot, UMM_ToSlot, 1 do -- for each inventory local slotitem = inventory.BagSlot[item]; local slotNumber = slotitem.SlotNumber - 60 if passesFilter(slotitem) then -- Check if split is necessary if _amount and (counter + slotitem.ItemCount > _amount) then -- split local emptyslot = inventory:findItem(0,"bags") if not emptyslot then error("Can't split stack for UMM_SendByNameOrId function. Inventory is full.") end local topickup = slotitem.ItemCount - (_amount - counter) RoMCode("SplitBagItem("..slotitem.BagId.." ,"..topickup..")") repeat yrest(50) until cursor:hasItem() emptyslot:pickup() repeat yrest(50) emptyslot:update() until not emptyslot.Empty -- yrest(1500) slotitem:update() end -- Increment counter counter = counter + slotitem.ItemCount -- Add to table table.insert(sendlist, slotNumber) itemlinks[slotNumber] = slotitem.ItemLink --! need code for check items in ItemQueue. -- Are we finished if _amount and counter >= _amount then break end end end cprintf(cli.green,"Sending items to ".._recipient.."... ") -- Check if nothing to send if #sendlist == 0 then cprintf(cli.lightgreen,"Nothing to send.\n") return true end local numberLeft = 0 stsnd = os.clock() repeat -- open Mailbox if not RoMScript("MailFrame:IsVisible()") then if not openMailbox() then if tryRelog() == false then return false, "Mailbox did not open" end end end -- Open correct tab openTab(3) -- Selecting items for __, slotNumber in pairs(sendlist) do markToSend(slotNumber) end yrest(1000) -- Enter recipients name RoMCode("UMMFrameTab3RecipientRecipient:SetText('".._recipient.."');") -- Sending RoMCode("UMMFrameTab3Action:Send()") -- Waiting until finished local st = os.clock() repeat yrest(2000) -- return if "Mail recipient does not exist!" Warning message if getLastWarning(getRecipientDoisNotExistString(), os.clock()-st) then inventory:update() cprintf(cli.lightgreen,"Mail recipient does not exist!\n") repeat RoMCode("MailFrame:Hide()") until not RoMScript("MailFrame:IsVisible()") return false, "Mail recipient does not exist!" end -- return if "Recipient's bags are full" Warning message if getLastWarning(getMailboxFullString(), os.clock()-st) then inventory:update() cprintf(cli.lightgreen,"Recipient's bags are full.\n") repeat RoMCode("MailFrame:Hide()") until not RoMScript("MailFrame:IsVisible()") return false, "Recipient's bags are full" end until RoMScript("UMMFrameTab3Status:IsVisible()") == false or RoMScript("MailFrame:IsVisible()") == false -- Check if all items are gone numberLeft = 0 inventory:update() for __, slotNumber in pairs(sendlist) do if type(inventory.BagSlot[slotNumber + 60].Empty) ~= "nil" and not inventory.BagSlot[slotNumber + 60].Empty and itemlinks[slotNumber] == inventory.BagSlot[slotNumber + 60].ItemLink then numberLeft = numberLeft + 1 else table.remove(sendlist, slotNumber) end end if numberLeft ~= 0 then -- Wait a bit more for "Recipient's bags are full" Warning message local stt = os.clock() repeat yrest(2000) if getLastWarning(getMailboxFullString(), os.clock()-st) then inventory:update() cprintf(cli.lightgreen,"Recipient's bags are full.\n") repeat RoMCode("MailFrame:Hide()") until not RoMScript("MailFrame:IsVisible()") return false, "Recipient's bags are full" end until os.clock()-stt > 2 -- 2s maximum if os.clock()-stsnd >= #sendlist*4 then if getZoneId() == 401 -- tryRelog not work in Guild castle or tryRelog() == false then break end end end until numberLeft == 0 inventory:update() if numberLeft == 0 then cprintf(cli.lightgreen,"Items sent.\n") return true else cprintf(cli.lightgreen,"Failed to send all items.\n") return false, "Failed to send all items" end end -- UMM_SendInventoryItem function UMM_SendInventoryItem(_recipient, _itemTable) ------------------------------------------------------- -- Sends an inventory item by item object or slotnumber or a table of objects and slotnumbers -- Error checks if not openMailbox() then return false, "Mailbox did not open" end if _recipient == nil then error("You must specify a recipient when using UMM_SendInventoryItem()") end -- Check if table of items if not (type(_itemTable) == "table") or (_itemTable.Id ~= nil) then -- Put into item table _itemTable = {_itemTable} end printf("Sending inventory items to ".._recipient.."... ") local slotitem local slotNumber local numberLeft local itemlinks = {} local mailsent = false repeat -- Open correct tab openTab(3) -- Mark to send for num, item in pairs(_itemTable) do if type(item) == "table" then slotitem = item slotNumber = item.SlotNumber - 60 else local itemslot = tonumber(item) if type(itemslot) == "nil" then error("UMM_SendInventoryItem() invalid item value, "..item or "nil") end slotNumber = itemslot - 60 slotitem = inventory.BagSlot[item] end if slotNumber < 1 or slotNumber > 180 then error("UMM_SendInventoryItem() can only send items from the bags, from slot 61 to 240.".. " If using 'inventory:findItem' make sure you use the second argument \"bags\" ".. "to restrict the search to the 'bags' and exclude the itemshop bag and magicbox.") end if slotitem.Available and not slotitem.Empty and bitAnd(slotitem.BoundStatus, 1) then itemlinks[slotNumber] = slotitem.ItemLink --! need code for check items in ItemQueue. mailsent = true markToSend(slotNumber) yrest(1000) else -- Can't send, remove from list _itemTable[num] = nil end end if not mailsent then printf("Nothing to send.\n") return true end -- Enter recipients name RoMCode("UMMFrameTab3RecipientRecipient:SetText('".._recipient.."');") -- Sending RoMCode("UMMFrameTab3Action:Send()") -- Waiting until finished local st = os.clock() repeat yrest(2000) if getLastWarning(getMailboxFullString(), os.clock()-st) then inventory:update() cprintf(cli.lightgreen,"Recipient's bags are full.\n") return false, "Recipient's bags are full" end until RoMScript("UMMFrameTab3Status:IsVisible()") == false or RoMScript("MailFrame:IsVisible()") == false -- Check if all items are gone numberLeft = 0 inventory:update() for __, slotNumber in pairs(_itemTable) do if type(slotNumber) == "table" then slotNumber = slotNumber.SlotNumber end if type(inventory.BagSlot[slotNumber + 60].Empty) ~= "nil" and not inventory.BagSlot[slotNumber + 60].Empty and itemlinks[slotNumber] == inventory.BagSlot[slotNumber + 60].ItemLink then numberLeft = numberLeft + 1 end end if numberLeft ~= 0 and tryRelog() == false then break end until numberLeft == 0 inventory:update() if numberLeft == 0 then cprintf(cli.lightgreen,"Items sent.\n") return true else cprintf(cli.lightgreen,"Failed to send all items.\n") return false, "Failed to send all items" end end -- UMM_SendByRange function UMM_SendByRange(_recipient, _from, _to) ------------------------------------------------------------ -- Sends all items in inventory in the slot range specified. -- Error checks if not openMailbox() then return false, "Mailbox did not open" end if _recipient == nil then error("You must specify a recipient and item or slotnumber when using UMM_SendByRange()") elseif type(_from) ~= "number" then error("Argument #2 to UMM_SendByRange(): Expected type 'number', got '" .. type(_from) .. "'") elseif type(_to) ~= "number" then error("Argument #3 to UMM_SendByRange(): Expected type 'number', got '" .. type(_to) .. "'") elseif _from < 61 or _to > 240 or _from > _to then error("Invalid range used in UMM_SendByRange(). Can only send items from slot 61 to 240.") end printf("Sending item range to ".._recipient.."... ") -- Open correct tab openTab(3) -- Mark items to send local marked = false for slot = _from, _to do local slotitem = inventory.BagSlot[slot] local slotNumber = slot - 60 if slotitem.Available and not slotitem.Empty and bitAnd(slotitem.BoundStatus, 1) then markToSend(slotNumber) yrest(1000) marked = true end end -- Were any marked for sending if not marked then printf("Nothing to send.\n") return true end -- Enter recipients name RoMCode("UMMFrameTab3RecipientRecipient:SetText('".._recipient.."');") -- Sending RoMCode("UMMFrameTab3Action:Send()") -- Waiting until finished local st = os.clock() repeat yrest(2000) if getLastWarning(getMailboxFullString(), os.clock()-st) then inventory:update() cprintf(cli.lightgreen,"Recipient's bags are full.\n") return false, "Recipient's bags are full" end until RoMScript("UMMFrameTab3Status:IsVisible()") == false or RoMScript("MailFrame:IsVisible()") == false printf("Items sent.\n") inventory:update() return true end --== Customised 'specific need' functions ==-- -- UMM_SendByQuality function UMM_SendByQuality(_recipient, _quality) ---------------------------------------- -- Sends bag items by quality or higher. -- 1 = green, 2 = blue, 3 = purple, etc. -- Error checks if not openMailbox() then return false, "Mailbox did not open" end if _recipient == nil then error("You must specify a recipient to use UMM_SendByQuality()") elseif type(_quality) ~= "number" then error("Argument #2 to UMM_SendByQuality(): Expected type 'number', got '" .. type(_quality) .. "'") elseif _quality < 0 or _quality > 5 then error("Incorrect quality level specified. Valid levels are 0 to 5, where 0 = white, 1 = green, etc.") end printf("Sending items by quality.\n") -- Sending items return UMM_SendAdvanced(_recipient, nil, _quality) end -- UMM_SendByStats function UMM_SendByStats(_recipient, _itemTable, _statsList, _statNo, _amount) -------------------------------------- -- Sending an inventory items by stats -- Error checks if not openMailbox() then return false, "Mailbox did not open" end if _recipient == nil then error("You must specify a recipient to use UMM_SendByStats()") elseif _statsList == nil or _itemTable == nil then error("You must specify a _statsList or _itemTable to use UMM_SendByStats()") elseif type(_itemTable) ~= "table" and type(_itemTable) ~= "number" and type(_itemTable) ~= "string" then error("Argument #2 to UMM_SendByStats(): Expected type 'table' or 'string' or 'number', got '" .. type(_itemTable) .. "'") elseif type(_statsList) ~= "table" and type(_statsList) ~= "string" and type(_statsList) ~= "number" then error("Argument #3 to UMM_SendByStats(): Expected type 'table' or 'string' or 'number', got '" .. type(_statsList) .. "'") elseif _statNo ~= nil and type(_statNo) ~= "number" then error("Argument #4 to UMM_SendByStats(): Expected type 'number', got '" .. type(_statNo) .. "'") elseif _amount ~= nil and type(_amount) ~= "number" then error("Argument #5 to UMM_SendByStats(): Expected type 'number', got '" .. type(_amount) .. "'") end printf("\nSending Items by stats.\n") -- Sending items UMM_SendAdvanced(_recipient,_itemTable,nil,nil,nil,nil,_statNo,nil,_amount,nil,nil,_statsList) end -- UMM_SendByStatNumber function UMM_SendByStatNumber(_recipient, _statNo) -------------------------------------- -- Sends bag items by number of stats. -- Error checks if not openMailbox() then return false, "Mailbox did not open" end if _recipient == nil then error("You must specify a recipient when using UMM_SendByStatNumber()") end if type(_statNo) ~= "number" or _statNo < 0 or _statNo > 6 then _statNo = 3 -- Default value if value invalid end printf("Sending items by stat number.\n") -- Sending items return UMM_SendAdvanced(_recipient, nil, nil, nil, nil, nil, _statNo) end -- UMM_SendByNameOrId function UMM_SendByNameOrId(_recipient, _itemTable, _amount) --------------------------------- -- Sends bag items by name or id. -- Error checks if not openMailbox() then return false, "Mailbox did not open" end if _recipient == nil or _itemTable == nil then error("You must specify a recipient and item table when using UMM_SendByNameOrId()") elseif type(_itemTable) ~= "table" and type(_itemTable) ~= "number" and type(_itemTable) ~= "string" then error("Argument #2 to UMM_SendByNameOrId(): Expected type 'table' or 'string' or 'number', got '" .. type(_itemTable) .. "'") elseif _amount and type(_amount) ~= "number" then error("Argument #3 to UMM_SendByNameOrId(): Expected type 'number' or 'nil', got '" .. type(_amount) .. "'") end printf("Sending items by name or id.\n") -- Sending items return UMM_SendAdvanced(_recipient, _itemTable, nil, nil, nil, nil, nil, nil, _amount) end -- UMM_SendByDura function UMM_SendByDura(_recipient, _dura, _statNo, _objType) ---------------------------------- -- Sends items by dura and statno. -- Error checks if not openMailbox() then return false, "Mailbox did not open" end if _recipient == nil or _dura == nil then error("You must specify a recipient and dura level when using UMM_SendByDura()") elseif type(_dura) ~= "number" then error("Argument #2 to UMM_SendByDura(): Expected type 'number', got '" .. type(_dura) .. "'") elseif _statNo ~= nil and type(_statNo) ~= "number" then error("Argument #3 to UMM_SendByDura(): Expected type 'number', got '" .. type(_statNo) .. "'") elseif _objType ~= nil and type(_objType) ~= "string" and type(_objType) ~= "table" then error("Argument #4 to UMM_SendByDura(): Expected type 'string' or 'table', got '" .. type(_objType) .. "'") end printf("Sending items by dura.\n") -- Sending items return UMM_SendAdvanced(_recipient, nil, nil, nil, nil, _objType, _statNo, _dura) end -- UMM_SendByStackSize function UMM_SendByStackSize(_recipient, _itemTable, _stackSize) --------------------------------- -- Sends bag items by stack size. -- Error checks if not openMailbox() then return false, "Mailbox did not open" end if _recipient == nil or _itemTable == nil or _stackSize == nil then error("You must specify a recipient, item table and stack size when using UMM_SendByStackSize()") elseif type(_itemTable) ~= "table" and type(_itemTable) ~= "number" and type(_itemTable) ~= "string" then error("Argument #2 to UMM_SendByStackSize(): Expected type 'table' or 'string' or 'number', got '" .. type(_itemTable) .. "'") elseif type(_stackSize) ~= "number" and string.lower(_stackSize) ~= "max" then error("Argument #3 to UMM_SendByStackSize(): Expected type 'number' or string 'max', got '" .. type(_stackSize) .. "'") end printf("Sending items by stack size.\n") -- Sending items return UMM_SendAdvanced(_recipient, _itemTable, nil, nil, nil, nil, nil, nil, nil, _stackSize) end -- UMM_SendByFusedTierLevel function UMM_SendByFusedTierLevel(_recipient, _fusedTier, _amount) --------------------------------- -- Sends bag items by fused tier. -- Error checks if not openMailbox() then return false, "Mailbox did not open" end if _recipient == nil or _fusedTier == nil then error("You must specify a recipient and fused tier when using UMM_SendByFusedTierLevel()") elseif type(_fusedTier) ~= "number" then error("Argument #2 to UMM_SendByFusedTierLevel(): Expected type 'number', got '" .. type(_fusedTier) .. "'") elseif _amount and type(_amount) ~= "number" then error("Argument #3 to UMM_SendByFusedTierLevel(): Expected type 'number' or 'nil', got '" .. type(_amount) .. "'") end printf("Sending items by fused tier.\n") -- Sending items return UMM_SendAdvanced(_recipient, nil, nil, nil, nil, nil, nil, nil, _amount, nil, _fusedTier) end