Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/test/externalTests/trade.js
Views: 789
const assert = require('assert')1const { once } = require('../../lib/promise_utils')23module.exports = () => async (bot) => {4function expectAmount (amount, greaterThan) {5// TODO: 1.20.5+ does not seem to respect "Count" NBT anymore in /summon6// ...as NBT was removed in favor of components that may have something to do7if (bot.registry.version['>=']('1.20.5')) {8if (amount < 1) throw new Error(`${amount} < 1`) // accept anything >=19} else {10assert.strictEqual(amount, greaterThan)11}12}1314const Item = require('prismarine-item')(bot.registry)1516const villagerType = bot.registry.entitiesByName.villager ? 'villager' : 'Villager'17const testFluctuations = bot.supportFeature('selectingTradeMovesItems')1819const summonCommand = bot.supportFeature('indexesVillagerRecipes')20? `/summon ${villagerType} ~ ~1 ~ {NoAI:1, Offers:{Recipes:[0:{maxUses:12,buy:{id:"minecraft:emerald",Count:2},sell:{id:"minecraft:pumpkin_pie",Count:2},uses: 1},1:{maxUses:12,buy:{id:"minecraft:emerald",Count:2},buyB:{id:"minecraft:pumpkin_pie",Count:2},sell:{id:"minecraft:wheat",Count:2}, uses:1},2:{maxUses:12,buy:{id:"minecraft:emerald",Count:1},sell:{id:"minecraft:glass",Count:4},uses: 1},3:{maxUses:12,buy:{id:"minecraft:emerald",Count:36},buyB:{id:"minecraft:book",Count:1},sell:{id:"minecraft:wooden_sword",Count:1},uses: 1}]}}`21: `/summon ${villagerType} ~ ~1 ~ {NoAI:1, Offers:{Recipes:[{maxUses:12,buy:{id:"minecraft:emerald",Count:2},sell:{id:"minecraft:pumpkin_pie",Count:2},${testFluctuations ? 'demand:60,priceMultiplier:0.05f,specialPrice:-4,' : ''}uses: 1},{maxUses:12,buy:{id:"minecraft:emerald",Count:2},buyB:{id:"minecraft:pumpkin_pie",Count:2},sell:{id:"minecraft:wheat",Count:2}, uses:1},{maxUses:12,buy:{id:"minecraft:emerald",Count:1},sell:{id:"minecraft:glass",Count:4},uses: 1},{maxUses:12,buy:{id:"minecraft:emerald",Count:36},buyB:{id:"minecraft:book",Count:1},sell:{id:"minecraft:wooden_sword",Count:1},uses: 1}]}}`2223const commandBlockPos = bot.entity.position.offset(0.5, 0, 0.5)24const redstoneBlockPos = commandBlockPos.offset(1, 0, 0)2526let shouldHaveEmeralds = 027for (let slot = 9; slot <= 17; slot += 1) {28await bot.test.setInventorySlot(slot, new Item(bot.registry.itemsByName.emerald.id, 64, 0))29shouldHaveEmeralds += 6430}31await bot.test.setInventorySlot(18, new Item(bot.registry.itemsByName.book.id, 11, 0))3233// A command block is needed to spawn the villager due to the chat's character limit in some versions34bot.test.sayEverywhere(`/setblock ${commandBlockPos.toArray().join(' ')} command_block`)35await bot.test.wait(500)36bot.setCommandBlock(commandBlockPos, summonCommand)37bot.test.sayEverywhere(`/setblock ${redstoneBlockPos.toArray().join(' ')} redstone_block`) // Activate the command block3839const [entity] = await once(bot, 'entitySpawn')40assert(entity.name === villagerType)4142const villager = await bot.openVillager(entity)43console.log('Opened villager')44console.dir(villager, { depth: null })4546// Handle trade #1 -- takes 2x emerald and returns 2x pumpkin_pie47{48const trade = villager.trades[0]49assert.strictEqual(trade.inputs.length, 1, 'Expected single input from villager on first trade')50verifyTrade(trade)5152const [input] = trade.inputs53assert.strictEqual(input.name, 'emerald')54expectAmount(input.count, 2)5556const [output] = trade.outputs57assert.strictEqual(output.name, 'pumpkin_pie')58expectAmount(output.count, 2)5960await bot.trade(villager, 0, 11)61shouldHaveEmeralds -= testFluctuations ? (2 * 2 * 11) : (2 * 11)62expectAmount(bot.currentWindow.count(bot.registry.itemsByName.emerald.id), shouldHaveEmeralds)63expectAmount(bot.currentWindow.count(bot.registry.itemsByName.pumpkin_pie.id), 22)64}6566// Handle trade #2 -- takes [2x emerald, 2x pumpkin_pie] and returns 2x wheat67{68const trade = villager.trades[1]69assert.strictEqual(trade.inputs.length, 2, 'Expected two inputs from villager on second trade')70verifyTrade(trade)7172const [input1, input2] = trade.inputs73assert.strictEqual(input1.name, 'emerald')74expectAmount(input1.count, 2)75assert.strictEqual(input2.name, 'pumpkin_pie')76expectAmount(input2.count, 2)7778const [output] = trade.outputs79assert.strictEqual(output.name, 'wheat')80expectAmount(output.count, 2)8182await bot.trade(villager, 1, 11)83shouldHaveEmeralds -= 11 * 284expectAmount(bot.currentWindow.count(bot.registry.itemsByName.emerald.id), shouldHaveEmeralds)85assert.strictEqual(bot.currentWindow.count(bot.registry.itemsByName.pumpkin_pie.id), 0)86expectAmount(bot.currentWindow.count(bot.registry.itemsByName.wheat.id), 22)87}8889// Handle trade #3 -- takes 1x emerald and returns 4x glass90{91const trade = villager.trades[2]92assert.strictEqual(trade.inputs.length, 1, 'Expected single input from villager on first trade')93verifyTrade(trade)9495const [input] = trade.inputs96assert.strictEqual(input.name, 'emerald')97expectAmount(input.count, 1)9899const [output] = trade.outputs100assert.strictEqual(output.name, 'glass')101expectAmount(output.count, 4)102103await bot.trade(villager, 2, 11)104shouldHaveEmeralds -= 11105expectAmount(bot.currentWindow.count(bot.registry.itemsByName.emerald.id), shouldHaveEmeralds)106expectAmount(bot.currentWindow.count(bot.registry.itemsByName.glass.id), 44)107}108109// Handle trade #4 -- takes [36x emerald, 1x book] and returns 1x wooden sword110{111const trade = villager.trades[3]112assert.strictEqual(trade.inputs.length, 2, 'Expected two inputs from villager on second trade')113verifyTrade(trade)114115const [input1, input2] = trade.inputs116assert.strictEqual(input1.name, 'emerald')117expectAmount(input1.count, 36)118assert.strictEqual(input2.name, 'book')119assert.strictEqual(input2.count, 1)120121const [output] = trade.outputs122assert.strictEqual(output.name, 'wooden_sword')123assert.strictEqual(output.count, 1)124125await bot.trade(villager, 3, 11)126shouldHaveEmeralds -= 11 * 36127expectAmount(bot.currentWindow.count(bot.registry.itemsByName.emerald.id), shouldHaveEmeralds)128assert.strictEqual(bot.currentWindow.count(bot.registry.itemsByName.book.id), 0)129expectAmount(bot.currentWindow.count(bot.registry.itemsByName.wooden_sword.id), 11)130}131132function verifyTrade (trade) {133assert.strictEqual(trade.nbTradeUses, 1)134assert.strictEqual(trade.maximumNbTradeUses, 12)135assert.strictEqual(trade.tradeDisabled, false)136137const printCountInv = function (item) {138return `${bot.currentWindow.count(bot.registry.itemsByName[item.name].id)}x ${item.displayName}`139}140const printCountTrade = function (item) {141return `${item.count}x ${item.displayName}`142}143144bot.test.sayEverywhere(`I have ${printCountInv(trade.inputItem1)} ${trade.hasItem2 ? 'and ' + printCountInv(trade.inputItem2) : ''}`)145bot.test.sayEverywhere(`I can trade ${printCountTrade(trade.inputItem1)} ${trade.hasItem2 ? 'and ' + printCountTrade(trade.inputItem2) : ''} for ${printCountTrade(trade.outputItem)}`)146}147148assert.rejects(bot.trade(villager, 1, 1)) // Shouldn't be able, the trade is blocked!149villager.close()150bot.test.sayEverywhere(`/kill @e[type=${villagerType}]`)151}152153154