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 "..\..\..\Minecraft.World\net.minecraft.world.item.trading.h"
3#include "..\..\..\Minecraft.World\net.minecraft.world.inventory.h"
4#include "..\..\..\Minecraft.World\net.minecraft.world.item.h"
5#include "..\..\..\Minecraft.World\net.minecraft.network.packet.h"
6#include "..\..\Minecraft.h"
7#include "..\..\MultiPlayerLocalPlayer.h"
8#include "..\..\ClientConnection.h"
9#include "IUIScene_TradingMenu.h"
10
11IUIScene_TradingMenu::IUIScene_TradingMenu()
12{
13 m_validOffersCount = 0;
14 m_selectedSlot = 0;
15 m_offersStartIndex = 0;
16 m_menu = NULL;
17 m_bHasUpdatedOnce = false;
18}
19
20shared_ptr<Merchant> IUIScene_TradingMenu::getMerchant()
21{
22 return m_merchant;
23}
24
25bool IUIScene_TradingMenu::handleKeyDown(int iPad, int iAction, bool bRepeat)
26{
27 bool handled = false;
28 //MerchantRecipeList *offers = m_merchant->getOffers(Minecraft::GetInstance()->localplayers[getPad()]);
29
30 bool changed = false;
31
32 Minecraft *pMinecraft = Minecraft::GetInstance();
33
34 if( pMinecraft->localgameModes[getPad()] != NULL )
35 {
36 Tutorial *tutorial = pMinecraft->localgameModes[getPad()]->getTutorial();
37 if(tutorial != NULL)
38 {
39 tutorial->handleUIInput(iAction);
40 if(ui.IsTutorialVisible(getPad()) && !tutorial->isInputAllowed(iAction))
41 {
42 return S_OK;
43 }
44 }
45 }
46
47
48 switch(iAction)
49 {
50 case ACTION_MENU_B:
51 ui.ShowTooltip( iPad, eToolTipButtonX, false );
52 ui.ShowTooltip( iPad, eToolTipButtonB, false );
53 ui.ShowTooltip( iPad, eToolTipButtonA, false );
54 ui.ShowTooltip( iPad, eToolTipButtonRB, false );
55 // kill the crafting xui
56 //ui.PlayUISFX(eSFX_Back);
57 ui.CloseUIScenes(iPad);
58
59 handled = true;
60 break;
61 case ACTION_MENU_A:
62#ifdef __ORBIS__
63 case ACTION_MENU_TOUCHPAD_PRESS:
64#endif
65 if(!m_activeOffers.empty())
66 {
67 int selectedShopItem = (m_selectedSlot + m_offersStartIndex);
68 if( selectedShopItem < m_activeOffers.size() )
69 {
70 MerchantRecipe *activeRecipe = m_activeOffers.at(selectedShopItem).first;
71 if(!activeRecipe->isDeprecated())
72 {
73 // Do we have the ingredients?
74 shared_ptr<ItemInstance> buyAItem = activeRecipe->getBuyAItem();
75 shared_ptr<ItemInstance> buyBItem = activeRecipe->getBuyBItem();
76 shared_ptr<MultiplayerLocalPlayer> player = Minecraft::GetInstance()->localplayers[getPad()];
77 int buyAMatches = player->inventory->countMatches(buyAItem);
78 int buyBMatches = player->inventory->countMatches(buyBItem);
79 if( (buyAItem != NULL && buyAMatches >= buyAItem->count) && (buyBItem == NULL || buyBMatches >= buyBItem->count) )
80 {
81 // 4J-JEV: Fix for PS4 #7111: [PATCH 1.12] Trading Librarian villagers for multiple �Enchanted Books� will cause the title to crash.
82 int actualShopItem = m_activeOffers.at(selectedShopItem).second;
83
84 m_merchant->notifyTrade(activeRecipe);
85
86 // Remove the items we are purchasing with
87 player->inventory->removeResources(buyAItem);
88 player->inventory->removeResources(buyBItem);
89
90 // Add the item we have purchased
91 shared_ptr<ItemInstance> result = activeRecipe->getSellItem()->copy();
92 if(!player->inventory->add( result ) )
93 {
94 player->drop(result);
95 }
96
97 // Send a packet to the server
98 player->connection->send( shared_ptr<TradeItemPacket>( new TradeItemPacket(m_menu->containerId, actualShopItem) ) );
99
100 updateDisplay();
101 }
102 }
103 }
104 }
105 handled = true;
106 break;
107 case ACTION_MENU_LEFT:
108 handled = true;
109 if(m_selectedSlot == 0)
110 {
111 if(m_offersStartIndex > 0)
112 {
113 --m_offersStartIndex;
114 changed = true;
115 }
116 }
117 else
118 {
119 --m_selectedSlot;
120 changed = true;
121 moveSelector(false);
122 }
123 break;
124 case ACTION_MENU_RIGHT:
125 handled = true;
126 if(m_selectedSlot == (DISPLAY_TRADES_COUNT - 1))
127 {
128 if((m_offersStartIndex + DISPLAY_TRADES_COUNT) < m_activeOffers.size())
129 {
130 ++m_offersStartIndex;
131 changed = true;
132 }
133 }
134 else
135 {
136 ++m_selectedSlot;
137 changed = true;
138 moveSelector(true);
139 }
140 break;
141 }
142 if (changed)
143 {
144 updateDisplay();
145
146 int selectedShopItem = (m_selectedSlot + m_offersStartIndex);
147 if( selectedShopItem < m_activeOffers.size() )
148 {
149 int actualShopItem = m_activeOffers.at(selectedShopItem).second;
150 m_menu->setSelectionHint(actualShopItem);
151
152 ByteArrayOutputStream rawOutput;
153 DataOutputStream output(&rawOutput);
154 output.writeInt(actualShopItem);
155 Minecraft::GetInstance()->getConnection(getPad())->send(shared_ptr<CustomPayloadPacket>( new CustomPayloadPacket(CustomPayloadPacket::TRADER_SELECTION_PACKET, rawOutput.toByteArray())));
156 }
157 }
158 return handled;
159}
160
161void IUIScene_TradingMenu::handleTick()
162{
163 int offerCount = 0;
164 MerchantRecipeList *offers = m_merchant->getOffers(Minecraft::GetInstance()->localplayers[getPad()]);
165 if (offers != NULL)
166 {
167 offerCount = offers->size();
168
169 if(!m_bHasUpdatedOnce)
170 {
171 updateDisplay();
172 }
173 }
174
175 showScrollRightArrow( (m_offersStartIndex + DISPLAY_TRADES_COUNT) < m_activeOffers.size());
176 showScrollLeftArrow(m_offersStartIndex > 0);
177}
178
179void IUIScene_TradingMenu::updateDisplay()
180{
181 int iA = -1;
182
183 MerchantRecipeList *unfilteredOffers = m_merchant->getOffers(Minecraft::GetInstance()->localplayers[getPad()]);
184 if (unfilteredOffers != NULL)
185 {
186 m_activeOffers.clear();
187 int unfilteredIndex = 0;
188 int firstValidTrade = INT_MAX;
189 for(AUTO_VAR(it, unfilteredOffers->begin()); it != unfilteredOffers->end(); ++it)
190 {
191 MerchantRecipe *recipe = *it;
192 if(!recipe->isDeprecated())
193 {
194 m_activeOffers.push_back( pair<MerchantRecipe *,int>(recipe,unfilteredIndex));
195 firstValidTrade = min(firstValidTrade,unfilteredIndex);
196 }
197 ++unfilteredIndex;
198 }
199
200 if(!m_bHasUpdatedOnce)
201 {
202 if(firstValidTrade != 0 && firstValidTrade < unfilteredOffers->size())
203 {
204 m_menu->setSelectionHint(firstValidTrade);
205
206 ByteArrayOutputStream rawOutput;
207 DataOutputStream output(&rawOutput);
208 output.writeInt(firstValidTrade);
209 Minecraft::GetInstance()->getConnection(getPad())->send(shared_ptr<CustomPayloadPacket>( new CustomPayloadPacket(CustomPayloadPacket::TRADER_SELECTION_PACKET, rawOutput.toByteArray())));
210 }
211 }
212
213 if( (m_offersStartIndex + DISPLAY_TRADES_COUNT) > m_activeOffers.size())
214 {
215 m_offersStartIndex = m_activeOffers.size() - DISPLAY_TRADES_COUNT;
216 if(m_offersStartIndex < 0) m_offersStartIndex = 0;
217 }
218
219 for(unsigned int i = 0; i < DISPLAY_TRADES_COUNT; ++i)
220 {
221 int offerIndex = i + m_offersStartIndex;
222 bool showRedBox = false;
223 if(offerIndex < m_activeOffers.size())
224 {
225 showRedBox = !canMake(m_activeOffers.at(offerIndex).first);
226 setTradeItem(i, m_activeOffers.at(offerIndex).first->getSellItem() );
227 }
228 else
229 {
230 setTradeItem(i, nullptr);
231 }
232 setTradeRedBox( i, showRedBox);
233 }
234
235 int selectedShopItem = (m_selectedSlot + m_offersStartIndex);
236 if( selectedShopItem < m_activeOffers.size() )
237 {
238 MerchantRecipe *activeRecipe = m_activeOffers.at(selectedShopItem).first;
239
240 wstring wsTemp;
241
242 // 4J-PB - need to get the villager type here
243 wsTemp = app.GetString(IDS_VILLAGER_OFFERS_ITEM);
244 wsTemp = replaceAll(wsTemp,L"{*VILLAGER_TYPE*}",m_merchant->getDisplayName());
245 int iPos=wsTemp.find(L"%s");
246 wsTemp.replace(iPos,2,activeRecipe->getSellItem()->getHoverName());
247
248 setTitle(wsTemp.c_str());
249
250 vector<HtmlString> *offerDescription = GetItemDescription(activeRecipe->getSellItem());
251 setOfferDescription(offerDescription);
252
253 shared_ptr<ItemInstance> buyAItem = activeRecipe->getBuyAItem();
254 shared_ptr<ItemInstance> buyBItem = activeRecipe->getBuyBItem();
255
256 setRequest1Item(buyAItem);
257 setRequest2Item(buyBItem);
258
259 if(buyAItem != NULL) setRequest1Name(buyAItem->getHoverName());
260 else setRequest1Name(L"");
261
262 if(buyBItem != NULL) setRequest2Name(buyBItem->getHoverName());
263 else setRequest2Name(L"");
264
265 bool canMake = true;
266
267 shared_ptr<MultiplayerLocalPlayer> player = Minecraft::GetInstance()->localplayers[getPad()];
268 int buyAMatches = player->inventory->countMatches(buyAItem);
269 if(buyAMatches > 0)
270 {
271 setRequest1RedBox(buyAMatches < buyAItem->count);
272 canMake = buyAMatches > buyAItem->count;
273 }
274 else
275 {
276 setRequest1RedBox(true);
277 canMake = false;
278 }
279
280 int buyBMatches = player->inventory->countMatches(buyBItem);
281 if(buyBMatches > 0)
282 {
283 setRequest2RedBox(buyBMatches < buyBItem->count);
284 canMake = canMake && buyBMatches > buyBItem->count;
285 }
286 else
287 {
288 if(buyBItem!=NULL)
289 {
290 setRequest2RedBox(true);
291 canMake = false;
292 }
293 else
294 {
295 setRequest2RedBox(buyBItem != NULL);
296 canMake = canMake && buyBItem == NULL;
297 }
298 }
299
300 if(canMake) iA = IDS_TOOLTIPS_TRADE;
301 }
302 else
303 {
304 setTitle(m_merchant->getDisplayName());
305 setRequest1Name(L"");
306 setRequest2Name(L"");
307 setRequest1RedBox(false);
308 setRequest2RedBox(false);
309 setRequest1Item(nullptr);
310 setRequest2Item(nullptr);
311 vector<HtmlString> offerDescription;
312 setOfferDescription(&offerDescription);
313 }
314
315 m_bHasUpdatedOnce = true;
316 }
317
318 ui.SetTooltips(getPad(), iA, IDS_TOOLTIPS_EXIT);
319}
320
321bool IUIScene_TradingMenu::canMake(MerchantRecipe *recipe)
322{
323 bool canMake = false;
324 if (recipe != NULL)
325 {
326 if(recipe->isDeprecated()) return false;
327
328 shared_ptr<ItemInstance> buyAItem = recipe->getBuyAItem();
329 shared_ptr<ItemInstance> buyBItem = recipe->getBuyBItem();
330
331 shared_ptr<MultiplayerLocalPlayer> player = Minecraft::GetInstance()->localplayers[getPad()];
332 int buyAMatches = player->inventory->countMatches(buyAItem);
333 if(buyAMatches > 0)
334 {
335 canMake = buyAMatches >= buyAItem->count;
336 }
337 else
338 {
339 canMake = buyAItem == NULL;
340 }
341
342 int buyBMatches = player->inventory->countMatches(buyBItem);
343 if(buyBMatches > 0)
344 {
345 canMake = canMake && buyBMatches >= buyBItem->count;
346 }
347 else
348 {
349 canMake = canMake && buyBItem == NULL;
350 }
351 }
352 return canMake;
353}
354
355
356void IUIScene_TradingMenu::setRequest1Item(shared_ptr<ItemInstance> item)
357{
358}
359
360void IUIScene_TradingMenu::setRequest2Item(shared_ptr<ItemInstance> item)
361{
362}
363
364void IUIScene_TradingMenu::setTradeItem(int index, shared_ptr<ItemInstance> item)
365{
366}
367
368vector<HtmlString> *IUIScene_TradingMenu::GetItemDescription(shared_ptr<ItemInstance> item)
369{
370 vector<HtmlString> *lines = item->getHoverText(nullptr, false);
371
372 // Add rarity to first line
373 if (lines->size() > 0)
374 {
375 lines->at(0).color = item->getRarity()->color;
376 }
377
378 return lines;
379}
380
381void IUIScene_TradingMenu::HandleInventoryUpdated()
382{
383 updateDisplay();
384}