the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 1424 lines 42 kB view raw
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}