#include "stdafx.h" #include "..\..\..\Minecraft.World\net.minecraft.world.item.crafting.h" #include "..\..\..\Minecraft.World\net.minecraft.world.level.tile.h" #include "..\..\..\Minecraft.World\net.minecraft.stats.h" #include "..\..\LocalPlayer.h" #include "IUIScene_CraftingMenu.h" Recipy::_eGroupType IUIScene_CraftingMenu::m_GroupTypeMapping4GridA[IUIScene_CraftingMenu::m_iMaxGroup2x2]= { Recipy::eGroupType_Structure, Recipy::eGroupType_Tool, Recipy::eGroupType_Food, Recipy::eGroupType_Mechanism, Recipy::eGroupType_Transport, Recipy::eGroupType_Decoration, }; Recipy::_eGroupType IUIScene_CraftingMenu::m_GroupTypeMapping9GridA[IUIScene_CraftingMenu::m_iMaxGroup3x3]= { Recipy::eGroupType_Structure, Recipy::eGroupType_Tool, Recipy::eGroupType_Food, Recipy::eGroupType_Armour, Recipy::eGroupType_Mechanism, Recipy::eGroupType_Transport, Recipy::eGroupType_Decoration, }; LPCWSTR IUIScene_CraftingMenu::m_GroupIconNameA[m_iMaxGroup3x3]= { L"Structures",//Recipy::eGroupType_Structure, L"Tools",//Recipy::eGroupType_Tool, L"Food",//Recipy::eGroupType_Food, L"Armour",//Recipy::eGroupType_Armour, L"Mechanisms",//Recipy::eGroupType_Mechanism, L"Transport",//Recipy::eGroupType_Transport, L"Decoration",//Recipy::eGroupType_Decoration, }; IUIScene_CraftingMenu::_eGroupTab IUIScene_CraftingMenu::m_GroupTabBkgMapping2x2A[m_iMaxGroup2x2]= { eGroupTab_Left, eGroupTab_Middle, eGroupTab_Middle, eGroupTab_Middle, eGroupTab_Middle, eGroupTab_Right, }; IUIScene_CraftingMenu::_eGroupTab IUIScene_CraftingMenu::m_GroupTabBkgMapping3x3A[m_iMaxGroup3x3]= { eGroupTab_Left, eGroupTab_Middle, eGroupTab_Middle, eGroupTab_Middle, eGroupTab_Middle, eGroupTab_Middle, eGroupTab_Right, }; // mapping array to map the base objects to their description string // This should map the enums // enum // { // eBaseItemType_undefined=0, // eBaseItemType_sword, // eBaseItemType_shovel, // eBaseItemType_pickaxe, // eBaseItemType_hatchet, // eBaseItemType_hoe, // eBaseItemType_door, // eBaseItemType_helmet, // eBaseItemType_chestplate, // eBaseItemType_leggings, // eBaseItemType_boots, // eBaseItemType_ingot, // eBaseItemType_rail, // eBaseItemType_block, // eBaseItemType_pressureplate, // eBaseItemType_stairs, // eBaseItemType_cloth, // eBaseItemType_dyepowder, // eBaseItemType_structplanks // eBaseItemType_structblock, // eBaseItemType_slab, // eBaseItemType_halfslab, // eBaseItemType_torch, // eBaseItemType_bow, // eBaseItemType_pockettool, // eBaseItemType_utensil, // // } // eBaseItemType; IUIScene_CraftingMenu::IUIScene_CraftingMenu() { m_iCurrentSlotHIndex=0; m_iCurrentSlotVIndex=1; for(int i=0;ilocalgameModes[getPad()] != NULL ) { Tutorial *tutorial = pMinecraft->localgameModes[getPad()]->getTutorial(); if(tutorial != NULL) { tutorial->handleUIInput(iAction); if(ui.IsTutorialVisible(getPad()) && !tutorial->isInputAllowed(iAction)) { return S_OK; } } } switch(iAction) { case ACTION_MENU_X: // change the display m_iDisplayDescription++; if(m_iDisplayDescription==DISPLAY_MAX) m_iDisplayDescription=DISPLAY_INVENTORY; ui.PlayUISFX(eSFX_Focus); UpdateMultiPanel(); UpdateTooltips(); break; case ACTION_MENU_PAUSEMENU: case ACTION_MENU_B: ui.ShowTooltip( iPad, eToolTipButtonX, false ); ui.ShowTooltip( iPad, eToolTipButtonB, false ); ui.ShowTooltip( iPad, eToolTipButtonA, false ); ui.ShowTooltip( iPad, eToolTipButtonRB, false ); // kill the crafting xui //ui.PlayUISFX(eSFX_Back); ui.CloseUIScenes(iPad); bHandled = true; break; case ACTION_MENU_A: #ifdef __ORBIS__ case ACTION_MENU_TOUCHPAD_PRESS: #endif // Do some crafting! if(m_pPlayer && m_pPlayer->inventory) { //RecipyList *recipes = ((Recipes *)Recipes::getInstance())->getRecipies(); Recipy::INGREDIENTS_REQUIRED *pRecipeIngredientsRequired=Recipes::getInstance()->getRecipeIngredientsArray(); // Force a make if the debug is on if(app.DebugSettingsOn() && app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad())&(1L< pTempItemInst=pRecipeIngredientsRequired[iRecipe].pRecipy->assemble(nullptr); //int iIcon=pTempItemInst->getItem()->getIcon(pTempItemInst->getAuxValue()); if( pMinecraft->localgameModes[iPad] != NULL) { Tutorial *tutorial = pMinecraft->localgameModes[iPad]->getTutorial(); if(tutorial != NULL) { tutorial->onCrafted(pTempItemInst); } } pMinecraft->localgameModes[iPad]->handleCraftItem(iRecipe,m_pPlayer); if(m_pPlayer->inventory->add(pTempItemInst)==false) { // no room in inventory, so throw it down m_pPlayer->drop(pTempItemInst); } // play a sound //pMinecraft->soundEngine->playUI( L"random.pop", 1.0f, 1.0f); ui.PlayUISFX(eSFX_Craft); } } else if(CanBeMadeA[m_iCurrentSlotHIndex].iCount!=0) { int iSlot; if(CanBeMadeA[m_iCurrentSlotHIndex].iCount>1) { iSlot=iVSlotIndexA[m_iCurrentSlotVIndex]; } else { iSlot=0; } int iRecipe= CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[iSlot]; std::shared_ptr pTempItemInst=pRecipeIngredientsRequired[iRecipe].pRecipy->assemble(nullptr); //int iIcon=pTempItemInst->getItem()->getIcon(pTempItemInst->getAuxValue()); if( pMinecraft->localgameModes[iPad] != NULL ) { Tutorial *tutorial = pMinecraft->localgameModes[iPad]->getTutorial(); if(tutorial != NULL) { tutorial->createItemSelected(pTempItemInst, pRecipeIngredientsRequired[iRecipe].bCanMake[iPad]); } } if(pRecipeIngredientsRequired[iRecipe].bCanMake[iPad]) { pTempItemInst->onCraftedBy(m_pPlayer->level, std::dynamic_pointer_cast( m_pPlayer->shared_from_this() ), pTempItemInst->count ); // TODO 4J Stu - handleCraftItem should do a lot more than what it does, loads of the "can we craft" code should also probably be // shifted to the GameMode pMinecraft->localgameModes[iPad]->handleCraftItem(iRecipe,m_pPlayer); // play a sound //pMinecraft->soundEngine->playUI( L"random.pop", 1.0f, 1.0f); ui.PlayUISFX(eSFX_Craft); // and remove those resources from your inventory for(int i=0;i ingItemInst = nullptr; // do we need to remove a specific aux value? if(pRecipeIngredientsRequired[iRecipe].iIngAuxValA[i]!=Recipes::ANY_AUX_VALUE) { ingItemInst = m_pPlayer->inventory->getResourceItem( pRecipeIngredientsRequired[iRecipe].iIngIDA[i],pRecipeIngredientsRequired[iRecipe].iIngAuxValA[i] ); m_pPlayer->inventory->removeResource(pRecipeIngredientsRequired[iRecipe].iIngIDA[i],pRecipeIngredientsRequired[iRecipe].iIngAuxValA[i]); } else { ingItemInst = m_pPlayer->inventory->getResourceItem( pRecipeIngredientsRequired[iRecipe].iIngIDA[i] ); m_pPlayer->inventory->removeResource(pRecipeIngredientsRequired[iRecipe].iIngIDA[i]); } // 4J Stu - Fix for #13097 - Bug: Milk Buckets are removed when crafting Cake if (ingItemInst != NULL) { if (ingItemInst->getItem()->hasCraftingRemainingItem()) { // replace item with remaining result m_pPlayer->inventory->add( std::shared_ptr( new ItemInstance(ingItemInst->getItem()->getCraftingRemainingItem()) ) ); } } } } // 4J Stu - Fix for #13119 - We should add the item after we remove the ingredients if(m_pPlayer->inventory->add(pTempItemInst)==false ) { // no room in inventory, so throw it down m_pPlayer->drop(pTempItemInst); } //4J Gordon: Achievements switch(pTempItemInst->id ) { case Tile::workBench_Id: m_pPlayer->awardStat(GenericStats::buildWorkbench(), GenericStats::param_buildWorkbench()); break; case Item::pickAxe_wood_Id: m_pPlayer->awardStat(GenericStats::buildPickaxe(), GenericStats::param_buildPickaxe()); break; case Tile::furnace_Id: m_pPlayer->awardStat(GenericStats::buildFurnace(), GenericStats::param_buildFurnace()); break; case Item::hoe_wood_Id: m_pPlayer->awardStat(GenericStats::buildHoe(), GenericStats::param_buildHoe()); break; case Item::bread_Id: m_pPlayer->awardStat(GenericStats::makeBread(), GenericStats::param_makeBread()); break; case Item::cake_Id: m_pPlayer->awardStat(GenericStats::bakeCake(), GenericStats::param_bakeCake()); break; case Item::pickAxe_stone_Id: m_pPlayer->awardStat(GenericStats::buildBetterPickaxe(), GenericStats::param_buildBetterPickaxe()); break; case Item::sword_wood_Id: m_pPlayer->awardStat(GenericStats::buildSword(), GenericStats::param_buildSword()); break; case Tile::dispenser_Id: m_pPlayer->awardStat(GenericStats::dispenseWithThis(), GenericStats::param_dispenseWithThis()); break; case Tile::enchantTable_Id: m_pPlayer->awardStat(GenericStats::enchantments(), GenericStats::param_enchantments()); break; case Tile::bookshelf_Id: m_pPlayer->awardStat(GenericStats::bookcase(), GenericStats::param_bookcase()); break; } // We've used some ingredients from our inventory, so update the recipes we can make CheckRecipesAvailable(); // don't reset the vertical slots - we want to stay where we are UpdateVerticalSlots(); UpdateHighlight(); } else { //pMinecraft->soundEngine->playUI( L"btn.back", 1.0f, 1.0f); ui.PlayUISFX(eSFX_CraftFail); } } } break; case ACTION_MENU_LEFT_SCROLL: // turn off the old group tab showTabHighlight(m_iGroupIndex,false); if(m_iGroupIndex==0) { if(m_iContainerType==RECIPE_TYPE_3x3) { m_iGroupIndex=m_iMaxGroup3x3-1; } else { m_iGroupIndex=m_iMaxGroup2x2-1; } } else { m_iGroupIndex--; } // turn on the new group showTabHighlight(m_iGroupIndex,true); m_iCurrentSlotHIndex=0; m_iCurrentSlotVIndex=1; CheckRecipesAvailable(); // reset the vertical slots iVSlotIndexA[0]=CanBeMadeA[m_iCurrentSlotHIndex].iCount-1; iVSlotIndexA[1]=0; iVSlotIndexA[2]=1; ui.PlayUISFX(eSFX_Focus); UpdateVerticalSlots(); UpdateHighlight(); setGroupText(GetGroupNameText(m_pGroupA[m_iGroupIndex])); break; case ACTION_MENU_RIGHT_SCROLL: // turn off the old group tab showTabHighlight(m_iGroupIndex,false); m_iGroupIndex++; if(m_iContainerType==RECIPE_TYPE_3x3) { if(m_iGroupIndex==m_iMaxGroup3x3) m_iGroupIndex=0; } else { if(m_iGroupIndex==m_iMaxGroup2x2) m_iGroupIndex=0; } // turn on the new group showTabHighlight(m_iGroupIndex,true); m_iCurrentSlotHIndex=0; m_iCurrentSlotVIndex=1; CheckRecipesAvailable(); // reset the vertical slots iVSlotIndexA[0]=CanBeMadeA[m_iCurrentSlotHIndex].iCount-1; iVSlotIndexA[1]=0; iVSlotIndexA[2]=1; ui.PlayUISFX(eSFX_Focus); UpdateVerticalSlots(); UpdateHighlight(); setGroupText(GetGroupNameText(m_pGroupA[m_iGroupIndex])); break; } // 4J-Tomk - check if we've only got one vertical scroll slot (480, splits & Vita) bool bNoScrollSlots = false; if(m_bSplitscreen ||(!RenderManager.IsHiDef() && !RenderManager.IsWidescreen())) { bNoScrollSlots = true; } #ifdef __PSVITA__ bNoScrollSlots = true; #endif // 4J Stu - We did used to swap the thumsticks based on Southpaw in this scene, but ONLY in this scene switch(iAction) { case ACTION_MENU_OTHER_STICK_UP: scrollDescriptionUp(); break; case ACTION_MENU_OTHER_STICK_DOWN: scrollDescriptionDown(); break; case ACTION_MENU_RIGHT: { int iOldHSlot=m_iCurrentSlotHIndex; m_iCurrentSlotHIndex++; if(m_iCurrentSlotHIndex>=m_iCraftablesMaxHSlotC) m_iCurrentSlotHIndex=0; m_iCurrentSlotVIndex=1; // clear the indices iVSlotIndexA[0]=CanBeMadeA[m_iCurrentSlotHIndex].iCount-1; iVSlotIndexA[1]=0; iVSlotIndexA[2]=1; UpdateVerticalSlots(); UpdateHighlight(); // re-enable the old hslot if(CanBeMadeA[iOldHSlot].iCount>0) { setShowCraftHSlot(iOldHSlot,true); } ui.PlayUISFX(eSFX_Focus); bHandled = true; } break; case ACTION_MENU_LEFT: { if(m_iCraftablesMaxHSlotC!=0) { int iOldHSlot=m_iCurrentSlotHIndex; if(m_iCurrentSlotHIndex==0) m_iCurrentSlotHIndex=m_iCraftablesMaxHSlotC-1; else m_iCurrentSlotHIndex--; m_iCurrentSlotVIndex=1; // clear the indices iVSlotIndexA[0]=CanBeMadeA[m_iCurrentSlotHIndex].iCount-1; iVSlotIndexA[1]=0; iVSlotIndexA[2]=1; UpdateVerticalSlots(); UpdateHighlight(); // re-enable the old hslot if(CanBeMadeA[iOldHSlot].iCount>0) { setShowCraftHSlot(iOldHSlot,true); } ui.PlayUISFX(eSFX_Focus); } bHandled = true; } break; case ACTION_MENU_UP: { if(CanBeMadeA[m_iCurrentSlotHIndex].iCount>1) { if(bNoScrollSlots) { if(iVSlotIndexA[1]==0) { iVSlotIndexA[1]=CanBeMadeA[m_iCurrentSlotHIndex].iCount-1; } else { iVSlotIndexA[1]--; } ui.PlayUISFX(eSFX_Focus); } else if(CanBeMadeA[m_iCurrentSlotHIndex].iCount>2) { { if(m_iCurrentSlotVIndex!=0) { // just move the highlight m_iCurrentSlotVIndex--; ui.PlayUISFX(eSFX_Focus); } else { //move the slots iVSlotIndexA[2]=iVSlotIndexA[1]; iVSlotIndexA[1]=iVSlotIndexA[0]; // on 0 and went up, so cycle the values if(iVSlotIndexA[0]==0) { iVSlotIndexA[0]=CanBeMadeA[m_iCurrentSlotHIndex].iCount-1; } else { iVSlotIndexA[0]--; } ui.PlayUISFX(eSFX_Focus); } } } else { if(m_iCurrentSlotVIndex!=1) { // just move the highlight m_iCurrentSlotVIndex--; ui.PlayUISFX(eSFX_Focus); } } UpdateVerticalSlots(); UpdateHighlight(); } } break; case ACTION_MENU_DOWN: { if(CanBeMadeA[m_iCurrentSlotHIndex].iCount>1) { if(bNoScrollSlots) { if(iVSlotIndexA[1]==(CanBeMadeA[m_iCurrentSlotHIndex].iCount-1)) { iVSlotIndexA[1]=0; } else { iVSlotIndexA[1]++; } ui.PlayUISFX(eSFX_Focus); } else if(CanBeMadeA[m_iCurrentSlotHIndex].iCount>2) { if(m_iCurrentSlotVIndex!=2) { m_iCurrentSlotVIndex++; ui.PlayUISFX(eSFX_Focus); } else { iVSlotIndexA[0]=iVSlotIndexA[1]; iVSlotIndexA[1]=iVSlotIndexA[2]; if(iVSlotIndexA[m_iCurrentSlotVIndex]==(CanBeMadeA[m_iCurrentSlotHIndex].iCount-1)) { iVSlotIndexA[2]=0; } else { iVSlotIndexA[2]++; } ui.PlayUISFX(eSFX_Focus); } } else { if(m_iCurrentSlotVIndex!=(CanBeMadeA[m_iCurrentSlotHIndex].iCount)) { m_iCurrentSlotVIndex++; ui.PlayUISFX(eSFX_Focus); } } UpdateVerticalSlots(); UpdateHighlight(); } } break; } return bHandled; } ////////////////////////////////////////////////////////////////////////// // // CheckRecipesAvailable // ////////////////////////////////////////////////////////////////////////// void IUIScene_CraftingMenu::CheckRecipesAvailable() { int iHSlotBrushControl=0; // clear the current list memset(CanBeMadeA,0,sizeof(CANBEMADE)*m_iCraftablesMaxHSlotC); hideAllHSlots(); if(m_pPlayer && m_pPlayer->inventory) { // dump out the inventory /* for (unsigned int k = 0; k < m_pPlayer->inventory->items.length; k++) { if (m_pPlayer->inventory->items[k] != NULL) { wstring itemstring=m_pPlayer->inventory->items[k]->toString(); //printf("--- Player has "); OutputDebugStringW(itemstring.c_str()); //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()); } } */ RecipyList *recipes = ((Recipes *)Recipes::getInstance())->getRecipies(); Recipy::INGREDIENTS_REQUIRED *pRecipeIngredientsRequired=Recipes::getInstance()->getRecipeIngredientsArray(); int iRecipeC=(int)recipes->size(); AUTO_VAR(itRecipe, recipes->begin()); // dump out the recipe products // for (int i = 0; i < iRecipeC; i++) // { // std::shared_ptr pTempItemInst=pRecipeIngredientsRequired[i].pRecipy->assemble(NULL); // if (pTempItemInst != NULL) // { // wstring itemstring=pTempItemInst->toString(); // // printf("Recipe [%d] = ",i); // OutputDebugStringW(itemstring.c_str()); // if(pTempItemInst->id!=0) // { // if(pTempItemInst->id<256) // { // Tile *pTile=Tile::tiles[pTempItemInst->id]; // 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()); // } // else // { // 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()); // } // // } // } // } for(int i=0;igetGroup()!=m_pGroupA[m_iGroupIndex]) { itRecipe++; pRecipeIngredientsRequired[i].bCanMake[getPad()]=false; continue; } // if we are in the inventory menu, then we have 2x2 crafting available only if((m_iContainerType==RECIPE_TYPE_2x2) && (pRecipeIngredientsRequired[i].iType==RECIPE_TYPE_3x3)) { // need a crafting table for this recipe itRecipe++; pRecipeIngredientsRequired[i].bCanMake[getPad()]=false; continue; } // clear the mask showing which ingredients are missing pRecipeIngredientsRequired[i].usBitmaskMissingGridIngredients[getPad()]=0; //bool bCanMakeRecipe=true; bool *bFoundA= new bool [pRecipeIngredientsRequired[i].iIngC]; for(int j=0;jinventory->items.length; k++) { if (m_pPlayer->inventory->items[k] != NULL) { // do they have the ingredient, and the aux value matches, and enough off it? if((m_pPlayer->inventory->items[k]->id == pRecipeIngredientsRequired[i].iIngIDA[j]) && // check if the ingredient required doesn't care about the aux value, or if it does, does the inventory item aux match it ((pRecipeIngredientsRequired[i].iIngAuxValA[j]==Recipes::ANY_AUX_VALUE) || (pRecipeIngredientsRequired[i].iIngAuxValA[j]==m_pPlayer->inventory->items[k]->getAuxValue())) ) { // 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) if(m_pPlayer->inventory->items[k]->GetCount()>=pRecipeIngredientsRequired[i].iIngValA[j]) { // they have enough with one slot bFoundA[j]=true; } else { // look at the combined value from the whole inventory for(unsigned int l=0;linventory->items.length;l++) { if (m_pPlayer->inventory->items[l] != NULL) { if( (m_pPlayer->inventory->items[l]->id == pRecipeIngredientsRequired[i].iIngIDA[j]) && ( (pRecipeIngredientsRequired[i].iIngAuxValA[j]==Recipes::ANY_AUX_VALUE) || (pRecipeIngredientsRequired[i].iIngAuxValA[j]==m_pPlayer->inventory->items[l]->getAuxValue() )) ) { iTotalCount+=m_pPlayer->inventory->items[l]->GetCount(); } } } if(iTotalCount>=pRecipeIngredientsRequired[i].iIngValA[j]) { bFoundA[j]=true; } } // 4J Stu - TU-1 hotfix // 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 break; } } } // 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 if(bFoundA[j]==false) { int iMissing = pRecipeIngredientsRequired[i].iIngValA[j]-iTotalCount; int iGridIndex=0; while(iMissing!=0) { // need to check if there is an aux val and match that if(((pRecipeIngredientsRequired[i].uiGridA[iGridIndex]&0x00FFFFFF)==pRecipeIngredientsRequired[i].iIngIDA[j]) && ((pRecipeIngredientsRequired[i].iIngAuxValA[j]==Recipes::ANY_AUX_VALUE) ||(pRecipeIngredientsRequired[i].iIngAuxValA[j]== ((pRecipeIngredientsRequired[i].uiGridA[iGridIndex]&0xFF000000)>>24))) ) { // this grid entry is the ingredient we don't have enough of pRecipeIngredientsRequired[i].usBitmaskMissingGridIngredients[getPad()]|=1< pTempItemInst=pRecipeIngredientsRequired[i].pRecipy->assemble(nullptr); //int iIcon=pTempItemInst->getItem()->getIcon(pTempItemInst->getAuxValue()); int iID=pTempItemInst->getItem()->id; int iBaseType; if(iID<256) // is it a tile? { iBaseType=Tile::tiles[iID]->getBaseItemType(); } else { iBaseType=pTempItemInst->getItem()->getBaseItemType(); } // ignore for the misc base type - these have not been placed in a base type group if(iBaseType!=Item::eBaseItemType_undefined) { for(int k=0;kgetDescriptionId())); #endif app.DebugPrintf("\n"); } } } else { app.DebugPrintf("Need more HSlots\n"); } delete [] bFoundA; itRecipe++; } } // run through the canbemade list and update the icons displayed int iIndex=0; //RecipyList *recipes = ((Recipes *)Recipes::getInstance())->getRecipies(); Recipy::INGREDIENTS_REQUIRED *pRecipeIngredientsRequired=Recipes::getInstance()->getRecipeIngredientsArray(); while((iIndex pTempItemInst=pRecipeIngredientsRequired[CanBeMadeA[iIndex].iRecipeA[0]].pRecipy->assemble(nullptr); assert(pTempItemInst->id!=0); unsigned int uiAlpha; if(app.DebugSettingsOn() && app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad())&(1L<id == Item::clock_Id || pTempItemInst->id == Item::compass_Id ) { pTempItemInst->setAuxValue( 255 ); } setCraftHSlotItem(getPad(),iIndex,pTempItemInst,uiAlpha); iIndex++; } // 4J-PB - Removed - UpdateTooltips will do this // Update tooltips /*if(CanBeMadeA[m_iCurrentSlotHIndex].iCount!=0) { ui.ShowTooltip( getPad(), eToolTipButtonA, true ); // 4J-PB - not implemented ! //ui.EnableTooltip( getPad(), eToolTipButtonA, true ); } else { ui.ShowTooltip( getPad(), eToolTipButtonA, false ); }*/ } ////////////////////////////////////////////////////////////////////////// // // UpdateHighlight // ////////////////////////////////////////////////////////////////////////// void IUIScene_CraftingMenu::UpdateHighlight() { updateHighlightAndScrollPositions(); bool bCanBeMade=CanBeMadeA[m_iCurrentSlotHIndex].iCount!=0; if(bCanBeMade) { //RecipyList *recipes = ((Recipes *)Recipes::getInstance())->getRecipies(); Recipy::INGREDIENTS_REQUIRED *pRecipeIngredientsRequired=Recipes::getInstance()->getRecipeIngredientsArray(); int iSlot; if(CanBeMadeA[m_iCurrentSlotHIndex].iCount>1) { iSlot=iVSlotIndexA[m_iCurrentSlotVIndex]; } else { iSlot=0; } std::shared_ptr pTempItemInstAdditional=pRecipeIngredientsRequired[CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[iSlot]].pRecipy->assemble(nullptr); // special case for the torch coal/charcoal int id=pTempItemInstAdditional->getDescriptionId(); LPCWSTR itemstring; switch(id) { case IDS_TILE_TORCH: { if(pRecipeIngredientsRequired[CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[iSlot]].iIngAuxValA[0]==1) { itemstring=app.GetString( IDS_TILE_TORCHCHARCOAL ); } else { itemstring=app.GetString( IDS_TILE_TORCHCOAL ); } } break; case IDS_ITEM_FIREBALL: { if(pRecipeIngredientsRequired[CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[iSlot]].iIngAuxValA[2]==1) { itemstring=app.GetString( IDS_ITEM_FIREBALLCHARCOAL ); } else { itemstring=app.GetString( IDS_ITEM_FIREBALLCOAL ); } } break; default: itemstring=app.GetString(id ); break; } setItemText(itemstring); } else { setItemText(L""); } UpdateDescriptionText(bCanBeMade); DisplayIngredients(); UpdateMultiPanel(); UpdateTooltips(); } ////////////////////////////////////////////////////////////////////////// // // UpdateVerticalSlots // ////////////////////////////////////////////////////////////////////////// void IUIScene_CraftingMenu::UpdateVerticalSlots() { //RecipyList *recipes = ((Recipes *)Recipes::getInstance())->getRecipies(); Recipy::INGREDIENTS_REQUIRED *pRecipeIngredientsRequired=Recipes::getInstance()->getRecipeIngredientsArray(); // update the vertical items for the current horizontal slot hideAllVSlots(); // could have either 1 or 2 vertical slots, above and below the horizontal slot if(CanBeMadeA[m_iCurrentSlotHIndex].iCount>1) { // turn off the horizontal one since we could be cycling through others setShowCraftHSlot(m_iCurrentSlotHIndex,false); int iSlots=(CanBeMadeA[m_iCurrentSlotHIndex].iCount>2)?3:2; // 4J-Tomk - check if we've only got one vertical scroll slot (480, splits & Vita) bool bNoScrollSlots = false; if(m_bSplitscreen ||(!RenderManager.IsHiDef() && !RenderManager.IsWidescreen())) { bNoScrollSlots = true; } #ifdef __PSVITA__ bNoScrollSlots = true; #endif for(int i=0;i pTempItemInstAdditional=pRecipeIngredientsRequired[CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[iVSlotIndexA[i]]].pRecipy->assemble(nullptr); assert(pTempItemInstAdditional->id!=0); unsigned int uiAlpha; if(app.DebugSettingsOn() && app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad())&(1L<id == Item::clock_Id || pTempItemInstAdditional->id == Item::compass_Id ) { pTempItemInstAdditional->setAuxValue( 255 ); } setCraftVSlotItem(getPad(),i,pTempItemInstAdditional,uiAlpha); updateVSlotPositions(iSlots, i); } } } ////////////////////////////////////////////////////////////////////////// // // DisplayIngredients // ////////////////////////////////////////////////////////////////////////// void IUIScene_CraftingMenu::DisplayIngredients() { //RecipyList *recipes = ((Recipes *)Recipes::getInstance())->getRecipies(); Recipy::INGREDIENTS_REQUIRED *pRecipeIngredientsRequired=Recipes::getInstance()->getRecipeIngredientsArray(); // hide the previous ingredients hideAllIngredientsSlots(); if(CanBeMadeA[m_iCurrentSlotHIndex].iCount!=0) { int iSlot,iRecipy; if(CanBeMadeA[m_iCurrentSlotHIndex].iCount>1) { iSlot=iVSlotIndexA[m_iCurrentSlotVIndex]; iRecipy=CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[iSlot]; } else { iSlot=0; iRecipy=CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[0]; } // show the 2x2 or 3x3 to make the current item int iBoxWidth=(m_iContainerType==RECIPE_TYPE_2x2)?2:3; int iRecipe=CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[iSlot]; bool bCanMakeRecipe = pRecipeIngredientsRequired[iRecipe].bCanMake[getPad()]; std::shared_ptr pTempItemInst=pRecipeIngredientsRequired[iRecipe].pRecipy->assemble(nullptr); m_iIngredientsC=pRecipeIngredientsRequired[iRecipe].iIngC; // update the ingredients required - these will all be hidden until cycled by the user for(int i=0;i itemInst= std::shared_ptr(new ItemInstance(item,pRecipeIngredientsRequired[iRecipe].iIngValA[i],iAuxVal)); setIngredientDescriptionItem(getPad(),i,itemInst); setIngredientDescriptionRedBox(i,false); // 4J-PB - a very special case - the bed can use any kind of wool, so we can't use the item description // and the same goes for the painting int idescID; if( ((pTempItemInst->id==Item::bed_Id) &&(id==Tile::cloth_Id)) || ((pTempItemInst->id==Item::painting_Id) &&(id==Tile::cloth_Id)) ) { idescID=IDS_ANY_WOOL; } else { idescID=itemInst->getDescriptionId(); } setIngredientDescriptionText(i,app.GetString(idescID)); } // 4J Stu - For clocks and compasses we set the aux value to a special one that signals we should use a default texture // rather than the dynamic one for the player if( pTempItemInst->id == Item::clock_Id || pTempItemInst->id == Item::compass_Id ) { pTempItemInst->setAuxValue( 255 ); } // don't grey out the output icon setCraftingOutputSlotItem(getPad(), pTempItemInst); if(app.DebugSettingsOn() && app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad())&(1L<>24; // 4J Stu - For clocks and compasses we set the aux value to a special one that signals we should use a default texture // rather than the dynamic one for the player if( id == Item::clock_Id || id == Item::compass_Id ) { iAuxVal = 0xFF; } std::shared_ptr itemInst= std::shared_ptr(new ItemInstance(id,1,iAuxVal)); setIngredientSlotItem(getPad(),index,itemInst); // show the ingredients we don't have if we can't make the recipe if(app.DebugSettingsOn() && app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad())&(1L<getRecipies(); Recipy::INGREDIENTS_REQUIRED *pRecipeIngredientsRequired=Recipes::getInstance()->getRecipeIngredientsArray(); if(bCanBeMade) { int iSlot;//,iRecipy; if(CanBeMadeA[m_iCurrentSlotHIndex].iCount>1) { iSlot=iVSlotIndexA[m_iCurrentSlotVIndex]; //iRecipy=CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[iSlot]; } else { iSlot=0; //iRecipy=CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[0]; } std::shared_ptr pTempItemInst=pRecipeIngredientsRequired[CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[iSlot]].pRecipy->assemble(nullptr); int iID=pTempItemInst->getItem()->id; int iAuxVal=pTempItemInst->getAuxValue(); int iBaseType; if(iID<256) // is it a tile? { iBaseType=Tile::tiles[iID]->getBaseItemType(); iIDSString = Tile::tiles[iID]->getUseDescriptionId(); } else { iBaseType=pTempItemInst->getItem()->getBaseItemType(); iIDSString = pTempItemInst->getUseDescriptionId(); } // A few special cases where the description required is specific to crafting, rather than the normal description if(iBaseType!=Item::eBaseItemType_undefined) { switch(iBaseType) { case Item::eBaseItemType_cloth: switch(iAuxVal) { case 0: iIDSString=IDS_DESC_WOOLSTRING; break; } break; } } // set the string mapped to by the base object mapping array if(iIDSString>=0) { // this is an html control now, so set the font size and colour //wstring wsText=app.GetString(iIDSString); wstring wsText=app.FormatHTMLString(getPad(),app.GetString(iIDSString)); // 12 for splitscreen, 14 for normal EHTMLFontSize size = eHTMLSize_Normal; if(m_bSplitscreen ||(!RenderManager.IsHiDef() && !RenderManager.IsWidescreen())) { size = eHTMLSize_Splitscreen; } wchar_t startTags[64]; swprintf(startTags,64,L"

",app.GetHTMLColour(eHTMLColor_Black)); wsText= startTags + wsText + L"

"; setDescriptionText(wsText.c_str()); } else { /// Missing string! #ifdef _DEBUG setDescriptionText(L"This is some placeholder description text about the craftable item."); #else setDescriptionText(L""); #endif } } else { setDescriptionText(L""); } } ////////////////////////////////////////////////////////////////////////// // // UpdateTooltips // ////////////////////////////////////////////////////////////////////////// void IUIScene_CraftingMenu::UpdateTooltips() { //RecipyList *recipes = ((Recipes *)Recipes::getInstance())->getRecipies(); Recipy::INGREDIENTS_REQUIRED *pRecipeIngredientsRequired=Recipes::getInstance()->getRecipeIngredientsArray(); // Update tooltips bool bDisplayCreate; if(CanBeMadeA[m_iCurrentSlotHIndex].iCount!=0) { int iSlot; if(CanBeMadeA[m_iCurrentSlotHIndex].iCount>1) { iSlot=iVSlotIndexA[m_iCurrentSlotVIndex]; } else { iSlot=0; } if(pRecipeIngredientsRequired[CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[iSlot]].bCanMake[getPad()]) { bDisplayCreate=true; } else { bDisplayCreate=false; } } else { bDisplayCreate=false; } switch(m_iDisplayDescription) { case DISPLAY_INVENTORY: ui.SetTooltips( getPad(), bDisplayCreate?IDS_TOOLTIPS_CREATE:-1,IDS_TOOLTIPS_EXIT, IDS_TOOLTIPS_SHOW_DESCRIPTION,-1,-1,-1,-2, IDS_TOOLTIPS_CHANGE_GROUP); break; case DISPLAY_DESCRIPTION: ui.SetTooltips( getPad(), bDisplayCreate?IDS_TOOLTIPS_CREATE:-1,IDS_TOOLTIPS_EXIT, IDS_TOOLTIPS_SHOW_INGREDIENTS,-1,-1,-1,-2, IDS_TOOLTIPS_CHANGE_GROUP); break; case DISPLAY_INGREDIENTS: ui.SetTooltips( getPad(), bDisplayCreate?IDS_TOOLTIPS_CREATE:-1,IDS_TOOLTIPS_EXIT, IDS_TOOLTIPS_SHOW_INVENTORY,-1,-1,-1,-2, IDS_TOOLTIPS_CHANGE_GROUP); break; } /*if(CanBeMadeA[m_iCurrentSlotHIndex].iCount!=0) { int iSlot; if(CanBeMadeA[m_iCurrentSlotHIndex].iCount>1) { iSlot=iVSlotIndexA[m_iCurrentSlotVIndex]; } else { iSlot=0; } if(pRecipeIngredientsRequired[CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[iSlot]].bCanMake[getPad()]) { ui.EnableTooltip( getPad(), eToolTipButtonA, true ); } else { ui.EnableTooltip( getPad(), eToolTipButtonA, false ); } } else { ui.ShowTooltip( getPad(), eToolTipButtonA, false ); }*/ } bool IUIScene_CraftingMenu::isItemSelected(int itemId) { bool isSelected = false; if(m_pPlayer && m_pPlayer->inventory) { //RecipyList *recipes = ((Recipes *)Recipes::getInstance())->getRecipies(); Recipy::INGREDIENTS_REQUIRED *pRecipeIngredientsRequired=Recipes::getInstance()->getRecipeIngredientsArray(); if(CanBeMadeA[m_iCurrentSlotHIndex].iCount!=0) { int iSlot; if(CanBeMadeA[m_iCurrentSlotHIndex].iCount>1) { iSlot=iVSlotIndexA[m_iCurrentSlotVIndex]; } else { iSlot=0; } int iRecipe= CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[iSlot]; ItemInstance *pTempItemInst = (ItemInstance *)pRecipeIngredientsRequired[iRecipe].pRecipy->getResultItem(); if(pTempItemInst->id == itemId) { isSelected = true; } } } return isSelected; }