CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PrismarineJS

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: PrismarineJS/mineflayer
Path: blob/master/test/externalTests/useChests.js
Views: 789
1
const { Vec3 } = require('vec3')
2
const assert = require('assert')
3
const { once, onceWithCleanup } = require('../../lib/promise_utils')
4
5
module.exports = () => async (bot) => {
6
const Item = require('prismarine-item')(bot.registry)
7
8
bot.test.groundY = bot.supportFeature('tallWorld') ? -60 : 4
9
10
const smallChestLocation = new Vec3(0, bot.test.groundY, -1)
11
const largeChestLocations = [new Vec3(0, bot.test.groundY, 1), new Vec3(1, bot.test.groundY, 1)]
12
const smallTrappedChestLocation = new Vec3(1, bot.test.groundY, 0)
13
const largeTrappedChestLocations = [
14
new Vec3(-1, bot.test.groundY, 1),
15
new Vec3(-1, bot.test.groundY, 0)
16
]
17
const chestSlot = 36
18
const trappedChestSlot = 37
19
const boneSlot = 38
20
21
let blockItemsByName
22
if (bot.supportFeature('itemsAreNotBlocks')) {
23
blockItemsByName = 'itemsByName'
24
} else if (bot.supportFeature('itemsAreAlsoBlocks')) {
25
blockItemsByName = 'blocksByName'
26
}
27
28
const chestBlockId = bot.registry.blocksByName.chest.id
29
const trappedChestBlockId = bot.registry.blocksByName.trapped_chest.id
30
31
function itemByName (items, name) {
32
for (let i = 0; i < items.length; ++i) {
33
const item = items[i]
34
if (item && item.name === name) return item
35
}
36
return null
37
}
38
39
async function depositBones (chestLocation, count) {
40
const chest = await bot.openContainer(bot.blockAt(chestLocation))
41
assert(chest.containerItems().length === 0)
42
assert(chest.items().length > 0)
43
const name = 'bone'
44
const item = itemByName(chest.items(), name)
45
if (!item) {
46
bot.test.sayEverywhere(`unknown item ${name}`)
47
throw new Error(`unknown item ${name}`)
48
}
49
await chest.deposit(item.type, null, count)
50
chest.close()
51
}
52
53
async function withdrawBones (chestLocation, count) {
54
const chest = await bot.openContainer(bot.blockAt(chestLocation))
55
const name = 'bone'
56
const item = itemByName(chest.containerItems(), name)
57
if (!item) {
58
bot.test.sayEverywhere(`unknown item ${name}`)
59
throw new Error(`unknown item ${name}`)
60
}
61
await chest.withdraw(item.type, null, count)
62
assert(chest.containerItems().length === 0)
63
assert(chest.items().length > 0)
64
chest.close()
65
}
66
67
await bot.test.setInventorySlot(chestSlot, new Item(bot.registry[blockItemsByName].chest.id, 3, 0))
68
await bot.test.setInventorySlot(trappedChestSlot, new Item(bot.registry[blockItemsByName].trapped_chest.id, 3, 0))
69
await bot.test.setInventorySlot(boneSlot, new Item(bot.registry.itemsByName.bone.id, 3, 0))
70
71
await bot.test.becomeSurvival()
72
73
// place the chests around us
74
await bot.test.placeBlock(chestSlot, largeChestLocations[0])
75
await bot.test.placeBlock(chestSlot, largeChestLocations[1])
76
await bot.test.placeBlock(chestSlot, smallChestLocation)
77
await bot.test.placeBlock(trappedChestSlot, largeTrappedChestLocations[0])
78
await bot.test.placeBlock(trappedChestSlot, largeTrappedChestLocations[1])
79
await bot.test.placeBlock(trappedChestSlot, smallTrappedChestLocation)
80
81
assert.strictEqual(bot.blockAt(largeChestLocations[0]).type, chestBlockId)
82
assert.strictEqual(bot.blockAt(largeChestLocations[1]).type, chestBlockId)
83
assert.strictEqual(bot.blockAt(smallChestLocation).type, chestBlockId)
84
assert.strictEqual(bot.blockAt(largeTrappedChestLocations[0]).type, trappedChestBlockId)
85
assert.strictEqual(bot.blockAt(largeTrappedChestLocations[1]).type, trappedChestBlockId)
86
assert.strictEqual(bot.blockAt(smallTrappedChestLocation).type, trappedChestBlockId)
87
88
// Test that "chestLidMove" is emitted only once when opening a double chest
89
let emitted = false
90
bot.on('chestLidMove', handler)
91
async function handler (block, isOpen, block2) {
92
if (emitted) {
93
assert.fail(new Error('chestLidMove emitted twice'))
94
} else {
95
emitted = true
96
97
let blockAssert = false; let block2Assert = false
98
for (const location of largeChestLocations) {
99
if (location.equals(block.position)) blockAssert = true
100
if (location.equals(block2.position)) block2Assert = true
101
}
102
assert(blockAssert && block2Assert, new Error('The block instance emitted by chestLidMove is not part of the chest oppened'))
103
assert.strictEqual(isOpen, 1, new Error('isOpen should be 1 when opened by one only player'))
104
105
await bot.test.wait(500)
106
107
bot.removeListener('chestLidMove', handler)
108
chest.close()
109
}
110
}
111
const chest = await bot.openContainer(bot.blockAt(largeChestLocations[0]))
112
await once(chest, 'close')
113
114
await depositBones(smallChestLocation, 1)
115
await depositBones(largeChestLocations[0], 2)
116
117
assert(bot.inventory.items().length === 0)
118
119
await withdrawBones(smallChestLocation, 1)
120
await withdrawBones(largeChestLocations[0], 2)
121
122
await depositBones(smallTrappedChestLocation, 1)
123
await depositBones(largeTrappedChestLocations[0], 2)
124
125
assert(bot.inventory.items().length === 0)
126
127
await withdrawBones(smallTrappedChestLocation, 1)
128
await withdrawBones(largeTrappedChestLocations[0], 2)
129
130
const itemsWithStackSize = {
131
64: ['stone', 'mycelium'],
132
16: ['ender_pearl', 'egg'],
133
1: ['fishing_rod', 'bow']
134
}
135
136
function getRandomStackableItem () {
137
if (Math.random() < 0.75) {
138
return itemsWithStackSize[64][~~(Math.random() * itemsWithStackSize[64].length)]
139
} else {
140
if (Math.random() < 0.5) {
141
return itemsWithStackSize[16][~~(Math.random() * itemsWithStackSize[16].length)]
142
} else {
143
return itemsWithStackSize[1][~~(Math.random() * itemsWithStackSize[1].length)]
144
}
145
}
146
}
147
148
async function createRandomLayout (window, slotPopulationFactor) {
149
await bot.test.becomeCreative()
150
151
for (let slot = 0; slot < window.inventoryStart; slot++) {
152
if (Math.random() < slotPopulationFactor) {
153
const randomItem = getRandomStackableItem()
154
const item = bot.registry.itemsByName[randomItem]
155
bot.chat(`/give ${bot.username} ${item.name} ${Math.ceil(Math.random() * item.stackSize)}`)
156
await onceWithCleanup(window, 'updateSlot', {
157
timeout: 5000,
158
checkCondition: (slot, oldItem, newItem) => slot === window.hotbarStart && newItem?.name === item.name
159
})
160
161
// await bot.clickWindow(slot, 0, 2)
162
await bot.moveSlotItem(window.hotbarStart, slot)
163
}
164
}
165
166
await bot.test.becomeSurvival()
167
}
168
169
async function testMouseClick (window, clicks) {
170
let iterations = 0
171
while (iterations++ < clicks) {
172
await bot.clickWindow(~~(Math.random() * window.inventoryStart), 0, 0)
173
}
174
}
175
176
function clearLargeChest () {
177
bot.chat(`/setblock ${largeChestLocations[0].x} ${largeChestLocations[0].y} ${largeChestLocations[0].z} chest`)
178
bot.chat(`/setblock ${largeChestLocations[1].x} ${largeChestLocations[1].y} ${largeChestLocations[1].z} chest`)
179
}
180
181
const window = await bot.openContainer(bot.blockAt(largeChestLocations[0]))
182
await createRandomLayout(window, 0.95)
183
184
await testMouseClick(window, 250)
185
186
window.close()
187
clearLargeChest()
188
}
189
190