1401 lines
40 KiB
C++
1401 lines
40 KiB
C++
#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;i<m_iMaxHSlotC;i++)
|
|
{
|
|
CanBeMadeA[i].iCount=0;
|
|
CanBeMadeA[i].iItemBaseType=0;
|
|
}
|
|
memset(CanBeMadeA,0,sizeof(CANBEMADE)*m_iMaxHSlotC);
|
|
m_iRecipeC=0;
|
|
m_iGroupIndex=0;
|
|
|
|
for(int i=0;i<m_iMaxDisplayedVSlotC;i++)
|
|
{
|
|
iVSlotIndexA[i]=i; // start with 0,1,2
|
|
}
|
|
|
|
m_iDisplayDescription=DISPLAY_INVENTORY;
|
|
m_iIngredientsC=0;
|
|
}
|
|
|
|
LPCWSTR IUIScene_CraftingMenu::GetGroupNameText(int iGroupType)
|
|
{
|
|
switch(iGroupType)
|
|
{
|
|
case ShapedRecipy::eGroupType_Tool:
|
|
return app.GetString( IDS_GROUPNAME_TOOLS );
|
|
case ShapedRecipy::eGroupType_Food:
|
|
return app.GetString( IDS_GROUPNAME_FOOD);
|
|
case ShapedRecipy::eGroupType_Structure:
|
|
return app.GetString( IDS_GROUPNAME_STRUCTURES );
|
|
case ShapedRecipy::eGroupType_Armour:
|
|
return app.GetString( IDS_GROUPNAME_ARMOUR );
|
|
case ShapedRecipy::eGroupType_Mechanism:
|
|
return app.GetString( IDS_GROUPNAME_MECHANISMS );
|
|
case ShapedRecipy::eGroupType_Transport:
|
|
return app.GetString( IDS_GROUPNAME_TRANSPORT );
|
|
case ShapedRecipy::eGroupType_Decoration:
|
|
default:
|
|
return app.GetString( IDS_GROUPNAME_DECORATIONS );
|
|
}
|
|
}
|
|
|
|
bool IUIScene_CraftingMenu::handleKeyDown(int iPad, int iAction, bool bRepeat)
|
|
{
|
|
bool bHandled = false;
|
|
|
|
if(m_bIgnoreKeyPresses) return bHandled;
|
|
|
|
// ignore key repeats of the X key - because it's X to open this menu, it can come through as a repeat on opening
|
|
if(bRepeat &&(iAction==ACTION_MENU_X))
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
Minecraft *pMinecraft = Minecraft::GetInstance();
|
|
|
|
if( pMinecraft->localgameModes[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<<eDebugSetting_CraftAnything))
|
|
{
|
|
if(CanBeMadeA[m_iCurrentSlotHIndex].iCount!=0)
|
|
{
|
|
int iSlot=iVSlotIndexA[m_iCurrentSlotVIndex];
|
|
|
|
int iRecipe= CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[iSlot];
|
|
std::shared_ptr<ItemInstance> 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<ItemInstance> 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, dynamic_pointer_cast<Player>( 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<pRecipeIngredientsRequired[iRecipe].iIngC;i++)
|
|
{
|
|
for(int j=0;j<pRecipeIngredientsRequired[iRecipe].iIngValA[i];j++)
|
|
{
|
|
std::shared_ptr<ItemInstance> 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<ItemInstance>( 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<ItemInstance> 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;i<iRecipeC;i++)
|
|
{
|
|
|
|
Recipy *r = *itRecipe;
|
|
|
|
// If this recipe isn't in the current grouptype, skip it
|
|
if(r->getGroup()!=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;j<pRecipeIngredientsRequired[i].iIngC;j++)
|
|
{
|
|
bFoundA[j]=false;
|
|
int iTotalCount=0;
|
|
|
|
// Does the player have this ingredient?
|
|
for (unsigned int k = 0; k < m_pPlayer->inventory->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;l<m_pPlayer->inventory->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<<iGridIndex;
|
|
iMissing--;
|
|
}
|
|
iGridIndex++;
|
|
}
|
|
}
|
|
}
|
|
|
|
// so can we make it?
|
|
bool bCanMake=true;
|
|
for(int j=0;j<pRecipeIngredientsRequired[i].iIngC;j++)
|
|
{
|
|
if(bFoundA[j]==false)
|
|
{
|
|
bCanMake=false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
pRecipeIngredientsRequired[i].bCanMake[getPad()]=bCanMake;
|
|
|
|
// Add the recipe to the CanBeMade list of lists
|
|
if(iHSlotBrushControl<=m_iCraftablesMaxHSlotC)
|
|
{
|
|
bool bFound=false;
|
|
std::shared_ptr<ItemInstance> 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;k<iHSlotBrushControl;k++)
|
|
{
|
|
// if the item base type is the same as one already in, then add it to that list
|
|
if(CanBeMadeA[k].iItemBaseType==iBaseType)
|
|
{
|
|
// base item type already in our list
|
|
bFound=true;
|
|
if(CanBeMadeA[k].iCount<m_iMaxVSlotC)
|
|
{
|
|
CanBeMadeA[k].iRecipeA[CanBeMadeA[k].iCount++]=i;
|
|
}
|
|
else
|
|
{
|
|
app.DebugPrintf("Need more V slots\n");
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!bFound)
|
|
{
|
|
if(iHSlotBrushControl<m_iCraftablesMaxHSlotC)
|
|
{
|
|
// add to the list
|
|
CanBeMadeA[iHSlotBrushControl].iItemBaseType=iBaseType;
|
|
CanBeMadeA[iHSlotBrushControl].iRecipeA[CanBeMadeA[iHSlotBrushControl].iCount++]=i;
|
|
iHSlotBrushControl++;
|
|
}
|
|
else
|
|
{
|
|
app.DebugPrintf("Need more H slots - ");
|
|
#ifndef _CONTENT_PACKAGE
|
|
OutputDebugStringW(app.GetString(pTempItemInst->getDescriptionId()));
|
|
#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<m_iCraftablesMaxHSlotC) && CanBeMadeA[iIndex].iCount!=0)
|
|
{
|
|
std::shared_ptr<ItemInstance> pTempItemInst=pRecipeIngredientsRequired[CanBeMadeA[iIndex].iRecipeA[0]].pRecipy->assemble(nullptr);
|
|
assert(pTempItemInst->id!=0);
|
|
unsigned int uiAlpha;
|
|
|
|
if(app.DebugSettingsOn() && app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad())&(1L<<eDebugSetting_CraftAnything))
|
|
{
|
|
uiAlpha = 31;
|
|
}
|
|
else
|
|
{
|
|
if(pRecipeIngredientsRequired[CanBeMadeA[iIndex].iRecipeA[0]].bCanMake[getPad()])
|
|
{
|
|
uiAlpha = 31;
|
|
}
|
|
else
|
|
{
|
|
uiAlpha= 16;
|
|
}
|
|
}
|
|
|
|
// 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 );
|
|
}
|
|
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<ItemInstance> 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<iSlots;i++)
|
|
{
|
|
// 4J this check determines if the crafting scene has only one vertical scroll slot
|
|
if(bNoScrollSlots)
|
|
{
|
|
if(i!=1) continue;
|
|
}
|
|
std::shared_ptr<ItemInstance> 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<<eDebugSetting_CraftAnything))
|
|
{
|
|
uiAlpha = 31;
|
|
}
|
|
else
|
|
{
|
|
if(pRecipeIngredientsRequired[CanBeMadeA[m_iCurrentSlotHIndex].iRecipeA[iVSlotIndexA[i]]].bCanMake[getPad()])
|
|
{
|
|
uiAlpha = 31;
|
|
}
|
|
else
|
|
{
|
|
uiAlpha= 16;
|
|
}
|
|
}
|
|
|
|
// 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( pTempItemInstAdditional->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<ItemInstance> 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<pRecipeIngredientsRequired[iRecipe].iIngC;i++)
|
|
{
|
|
int id=pRecipeIngredientsRequired[iRecipe].iIngIDA[i];
|
|
int iAuxVal=pRecipeIngredientsRequired[iRecipe].iIngAuxValA[i];
|
|
Item *item = Item::items[id];
|
|
if( (iAuxVal & 0xFF) == 0xFF) // 4J Stu - If the aux value is set to match any
|
|
iAuxVal = 0;
|
|
|
|
// 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<ItemInstance> itemInst= std::shared_ptr<ItemInstance>(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<<eDebugSetting_CraftAnything))
|
|
{
|
|
setCraftingOutputSlotRedBox(false);
|
|
}
|
|
else
|
|
{
|
|
if(bCanMakeRecipe==false)
|
|
{
|
|
setCraftingOutputSlotRedBox(true);
|
|
}
|
|
else
|
|
{
|
|
setCraftingOutputSlotRedBox(false);
|
|
}
|
|
|
|
}
|
|
for (int x = 0; x < iBoxWidth; x++)
|
|
{
|
|
for (int y = 0; y < iBoxWidth; y++)
|
|
{
|
|
int index = x+y*iBoxWidth;
|
|
if(pRecipeIngredientsRequired[iRecipy].uiGridA[x+y*3]!=0)
|
|
{
|
|
int id=pRecipeIngredientsRequired[iRecipy].uiGridA[x+y*3]&0x00FFFFFF;
|
|
assert(id!=0);
|
|
int iAuxVal=(pRecipeIngredientsRequired[iRecipy].uiGridA[x+y*3]&0xFF000000)>>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<ItemInstance> itemInst= std::shared_ptr<ItemInstance>(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<<eDebugSetting_CraftAnything))
|
|
{
|
|
setIngredientSlotRedBox(index, false);
|
|
}
|
|
else
|
|
{
|
|
if((pRecipeIngredientsRequired[iRecipy].usBitmaskMissingGridIngredients[getPad()]&(1<<(x+y*3)))!=0)
|
|
{
|
|
setIngredientSlotRedBox(index, true);
|
|
}
|
|
else
|
|
{
|
|
setIngredientSlotRedBox(index, false);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
setIngredientSlotRedBox(index, false);
|
|
setIngredientSlotItem(getPad(),index,nullptr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
setCraftingOutputSlotItem(getPad(), nullptr);
|
|
setCraftingOutputSlotRedBox(false);
|
|
m_iIngredientsC=0;
|
|
int iIngredientsSlots;
|
|
// if it's a 2x2 , only clear the 4 m_pCraftingIngredientA slots
|
|
if(m_iContainerType==RECIPE_TYPE_2x2)
|
|
{
|
|
iIngredientsSlots=4;
|
|
}
|
|
else
|
|
{
|
|
iIngredientsSlots=m_iIngredients3x3SlotC;
|
|
}
|
|
|
|
for(int i=0;i<iIngredientsSlots;i++)
|
|
{
|
|
setIngredientSlotRedBox(i, false);
|
|
setIngredientSlotItem(getPad(),i,nullptr);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// UpdateDescriptionText
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void IUIScene_CraftingMenu::UpdateDescriptionText(bool bCanBeMade)
|
|
{
|
|
int iIDSString=0;
|
|
//RecipyList *recipes = ((Recipes *)Recipes::getInstance())->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<ItemInstance> 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"<font color=\"#%08x\"><P ALIGN=LEFT>",app.GetHTMLColour(eHTMLColor_Black));
|
|
wsText= startTags + wsText + L"</P>";
|
|
|
|
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;
|
|
}
|