4jcraft/Minecraft.Client/Platform/Common/UI/IUIScene_CraftingMenu.cpp
MatthewBeshay a0fdc643d1 Merge branch 'upstream-dev' into cleanup/nullptr-replacement
# Conflicts:
#	Minecraft.Client/Network/PlayerChunkMap.cpp
#	Minecraft.Client/Network/PlayerList.cpp
#	Minecraft.Client/Network/ServerChunkCache.cpp
#	Minecraft.Client/Platform/Common/Consoles_App.cpp
#	Minecraft.Client/Platform/Common/DLC/DLCManager.cpp
#	Minecraft.Client/Platform/Common/GameRules/LevelGenerationOptions.cpp
#	Minecraft.Client/Platform/Common/GameRules/LevelRuleset.cpp
#	Minecraft.Client/Platform/Common/Tutorial/Tutorial.cpp
#	Minecraft.Client/Platform/Common/Tutorial/TutorialTask.cpp
#	Minecraft.Client/Platform/Common/UI/IUIScene_CreativeMenu.cpp
#	Minecraft.Client/Platform/Common/UI/UIComponent_Panorama.cpp
#	Minecraft.Client/Platform/Common/UI/UIController.cpp
#	Minecraft.Client/Platform/Common/UI/UIController.h
#	Minecraft.Client/Platform/Extrax64Stubs.cpp
#	Minecraft.Client/Platform/Windows64/4JLibs/inc/4J_Input.h
#	Minecraft.Client/Platform/Windows64/4JLibs/inc/4J_Storage.h
#	Minecraft.Client/Player/EntityTracker.cpp
#	Minecraft.Client/Player/ServerPlayer.cpp
#	Minecraft.Client/Rendering/EntityRenderers/PlayerRenderer.cpp
#	Minecraft.Client/Textures/Packs/DLCTexturePack.cpp
#	Minecraft.Client/Textures/Stitching/StitchedTexture.cpp
#	Minecraft.Client/Textures/Stitching/TextureMap.cpp
#	Minecraft.Client/Textures/Textures.cpp
#	Minecraft.World/Blocks/NotGateTile.cpp
#	Minecraft.World/Blocks/PressurePlateTile.cpp
#	Minecraft.World/Blocks/TileEntities/PotionBrewing.cpp
#	Minecraft.World/Enchantments/EnchantmentHelper.cpp
#	Minecraft.World/Entities/HangingEntity.cpp
#	Minecraft.World/Entities/LeashFenceKnotEntity.cpp
#	Minecraft.World/Entities/LivingEntity.cpp
#	Minecraft.World/Entities/Mobs/Boat.cpp
#	Minecraft.World/Entities/Mobs/Minecart.cpp
#	Minecraft.World/Entities/Mobs/Witch.cpp
#	Minecraft.World/Entities/SyncedEntityData.cpp
#	Minecraft.World/Items/LeashItem.cpp
#	Minecraft.World/Items/PotionItem.cpp
#	Minecraft.World/Level/BaseMobSpawner.cpp
#	Minecraft.World/Level/CustomLevelSource.cpp
#	Minecraft.World/Level/Level.cpp
#	Minecraft.World/Level/Storage/DirectoryLevelStorage.cpp
#	Minecraft.World/Level/Storage/McRegionLevelStorage.cpp
#	Minecraft.World/Level/Storage/RegionFileCache.cpp
#	Minecraft.World/Player/Player.cpp
#	Minecraft.World/WorldGen/Biomes/BiomeCache.cpp
#	Minecraft.World/WorldGen/Features/RandomScatteredLargeFeature.cpp
#	Minecraft.World/WorldGen/Layers/BiomeOverrideLayer.cpp
2026-03-30 16:28:40 +11:00

1424 lines
59 KiB
C++

#include "../../Minecraft.World/Platform/stdafx.h"
#include "../../Minecraft.World/Headers/net.minecraft.world.item.crafting.h"
#include "../../Minecraft.World/Headers/net.minecraft.world.level.tile.h"
#include "../../Minecraft.World/Headers/net.minecraft.stats.h"
#include "../../Minecraft.Client/Player/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,
};
const wchar_t* 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;
}
const wchar_t* 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()] != nullptr) {
Tutorial* tutorial =
pMinecraft->localgameModes[getPad()]->getTutorial();
if (tutorial != nullptr) {
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:
// 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] != nullptr) {
Tutorial* tutorial =
pMinecraft->localgameModes[iPad]->getTutorial();
if (tutorial != nullptr) {
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] != nullptr) {
Tutorial* tutorial =
pMinecraft->localgameModes[iPad]->getTutorial();
if (tutorial != nullptr) {
tutorial->createItemSelected(
pTempItemInst,
pRecipeIngredientsRequired[iRecipe]
.bCanMake[iPad]);
}
}
if (pRecipeIngredientsRequired[iRecipe].bCanMake[iPad]) {
pTempItemInst->onCraftedBy(
m_pPlayer->level,
std::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);
if (pTempItemInst->id != Item::fireworksCharge_Id &&
pTempItemInst->id != Item::fireworks_Id) {
// 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 != nullptr) {
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;
}
// 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] != nullptr)
{
std::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 itRecipe = recipes->begin();
// dump out the recipe products
// for (int i = 0; i < iRecipeC; i++)
// {
// std::shared_ptr<ItemInstance>
// pTempItemInst=pRecipeIngredientsRequired[i].pRecipy->assemble(nullptr);
// if (pTempItemInst != nullptr)
// {
// std::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] != nullptr) {
// 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] !=
nullptr) {
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 - ");
#if !defined(_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();
const wchar_t* 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;
}
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];
std::shared_ptr<ItemInstance> itemInst =
std::shared_ptr<ItemInstance>(new ItemInstance(
item, pRecipeIngredientsRequired[iRecipe].iIngValA[i],
iAuxVal));
// 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::wool_Id)) ||
((pTempItemInst->id == Item::painting_Id) &&
(id == Tile::wool_Id))) {
idescID = IDS_ANY_WOOL;
} else {
idescID = itemInst->getDescriptionId();
}
setIngredientDescriptionText(i, app.GetString(idescID));
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;
}
itemInst->setAuxValue(iAuxVal);
setIngredientDescriptionItem(getPad(), i, itemInst);
setIngredientDescriptionRedBox(i, false);
}
// 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;
} else if (pTempItemInst->id == Item::fireworksCharge_Id &&
id == Item::dye_powder_Id) {
iAuxVal = 1;
}
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
// std::wstring wsText=app.GetString(iIDSString);
std::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!
#if defined(_DEBUG)
setDescriptionText(
L"This is some placeholder description text about the "
L"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 );
}*/
}
void IUIScene_CraftingMenu::HandleInventoryUpdated() {
// Check which recipes are available with the resources we have
CheckRecipesAvailable();
UpdateVerticalSlots();
UpdateHighlight();
UpdateTooltips();
}
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;
}