the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
1#include "stdafx.h"
2
3#include "..\..\..\Minecraft.World\net.minecraft.world.item.crafting.h"
4#include "..\..\..\Minecraft.World\net.minecraft.world.level.tile.h"
5#include "..\..\..\Minecraft.World\net.minecraft.stats.h"
6#include "..\..\LocalPlayer.h"
7#include "IUIScene_CraftingMenu.h"
8
9Recipy::_eGroupType IUIScene_CraftingMenu::m_GroupTypeMapping4GridA[IUIScene_CraftingMenu::m_iMaxGroup2x2]=
10{
11 Recipy::eGroupType_Structure,
12 Recipy::eGroupType_Tool,
13 Recipy::eGroupType_Food,
14 Recipy::eGroupType_Mechanism,
15 Recipy::eGroupType_Transport,
16 Recipy::eGroupType_Decoration,
17};
18
19Recipy::_eGroupType IUIScene_CraftingMenu::m_GroupTypeMapping9GridA[IUIScene_CraftingMenu::m_iMaxGroup3x3]=
20{
21 Recipy::eGroupType_Structure,
22 Recipy::eGroupType_Tool,
23 Recipy::eGroupType_Food,
24 Recipy::eGroupType_Armour,
25 Recipy::eGroupType_Mechanism,
26 Recipy::eGroupType_Transport,
27 Recipy::eGroupType_Decoration,
28};
29
30
31LPCWSTR IUIScene_CraftingMenu::m_GroupIconNameA[m_iMaxGroup3x3]=
32{
33 L"Structures",//Recipy::eGroupType_Structure,
34 L"Tools",//Recipy::eGroupType_Tool,
35 L"Food",//Recipy::eGroupType_Food,
36 L"Armour",//Recipy::eGroupType_Armour,
37 L"Mechanisms",//Recipy::eGroupType_Mechanism,
38 L"Transport",//Recipy::eGroupType_Transport,
39 L"Decoration",//Recipy::eGroupType_Decoration,
40};
41
42IUIScene_CraftingMenu::_eGroupTab IUIScene_CraftingMenu::m_GroupTabBkgMapping2x2A[m_iMaxGroup2x2]=
43{
44 eGroupTab_Left,
45 eGroupTab_Middle,
46 eGroupTab_Middle,
47 eGroupTab_Middle,
48 eGroupTab_Middle,
49 eGroupTab_Right,
50};
51
52IUIScene_CraftingMenu::_eGroupTab IUIScene_CraftingMenu::m_GroupTabBkgMapping3x3A[m_iMaxGroup3x3]=
53{
54 eGroupTab_Left,
55 eGroupTab_Middle,
56 eGroupTab_Middle,
57 eGroupTab_Middle,
58 eGroupTab_Middle,
59 eGroupTab_Middle,
60 eGroupTab_Right,
61};
62
63
64// mapping array to map the base objects to their description string
65// This should map the enums
66// enum
67// {
68// eBaseItemType_undefined=0,
69// eBaseItemType_sword,
70// eBaseItemType_shovel,
71// eBaseItemType_pickaxe,
72// eBaseItemType_hatchet,
73// eBaseItemType_hoe,
74// eBaseItemType_door,
75// eBaseItemType_helmet,
76// eBaseItemType_chestplate,
77// eBaseItemType_leggings,
78// eBaseItemType_boots,
79// eBaseItemType_ingot,
80// eBaseItemType_rail,
81// eBaseItemType_block,
82// eBaseItemType_pressureplate,
83// eBaseItemType_stairs,
84// eBaseItemType_cloth,
85// eBaseItemType_dyepowder,
86// eBaseItemType_structplanks
87// eBaseItemType_structblock,
88// eBaseItemType_slab,
89// eBaseItemType_halfslab,
90// eBaseItemType_torch,
91// eBaseItemType_bow,
92// eBaseItemType_pockettool,
93// eBaseItemType_utensil,
94//
95// }
96// eBaseItemType;
97
98IUIScene_CraftingMenu::IUIScene_CraftingMenu()
99{
100 m_iCurrentSlotHIndex=0;
101 m_iCurrentSlotVIndex=1;
102
103 for(int i=0;i<m_iMaxHSlotC;i++)
104 {
105 CanBeMadeA[i].iCount=0;
106 CanBeMadeA[i].iItemBaseType=0;
107 }
108 memset(CanBeMadeA,0,sizeof(CANBEMADE)*m_iMaxHSlotC);
109 m_iRecipeC=0;
110 m_iGroupIndex=0;
111
112 for(int i=0;i<m_iMaxDisplayedVSlotC;i++)
113 {
114 iVSlotIndexA[i]=i; // start with 0,1,2
115 }
116
117 m_iDisplayDescription=DISPLAY_INVENTORY;
118 m_iIngredientsC=0;
119}
120
121LPCWSTR IUIScene_CraftingMenu::GetGroupNameText(int iGroupType)
122{
123 switch(iGroupType)
124 {
125 case ShapedRecipy::eGroupType_Tool:
126 return app.GetString( IDS_GROUPNAME_TOOLS );
127 case ShapedRecipy::eGroupType_Food:
128 return app.GetString( IDS_GROUPNAME_FOOD);
129 case ShapedRecipy::eGroupType_Structure:
130 return app.GetString( IDS_GROUPNAME_STRUCTURES );
131 case ShapedRecipy::eGroupType_Armour:
132 return app.GetString( IDS_GROUPNAME_ARMOUR );
133 case ShapedRecipy::eGroupType_Mechanism:
134 return app.GetString( IDS_GROUPNAME_MECHANISMS );
135 case ShapedRecipy::eGroupType_Transport:
136 return app.GetString( IDS_GROUPNAME_TRANSPORT );
137 case ShapedRecipy::eGroupType_Decoration:
138 default:
139 return app.GetString( IDS_GROUPNAME_DECORATIONS );
140 }
141}
142
143bool IUIScene_CraftingMenu::handleKeyDown(int iPad, int iAction, bool bRepeat)
144{
145 bool bHandled = false;
146
147 if(m_bIgnoreKeyPresses) return bHandled;
148
149 // ignore key repeats of the X key - because it's X to open this menu, it can come through as a repeat on opening
150 if(bRepeat &&(iAction==ACTION_MENU_X))
151 {
152 return S_OK;
153 }
154
155 Minecraft *pMinecraft = Minecraft::GetInstance();
156
157 if( pMinecraft->localgameModes[getPad()] != NULL )
158 {
159 Tutorial *tutorial = pMinecraft->localgameModes[getPad()]->getTutorial();
160 if(tutorial != NULL)
161 {
162 tutorial->handleUIInput(iAction);
163 if(ui.IsTutorialVisible(getPad()) && !tutorial->isInputAllowed(iAction))
164 {
165 return S_OK;
166 }
167 }
168 }
169
170
171 switch(iAction)
172 {
173 case ACTION_MENU_X:
174
175 // change the display
176 m_iDisplayDescription++;
177 if(m_iDisplayDescription==DISPLAY_MAX) m_iDisplayDescription=DISPLAY_INVENTORY;
178 ui.PlayUISFX(eSFX_Focus);
179 UpdateMultiPanel();
180 UpdateTooltips();
181 break;
182 case ACTION_MENU_PAUSEMENU:
183 case ACTION_MENU_B:
184 ui.ShowTooltip( iPad, eToolTipButtonX, false );
185 ui.ShowTooltip( iPad, eToolTipButtonB, false );
186 ui.ShowTooltip( iPad, eToolTipButtonA, false );
187 ui.ShowTooltip( iPad, eToolTipButtonRB, false );
188 // kill the crafting xui
189 //ui.PlayUISFX(eSFX_Back);
190 ui.CloseUIScenes(iPad);
191
192 bHandled = true;
193 break;
194 case ACTION_MENU_A:
195#ifdef __ORBIS__
196 case ACTION_MENU_TOUCHPAD_PRESS:
197#endif
198 // Do some crafting!
199 if(m_pPlayer && m_pPlayer->inventory)
200 {
201 //RecipyList *recipes = ((Recipes *)Recipes::getInstance())->getRecipies();
202 Recipy::INGREDIENTS_REQUIRED *pRecipeIngredientsRequired=Recipes::getInstance()->getRecipeIngredientsArray();
203 // Force a make if the debug is on
204 if(app.DebugSettingsOn() && app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad())&(1L<<eDebugSetting_CraftAnything))
205 {
206 if(CanBeMadeA[m_iCurrentSlotHIndex].iCount!=0)
207 {
208 int iSlot=iVSlotIndexA[m_iCurrentSlotVIndex];
209
210 int iRecipe= CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[iSlot];
211 shared_ptr<ItemInstance> pTempItemInst=pRecipeIngredientsRequired[iRecipe].pRecipy->assemble(nullptr);
212 //int iIcon=pTempItemInst->getItem()->getIcon(pTempItemInst->getAuxValue());
213
214 if( pMinecraft->localgameModes[iPad] != NULL)
215 {
216 Tutorial *tutorial = pMinecraft->localgameModes[iPad]->getTutorial();
217 if(tutorial != NULL)
218 {
219 tutorial->onCrafted(pTempItemInst);
220 }
221 }
222
223 pMinecraft->localgameModes[iPad]->handleCraftItem(iRecipe,m_pPlayer);
224
225 if(m_pPlayer->inventory->add(pTempItemInst)==false)
226 {
227 // no room in inventory, so throw it down
228 m_pPlayer->drop(pTempItemInst);
229 }
230 // play a sound
231 //pMinecraft->soundEngine->playUI( L"random.pop", 1.0f, 1.0f);
232 ui.PlayUISFX(eSFX_Craft);
233 }
234 }
235 else if(CanBeMadeA[m_iCurrentSlotHIndex].iCount!=0)
236 {
237 int iSlot;
238 if(CanBeMadeA[m_iCurrentSlotHIndex].iCount>1)
239 {
240 iSlot=iVSlotIndexA[m_iCurrentSlotVIndex];
241 }
242 else
243 {
244 iSlot=0;
245 }
246 int iRecipe= CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[iSlot];
247 shared_ptr<ItemInstance> pTempItemInst=pRecipeIngredientsRequired[iRecipe].pRecipy->assemble(nullptr);
248 //int iIcon=pTempItemInst->getItem()->getIcon(pTempItemInst->getAuxValue());
249
250 if( pMinecraft->localgameModes[iPad] != NULL )
251 {
252 Tutorial *tutorial = pMinecraft->localgameModes[iPad]->getTutorial();
253 if(tutorial != NULL)
254 {
255 tutorial->createItemSelected(pTempItemInst, pRecipeIngredientsRequired[iRecipe].bCanMake[iPad]);
256 }
257 }
258
259 if(pRecipeIngredientsRequired[iRecipe].bCanMake[iPad])
260 {
261 pTempItemInst->onCraftedBy(m_pPlayer->level, dynamic_pointer_cast<Player>( m_pPlayer->shared_from_this() ), pTempItemInst->count );
262 // TODO 4J Stu - handleCraftItem should do a lot more than what it does, loads of the "can we craft" code should also probably be
263 // shifted to the GameMode
264 pMinecraft->localgameModes[iPad]->handleCraftItem(iRecipe,m_pPlayer);
265
266 // play a sound
267 //pMinecraft->soundEngine->playUI( L"random.pop", 1.0f, 1.0f);
268 ui.PlayUISFX(eSFX_Craft);
269
270 if(pTempItemInst->id != Item::fireworksCharge_Id && pTempItemInst->id != Item::fireworks_Id)
271 {
272 // and remove those resources from your inventory
273 for(int i=0;i<pRecipeIngredientsRequired[iRecipe].iIngC;i++)
274 {
275 for(int j=0;j<pRecipeIngredientsRequired[iRecipe].iIngValA[i];j++)
276 {
277 shared_ptr<ItemInstance> ingItemInst = nullptr;
278 // do we need to remove a specific aux value?
279 if(pRecipeIngredientsRequired[iRecipe].iIngAuxValA[i]!=Recipes::ANY_AUX_VALUE)
280 {
281 ingItemInst = m_pPlayer->inventory->getResourceItem( pRecipeIngredientsRequired[iRecipe].iIngIDA[i],pRecipeIngredientsRequired[iRecipe].iIngAuxValA[i] );
282 m_pPlayer->inventory->removeResource(pRecipeIngredientsRequired[iRecipe].iIngIDA[i],pRecipeIngredientsRequired[iRecipe].iIngAuxValA[i]);
283 }
284 else
285 {
286 ingItemInst = m_pPlayer->inventory->getResourceItem( pRecipeIngredientsRequired[iRecipe].iIngIDA[i] );
287 m_pPlayer->inventory->removeResource(pRecipeIngredientsRequired[iRecipe].iIngIDA[i]);
288 }
289
290 // 4J Stu - Fix for #13097 - Bug: Milk Buckets are removed when crafting Cake
291 if (ingItemInst != NULL)
292 {
293 if (ingItemInst->getItem()->hasCraftingRemainingItem())
294 {
295 // replace item with remaining result
296 m_pPlayer->inventory->add( shared_ptr<ItemInstance>( new ItemInstance(ingItemInst->getItem()->getCraftingRemainingItem()) ) );
297 }
298
299 }
300 }
301 }
302
303 // 4J Stu - Fix for #13119 - We should add the item after we remove the ingredients
304 if(m_pPlayer->inventory->add(pTempItemInst)==false )
305 {
306 // no room in inventory, so throw it down
307 m_pPlayer->drop(pTempItemInst);
308 }
309
310 //4J Gordon: Achievements
311 switch(pTempItemInst->id )
312 {
313 case Tile::workBench_Id: m_pPlayer->awardStat(GenericStats::buildWorkbench(), GenericStats::param_buildWorkbench()); break;
314 case Item::pickAxe_wood_Id: m_pPlayer->awardStat(GenericStats::buildPickaxe(), GenericStats::param_buildPickaxe()); break;
315 case Tile::furnace_Id: m_pPlayer->awardStat(GenericStats::buildFurnace(), GenericStats::param_buildFurnace()); break;
316 case Item::hoe_wood_Id: m_pPlayer->awardStat(GenericStats::buildHoe(), GenericStats::param_buildHoe()); break;
317 case Item::bread_Id: m_pPlayer->awardStat(GenericStats::makeBread(), GenericStats::param_makeBread()); break;
318 case Item::cake_Id: m_pPlayer->awardStat(GenericStats::bakeCake(), GenericStats::param_bakeCake()); break;
319 case Item::pickAxe_stone_Id: m_pPlayer->awardStat(GenericStats::buildBetterPickaxe(), GenericStats::param_buildBetterPickaxe()); break;
320 case Item::sword_wood_Id: m_pPlayer->awardStat(GenericStats::buildSword(), GenericStats::param_buildSword()); break;
321 case Tile::dispenser_Id: m_pPlayer->awardStat(GenericStats::dispenseWithThis(), GenericStats::param_dispenseWithThis()); break;
322 case Tile::enchantTable_Id: m_pPlayer->awardStat(GenericStats::enchantments(), GenericStats::param_enchantments()); break;
323 case Tile::bookshelf_Id: m_pPlayer->awardStat(GenericStats::bookcase(), GenericStats::param_bookcase()); break;
324 }
325
326 // We've used some ingredients from our inventory, so update the recipes we can make
327 CheckRecipesAvailable();
328 // don't reset the vertical slots - we want to stay where we are
329 UpdateVerticalSlots();
330 UpdateHighlight();
331 }
332 }
333 else
334 {
335 //pMinecraft->soundEngine->playUI( L"btn.back", 1.0f, 1.0f);
336 ui.PlayUISFX(eSFX_CraftFail);
337 }
338 }
339 }
340 break;
341
342 case ACTION_MENU_LEFT_SCROLL:
343 // turn off the old group tab
344 showTabHighlight(m_iGroupIndex,false);
345
346 if(m_iGroupIndex==0)
347 {
348 if(m_iContainerType==RECIPE_TYPE_3x3)
349 {
350 m_iGroupIndex=m_iMaxGroup3x3-1;
351 }
352 else
353 {
354 m_iGroupIndex=m_iMaxGroup2x2-1;
355 }
356 }
357 else
358 {
359 m_iGroupIndex--;
360 }
361 // turn on the new group
362 showTabHighlight(m_iGroupIndex,true);
363
364 m_iCurrentSlotHIndex=0;
365 m_iCurrentSlotVIndex=1;
366
367 CheckRecipesAvailable();
368 // reset the vertical slots
369 iVSlotIndexA[0]=CanBeMadeA[m_iCurrentSlotHIndex].iCount-1;
370 iVSlotIndexA[1]=0;
371 iVSlotIndexA[2]=1;
372 ui.PlayUISFX(eSFX_Focus);
373 UpdateVerticalSlots();
374 UpdateHighlight();
375 setGroupText(GetGroupNameText(m_pGroupA[m_iGroupIndex]));
376
377 break;
378 case ACTION_MENU_RIGHT_SCROLL:
379 // turn off the old group tab
380 showTabHighlight(m_iGroupIndex,false);
381
382 m_iGroupIndex++;
383 if(m_iContainerType==RECIPE_TYPE_3x3)
384 {
385 if(m_iGroupIndex==m_iMaxGroup3x3) m_iGroupIndex=0;
386 }
387 else
388 {
389 if(m_iGroupIndex==m_iMaxGroup2x2) m_iGroupIndex=0;
390 }
391 // turn on the new group
392 showTabHighlight(m_iGroupIndex,true);
393
394 m_iCurrentSlotHIndex=0;
395 m_iCurrentSlotVIndex=1;
396 CheckRecipesAvailable();
397 // reset the vertical slots
398 iVSlotIndexA[0]=CanBeMadeA[m_iCurrentSlotHIndex].iCount-1;
399 iVSlotIndexA[1]=0;
400 iVSlotIndexA[2]=1;
401 ui.PlayUISFX(eSFX_Focus);
402 UpdateVerticalSlots();
403 UpdateHighlight();
404 setGroupText(GetGroupNameText(m_pGroupA[m_iGroupIndex]));
405 break;
406 }
407
408 // 4J-Tomk - check if we've only got one vertical scroll slot (480, splits & Vita)
409 bool bNoScrollSlots = false;
410 if(m_bSplitscreen ||(!RenderManager.IsHiDef() && !RenderManager.IsWidescreen()))
411 {
412 bNoScrollSlots = true;
413 }
414#ifdef __PSVITA__
415 bNoScrollSlots = true;
416#endif
417
418 // 4J Stu - We did used to swap the thumsticks based on Southpaw in this scene, but ONLY in this scene
419 switch(iAction)
420 {
421 case ACTION_MENU_OTHER_STICK_UP:
422 scrollDescriptionUp();
423 break;
424 case ACTION_MENU_OTHER_STICK_DOWN:
425 scrollDescriptionDown();
426 break;
427 case ACTION_MENU_RIGHT:
428 {
429 int iOldHSlot=m_iCurrentSlotHIndex;
430
431 m_iCurrentSlotHIndex++;
432 if(m_iCurrentSlotHIndex>=m_iCraftablesMaxHSlotC) m_iCurrentSlotHIndex=0;
433 m_iCurrentSlotVIndex=1;
434 // clear the indices
435 iVSlotIndexA[0]=CanBeMadeA[m_iCurrentSlotHIndex].iCount-1;
436 iVSlotIndexA[1]=0;
437 iVSlotIndexA[2]=1;
438
439 UpdateVerticalSlots();
440 UpdateHighlight();
441 // re-enable the old hslot
442 if(CanBeMadeA[iOldHSlot].iCount>0)
443 {
444 setShowCraftHSlot(iOldHSlot,true);
445 }
446 ui.PlayUISFX(eSFX_Focus);
447 bHandled = true;
448 }
449 break;
450 case ACTION_MENU_LEFT:
451 {
452 if(m_iCraftablesMaxHSlotC!=0)
453 {
454 int iOldHSlot=m_iCurrentSlotHIndex;
455 if(m_iCurrentSlotHIndex==0) m_iCurrentSlotHIndex=m_iCraftablesMaxHSlotC-1;
456 else m_iCurrentSlotHIndex--;
457 m_iCurrentSlotVIndex=1;
458 // clear the indices
459 iVSlotIndexA[0]=CanBeMadeA[m_iCurrentSlotHIndex].iCount-1;
460 iVSlotIndexA[1]=0;
461 iVSlotIndexA[2]=1;
462
463 UpdateVerticalSlots();
464 UpdateHighlight();
465 // re-enable the old hslot
466 if(CanBeMadeA[iOldHSlot].iCount>0)
467 {
468 setShowCraftHSlot(iOldHSlot,true);
469 }
470 ui.PlayUISFX(eSFX_Focus);
471 }
472 bHandled = true;
473 }
474 break;
475 case ACTION_MENU_UP:
476 {
477 if(CanBeMadeA[m_iCurrentSlotHIndex].iCount>1)
478 {
479 if(bNoScrollSlots)
480 {
481 if(iVSlotIndexA[1]==0)
482 {
483 iVSlotIndexA[1]=CanBeMadeA[m_iCurrentSlotHIndex].iCount-1;
484 }
485 else
486 {
487 iVSlotIndexA[1]--;
488 }
489 ui.PlayUISFX(eSFX_Focus);
490 }
491 else
492 if(CanBeMadeA[m_iCurrentSlotHIndex].iCount>2)
493 {
494 {
495 if(m_iCurrentSlotVIndex!=0)
496 {
497 // just move the highlight
498 m_iCurrentSlotVIndex--;
499 ui.PlayUISFX(eSFX_Focus);
500 }
501 else
502 {
503 //move the slots
504 iVSlotIndexA[2]=iVSlotIndexA[1];
505 iVSlotIndexA[1]=iVSlotIndexA[0];
506 // on 0 and went up, so cycle the values
507 if(iVSlotIndexA[0]==0)
508 {
509 iVSlotIndexA[0]=CanBeMadeA[m_iCurrentSlotHIndex].iCount-1;
510 }
511 else
512 {
513 iVSlotIndexA[0]--;
514 }
515 ui.PlayUISFX(eSFX_Focus);
516 }
517 }
518 }
519 else
520 {
521 if(m_iCurrentSlotVIndex!=1)
522 {
523 // just move the highlight
524 m_iCurrentSlotVIndex--;
525 ui.PlayUISFX(eSFX_Focus);
526 }
527 }
528 UpdateVerticalSlots();
529 UpdateHighlight();
530 }
531
532 }
533 break;
534 case ACTION_MENU_DOWN:
535 {
536 if(CanBeMadeA[m_iCurrentSlotHIndex].iCount>1)
537 {
538 if(bNoScrollSlots)
539 {
540 if(iVSlotIndexA[1]==(CanBeMadeA[m_iCurrentSlotHIndex].iCount-1))
541 {
542 iVSlotIndexA[1]=0;
543 }
544 else
545 {
546 iVSlotIndexA[1]++;
547 }
548 ui.PlayUISFX(eSFX_Focus);
549
550 }
551 else
552 if(CanBeMadeA[m_iCurrentSlotHIndex].iCount>2)
553 {
554 if(m_iCurrentSlotVIndex!=2)
555 {
556 m_iCurrentSlotVIndex++;
557 ui.PlayUISFX(eSFX_Focus);
558 }
559 else
560 {
561 iVSlotIndexA[0]=iVSlotIndexA[1];
562 iVSlotIndexA[1]=iVSlotIndexA[2];
563 if(iVSlotIndexA[m_iCurrentSlotVIndex]==(CanBeMadeA[m_iCurrentSlotHIndex].iCount-1))
564 {
565 iVSlotIndexA[2]=0;
566 }
567 else
568 {
569 iVSlotIndexA[2]++;
570 }
571 ui.PlayUISFX(eSFX_Focus);
572 }
573 }
574 else
575 {
576 if(m_iCurrentSlotVIndex!=(CanBeMadeA[m_iCurrentSlotHIndex].iCount))
577 {
578 m_iCurrentSlotVIndex++;
579 ui.PlayUISFX(eSFX_Focus);
580 }
581 }
582 UpdateVerticalSlots();
583 UpdateHighlight();
584 }
585 }
586 break;
587 }
588
589 return bHandled;
590}
591
592//////////////////////////////////////////////////////////////////////////
593//
594// CheckRecipesAvailable
595//
596//////////////////////////////////////////////////////////////////////////
597void IUIScene_CraftingMenu::CheckRecipesAvailable()
598{
599 int iHSlotBrushControl=0;
600
601 // clear the current list
602 memset(CanBeMadeA,0,sizeof(CANBEMADE)*m_iCraftablesMaxHSlotC);
603
604 hideAllHSlots();
605
606 if(m_pPlayer && m_pPlayer->inventory)
607 {
608 // dump out the inventory
609 /* for (unsigned int k = 0; k < m_pPlayer->inventory->items.length; k++)
610 {
611 if (m_pPlayer->inventory->items[k] != NULL)
612 {
613 wstring itemstring=m_pPlayer->inventory->items[k]->toString();
614
615 //printf("--- Player has ");
616 OutputDebugStringW(itemstring.c_str());
617 //printf(" with Aux val = %d, base type = %d, Material = %d\n",m_pPlayer->inventory->items[k]->getAuxValue(),m_pPlayer->inventory->items[k]->getItem()->getBaseItemType(),m_pPlayer->inventory->items[k]->getItem()->getMaterial());
618 }
619 }
620 */
621 RecipyList *recipes = ((Recipes *)Recipes::getInstance())->getRecipies();
622 Recipy::INGREDIENTS_REQUIRED *pRecipeIngredientsRequired=Recipes::getInstance()->getRecipeIngredientsArray();
623 int iRecipeC=(int)recipes->size();
624 AUTO_VAR(itRecipe, recipes->begin());
625
626 // dump out the recipe products
627
628 // for (int i = 0; i < iRecipeC; i++)
629 // {
630 // shared_ptr<ItemInstance> pTempItemInst=pRecipeIngredientsRequired[i].pRecipy->assemble(NULL);
631 // if (pTempItemInst != NULL)
632 // {
633 // wstring itemstring=pTempItemInst->toString();
634 //
635 // printf("Recipe [%d] = ",i);
636 // OutputDebugStringW(itemstring.c_str());
637 // if(pTempItemInst->id!=0)
638 // {
639 // if(pTempItemInst->id<256)
640 // {
641 // Tile *pTile=Tile::tiles[pTempItemInst->id];
642 // printf("[TILE] ID\t%d\tAux val\t%d\tBase type\t%d\tMaterial\t%d\t Count=%d\n",pTempItemInst->id, pTempItemInst->getAuxValue(),pTile->getBaseItemType(),pTile->getMaterial(),pTempItemInst->GetCount());
643 // }
644 // else
645 // {
646 // printf("ID\t%d\tAux val\t%d\tBase type\t%d\tMaterial\t%d Count=%d\n",pTempItemInst->id, pTempItemInst->getAuxValue(),pTempItemInst->getItem()->getBaseItemType(),pTempItemInst->getItem()->getMaterial(),pTempItemInst->GetCount());
647 // }
648 //
649 // }
650 // }
651 // }
652
653 for(int i=0;i<iRecipeC;i++)
654 {
655
656 Recipy *r = *itRecipe;
657
658 // If this recipe isn't in the current grouptype, skip it
659 if(r->getGroup()!=m_pGroupA[m_iGroupIndex])
660 {
661 itRecipe++;
662 pRecipeIngredientsRequired[i].bCanMake[getPad()]=false;
663 continue;
664 }
665 // if we are in the inventory menu, then we have 2x2 crafting available only
666 if((m_iContainerType==RECIPE_TYPE_2x2) && (pRecipeIngredientsRequired[i].iType==RECIPE_TYPE_3x3))
667 {
668 // need a crafting table for this recipe
669 itRecipe++;
670 pRecipeIngredientsRequired[i].bCanMake[getPad()]=false;
671 continue;
672 }
673 // clear the mask showing which ingredients are missing
674 pRecipeIngredientsRequired[i].usBitmaskMissingGridIngredients[getPad()]=0;
675
676 //bool bCanMakeRecipe=true;
677 bool *bFoundA= new bool [pRecipeIngredientsRequired[i].iIngC];
678 for(int j=0;j<pRecipeIngredientsRequired[i].iIngC;j++)
679 {
680 bFoundA[j]=false;
681 int iTotalCount=0;
682
683 // Does the player have this ingredient?
684 for (unsigned int k = 0; k < m_pPlayer->inventory->items.length; k++)
685 {
686 if (m_pPlayer->inventory->items[k] != NULL)
687 {
688 // do they have the ingredient, and the aux value matches, and enough off it?
689 if((m_pPlayer->inventory->items[k]->id == pRecipeIngredientsRequired[i].iIngIDA[j]) &&
690 // check if the ingredient required doesn't care about the aux value, or if it does, does the inventory item aux match it
691 ((pRecipeIngredientsRequired[i].iIngAuxValA[j]==Recipes::ANY_AUX_VALUE) || (pRecipeIngredientsRequired[i].iIngAuxValA[j]==m_pPlayer->inventory->items[k]->getAuxValue()))
692 )
693 {
694 // do they have enough? We need to check the whole inventory, since they may have enough in different slots (milk isn't milkx3, but milk,milk,milk)
695 if(m_pPlayer->inventory->items[k]->GetCount()>=pRecipeIngredientsRequired[i].iIngValA[j])
696 {
697 // they have enough with one slot
698 bFoundA[j]=true;
699 }
700 else
701 {
702 // look at the combined value from the whole inventory
703
704 for(unsigned int l=0;l<m_pPlayer->inventory->items.length;l++)
705 {
706 if (m_pPlayer->inventory->items[l] != NULL)
707 {
708 if(
709 (m_pPlayer->inventory->items[l]->id == pRecipeIngredientsRequired[i].iIngIDA[j]) &&
710 ( (pRecipeIngredientsRequired[i].iIngAuxValA[j]==Recipes::ANY_AUX_VALUE) || (pRecipeIngredientsRequired[i].iIngAuxValA[j]==m_pPlayer->inventory->items[l]->getAuxValue() ))
711 )
712 {
713 iTotalCount+=m_pPlayer->inventory->items[l]->GetCount();
714 }
715 }
716 }
717
718 if(iTotalCount>=pRecipeIngredientsRequired[i].iIngValA[j])
719 {
720 bFoundA[j]=true;
721 }
722 }
723
724 // 4J Stu - TU-1 hotfix
725 // Fix for #13143 - Players are able to craft items they do not have enough ingredients for if they store the ingredients in multiple, smaller stacks
726 break;
727 }
728 }
729 }
730 // if bFoundA[j] is false, then we didn't have enough of the ingredient required by the recipe, so mark the grid items we're short of
731 if(bFoundA[j]==false)
732 {
733 int iMissing = pRecipeIngredientsRequired[i].iIngValA[j]-iTotalCount;
734 int iGridIndex=0;
735 while(iMissing!=0)
736 {
737 // need to check if there is an aux val and match that
738 if(((pRecipeIngredientsRequired[i].uiGridA[iGridIndex]&0x00FFFFFF)==pRecipeIngredientsRequired[i].iIngIDA[j]) &&
739 ((pRecipeIngredientsRequired[i].iIngAuxValA[j]==Recipes::ANY_AUX_VALUE) ||(pRecipeIngredientsRequired[i].iIngAuxValA[j]== ((pRecipeIngredientsRequired[i].uiGridA[iGridIndex]&0xFF000000)>>24))) )
740 {
741 // this grid entry is the ingredient we don't have enough of
742 pRecipeIngredientsRequired[i].usBitmaskMissingGridIngredients[getPad()]|=1<<iGridIndex;
743 iMissing--;
744 }
745 iGridIndex++;
746 }
747 }
748 }
749
750 // so can we make it?
751 bool bCanMake=true;
752 for(int j=0;j<pRecipeIngredientsRequired[i].iIngC;j++)
753 {
754 if(bFoundA[j]==false)
755 {
756 bCanMake=false;
757 break;
758 }
759 }
760
761 pRecipeIngredientsRequired[i].bCanMake[getPad()]=bCanMake;
762
763 // Add the recipe to the CanBeMade list of lists
764 if(iHSlotBrushControl<=m_iCraftablesMaxHSlotC)
765 {
766 bool bFound=false;
767 shared_ptr<ItemInstance> pTempItemInst=pRecipeIngredientsRequired[i].pRecipy->assemble(nullptr);
768 //int iIcon=pTempItemInst->getItem()->getIcon(pTempItemInst->getAuxValue());
769 int iID=pTempItemInst->getItem()->id;
770 int iBaseType;
771
772 if(iID<256) // is it a tile?
773 {
774 iBaseType=Tile::tiles[iID]->getBaseItemType();
775 }
776 else
777 {
778 iBaseType=pTempItemInst->getItem()->getBaseItemType();
779 }
780
781 // ignore for the misc base type - these have not been placed in a base type group
782 if(iBaseType!=Item::eBaseItemType_undefined)
783 {
784 for(int k=0;k<iHSlotBrushControl;k++)
785 {
786 // if the item base type is the same as one already in, then add it to that list
787 if(CanBeMadeA[k].iItemBaseType==iBaseType)
788 {
789 // base item type already in our list
790 bFound=true;
791 if(CanBeMadeA[k].iCount<m_iMaxVSlotC)
792 {
793 CanBeMadeA[k].iRecipeA[CanBeMadeA[k].iCount++]=i;
794 }
795 else
796 {
797 app.DebugPrintf("Need more V slots\n");
798 }
799 break;
800 }
801 }
802 }
803
804 if(!bFound)
805 {
806 if(iHSlotBrushControl<m_iCraftablesMaxHSlotC)
807 {
808 // add to the list
809 CanBeMadeA[iHSlotBrushControl].iItemBaseType=iBaseType;
810 CanBeMadeA[iHSlotBrushControl].iRecipeA[CanBeMadeA[iHSlotBrushControl].iCount++]=i;
811 iHSlotBrushControl++;
812 }
813 else
814 {
815 app.DebugPrintf("Need more H slots - ");
816#ifndef _CONTENT_PACKAGE
817 OutputDebugStringW(app.GetString(pTempItemInst->getDescriptionId()));
818#endif
819 app.DebugPrintf("\n");
820
821 }
822 }
823 }
824 else
825 {
826 app.DebugPrintf("Need more HSlots\n");
827 }
828
829 delete [] bFoundA;
830 itRecipe++;
831 }
832 }
833
834 // run through the canbemade list and update the icons displayed
835 int iIndex=0;
836 //RecipyList *recipes = ((Recipes *)Recipes::getInstance())->getRecipies();
837 Recipy::INGREDIENTS_REQUIRED *pRecipeIngredientsRequired=Recipes::getInstance()->getRecipeIngredientsArray();
838
839 while((iIndex<m_iCraftablesMaxHSlotC) && CanBeMadeA[iIndex].iCount!=0)
840 {
841 shared_ptr<ItemInstance> pTempItemInst=pRecipeIngredientsRequired[CanBeMadeA[iIndex].iRecipeA[0]].pRecipy->assemble(nullptr);
842 assert(pTempItemInst->id!=0);
843 unsigned int uiAlpha;
844
845 if(app.DebugSettingsOn() && app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad())&(1L<<eDebugSetting_CraftAnything))
846 {
847 uiAlpha = 31;
848 }
849 else
850 {
851 if(pRecipeIngredientsRequired[CanBeMadeA[iIndex].iRecipeA[0]].bCanMake[getPad()])
852 {
853 uiAlpha = 31;
854 }
855 else
856 {
857 uiAlpha= 16;
858 }
859 }
860
861 // 4J Stu - For clocks and compasses we set the aux value to a special one that signals we should use a default texture
862 // rather than the dynamic one for the player
863 if( pTempItemInst->id == Item::clock_Id || pTempItemInst->id == Item::compass_Id )
864 {
865 pTempItemInst->setAuxValue( 255 );
866 }
867 setCraftHSlotItem(getPad(),iIndex,pTempItemInst,uiAlpha);
868
869 iIndex++;
870 }
871
872 // 4J-PB - Removed - UpdateTooltips will do this
873 // Update tooltips
874 /*if(CanBeMadeA[m_iCurrentSlotHIndex].iCount!=0)
875 {
876 ui.ShowTooltip( getPad(), eToolTipButtonA, true );
877 // 4J-PB - not implemented !
878 //ui.EnableTooltip( getPad(), eToolTipButtonA, true );
879 }
880 else
881 {
882 ui.ShowTooltip( getPad(), eToolTipButtonA, false );
883 }*/
884}
885
886//////////////////////////////////////////////////////////////////////////
887//
888// UpdateHighlight
889//
890//////////////////////////////////////////////////////////////////////////
891void IUIScene_CraftingMenu::UpdateHighlight()
892{
893 updateHighlightAndScrollPositions();
894
895 bool bCanBeMade=CanBeMadeA[m_iCurrentSlotHIndex].iCount!=0;
896 if(bCanBeMade)
897 {
898 //RecipyList *recipes = ((Recipes *)Recipes::getInstance())->getRecipies();
899 Recipy::INGREDIENTS_REQUIRED *pRecipeIngredientsRequired=Recipes::getInstance()->getRecipeIngredientsArray();
900 int iSlot;
901 if(CanBeMadeA[m_iCurrentSlotHIndex].iCount>1)
902 {
903 iSlot=iVSlotIndexA[m_iCurrentSlotVIndex];
904 }
905 else
906 {
907 iSlot=0;
908 }
909 shared_ptr<ItemInstance> pTempItemInstAdditional=pRecipeIngredientsRequired[CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[iSlot]].pRecipy->assemble(nullptr);
910
911 // special case for the torch coal/charcoal
912 int id=pTempItemInstAdditional->getDescriptionId();
913 LPCWSTR itemstring;
914
915 switch(id)
916 {
917 case IDS_TILE_TORCH:
918 {
919 if(pRecipeIngredientsRequired[CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[iSlot]].iIngAuxValA[0]==1)
920 {
921 itemstring=app.GetString( IDS_TILE_TORCHCHARCOAL );
922 }
923 else
924 {
925 itemstring=app.GetString( IDS_TILE_TORCHCOAL );
926 }
927 }
928 break;
929 case IDS_ITEM_FIREBALL:
930 {
931 if(pRecipeIngredientsRequired[CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[iSlot]].iIngAuxValA[2]==1)
932 {
933 itemstring=app.GetString( IDS_ITEM_FIREBALLCHARCOAL );
934 }
935 else
936 {
937 itemstring=app.GetString( IDS_ITEM_FIREBALLCOAL );
938 }
939 }
940 break;
941 default:
942 itemstring=app.GetString(id );
943 break;
944 }
945
946 setItemText(itemstring);
947 }
948 else
949 {
950 setItemText(L"");
951 }
952 UpdateDescriptionText(bCanBeMade);
953 DisplayIngredients();
954
955 UpdateMultiPanel();
956
957 UpdateTooltips();
958}
959
960//////////////////////////////////////////////////////////////////////////
961//
962// UpdateVerticalSlots
963//
964//////////////////////////////////////////////////////////////////////////
965void IUIScene_CraftingMenu::UpdateVerticalSlots()
966{
967 //RecipyList *recipes = ((Recipes *)Recipes::getInstance())->getRecipies();
968 Recipy::INGREDIENTS_REQUIRED *pRecipeIngredientsRequired=Recipes::getInstance()->getRecipeIngredientsArray();
969
970 // update the vertical items for the current horizontal slot
971 hideAllVSlots();
972
973 // could have either 1 or 2 vertical slots, above and below the horizontal slot
974 if(CanBeMadeA[m_iCurrentSlotHIndex].iCount>1)
975 {
976 // turn off the horizontal one since we could be cycling through others
977 setShowCraftHSlot(m_iCurrentSlotHIndex,false);
978 int iSlots=(CanBeMadeA[m_iCurrentSlotHIndex].iCount>2)?3:2;
979
980 // 4J-Tomk - check if we've only got one vertical scroll slot (480, splits & Vita)
981 bool bNoScrollSlots = false;
982 if(m_bSplitscreen ||(!RenderManager.IsHiDef() && !RenderManager.IsWidescreen()))
983 {
984 bNoScrollSlots = true;
985 }
986#ifdef __PSVITA__
987 bNoScrollSlots = true;
988#endif
989
990 for(int i=0;i<iSlots;i++)
991 {
992 // 4J this check determines if the crafting scene has only one vertical scroll slot
993 if(bNoScrollSlots)
994 {
995 if(i!=1) continue;
996 }
997 shared_ptr<ItemInstance> pTempItemInstAdditional=pRecipeIngredientsRequired[CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[iVSlotIndexA[i]]].pRecipy->assemble(nullptr);
998
999 assert(pTempItemInstAdditional->id!=0);
1000 unsigned int uiAlpha;
1001
1002 if(app.DebugSettingsOn() && app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad())&(1L<<eDebugSetting_CraftAnything))
1003 {
1004 uiAlpha = 31;
1005 }
1006 else
1007 {
1008 if(pRecipeIngredientsRequired[CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[iVSlotIndexA[i]]].bCanMake[getPad()])
1009 {
1010 uiAlpha = 31;
1011 }
1012 else
1013 {
1014 uiAlpha= 16;
1015 }
1016 }
1017
1018 // 4J Stu - For clocks and compasses we set the aux value to a special one that signals we should use a default texture
1019 // rather than the dynamic one for the player
1020 if( pTempItemInstAdditional->id == Item::clock_Id || pTempItemInstAdditional->id == Item::compass_Id )
1021 {
1022 pTempItemInstAdditional->setAuxValue( 255 );
1023 }
1024
1025 setCraftVSlotItem(getPad(),i,pTempItemInstAdditional,uiAlpha);
1026
1027 updateVSlotPositions(iSlots, i);
1028 }
1029 }
1030}
1031
1032//////////////////////////////////////////////////////////////////////////
1033//
1034// DisplayIngredients
1035//
1036//////////////////////////////////////////////////////////////////////////
1037void IUIScene_CraftingMenu::DisplayIngredients()
1038{
1039 //RecipyList *recipes = ((Recipes *)Recipes::getInstance())->getRecipies();
1040 Recipy::INGREDIENTS_REQUIRED *pRecipeIngredientsRequired=Recipes::getInstance()->getRecipeIngredientsArray();
1041
1042 // hide the previous ingredients
1043 hideAllIngredientsSlots();
1044
1045 if(CanBeMadeA[m_iCurrentSlotHIndex].iCount!=0)
1046 {
1047 int iSlot,iRecipy;
1048 if(CanBeMadeA[m_iCurrentSlotHIndex].iCount>1)
1049 {
1050 iSlot=iVSlotIndexA[m_iCurrentSlotVIndex];
1051 iRecipy=CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[iSlot];
1052 }
1053 else
1054 {
1055 iSlot=0;
1056 iRecipy=CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[0];
1057 }
1058
1059 // show the 2x2 or 3x3 to make the current item
1060 int iBoxWidth=(m_iContainerType==RECIPE_TYPE_2x2)?2:3;
1061 int iRecipe=CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[iSlot];
1062 bool bCanMakeRecipe = pRecipeIngredientsRequired[iRecipe].bCanMake[getPad()];
1063 shared_ptr<ItemInstance> pTempItemInst=pRecipeIngredientsRequired[iRecipe].pRecipy->assemble(nullptr);
1064
1065 m_iIngredientsC=pRecipeIngredientsRequired[iRecipe].iIngC;
1066
1067 // update the ingredients required - these will all be hidden until cycled by the user
1068 for(int i=0;i<pRecipeIngredientsRequired[iRecipe].iIngC;i++)
1069 {
1070 int id=pRecipeIngredientsRequired[iRecipe].iIngIDA[i];
1071 int iAuxVal=pRecipeIngredientsRequired[iRecipe].iIngAuxValA[i];
1072 Item *item = Item::items[id];
1073
1074 shared_ptr<ItemInstance> itemInst= shared_ptr<ItemInstance>(new ItemInstance(item,pRecipeIngredientsRequired[iRecipe].iIngValA[i],iAuxVal));
1075
1076 // 4J-PB - a very special case - the bed can use any kind of wool, so we can't use the item description
1077 // and the same goes for the painting
1078 int idescID;
1079
1080 if( ((pTempItemInst->id==Item::bed_Id) &&(id==Tile::wool_Id)) ||
1081 ((pTempItemInst->id==Item::painting_Id) &&(id==Tile::wool_Id)) )
1082 {
1083 idescID=IDS_ANY_WOOL;
1084 }
1085 else if((pTempItemInst->id==Item::fireworksCharge_Id) && (id==Item::dye_powder_Id))
1086 {
1087 idescID=IDS_ITEM_DYE_POWDER;
1088 iAuxVal = 1;
1089 }
1090 else
1091 {
1092 idescID=itemInst->getDescriptionId();
1093 }
1094 setIngredientDescriptionText(i,app.GetString(idescID));
1095
1096
1097 if( (iAuxVal & 0xFF) == 0xFF) // 4J Stu - If the aux value is set to match any
1098 iAuxVal = 0;
1099
1100 // 4J Stu - For clocks and compasses we set the aux value to a special one that signals we should use a default texture
1101 // rather than the dynamic one for the player
1102 if( id == Item::clock_Id || id == Item::compass_Id )
1103 {
1104 iAuxVal = 0xFF;
1105 }
1106 itemInst->setAuxValue(iAuxVal);
1107
1108 setIngredientDescriptionItem(getPad(),i,itemInst);
1109 setIngredientDescriptionRedBox(i,false);
1110 }
1111
1112 // 4J Stu - For clocks and compasses we set the aux value to a special one that signals we should use a default texture
1113 // rather than the dynamic one for the player
1114 if( pTempItemInst->id == Item::clock_Id || pTempItemInst->id == Item::compass_Id )
1115 {
1116 pTempItemInst->setAuxValue( 255 );
1117 }
1118
1119 // don't grey out the output icon
1120 setCraftingOutputSlotItem(getPad(), pTempItemInst);
1121
1122 if(app.DebugSettingsOn() && app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad())&(1L<<eDebugSetting_CraftAnything))
1123 {
1124 setCraftingOutputSlotRedBox(false);
1125 }
1126 else
1127 {
1128 if(bCanMakeRecipe==false)
1129 {
1130 setCraftingOutputSlotRedBox(true);
1131 }
1132 else
1133 {
1134 setCraftingOutputSlotRedBox(false);
1135 }
1136
1137 }
1138 for (int x = 0; x < iBoxWidth; x++)
1139 {
1140 for (int y = 0; y < iBoxWidth; y++)
1141 {
1142 int index = x+y*iBoxWidth;
1143 if(pRecipeIngredientsRequired[iRecipy].uiGridA[x+y*3]!=0)
1144 {
1145 int id=pRecipeIngredientsRequired[iRecipy].uiGridA[x+y*3]&0x00FFFFFF;
1146 assert(id!=0);
1147 int iAuxVal=(pRecipeIngredientsRequired[iRecipy].uiGridA[x+y*3]&0xFF000000)>>24;
1148
1149 // 4J Stu - For clocks and compasses we set the aux value to a special one that signals we should use a default texture
1150 // rather than the dynamic one for the player
1151 if( id == Item::clock_Id || id == Item::compass_Id )
1152 {
1153 iAuxVal = 0xFF;
1154 }
1155 else if( pTempItemInst->id==Item::fireworksCharge_Id && id == Item::dye_powder_Id)
1156 {
1157 iAuxVal = 1;
1158 }
1159 shared_ptr<ItemInstance> itemInst= shared_ptr<ItemInstance>(new ItemInstance(id,1,iAuxVal));
1160 setIngredientSlotItem(getPad(),index,itemInst);
1161 // show the ingredients we don't have if we can't make the recipe
1162 if(app.DebugSettingsOn() && app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad())&(1L<<eDebugSetting_CraftAnything))
1163 {
1164 setIngredientSlotRedBox(index, false);
1165 }
1166 else
1167 {
1168 if((pRecipeIngredientsRequired[iRecipy].usBitmaskMissingGridIngredients[getPad()]&(1<<(x+y*3)))!=0)
1169 {
1170 setIngredientSlotRedBox(index, true);
1171 }
1172 else
1173 {
1174 setIngredientSlotRedBox(index, false);
1175 }
1176 }
1177 }
1178 else
1179 {
1180 setIngredientSlotRedBox(index, false);
1181 setIngredientSlotItem(getPad(),index,nullptr);
1182 }
1183 }
1184 }
1185 }
1186 else
1187 {
1188 setCraftingOutputSlotItem(getPad(), nullptr);
1189 setCraftingOutputSlotRedBox(false);
1190 m_iIngredientsC=0;
1191 int iIngredientsSlots;
1192 // if it's a 2x2 , only clear the 4 m_pCraftingIngredientA slots
1193 if(m_iContainerType==RECIPE_TYPE_2x2)
1194 {
1195 iIngredientsSlots=4;
1196 }
1197 else
1198 {
1199 iIngredientsSlots=m_iIngredients3x3SlotC;
1200 }
1201
1202 for(int i=0;i<iIngredientsSlots;i++)
1203 {
1204 setIngredientSlotRedBox(i, false);
1205 setIngredientSlotItem(getPad(),i,nullptr);
1206 }
1207 }
1208}
1209
1210
1211//////////////////////////////////////////////////////////////////////////
1212//
1213// UpdateDescriptionText
1214//
1215//////////////////////////////////////////////////////////////////////////
1216void IUIScene_CraftingMenu::UpdateDescriptionText(bool bCanBeMade)
1217{
1218 int iIDSString=0;
1219 //RecipyList *recipes = ((Recipes *)Recipes::getInstance())->getRecipies();
1220 Recipy::INGREDIENTS_REQUIRED *pRecipeIngredientsRequired=Recipes::getInstance()->getRecipeIngredientsArray();
1221
1222 if(bCanBeMade)
1223 {
1224 int iSlot;//,iRecipy;
1225 if(CanBeMadeA[m_iCurrentSlotHIndex].iCount>1)
1226 {
1227 iSlot=iVSlotIndexA[m_iCurrentSlotVIndex];
1228 //iRecipy=CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[iSlot];
1229 }
1230 else
1231 {
1232 iSlot=0;
1233 //iRecipy=CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[0];
1234 }
1235
1236 shared_ptr<ItemInstance> pTempItemInst=pRecipeIngredientsRequired[CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[iSlot]].pRecipy->assemble(nullptr);
1237 int iID=pTempItemInst->getItem()->id;
1238 int iAuxVal=pTempItemInst->getAuxValue();
1239 int iBaseType;
1240
1241 if(iID<256) // is it a tile?
1242 {
1243 iBaseType=Tile::tiles[iID]->getBaseItemType();
1244
1245 iIDSString = Tile::tiles[iID]->getUseDescriptionId();
1246 }
1247 else
1248 {
1249 iBaseType=pTempItemInst->getItem()->getBaseItemType();
1250
1251 iIDSString = pTempItemInst->getUseDescriptionId();
1252 }
1253
1254 // A few special cases where the description required is specific to crafting, rather than the normal description
1255 if(iBaseType!=Item::eBaseItemType_undefined)
1256 {
1257 switch(iBaseType)
1258 {
1259 case Item::eBaseItemType_cloth:
1260 switch(iAuxVal)
1261 {
1262 case 0:
1263 iIDSString=IDS_DESC_WOOLSTRING;
1264 break;
1265 }
1266 break;
1267 }
1268 }
1269
1270 // set the string mapped to by the base object mapping array
1271
1272 if(iIDSString>=0)
1273 {
1274 // this is an html control now, so set the font size and colour
1275 //wstring wsText=app.GetString(iIDSString);
1276 wstring wsText=app.FormatHTMLString(getPad(),app.GetString(iIDSString));
1277
1278 // 12 for splitscreen, 14 for normal
1279 EHTMLFontSize size = eHTMLSize_Normal;
1280 if(m_bSplitscreen ||(!RenderManager.IsHiDef() && !RenderManager.IsWidescreen()))
1281 {
1282 size = eHTMLSize_Splitscreen;
1283 }
1284 wchar_t startTags[64];
1285 swprintf(startTags,64,L"<font color=\"#%08x\"><P ALIGN=LEFT>",app.GetHTMLColour(eHTMLColor_Black));
1286 wsText= startTags + wsText + L"</P>";
1287
1288 setDescriptionText(wsText.c_str());
1289 }
1290 else
1291 {
1292 /// Missing string!
1293#ifdef _DEBUG
1294 setDescriptionText(L"This is some placeholder description text about the craftable item.");
1295#else
1296 setDescriptionText(L"");
1297#endif
1298 }
1299 }
1300 else
1301 {
1302 setDescriptionText(L"");
1303 }
1304}
1305
1306//////////////////////////////////////////////////////////////////////////
1307//
1308// UpdateTooltips
1309//
1310//////////////////////////////////////////////////////////////////////////
1311void IUIScene_CraftingMenu::UpdateTooltips()
1312{
1313 //RecipyList *recipes = ((Recipes *)Recipes::getInstance())->getRecipies();
1314 Recipy::INGREDIENTS_REQUIRED *pRecipeIngredientsRequired=Recipes::getInstance()->getRecipeIngredientsArray();
1315 // Update tooltips
1316
1317 bool bDisplayCreate;
1318
1319 if(CanBeMadeA[m_iCurrentSlotHIndex].iCount!=0)
1320 {
1321 int iSlot;
1322 if(CanBeMadeA[m_iCurrentSlotHIndex].iCount>1)
1323 {
1324 iSlot=iVSlotIndexA[m_iCurrentSlotVIndex];
1325 }
1326 else
1327 {
1328 iSlot=0;
1329 }
1330
1331 if(pRecipeIngredientsRequired[CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[iSlot]].bCanMake[getPad()])
1332 {
1333 bDisplayCreate=true;
1334 }
1335 else
1336 {
1337 bDisplayCreate=false;
1338 }
1339 }
1340 else
1341 {
1342 bDisplayCreate=false;
1343 }
1344
1345
1346 switch(m_iDisplayDescription)
1347 {
1348 case DISPLAY_INVENTORY:
1349 ui.SetTooltips( getPad(), bDisplayCreate?IDS_TOOLTIPS_CREATE:-1,IDS_TOOLTIPS_EXIT, IDS_TOOLTIPS_SHOW_DESCRIPTION,-1,-1,-1,-2, IDS_TOOLTIPS_CHANGE_GROUP);
1350 break;
1351 case DISPLAY_DESCRIPTION:
1352 ui.SetTooltips( getPad(), bDisplayCreate?IDS_TOOLTIPS_CREATE:-1,IDS_TOOLTIPS_EXIT, IDS_TOOLTIPS_SHOW_INGREDIENTS,-1,-1,-1,-2, IDS_TOOLTIPS_CHANGE_GROUP);
1353 break;
1354 case DISPLAY_INGREDIENTS:
1355 ui.SetTooltips( getPad(), bDisplayCreate?IDS_TOOLTIPS_CREATE:-1,IDS_TOOLTIPS_EXIT, IDS_TOOLTIPS_SHOW_INVENTORY,-1,-1,-1,-2, IDS_TOOLTIPS_CHANGE_GROUP);
1356 break;
1357 }
1358
1359 /*if(CanBeMadeA[m_iCurrentSlotHIndex].iCount!=0)
1360 {
1361 int iSlot;
1362 if(CanBeMadeA[m_iCurrentSlotHIndex].iCount>1)
1363 {
1364 iSlot=iVSlotIndexA[m_iCurrentSlotVIndex];
1365 }
1366 else
1367 {
1368 iSlot=0;
1369 }
1370
1371 if(pRecipeIngredientsRequired[CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[iSlot]].bCanMake[getPad()])
1372 {
1373 ui.EnableTooltip( getPad(), eToolTipButtonA, true );
1374 }
1375 else
1376 {
1377 ui.EnableTooltip( getPad(), eToolTipButtonA, false );
1378 }
1379 }
1380 else
1381 {
1382 ui.ShowTooltip( getPad(), eToolTipButtonA, false );
1383 }*/
1384}
1385
1386void IUIScene_CraftingMenu::HandleInventoryUpdated()
1387{
1388 // Check which recipes are available with the resources we have
1389 CheckRecipesAvailable();
1390 UpdateVerticalSlots();
1391 UpdateHighlight();
1392 UpdateTooltips();
1393}
1394
1395bool IUIScene_CraftingMenu::isItemSelected(int itemId)
1396{
1397 bool isSelected = false;
1398 if(m_pPlayer && m_pPlayer->inventory)
1399 {
1400 //RecipyList *recipes = ((Recipes *)Recipes::getInstance())->getRecipies();
1401 Recipy::INGREDIENTS_REQUIRED *pRecipeIngredientsRequired=Recipes::getInstance()->getRecipeIngredientsArray();
1402
1403 if(CanBeMadeA[m_iCurrentSlotHIndex].iCount!=0)
1404 {
1405 int iSlot;
1406 if(CanBeMadeA[m_iCurrentSlotHIndex].iCount>1)
1407 {
1408 iSlot=iVSlotIndexA[m_iCurrentSlotVIndex];
1409 }
1410 else
1411 {
1412 iSlot=0;
1413 }
1414 int iRecipe= CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[iSlot];
1415 ItemInstance *pTempItemInst = (ItemInstance *)pRecipeIngredientsRequired[iRecipe].pRecipy->getResultItem();
1416
1417 if(pTempItemInst->id == itemId)
1418 {
1419 isSelected = true;
1420 }
1421 }
1422 }
1423 return isSelected;
1424}