the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
1#include "stdafx.h"
2#include "net.minecraft.world.entity.player.h"
3#include "net.minecraft.world.inventory.h"
4#include "net.minecraft.world.level.h"
5#include "net.minecraft.world.level.tile.h"
6#include "net.minecraft.world.item.h"
7#include "net.minecraft.world.item.enchantment.h"
8#include "EnchantmentMenu.h"
9
10EnchantmentMenu::EnchantmentMenu(shared_ptr<Inventory> inventory, Level *level, int xt, int yt, int zt)
11{
12 enchantSlots = shared_ptr<EnchantmentContainer>( new EnchantmentContainer(this) );
13
14 for(int i = 0; i < 3; ++i)
15 {
16 costs[i] = 0;
17 }
18
19 this->level = level;
20 x = xt;
21 y = yt;
22 z = zt;
23 addSlot(new EnchantmentSlot(enchantSlots, 0, 21 + 4, 43 + 4));
24
25 for (int y = 0; y < 3; y++)
26 {
27 for (int x = 0; x < 9; x++)
28 {
29 addSlot(new Slot(inventory, x + y * 9 + 9, 8 + x * 18, 84 + y * 18));
30 }
31 }
32 for (int x = 0; x < 9; x++)
33 {
34 addSlot(new Slot(inventory, x, 8 + x * 18, 142));
35 }
36
37 m_costsChanged = false;
38}
39
40void EnchantmentMenu::addSlotListener(ContainerListener *listener)
41{
42 AbstractContainerMenu::addSlotListener(listener);
43
44 listener->setContainerData(this, 0, costs[0]);
45 listener->setContainerData(this, 1, costs[1]);
46 listener->setContainerData(this, 2, costs[2]);
47}
48
49void EnchantmentMenu::broadcastChanges()
50{
51 AbstractContainerMenu::broadcastChanges();
52
53 // 4J Added m_costsChanged to stop continually sending update packets even when no changes have been made
54 if(m_costsChanged)
55 {
56 for (int i = 0; i < containerListeners.size(); i++)
57 {
58 ContainerListener *listener = containerListeners.at(i);
59 listener->setContainerData(this, 0, costs[0]);
60 listener->setContainerData(this, 1, costs[1]);
61 listener->setContainerData(this, 2, costs[2]);
62 }
63 m_costsChanged = false;
64 }
65}
66
67void EnchantmentMenu::setData(int id, int value)
68{
69 if (id >= 0 && id <= 2)
70 {
71 costs[id] = value;
72 m_costsChanged = true;
73 }
74 else
75 {
76 AbstractContainerMenu::setData(id, value);
77 }
78}
79
80void EnchantmentMenu::slotsChanged() // 4J used to take a shared_ptr<Container> container but wasn't using it, so removed to simplify things
81{
82 shared_ptr<ItemInstance> item = enchantSlots->getItem(0);
83
84 if (item == NULL || !item->isEnchantable())
85 {
86 for (int i = 0; i < 3; i++)
87 {
88 costs[i] = 0;
89 }
90 m_costsChanged = true;
91 }
92 else
93 {
94 nameSeed = random.nextLong();
95
96 if (!level->isClientSide)
97 {
98 // find book cases
99 int bookcases = 0;
100 for (int oz = -1; oz <= 1; oz++)
101 {
102 for (int ox = -1; ox <= 1; ox++)
103 {
104 if (oz == 0 && ox == 0)
105 {
106 continue;
107 }
108
109 if (level->isEmptyTile(x + ox, y, z + oz) && level->isEmptyTile(x + ox, y + 1, z + oz))
110 {
111 if (level->getTile(x + ox * 2, y, z + oz * 2) == Tile::bookshelf_Id)
112 {
113 bookcases++;
114 }
115 if (level->getTile(x + ox * 2, y + 1, z + oz * 2) == Tile::bookshelf_Id)
116 {
117 bookcases++;
118 }
119 // corners
120 if (ox != 0 && oz != 0)
121 {
122 if (level->getTile(x + ox * 2, y, z + oz) == Tile::bookshelf_Id)
123 {
124 bookcases++;
125 }
126 if (level->getTile(x + ox * 2, y + 1, z + oz) == Tile::bookshelf_Id)
127 {
128 bookcases++;
129 }
130 if (level->getTile(x + ox, y, z + oz * 2) == Tile::bookshelf_Id)
131 {
132 bookcases++;
133 }
134 if (level->getTile(x + ox, y + 1, z + oz * 2) == Tile::bookshelf_Id)
135 {
136 bookcases++;
137 }
138 }
139 }
140 }
141 }
142
143 for (int i = 0; i < 3; i++)
144 {
145 costs[i] = EnchantmentHelper::getEnchantmentCost(&random, i, bookcases, item);
146 }
147 m_costsChanged = true;
148 broadcastChanges();
149 }
150 }
151}
152
153bool EnchantmentMenu::clickMenuButton(shared_ptr<Player> player, int i)
154{
155 shared_ptr<ItemInstance> item = enchantSlots->getItem(0);
156 if (costs[i] > 0 && item != NULL && (player->experienceLevel >= costs[i] || player->abilities.instabuild) )
157 {
158 if (!level->isClientSide)
159 {
160 bool isBook = item->id == Item::book_Id;
161
162 vector<EnchantmentInstance *> *newEnchantment = EnchantmentHelper::selectEnchantment(&random, item, costs[i]);
163 if (newEnchantment != NULL)
164 {
165 player->giveExperienceLevels(-costs[i]);
166 if (isBook) item->id = Item::enchantedBook_Id;
167 int randomIndex = isBook ? random.nextInt(newEnchantment->size()) : -1;
168 //for (EnchantmentInstance e : newEnchantment)
169 for (int index = 0; index < newEnchantment->size(); index++)
170 {
171 EnchantmentInstance *e = newEnchantment->at(index);
172 if (isBook && index != randomIndex)
173 {}
174 else
175 {
176 if (isBook)
177 {
178 Item::enchantedBook->addEnchantment(item, e);
179 }
180 else
181 {
182 item->enchant(e->enchantment, e->level);
183 }
184 }
185 delete e;
186 }
187 delete newEnchantment;
188 slotsChanged();// Removed enchantSlots parameter as the function can reference it directly
189 }
190 }
191 return true;
192 }
193 return false;
194}
195
196
197void EnchantmentMenu::removed(shared_ptr<Player> player)
198{
199 AbstractContainerMenu::removed(player);
200 if (level->isClientSide) return;
201
202 shared_ptr<ItemInstance> item = enchantSlots->removeItemNoUpdate(0);
203 if (item != NULL)
204 {
205 player->drop(item);
206 }
207}
208
209bool EnchantmentMenu::stillValid(shared_ptr<Player> player)
210{
211 if (level->getTile(x, y, z) != Tile::enchantTable_Id) return false;
212 if (player->distanceToSqr(x + 0.5, y + 0.5, z + 0.5) > 8 * 8) return false;
213 return true;
214}
215
216shared_ptr<ItemInstance> EnchantmentMenu::quickMoveStack(shared_ptr<Player> player, int slotIndex)
217{
218 shared_ptr<ItemInstance> clicked = nullptr;
219 Slot *slot = slots.at(slotIndex);
220 Slot *IngredientSlot = slots.at(INGREDIENT_SLOT);
221
222 if (slot != NULL && slot->hasItem())
223 {
224 shared_ptr<ItemInstance> stack = slot->getItem();
225 clicked = stack->copy();
226
227 if (slotIndex == INGREDIENT_SLOT)
228 {
229 if (!moveItemStackTo(stack, INV_SLOT_START, INV_SLOT_END, true))
230 {
231 if (!moveItemStackTo(stack, USE_ROW_SLOT_START, USE_ROW_SLOT_END, false))
232 {
233 return nullptr;
234 }
235
236 }
237 }
238 else if (slotIndex >= INV_SLOT_START && slotIndex < INV_SLOT_END)
239 {
240 // if the item is an enchantable tool
241
242 if(stack->isEnchantable() && (!IngredientSlot->hasItem() ) )
243 {
244 if(!moveItemStackTo(stack, INGREDIENT_SLOT, INGREDIENT_SLOT+1, false))
245 {
246 return nullptr;
247 }
248 }
249 else
250 {
251 if(!moveItemStackTo(stack, USE_ROW_SLOT_START, USE_ROW_SLOT_END, false))
252 {
253 return nullptr;
254 }
255 }
256 }
257 else if (slotIndex >= USE_ROW_SLOT_START && slotIndex < USE_ROW_SLOT_END)
258 {
259 // if the item is an enchantable tool
260
261 if(stack->isEnchantable() && (!IngredientSlot->hasItem() ) )
262 {
263 if(!moveItemStackTo(stack, INGREDIENT_SLOT, INGREDIENT_SLOT+1, false))
264 {
265 return nullptr;
266 }
267 }
268 else
269 {
270 if(!moveItemStackTo(stack, INV_SLOT_START, INV_SLOT_END, false))
271 {
272 return nullptr;
273 }
274 }
275 }
276 else
277 {
278 return nullptr;
279 }
280
281 if (stack->count == 0)
282 {
283 slot->set(nullptr);
284 }
285 else
286 {
287 slot->setChanged();
288 }
289 if (stack->count == clicked->count)
290 {
291 return nullptr;
292 }
293 else
294 {
295 slot->onTake(player, stack);
296 }
297 }
298 return clicked;
299}