-- ================================================================================ -- -- EMA - ( Ebony's MultiBoxing Assistant ) -- -- Current Author: Jennifer Cally (Ebony) -- -- -- -- License: All Rights Reserved 2018-2020 Jennifer Cally -- -- -- -- Some Code Used from "Jamba" that is -- -- Released under the MIT License -- -- "Jamba" Copyright 2008-2015 Michael "Jafula" Miller -- -- -- -- ================================================================================ -- -- Create the addon using AceAddon-3.0 and embed some libraries. local EMA = LibStub( "AceAddon-3.0" ):NewAddon( "Purchase", "Module-1.0", "AceConsole-3.0", "AceEvent-3.0", "AceHook-3.0" ) -- Load libraries. local EMAUtilities = LibStub:GetLibrary( "EbonyUtilities-1.0" ) local EMAHelperSettings = LibStub:GetLibrary( "EMAHelperSettings-1.0" ) local LibBagUtils = LibStub:GetLibrary( "LibBagUtils-1.0" ) local AceGUI = LibStub:GetLibrary( "AceGUI-3.0" ) -- Constants and Locale for this module. EMA.moduleName = "Purchase" EMA.settingsDatabaseName = "PurchaseProfileDB" EMA.chatCommand = "ema-purchase" local L = LibStub( "AceLocale-3.0" ):GetLocale( "Core" ) EMA.parentDisplayName = L["VENDER"] EMA.moduleDisplayName = L["PURCHASE"] -- Icon EMA.moduleIcon = "Interface\\Addons\\EMA\\Media\\SellIcon.tga" -- order EMA.moduleOrder = 60 -- Settings - the values to store and their defaults for the settings database. EMA.settings = { global = { ['**'] = { autoBuyItemsListGlobal = {}, }, }, profile = { autoBuy = false, autoBuyOverflow = true, globalBuyList = false, messageArea = EMAApi.DefaultMessageArea(), autoBuyItems = {} }, } -- Configuration. function EMA:GetConfiguration() local configuration = { name = EMA.moduleDisplayName, handler = EMA, type = 'group', childGroups = "tab", get = "EMAConfigurationGetSetting", set = "EMAConfigurationSetSetting", args = { config = { type = "input", name = L["OPEN_CONFIG"], desc = L["OPEN_CONFIG_HELP"], usage = "/ema-purchase config", get = false, set = "", }, push = { type = "input", name = L["PUSH_SETTINGS"], desc = L["PUSH_ALL_SETTINGS"], usage = "/ema-purchase push", get = false, set = "EMASendSettings", }, copy = { type = "input", name = L["COPY"], desc = L["COPY_HELP"], usage = "/ema-purchase copy", get = false, set = "CopyListCommmand", }, }, } return configuration end ------------------------------------------------------------------------------------------------------------- -- Command this module sends. ------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------- -- Messages module sends. ------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------- -- Purchase Management. ------------------------------------------------------------------------------------------------------------- function EMA:BeforeEMAProfileChanged() end function EMA:OnEMAProfileChanged() EMA:SettingsRefresh() end function EMA:SettingsRefresh() EMA.settingsControl.checkBoxAutoBuy:SetValue( EMA.db.autoBuy ) -- global CheckBox EMA.settingsControl.checkBoxGlobalBuyList:SetValue( EMA.db.globalBuyList ) EMA.settingsControl.checkBoxGlobalBuyList:SetDisabled( not EMA.db.autoBuy ) EMA.settingsControl.checkBoxAutoBuyOverflow:SetValue( EMA.db.autoBuyOverflow ) EMA.settingsControl.editBoxTag:SetText( EMA.autoBuyItemTag ) EMA.settingsControl.editBoxAmount:SetText( EMA.autoBuyAmount ) EMA.settingsControl.dropdownMessageArea:SetValue( EMA.db.messageArea ) EMA.settingsControl.checkBoxAutoBuyOverflow:SetDisabled( not EMA.db.autoBuy ) EMA.settingsControl.editBoxItem:SetDisabled( not EMA.db.autoBuy ) EMA.settingsControl.editBoxTag:SetDisabled( not EMA.db.autoBuy ) EMA.settingsControl.editBoxAmount:SetDisabled( not EMA.db.autoBuy ) EMA.settingsControl.buttonRemove:SetDisabled( not EMA.db.autoBuy ) EMA.settingsControl.buttonAdd:SetDisabled( not EMA.db.autoBuy ) EMA:SettingsScrollRefresh() end -- Settings received. function EMA:EMAOnSettingsReceived( characterName, settings ) if characterName ~= EMA.characterName then -- Update the settings. EMA.db.autoBuy = settings.autoBuy EMA.db.globalBuyList = settings.globalBuyList EMA.db.autoBuyOverflow = settings.autoBuyOverflow EMA.db.messageArea = settings.messageArea EMA.db.autoBuyItems = EMAUtilities:CopyTable( settings.autoBuyItems ) EMA.db.global.autoBuyItemsListGlobal = EMAUtilities:CopyTable( settings.global.autoBuyItemsListGlobal ) -- Refresh the settings. EMA:SettingsRefresh() -- Tell the player. EMA:Print( L["SETTINGS_RECEIVED_FROM_A"]( characterName ) ) end end ------------------------------------------------------------------------------------------------------------- -- Settings Dialogs. ------------------------------------------------------------------------------------------------------------- local function SettingsCreateOptions( top ) -- Position and size constants. local buttonControlWidth = 105 local checkBoxHeight = EMAHelperSettings:GetCheckBoxHeight() local buttonHeight = EMAHelperSettings:GetButtonHeight() local editBoxHeight = EMAHelperSettings:GetEditBoxHeight() local dropdownHeight = EMAHelperSettings:GetDropdownHeight() local left = EMAHelperSettings:LeftOfSettings() local headingHeight = EMAHelperSettings:HeadingHeight() local headingWidth = EMAHelperSettings:HeadingWidth( false ) local horizontalSpacing = EMAHelperSettings:GetHorizontalSpacing() local indentContinueLabel = horizontalSpacing * 18 local verticalSpacing = EMAHelperSettings:GetVerticalSpacing() local halfWidth = (headingWidth - horizontalSpacing) / 2 local thirdWidth = (headingWidth - indentContinueLabel) / 3 local left2 = left + thirdWidth + horizontalSpacing local left3 = left2 + thirdWidth + horizontalSpacing local dropBoxWidth = (headingWidth - horizontalSpacing) / 4 local movingTop = top -- A blank to get layout to show right? EMAHelperSettings:CreateHeading( EMA.settingsControl, L[""], movingTop, false ) movingTop = movingTop - headingHeight EMAHelperSettings:CreateHeading( EMA.settingsControl, L["PURCHASE_ITEMS"], movingTop, false ) movingTop = movingTop - headingHeight EMA.settingsControl.checkBoxAutoBuy = EMAHelperSettings:CreateCheckBox( EMA.settingsControl, thirdWidth, left, movingTop, L["AUTO_BUY_ITEMS"], EMA.SettingsToggleAutoBuyItems ) EMA.settingsControl.checkBoxAutoBuyOverflow = EMAHelperSettings:CreateCheckBox( EMA.settingsControl, thirdWidth, left2, movingTop, L["OVERFLOW"], EMA.SettingsToggleAutoBuyItemsOverflow ) EMA.settingsControl.checkBoxGlobalBuyList = EMAHelperSettings:CreateCheckBox( EMA.settingsControl, thirdWidth, left3, movingTop, L["GLOBAL_LIST"], EMA.SettingsToggleGlobalBuyList, L["GLOBAL_SETTINGS_LIST_HELP"] ) movingTop = movingTop - checkBoxHeight EMA.settingsControl.highlightRow = 1 EMA.settingsControl.offset = 1 local list = {} list.listFrameName = "EMAPurchaseSettingsFrame" list.parentFrame = EMA.settingsControl.widgetSettings.content list.listTop = movingTop list.listLeft = left list.listWidth = headingWidth list.rowHeight = 20 list.rowsToDisplay = 8 list.columnsToDisplay = 3 list.columnInformation = {} list.columnInformation[1] = {} list.columnInformation[1].width = 60 list.columnInformation[1].alignment = "LEFT" list.columnInformation[2] = {} list.columnInformation[2].width = 10 list.columnInformation[2].alignment = "RIGHT" list.columnInformation[3] = {} list.columnInformation[3].width = 30 list.columnInformation[3].alignment = "LEFT" list.scrollRefreshCallback = EMA.SettingsScrollRefresh list.rowClickCallback = EMA.SettingsRowClick EMA.settingsControl.list = list EMAHelperSettings:CreateScrollList( EMA.settingsControl.list ) movingTop = movingTop - list.listHeight - verticalSpacing EMA.settingsControl.buttonRemove = EMAHelperSettings:CreateButton( EMA.settingsControl, buttonControlWidth, left2 + 50, movingTop, L["REMOVE"], EMA.SettingsRemoveClick, L["REMOVE_VENDER_LIST"] ) movingTop = movingTop - buttonHeight - verticalSpacing EMAHelperSettings:CreateHeading( EMA.settingsControl, L["ADD_ITEM"], movingTop, false ) movingTop = movingTop - headingHeight EMA.settingsControl.editBoxItem = EMAHelperSettings:CreateEditBox( EMA.settingsControl, thirdWidth, left2, movingTop, L["ITEM_DROP"] ) EMA.settingsControl.editBoxItem:SetCallback( "OnEnterPressed", EMA.SettingsEditBoxChangedItem ) movingTop = movingTop - editBoxHeight EMA.settingsControl.editBoxTag = EMAHelperSettings:CreateDropdown( EMA.settingsControl, thirdWidth, left, movingTop, L["GROUP_LIST"] ) EMA.settingsControl.editBoxTag:SetList( EMAApi.GroupList() ) EMA.settingsControl.editBoxTag:SetCallback( "OnValueChanged", EMA.GroupDropDownList ) EMA.settingsControl.editBoxAmount = EMAHelperSettings:CreateEditBox( EMA.settingsControl, dropBoxWidth, left3, movingTop, L["AMOUNT"] ) EMA.settingsControl.editBoxAmount:SetCallback( "OnEnterPressed", EMA.SettingsEditBoxChangedAmount ) movingTop = movingTop - editBoxHeight EMA.settingsControl.buttonAdd = EMAHelperSettings:CreateButton( EMA.settingsControl, buttonControlWidth, left2 + 50, movingTop, L["ADD"], EMA.SettingsAddClick ) movingTop = movingTop - buttonHeight EMAHelperSettings:CreateHeading( EMA.settingsControl, L["PURCHASE_MSG"], movingTop, false ) movingTop = movingTop - headingHeight EMA.settingsControl.dropdownMessageArea = EMAHelperSettings:CreateDropdown( EMA.settingsControl, headingWidth, left, movingTop, L["MESSAGE_AREA"] ) EMA.settingsControl.dropdownMessageArea:SetList( EMAApi.MessageAreaList() ) EMA.settingsControl.dropdownMessageArea:SetCallback( "OnValueChanged", EMA.SettingsSetMessageArea ) movingTop = movingTop - dropdownHeight - verticalSpacing return movingTop end function EMA:OnMessageAreasChanged( message ) EMA.settingsControl.dropdownMessageArea:SetList( EMAApi.MessageAreaList() ) end function EMA:OnGroupAreasChanged( message ) EMA.settingsControl.editBoxTag:SetList( EMAApi.GroupList() ) end local function SettingsCreate() EMA.settingsControl = {} EMAHelperSettings:CreateSettings( EMA.settingsControl, EMA.moduleDisplayName, EMA.parentDisplayName, EMA.SettingsPushSettingsClick, EMA.moduleIcon, EMA.moduleOrder ) local bottomOfSettings = SettingsCreateOptions( EMAHelperSettings:TopOfSettings() ) EMA.settingsControl.widgetSettings.content:SetHeight( -bottomOfSettings ) -- Help local helpTable = {} EMAHelperSettings:CreateHelp( EMA.settingsControl, helpTable, EMA:GetConfiguration() ) end ------------------------------------------------------------------------------------------------------------- -- Settings Callbacks. ------------------------------------------------------------------------------------------------------------- function EMA:SettingsScrollRefresh() FauxScrollFrame_Update( EMA.settingsControl.list.listScrollFrame, EMA:GetItemsMaxPosition(), EMA.settingsControl.list.rowsToDisplay, EMA.settingsControl.list.rowHeight ) EMA.settingsControl.offset = FauxScrollFrame_GetOffset( EMA.settingsControl.list.listScrollFrame ) for iterateDisplayRows = 1, EMA.settingsControl.list.rowsToDisplay do -- Reset. EMA.settingsControl.list.rows[iterateDisplayRows].columns[1].textString:SetText( "" ) EMA.settingsControl.list.rows[iterateDisplayRows].columns[1].textString:SetTextColor( 1.0, 1.0, 1.0, 1.0 ) EMA.settingsControl.list.rows[iterateDisplayRows].columns[2].textString:SetText( "" ) EMA.settingsControl.list.rows[iterateDisplayRows].columns[2].textString:SetTextColor( 1.0, 1.0, 1.0, 1.0 ) EMA.settingsControl.list.rows[iterateDisplayRows].columns[3].textString:SetText( "" ) EMA.settingsControl.list.rows[iterateDisplayRows].columns[3].textString:SetTextColor( 1.0, 1.0, 1.0, 1.0 ) EMA.settingsControl.list.rows[iterateDisplayRows].highlight:SetColorTexture( 0.0, 0.0, 0.0, 0.0 ) -- Get data. local dataRowNumber = iterateDisplayRows + EMA.settingsControl.offset if dataRowNumber <= EMA:GetItemsMaxPosition() then -- Put data information into columns. local itemInformation = EMA:GetItemAtPosition( dataRowNumber ) EMA.settingsControl.list.rows[iterateDisplayRows].columns[1].textString:SetText( itemInformation.name ) EMA.settingsControl.list.rows[iterateDisplayRows].columns[2].textString:SetText( itemInformation.amount ) EMA.settingsControl.list.rows[iterateDisplayRows].columns[3].textString:SetText( itemInformation.tag ) -- Highlight the selected row. if dataRowNumber == EMA.settingsControl.highlightRow then EMA.settingsControl.list.rows[iterateDisplayRows].highlight:SetColorTexture( 1.0, 1.0, 0.0, 0.5 ) end end end end function EMA:SettingsRowClick( rowNumber, columnNumber ) if EMA.settingsControl.offset + rowNumber <= EMA:GetItemsMaxPosition() then EMA.settingsControl.highlightRow = EMA.settingsControl.offset + rowNumber EMA:SettingsScrollRefresh() end end function EMA:SettingsPushSettingsClick( event ) EMA:EMASendSettings() end function EMA:SettingsSetMessageArea( event, value ) EMA.db.messageArea = value EMA:SettingsRefresh() end function EMA:SettingsToggleAutoBuyItems( event, checked ) EMA.db.autoBuy = checked EMA:SettingsRefresh() end function EMA:SettingsToggleAutoBuyItemsOverflow( event, checked ) EMA.db.autoBuyOverflow = checked EMA:SettingsRefresh() end function EMA:SettingsToggleGlobalBuyList( event, checked ) EMA.db.globalBuyList = checked EMA:SettingsRefresh() end function EMA:SettingsRemoveClick( event ) StaticPopup_Show( "EMAPURCHASE_CONFIRM_REMOVE_AUTO_BUY_ITEM" ) end function EMA:SettingsEditBoxChangedItem( event, text ) EMA.autoBuyItemLink = text EMA:SettingsRefresh() end function EMA:GroupDropDownList (event, value ) -- if nil or the blank group then don't get Name. if value == " " or value == nil then return end for index, groupName in ipairs( EMAApi.GroupList() ) do if index == value then EMA.autoBuyItemTag = groupName break end end EMA:SettingsRefresh() end function EMA:SettingsEditBoxChangedAmount( event, text ) if not text or text:trim() == "" or text:find( "^(%d+)$" ) == nil then EMA:Print( L["NUM_ERROR"] ) return end EMA.autoBuyAmount = text EMA:SettingsRefresh() end function EMA:SettingsAddClick( event ) if EMA.autoBuyItemLink ~= nil and EMA.autoBuyItemTag ~= nil then EMA:AddItem( EMA.autoBuyItemLink, EMA.autoBuyItemTag, EMA.autoBuyAmount ) EMA.autoBuyItemLink = nil EMA.settingsControl.editBoxItem:SetText( "" ) EMA:SettingsRefresh() end end function EMA:CopyListCommmand() EMA:Print("Copying Local List To Global List") EMA.db.global.autoBuyItemsListGlobal = EMAUtilities:CopyTable( EMA.db.autoBuyItems ) EMA:SettingsRefresh() end ------------------------------------------------------------------------------------------------------------- -- Popup Dialogs. ------------------------------------------------------------------------------------------------------------- -- Initialize Popup Dialogs. local function InitializePopupDialogs() StaticPopupDialogs["EMAPURCHASE_CONFIRM_REMOVE_AUTO_BUY_ITEM"] = { text = L["BUY_POPUP_ACCEPT"], button1 = YES, button2 = NO, timeout = 0, whileDead = 1, hideOnEscape = 1, OnAccept = function() EMA:RemoveItem() end, } end ------------------------------------------------------------------------------------------------------------- -- Addon initialization, enabling and disabling. ------------------------------------------------------------------------------------------------------------- -- Initialise the module. function EMA:OnInitialize() EMA.autoBuyItemTag = EMAApi.AllTag() EMA.autoBuyItemLink = nil EMA.autoBuyAmount = 20 -- Create the settings control. SettingsCreate() -- Initialise the EMAModule part of this module. EMA:EMAModuleInitialize( EMA.settingsControl.widgetSettings.frame ) -- Initialise the popup dialogs. InitializePopupDialogs() -- Populate the settings. EMA:SettingsRefresh() end -- Called when the addon is enabled. function EMA:OnEnable() EMA:RegisterEvent( "MERCHANT_SHOW" ) EMA:RawHook( "ContainerFrameItemButton_OnModifiedClick", true) EMA:RegisterMessage( EMAApi.MESSAGE_MESSAGE_AREAS_CHANGED, "OnMessageAreasChanged" ) EMA:RegisterMessage( EMAApi.GROUP_LIST_CHANGED , "OnGroupAreasChanged" ) end -- Called when the addon is disabled. function EMA:OnDisable() end ------------------------------------------------------------------------------------------------------------- -- Purchase functionality. ------------------------------------------------------------------------------------------------------------- function EMA:ContainerFrameItemButton_OnModifiedClick( self, event, ... ) local isConfigOpen = EMAPrivate.SettingsFrame.Widget:IsVisible() if isConfigOpen == true and IsShiftKeyDown() == true then local GUIPanel = EMAPrivate.SettingsFrame.TreeGroupStatus.selected local currentModule = string.find(GUIPanel, EMA.moduleDisplayName) --EMA:Print("test2", GUIPanel, "vs", currentModule ) if currentModule ~= nil then local itemID, itemLink = GameTooltip:GetItem() --EMA:Print("test1", itemID, itemLink ) if itemLink ~= nil then EMA.settingsControl.editBoxItem:SetText( "" ) EMA.settingsControl.editBoxItem:SetText( itemLink ) EMA.autoBuyItemLink = itemLink return end end end return EMA.hooks["ContainerFrameItemButton_OnModifiedClick"]( self, event, ... ) end function EMA:GetItemsMaxPosition() if EMA.db.globalBuyList == true then return #EMA.db.global.autoBuyItemsListGlobal else return #EMA.db.autoBuyItems end end function EMA:GetItemAtPosition( position ) if EMA.db.globalBuyList == true then return EMA.db.global.autoBuyItemsListGlobal[position] else return EMA.db.autoBuyItems[position] end end function EMA:AddItem( itemLink, itemTag, amountToBuy ) -- Get some more information about the item. local name, link, quality, iLevel, reqLevel, class, subclass, maxStack, equipSlot, texture, vendorPrice = GetItemInfo( itemLink ) -- If the item could be found. if name ~= nil then local itemInformation = {} itemInformation.link = itemLink itemInformation.name = name itemInformation.tag = itemTag itemInformation.amount = amountToBuy if EMA.db.globalBuyList == true then table.insert( EMA.db.global.autoBuyItemsListGlobal, itemInformation ) else table.insert( EMA.db.autoBuyItems, itemInformation ) end EMA:SettingsRefresh() EMA:SettingsRowClick( 1, 1 ) end end function EMA:RemoveItem() if EMA.db.globalBuyList == true then table.remove( EMA.db.global.autoBuyItemsListGlobal, EMA.settingsControl.highlightRow ) else table.remove( EMA.db.autoBuyItems, EMA.settingsControl.highlightRow ) end EMA:SettingsRefresh() EMA:SettingsRowClick( 1, 1 ) end function EMA:MERCHANT_SHOW() if EMA.db.autoBuy == true then EMA:DoMerchantAutoBuy() end end -- A EMA command has been recieved. function EMA:EMAOnCommandReceived( characterName, commandName, ... ) end function EMA:DoMerchantAutoBuy() -- Flags will be set if the character does not have enough bag space or money. local outOfBagSpace = false local outOfMoney = false local outOfOtherCurrency = false -- Iterate all the wanted items... if EMA.db.globalBuyList == true then itemTable = EMA.db.global.autoBuyItemsListGlobal else itemTable = EMA.db.autoBuyItems end for position, itemInfoTable in pairs( itemTable ) do local maxItemAmount = tonumber( itemInfoTable.amount ) local itemTag = itemInfoTable.tag local itemLink = itemInfoTable.link -- Does this character have the item tag? No, don't buy. if EMAApi.IsCharacterInGroup( EMA.characterName, itemTag ) then -- Does the merchant have the item in stock? local itemIndexMerchant = EMA:DoesMerchantHaveItemInStock( itemLink ) if itemIndexMerchant ~= nil then -- Yes, item is in stock, how many does the character need? local amountNeeded = EMA:GetAmountNeededForItemTopUp( itemLink, maxItemAmount ) -- Need more than 0 items, buy them. if amountNeeded > 0 then -- Attempt to buy the items. local noFreeBagSpace, notEnoughMoney, notEnoughOtherCurrency = EMA:BuyItemFromMerchant( itemIndexMerchant, amountNeeded ) -- Set flags if problems occurred. if noFreeBagSpace then outOfBagSpace = true end if notEnoughMoney then outOfMoney = true end if notEnoughOtherCurrency then outOfOtherCurrency = true end end end end end -- If there was a problem, tell the master. if outOfBagSpace then EMA:EMASendMessageToTeam( EMA.db.messageArea, L["ERROR_BAGS_FULL"], false ) end if outOfMoney then EMA:EMASendMessageToTeam( EMA.db.messageArea, L["ERROR_GOLD"], false ) end if outOfOtherCurrency then EMA:EMASendMessageToTeam( EMA.db.messageArea, L["ERROR_CURR"], false ) end end function EMA:DoesMerchantHaveItemInStock( itemLink ) -- The index of the item to be found in the merchants inventory; initially nil, not found. local indexOfItemToFind = nil -- Get the name of the item to find from the item link. local itemNameToFind = GetItemInfo( itemLink ) -- How many items does the merchant have? local numberMerchantItems = GetMerchantNumItems() -- Iterate all the merchants items... for merchantIndex = 1, numberMerchantItems do -- Is there an item link for this item. local merchantItemLink = GetMerchantItemLink( merchantIndex ) if merchantItemLink then -- Yes, get the item name. local itemNameMerchant = GetItemInfo( merchantItemLink ) if itemNameMerchant == itemNameToFind then indexOfItemToFind = merchantIndex break end end end -- Return the index into the merchants inventory of the item. return indexOfItemToFind end function EMA:GetAmountNeededForItemTopUp( itemLink, maxItemAmount ) -- The amount of the item needed to top up the item. local amountNeeded = 0 -- How much of this item does the character have in it's bags? local amountInBags = GetItemCount( itemLink ) -- Does the character need more? if amountInBags < maxItemAmount then -- Yes, how much more? amountNeeded = maxItemAmount - amountInBags end -- Return the amount needed. return amountNeeded end function EMA:BuyItemFromMerchant( itemIndexMerchant, amountToBuy ) -- Flags will be set if the character does not have enough bag space or money. local noFreeBagSpace = false local notEnoughMoney = false local notEnoughOtherCurrency = false -- Processing variables. local buyThisAmount = 0 local amountLeftToBuy = amountToBuy local actualAmountToBuy = 0 local costToBuy = 0 local moneyAvailable = 0 -- Get information about the item from the merchant. local name, texture, price, itemsPerStack, numberAvailable, isUsable, extendedCost = GetMerchantItemInfo( itemIndexMerchant ) local maximumCanBuyAtATime = GetMerchantItemMaxStack( itemIndexMerchant ) -- Loop buying stacks from the merchant until the required number has been purchased. repeat -- Still need to buy more than the maximum? if amountLeftToBuy >= maximumCanBuyAtATime then -- Yes, buy the maximum amount. buyThisAmount = maximumCanBuyAtATime else -- No, just buy the amount left. buyThisAmount = amountLeftToBuy end -- Attempt to buy this amount from the merchant; although actual amount bought may differ, -- depending on merchant stock and over buy flag. -- How many does the merchant have left? numberAvailable = select( 5, GetMerchantItemInfo( itemIndexMerchant ) ) -- Calculate how many to buy depending on the stacksize and whether over buying is allowed. actualAmountToBuy = buyThisAmount if EMA.db.autoBuyOverflow == true then actualAmountToBuy = ceil(actualAmountToBuy) else actualAmountToBuy = floor(actualAmountToBuy) end -- If requesting more than the number available, then just buy as much as possible. -- If numberAvailable is -1 then there is unlimited stock available. if numberAvailable ~= -1 then if actualAmountToBuy > numberAvailable then actualAmountToBuy = numberAvailable end end -- Does the character have enough money? costToBuy = actualAmountToBuy * price moneyAvailable = GetMoney() if moneyAvailable < costToBuy then notEnoughMoney = true end -- Is there enough free space for this item in the characters bags? --TODO - need to find items family type and compare to each container. local numFreeSlots, numTotalSlots = LibBagUtils:CountSlots("BAGS", 0) if numFreeSlots == 0 then noFreeBagSpace = true end -- Buy from the merchant, if there is a valid amount to buy and the character has enough money. if (actualAmountToBuy > 0) and (not notEnoughMoney) then BuyMerchantItem( itemIndexMerchant, actualAmountToBuy ) end -- How much left to buy? amountLeftToBuy = amountLeftToBuy - buyThisAmount until (amountLeftToBuy == 0 or noFreeBagSpace == true) -- TODO -- Return the success flags. return noFreeBagSpace, notEnoughMoney, notEnoughOtherCurrency end