diff --git a/core/ShopState.lua b/core/ShopState.lua index 4655462..bab77ee 100644 --- a/core/ShopState.lua +++ b/core/ShopState.lua @@ -111,9 +111,44 @@ if purchasedProduct then local productPrice = Pricing.getProductPrice(purchasedProduct, transactionCurrency) local amountPurchased = math.floor(transaction.value / productPrice) + if purchasedProduct.maxQuantity then + amountPurchased = math.min(amountPurchased, purchasedProduct.maxQuantity) + end if amountPurchased > 0 then - if purchasedProduct.quantity and purchasedProduct.quantity > 0 then - local productSources, available = ScanInventory.findProductItems(state.products, purchasedProduct, amountPurchased) + local productsPurchased = {} + if purchasedProduct.modid then + table.insert(productsPurchased, { product = purchasedProduct, quantity = 1 }) + end + if purchasedProduct.bundle and #purchasedProduct.bundle > 0 then + for _, bundleProduct in ipairs(purchasedProduct.bundle) do + for _, product in ipairs(state.products) do + if product.address:lower() == bundleProduct.product:lower() or product.name:lower() == bundleProduct.product:lower() or (product.productId and product.productId:lower() == bundleProduct.product:lower()) then + local productFound = false + for _, productPurchased in ipairs(productsPurchased) do + if productPurchased.product == product then + productPurchased.quantity = productPurchased.quantity + bundleProduct.quantity + productFound = true + break + end + end + if not productFound then + table.insert(productsPurchased, { product = product, quantity = bundleProduct.quantity }) + end + break + end + end + end + end + local available = amountPurchased + for _, productPurchased in ipairs(productsPurchased) do + local productSources, productAvailable = ScanInventory.findProductItems(state.products, productPurchased.product, productPurchased.quantity * amountPurchased) + available = math.min(available, math.floor(productAvailable / productPurchased.quantity)) + productPurchased.sources = productSources + if available == 0 then + break + end + end + if available > 0 then local refundAmount = math.floor(transaction.value - (available * productPrice)) if available > 0 then local allowPurchase = true @@ -124,33 +159,38 @@ end if allowPurchase ~= false then print("Purchased " .. available .. " of " .. purchasedProduct.name .. " for " .. transaction.from .. " for " .. transaction.value .. " " .. transactionCurrency.id .. " (refund " .. refundAmount .. ")") - for _, productSource in ipairs(productSources) do - if state.config.peripherals.outputChest == "self" then - if not turtle then - error("Self output but not a turtle!") - end - if not state.peripherals.modem.getNameLocal() then - error("Modem is not connected! Try right clicking it") - end - if turtle.getSelectedSlot() ~= 1 then - turtle.select(1) - end - peripheral.call(productSource.inventory, "pushItems", state.peripherals.modem.getNameLocal(), productSource.slot, productSource.amount, 1) - if state.config.settings.dropDirection == "forward" then - turtle.drop(productSource.amount) - elseif state.config.settings.dropDirection == "up" then - turtle.dropUp(productSource.amount) - elseif state.config.settings.dropDirection == "down" then - turtle.dropDown(productSource.amount) + for _, productPurchased in ipairs(productsPurchased) do + for _, productSource in ipairs(productPurchased.sources) do + if state.config.peripherals.outputChest == "self" then + if not turtle then + error("Self output but not a turtle!") + end + if not state.peripherals.modem.getNameLocal() then + error("Modem is not connected! Try right clicking it") + end + if turtle.getSelectedSlot() ~= 1 then + turtle.select(1) + end + peripheral.call(productSource.inventory, "pushItems", state.peripherals.modem.getNameLocal(), productSource.slot, productSource.amount, 1) + if state.config.settings.dropDirection == "forward" then + turtle.drop(productSource.amount) + elseif state.config.settings.dropDirection == "up" then + turtle.dropUp(productSource.amount) + elseif state.config.settings.dropDirection == "down" then + turtle.dropDown(productSource.amount) + else + error("Invalid drop direction: " .. state.config.settings.dropDirection) + end else - error("Invalid drop direction: " .. state.config.settings.dropDirection) + peripheral.call(productSource.inventory, "pushItems", state.config.peripherals.outputChest, productSource.slot, productSource.amount, 1) + --peripheral.call(state.config.peripherals.outputChest, "drop", 1, productSource.amount, state.config.settings.dropDirection) end - else - peripheral.call(productSource.inventory, "pushItems", state.config.peripherals.outputChest, productSource.slot, productSource.amount, 1) - --peripheral.call(state.config.peripherals.outputChest, "drop", 1, productSource.amount, state.config.settings.dropDirection) end + productPurchased.product.quantity = productPurchased.product.quantity - (productPurchased.quantity * available) end - purchasedProduct.quantity = purchasedProduct.quantity - available + if not purchasedProduct.modid then + purchasedProduct.quantity = math.max(0, purchasedProduct.quantity - available) + end if refundAmount > 0 then refund(transactionCurrency, transaction.from, meta, refundAmount, state.config.lang.refundRemaining) end diff --git a/core/inventory/ScanInventory.lua b/core/inventory/ScanInventory.lua index b8ecca3..9de2271 100644 --- a/core/inventory/ScanInventory.lua +++ b/core/inventory/ScanInventory.lua @@ -140,6 +140,25 @@ for i = 1, #products do local product = products[i] product.quantity = product.newQty + if product.bundle and #product.bundle > 0 then + if not product.modid then + product.quantity = nil + end + for _, bundledProduct in ipairs(product.bundle) do + for _, searchProduct in ipairs(products) do + if searchProduct.address:lower() == bundledProduct.product:lower() or searchProduct.name:lower() == bundledProduct.product:lower() or (searchProduct.productId and searchProduct.productId:lower() == bundledProduct.product:lower()) then + local searchQty = searchProduct.newQty + if not searchQty then + searchQty = searchProduct.quantity + end + if not product.quantity then + product.quantity = searchQty + end + product.quantity = math.min(product.quantity, math.min(searchQty / bundledProduct.quantity)) + end + end + end + end product.newQty = nil end if onInventoryRefresh then diff --git a/core/schemas.lua b/core/schemas.lua index 28c3da5..d3705a4 100644 --- a/core/schemas.lua +++ b/core/schemas.lua @@ -214,11 +214,13 @@ local productsSchema = { __type = "array", __entry = { - modid = "string", - name = "string?", + modid = "string?", + productId = "string?", + name = "string", address = "string", category = "string?", hidden = "boolean?", + maxQuantity = "number?", price = "number", priceOverrides = { __type = "array?", @@ -227,6 +229,13 @@ price = "number" } }, + bundle = { + __type = "array?", + __entry = { + product = "string", + quantity = "number" + } + }, predicate = "table?" } } diff --git a/products.lua b/products.lua index dc5f839..5be020a 100644 --- a/products.lua +++ b/products.lua @@ -7,6 +7,7 @@ }, { modid = "minecraft:lapis_block", + productId = "lapis_block", name = "Lapis Block", address = "lapis", category = "ore", @@ -19,6 +20,22 @@ }, }, { + name = "Lapis on a stick", + address = "ls", + price = 9.0, + maxQuantity = 1, + bundle = { + { + product = "stick", + quantity = 1 + }, + { + product = "lapis_block", + quantity = 1 + } + } + }, + { modid = "minecraft:diamond_pickaxe", name = "Diamond Pickaxe eff5", address = "dpick", diff --git a/radon.lua b/radon.lua index cd01fb8..54f679a 100644 --- a/radon.lua +++ b/radon.lua @@ -1,4 +1,4 @@ -local version = "1.3.15" +local version = "1.3.16" local configHelpers = require "util.configHelpers" local schemas = require "core.schemas" local oldPullEvent = os.pullEvent