Fixed detection of craftable items that aren't enhanceable (failed out of bounds checks). Hide information about craftable items that have yet to be unlocked.

pull/28/head
sigonasr2 1 year ago
parent 4e3c9877e7
commit c876f8a6ea
  1. 106
      Crawler/ConsumableCraftingWindow.cpp
  2. 3
      Crawler/Crawler.cpp
  3. 40
      Crawler/Item.cpp
  4. 3
      Crawler/Item.h
  5. 8
      Crawler/Menu.cpp
  6. 2
      Crawler/Menu.h
  7. 4
      Crawler/MenuComponent.cpp
  8. 1
      Crawler/MenuComponent.h
  9. 3
      Crawler/MenuIconButton.h
  10. 14
      Crawler/MenuItemItemButton.h
  11. 1
      Crawler/RowInventoryScrollableWindowComponent.h
  12. 35
      Crawler/RowItemDisplay.h
  13. 3
      Crawler/State_OverworldMap.cpp
  14. 2
      Crawler/Version.h
  15. 2
      Crawler/assets/config/items/ItemDatabase.txt

@ -51,47 +51,9 @@ INCLUDE_GFX
void Menu::InitializeConsumableCraftingWindow(){
Menu*consumableCraftingWindow=CreateMenu(CRAFT_CONSUMABLE,CENTERED,game->GetScreenSize()-vi2d{52,52});
std::vector<std::pair<std::string,int>>categories;
std::vector<std::weak_ptr<Item>>weaponInventory;
std::vector<std::weak_ptr<Item>>armorInventory;
#pragma region Build Equipment Lists
std::for_each(Inventory::get("Equipment").begin(),Inventory::get("Equipment").end(),[&](const std::shared_ptr<Item> item){
switch(item.get()->GetEquipSlot()){
case EquipSlot::WEAPON:{
weaponInventory.push_back(item);
}break;
case EquipSlot::NONE:
case EquipSlot::RING1:
case EquipSlot::RING2:break;//No-op
default:{ //We assume everything else is armor.
armorInventory.push_back(item);
}
}
});
#pragma endregion
auto weaponTab=consumableCraftingWindow->ADD("Weapon Tab",MenuComponent)({{2,0},{consumableCraftingWindow->size.x/2-4,24}},"Weapon",[](MenuFuncData data){
Component<MenuComponent>(CRAFT_CONSUMABLE,"Armor Tab")->selected=false;
Component<RowInventoryScrollableWindowComponent>(CRAFT_CONSUMABLE,"Weapon Inventory Display")->Enable(true);
Component<RowInventoryScrollableWindowComponent>(CRAFT_CONSUMABLE,"Armor Inventory Display")->Enable(false);
data.component->selected=true;
return true;
})END;
weaponTab->selected=true;
weaponTab->selectionType=SelectionType::HIGHLIGHT;
auto armorTab=consumableCraftingWindow->ADD("Armor Tab",MenuComponent)({{consumableCraftingWindow->size.x/2+2,0},{consumableCraftingWindow->size.x/2-4,24}},"Armor",[](MenuFuncData data){
Component<MenuComponent>(CRAFT_CONSUMABLE,"Weapon Tab")->selected=false;
Component<RowInventoryScrollableWindowComponent>(CRAFT_CONSUMABLE,"Weapon Inventory Display")->Enable(false);
Component<RowInventoryScrollableWindowComponent>(CRAFT_CONSUMABLE,"Armor Inventory Display")->Enable(true);
data.component->selected=true;
return true;
})END;
armorTab->selectionType=SelectionType::HIGHLIGHT;
#pragma region Weapon Inventory Display
auto weaponsDisplay=consumableCraftingWindow->ADD("Weapon Inventory Display",RowInventoryScrollableWindowComponent)({{2,28},{220,consumableCraftingWindow->size.y-44}},"Item Name Label","Item Description Label",
#pragma region Craftables Inventory Display
auto craftingItemsDisplay=consumableCraftingWindow->ADD("Crafting Inventory Display",RowInventoryScrollableWindowComponent)({{2,28},{220,consumableCraftingWindow->size.y-44}},"Item Name Label","Item Description Label",
[](MenuFuncData data){
RowItemDisplay*comp=DYNAMIC_CAST<RowItemDisplay*>(data.component);
const std::weak_ptr<Item>item=comp->GetItem();
@ -110,6 +72,11 @@ void Menu::InitializeConsumableCraftingWindow(){
},
[](MenuFuncData data){
RowItemDisplay*rowItem=DYNAMIC_CAST<RowItemDisplay*>(data.component);
if(rowItem->GetItem().lock()->GetEnhancementInfo().AvailableChapter()<=game->GetCurrentChapter()){
Component<MenuItemItemButton>(CRAFT_CONSUMABLE,"Item Icon")->SetHideDetails(false);
}else{
Component<MenuItemItemButton>(CRAFT_CONSUMABLE,"Item Icon")->SetHideDetails(true);
}
Component<MenuItemItemButton>(CRAFT_CONSUMABLE,"Item Icon")->SetItem(rowItem->GetItem());
return true;
},
@ -120,49 +87,36 @@ void Menu::InitializeConsumableCraftingWindow(){
InventoryCreator::RowPlayerWeapons_InventoryUpdate,
{.padding=1,.size={207,28}}
)END;
AddInventoryListener(weaponsDisplay,"Equipment");
weaponsDisplay->SetCompactDescriptions(CRAFTING_INFO);
#pragma endregion
#pragma region Armor Inventory Display
auto armorDisplay=consumableCraftingWindow->ADD("Armor Inventory Display",RowInventoryScrollableWindowComponent)({{2,28},{220,consumableCraftingWindow->size.y-44}},"Item Name Label","Item Description Label",
[](MenuFuncData data){
Menu::OpenMenu(CRAFT_ITEM);
RowItemDisplay*comp=DYNAMIC_CAST<RowItemDisplay*>(data.component);
const std::weak_ptr<Item>item=comp->GetItem();
craftingItemsDisplay->SetCompactDescriptions(CRAFTING_INFO);
vf2d buttonSize=craftingItemsDisplay->options.size;
vf2d totalSpacing={craftingItemsDisplay->options.padding+buttonSize.x,craftingItemsDisplay->options.padding+buttonSize.y};
for(auto item:ItemInfo::craftableConsumables){
size_t invSize=craftingItemsDisplay->components.size()+1;
int invWidth=int(craftingItemsDisplay->rect.size.x/(float(craftingItemsDisplay->options.size.x)+craftingItemsDisplay->options.padding));
int x=int((invSize-1)%invWidth);
int y=int((invSize-1)/invWidth);
int itemIndex=y*invWidth+x;
auto newItem=craftingItemsDisplay->ADD("item_Craftables_"+std::to_string(itemIndex),RowItemDisplay)({totalSpacing*vf2d{float(x),float(y)},buttonSize},item,craftingItemsDisplay->inventoryButtonClickAction,craftingItemsDisplay->itemNameLabelName,craftingItemsDisplay->itemDescriptionLabelName,craftingItemsDisplay->inventoryButtonsActive?ButtonAttr::NONE:ButtonAttr::UNSELECTABLE)END;
newItem->SetShowQuantity(false);
newItem->SetCompactDescriptions(craftingItemsDisplay->compact);
newItem->SetPriceLabelType(craftingItemsDisplay->priceLabel);
newItem->SetHoverFunc(craftingItemsDisplay->inventoryButtonHoverAction);
newItem->SetMouseOutFunc(craftingItemsDisplay->inventoryButtonMouseOutAction);
newItem->SetCheckCraftingRequirements(true);
newItem->SetHideLabelWhileLocked(true);
}
std::string label="";
if(item.lock()->EnhancementIsPossible()&&item.lock()->GetEnhancementInfo().size()>item.lock()->EnhancementLevel()+1){
label=std::format("Level {} ->#00AA00 {}",item.lock()->EnhancementLevel(),item.lock()->EnhancementLevel()+1);
}
Component<MenuLabel>(CRAFT_ITEM,"Enhancement Level Header")->SetLabel(label);
Component<MenuLabel>(CRAFT_ITEM,"Item Name Header")->SetLabel(std::format("Crafting {}",item.lock()->DisplayName()));
Component<EnhancementStatsLabel>(CRAFT_ITEM,"Enhancement Stats Label")->SetItem(item);
Component<RequiredMaterialsList>(CRAFT_ITEM,"Required Materials List")->SetItem(item);
Component<MenuComponent>(CRAFT_ITEM,"Craft Button")->SetGrayedOut(!item.lock()->CanEnhanceItem());
return true;
},
[](MenuFuncData data){
RowItemDisplay*rowItem=DYNAMIC_CAST<RowItemDisplay*>(data.component);
Component<MenuItemItemButton>(CRAFT_CONSUMABLE,"Item Icon")->SetItem(rowItem->GetItem());
return true;
},
[](MenuFuncData data){
Component<MenuItemItemButton>(CRAFT_CONSUMABLE,"Item Icon")->SetItem(Item::BLANK);
return true;
},
InventoryCreator::RowPlayerArmor_InventoryUpdate,
{.padding=1,.size={207,28}}
)END;
AddInventoryListener(armorDisplay,"Equipment");
armorDisplay->Enable(false);
armorDisplay->SetCompactDescriptions(CRAFTING_INFO);
#pragma endregion
#pragma region Inventory Description
float inventoryDescriptionWidth=consumableCraftingWindow->pos.x+consumableCraftingWindow->size.x-26-224;
consumableCraftingWindow->ADD("Item Description Outline",MenuLabel)({{224,28},{inventoryDescriptionWidth,consumableCraftingWindow->size.y-44}},"",1,ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND)END;
consumableCraftingWindow->ADD("Item Icon",MenuItemItemButton)({{226+inventoryDescriptionWidth/2-24,30},{48,48}},Item::BLANK,MenuType::ENUM_END,DO_NOTHING,"","",IconButtonAttr::NOT_SELECTABLE)END;
consumableCraftingWindow->ADD("Item Icon",MenuItemItemButton)({{226+inventoryDescriptionWidth/2-24,30},{48,48}},Item::BLANK,MenuType::ENUM_END,DO_NOTHING,"","",IconButtonAttr::NOT_SELECTABLE)END
->SetShowQuantity(false);
consumableCraftingWindow->ADD("Item Name Label",MenuLabel)({{226,84},{inventoryDescriptionWidth-6,12}},"",0.75f,ComponentAttr::LEFT_ALIGN|ComponentAttr::SHADOW)END;
consumableCraftingWindow->ADD("Item Description Label",MenuLabel)({{226,94},{inventoryDescriptionWidth-6,consumableCraftingWindow->size.y-44-66}},"",0.5f,ComponentAttr::LEFT_ALIGN|ComponentAttr::SHADOW)END;
#pragma endregion

@ -2337,6 +2337,9 @@ int Crawler::GetCurrentChapter(){
void Crawler::SetChapter(int chapter){
this->chapter=chapter;
for(MenuComponent*component:Menu::chapterListeners){
component->OnChapterUpdate(chapter);
}
}
const std::weak_ptr<Item>Crawler::GetLoadoutItem(int slot){

@ -60,7 +60,7 @@ std::map<std::string,EquipSlot>ItemInfo::nameToEquipSlot;
int Item::IsBlankStaticCallCounter=0;
safemap<int,float>Stats::maxDamageReductionTable;
ItemEnhancementFunctionPrimingData Item::enhanceFunctionPrimed("CanEnhanceItem()");
std::vector<ItemInfo*>ItemInfo::craftableConsumables;
std::vector<std::shared_ptr<Item>>ItemInfo::craftableConsumables;
ItemInfo::ItemInfo()
:customProps({nullptr,nullptr}),img(nullptr){}
@ -186,7 +186,8 @@ void ItemInfo::InitializeItems(){
if(data[key]["Crafting"].HasProperty("AvailableChapter")){
availableChapter=data[key]["Crafting"]["AvailableChapter"].GetInt();
}
craftableConsumables.push_back(&it);
craftableConsumables.push_back(std::make_shared<Item>(1,key));
it.enhancement.SetAttribute(1,ItemAttribute::Get("Attack"),0.f);
it.enhancement.SetCraftingRequirements(1,itemsRequired,goldCost,availableChapter);
}
@ -543,23 +544,23 @@ const std::string Item::Description(CompactText compact)const{
first=false;
}
}
if(compact==CRAFTING_INFO){
description+="\n\nCrafting Requirements:\n---------\n";
if(IsEquippable()&&EnhancementLevel()<"Item.Item Max Enhancement Level"_I||IsCraftable()){
const EnhancementLevelInfo&info=GetEnhancementInfo()[EnhancementLevel()+1];
for(const auto&[name,amt]:info.craftingRequirement.GetItems()){
description+=std::format("{}{} x{} ({})\n",
Inventory::GetItemCount(name)<amt?"#FF0000":"#FFFFFF",
name,
amt,
Inventory::GetItemCount(name));
}
description+="\n";
description+=std::format("{}Crafting Cost: {} {}",
game->GetPlayer()->GetMoney()<info.craftingRequirement.GetCost()?"#FF0000":"#FFFFFF",
info.craftingRequirement.GetCost(),
"Item.Currency Name"_S);
}
if(compact==CRAFTING_INFO){
description+="\n\nCrafting Requirements:\n---------\n";
if(IsCraftable()){
const EnhancementLevelInfo&info=GetEnhancementInfo()[EnhancementLevel()+1];
for(const auto&[name,amt]:info.craftingRequirement.GetItems()){
description+=std::format("{}{} x{} ({})\n",
Inventory::GetItemCount(name)<amt?"#FF0000":"#FFFFFF",
name,
amt,
Inventory::GetItemCount(name));
}
description+="\n";
description+=std::format("{}Crafting Cost: {} {}",
game->GetPlayer()->GetMoney()<info.craftingRequirement.GetCost()?"#FF0000":"#FFFFFF",
info.craftingRequirement.GetCost(),
"Item.Currency Name"_S);
}
}
return description;
@ -909,6 +910,7 @@ void EnhancementInfo::SetCraftingRequirements(const int enhanceLevel,const std::
while(craftingRequirements.size()<=enhanceLevel){
craftingRequirements.push_back(CraftingRequirement({},0));
}
this->availableChapter=availableChapter;
craftingRequirements[enhanceLevel]=CraftingRequirement(requiredItems,goldCost);
}
@ -944,7 +946,7 @@ const EnhancementInfo&Item::GetEnhancementInfo()const{
}
const bool EnhancementInfo::CanBeEnhanced()const{
return enhancementStats.size()>0&&craftingRequirements.size()>0;
return craftingRequirements.size()>0;
};

@ -265,6 +265,7 @@ public:
class ItemInfo{
friend class Inventory;
friend class Menu;
std::string name;
std::string description;
std::string category;
@ -287,7 +288,7 @@ private:
static void InitializeScripts();
static void InitializeSets();
static std::map<std::string,EquipSlot>nameToEquipSlot;
static std::vector<ItemInfo*>craftableConsumables;
static std::vector<std::shared_ptr<Item>>craftableConsumables;
public:
static void InitializeItems();
ItemInfo();

@ -56,6 +56,7 @@ safeunorderedmap<std::string,Theme>Menu::themes;
safemap<ITCategory,std::vector<MenuComponent*>>Menu::inventoryListeners;
safemap<ITCategory,std::vector<MenuComponent*>>Menu::merchantInventoryListeners;
std::vector<MenuComponent*>Menu::equipStatListeners;
std::vector<MenuComponent*>Menu::chapterListeners;
const vf2d Menu::CENTERED = {-456,-456};
std::vector<MenuComponent*>Menu::unhandledComponents;
//////////////////////////////////////////////////////////////////////////////////////////////////
@ -700,4 +701,11 @@ MenuType Menu::GetType(){
void Menu::LockInListeners(){
inventoryListeners.SetInitialized();
merchantInventoryListeners.SetInitialized();
}
void Menu::AddChapterListener(MenuComponent*component){
if(std::find(chapterListeners.begin(),chapterListeners.end(),component)!=chapterListeners.end()){
ERR("WARNING! Component "<<component->name<<" has already been added to the Chapter listener list! There should not be any duplicates!!")
}
chapterListeners.push_back(component);
}

@ -118,6 +118,7 @@ class Menu:public IAttributable{
static safemap<ITCategory,std::vector<MenuComponent*>>inventoryListeners; //All menu components that care about inventory updates subscribe to this list indirectly (See Menu::AddInventoryListener()).
static safemap<ITCategory,std::vector<MenuComponent*>>merchantInventoryListeners; //All menu components that care about merchant inventory updates subscribe to this list indirectly (See Menu::AddMerchantInventoryListener()).
static std::vector<MenuComponent*>equipStatListeners; //All menu components that care about stat/equip updates subscribe to this list indirectly (See Menu::AddStatListener()).
static std::vector<MenuComponent*>chapterListeners; //All menu components that care about story chapter updates subscribe to this list indirectly (See Menu::AddChapterListener()).
public:
//The constructor is private. Use CreateMenu() instead!
Menu()=default;
@ -210,6 +211,7 @@ public:
static void AddInventoryListener(MenuComponent*component,ITCategory category); //Adds a component to be in a given listener category.
static void AddMerchantInventoryListener(MenuComponent*component,ITCategory category); //Adds a component to be in a given listener category.
static void AddEquipStatListener(MenuComponent*component); //Adds a component to be in an equip stat listener. Will receive updates whenever stats are updated via equips.
static void AddChapterListener(MenuComponent*component); //Adds a component to be in a chapter listener. Will receive updates anytime the chapter in-game changes.
vf2d center();
//Returns the last menu type created and last registered component, in case a component is detected as memory leaking, provides this information to each component for safety.
static std::pair<MenuType,std::string>GetMemoryLeakReportInfo();

@ -250,4 +250,6 @@ void MenuComponent::SetGrayedOut(bool grayedOut){
this->grayedOut=grayedOut;
}
void MenuComponent::OnPlayerMoneyUpdate(uint32_t newMoney){}
void MenuComponent::OnPlayerMoneyUpdate(uint32_t newMoney){}
void MenuComponent::OnChapterUpdate(uint8_t newChapter){}

@ -151,4 +151,5 @@ public:
virtual void SetMouseOutFunc(std::function<bool(MenuFuncData)>func);
void SetGrayedOut(bool grayedOut);
virtual void OnPlayerMoneyUpdate(uint32_t newMoney);
virtual void OnChapterUpdate(uint8_t newChapter);
};

@ -53,6 +53,7 @@ enum class IconButtonAttr{
class MenuIconButton:public MenuComponent{
protected:
Decal*icon;
Pixel tint=WHITE;
public:
inline MenuIconButton(geom2d::rect<float>rect,Decal*icon,MenuFunc onClick,IconButtonAttr attributes=IconButtonAttr::SELECTABLE)
:MenuIconButton(rect,icon,MenuType::ENUM_END,onClick,attributes){}
@ -69,7 +70,7 @@ protected:
MenuComponent::DrawDecal(window,focused);
if(icon!=nullptr){
vf2d iconScale=rect.size/24.f;
window.DrawDecal(rect.middle()-icon->sprite->Size()*iconScale/2,icon,iconScale);
window.DrawDecal(rect.middle()-icon->sprite->Size()*iconScale/2,icon,iconScale,tint);
}
}
};

@ -54,6 +54,7 @@ private:
std::string itemDescriptionLabelName;
bool hideQty=false;
CompactText compact=COMPACT;
bool hideDetails=false;
public:
inline MenuItemItemButton(geom2d::rect<float>rect,const std::weak_ptr<Item>itemRef,MenuType menuDest,MenuFunc onClick,std::string itemNameLabelName,std::string itemDescriptionLabelName,IconButtonAttr attributes=IconButtonAttr::SELECTABLE)
:MenuIconButton(rect,!ISBLANK(itemRef)?const_cast<Decal*>(itemRef.lock()->Decal()):nullptr,menuDest,onClick,attributes),itemRef(itemRef),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName){
@ -74,6 +75,7 @@ public:
inline const std::weak_ptr<Item>SetItem(const std::weak_ptr<Item>newItem){
itemRef=newItem;
UpdateIcon();
UpdateLabel();
return itemRef;
}
inline void SetShowQuantity(bool show){
@ -90,6 +92,14 @@ public:
}
icon=const_cast<Decal*>(itemRef.lock()->Decal());
}
inline void SetHideDetails(bool hideDetails){
this->hideDetails=hideDetails;
if(hideDetails){
tint=BLACK;
}else{
tint=WHITE;
}
}
protected:
virtual inline void OnMouseOut()override{
if(itemNameLabelName!=""){
@ -116,6 +126,10 @@ protected:
icon=const_cast<Decal*>(itemRef.lock()->Decal());
labelNameText=itemRef.lock()->DisplayName();
labelDescriptionText=itemRef.lock()->Description(compact);
if(hideDetails){
std::for_each(labelNameText.begin(),labelNameText.end(),[](char&c){c='?';});
std::for_each(labelDescriptionText.begin(),labelDescriptionText.end(),[](char&c){c='?';});
}
if(itemNameLabelName!=""){
Component<MenuLabel>(parentMenu,itemNameLabelName)->label=labelNameText;
Component<MenuLabel>(parentMenu,itemNameLabelName)->Enable(true);

@ -42,6 +42,7 @@ All rights reserved.
class RowInventoryScrollableWindowComponent:public InventoryScrollableWindowComponent{
friend class InventoryCreator;
friend class Menu;
protected:
PriceLabel::PriceLabel priceLabel=PriceLabel::NONE;
public:

@ -52,20 +52,23 @@ namespace PriceLabel{
}
class RowItemDisplay:public MenuComponent{
std::weak_ptr<Item>itemRef;
std::string itemNameLabelName;
std::string itemDescriptionLabelName;
CompactText compact=NON_COMPACT;
bool showQuantity=true;
PriceLabel::PriceLabel priceLabel=PriceLabel::NONE;
bool fadeOutIfMissingRequirements=false;
bool hideLabelWhileLocked=false;
protected:
std::weak_ptr<Item>itemRef;
public:
inline RowItemDisplay(geom2d::rect<float>rect,const std::weak_ptr<Item>itemRef,MenuFunc onClick,std::string itemNameLabelName,std::string itemDescriptionLabelName,ButtonAttr attributes=ButtonAttr::NONE)
:MenuComponent(rect,"",onClick,attributes),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName),itemRef(itemRef){
if(itemRef.lock()->IsEquippable())SetShowQuantity(false);
}
virtual inline void DrawDecal(ViewPort&window,bool focused)final{
virtual inline void DrawDecal(ViewPort&window,bool focused)override{
bool canEnhance=itemRef.lock()->CanEnhanceItem();
bool locked=itemRef.lock()->EnhancementIsPossible()&&itemRef.lock()->GetEnhancementInfo().AvailableChapter()>game->GetCurrentChapter();
MenuComponent::DrawDecal(window,focused);
@ -77,17 +80,24 @@ public:
float scaleFactor=(rect.size.y-4)/24;
vf2d iconSize=vf2d{scaleFactor,scaleFactor}*24.f;
window.DrawDecal(rect.pos+vf2d{2,2},const_cast<Decal*>(itemRef.lock()->Decal()),{scaleFactor,scaleFactor});
Pixel tint=WHITE;
if(locked)tint=BLACK;
window.DrawDecal(rect.pos+vf2d{2,2},const_cast<Decal*>(itemRef.lock()->Decal()),{scaleFactor,scaleFactor},tint);
window.DrawRectDecal(rect.pos+vf2d{2,2},iconSize);
std::string itemName=itemRef.lock()->DisplayName();
vf2d scaledSize={std::min(1.f,(rect.size.x-6-iconSize.x)/game->GetTextSizeProp(itemName).x),1};
#pragma region Item Name Display
std::string itemName=itemRef.lock()->DisplayName();
vf2d scaledSize={std::min(1.f,(rect.size.x-6-iconSize.x)/game->GetTextSizeProp(itemName).x),1};
if(!canEnhance&&fadeOutIfMissingRequirements){
itemName="#666666"+itemName;
}
if(!canEnhance&&fadeOutIfMissingRequirements){
itemName="#666666"+itemName;
}
if(locked&&hideLabelWhileLocked)std::for_each(itemName.begin(),itemName.end(),[](char&c){if(c>='0'&&c<='z'){c='?';}});
window.DrawShadowStringPropDecal(rect.pos+vf2d{4,4}+vf2d{iconSize.x,iconSize.y/2-4},itemName,WHITE,BLACK,scaledSize);
window.DrawShadowStringPropDecal(rect.pos+vf2d{4,4}+vf2d{iconSize.x,iconSize.y/2-4},itemName,WHITE,BLACK,scaledSize);
#pragma endregion
if(showQuantity&&itemRef.lock()->Amt()!=INFINITE){
std::string quantityText=std::format("x{}",itemRef.lock()->Amt());
@ -161,6 +171,10 @@ public:
labelNameText="";
labelDescriptionText="";
}
if(hideLabelWhileLocked&&itemRef.lock()->EnhancementIsPossible()&&itemRef.lock()->GetEnhancementInfo().AvailableChapter()>game->GetCurrentChapter()){
std::for_each(labelNameText.begin(),labelNameText.end(),[](char&c){if(c>='0'&&c<='z'){c='?';}});
std::for_each(labelDescriptionText.begin(),labelDescriptionText.end(),[](char&c){if(c>='0'&&c<='z'){c='?';}});
}
if(itemNameLabelName!=""){
Component<MenuLabel>(parentMenu,itemNameLabelName)->label=labelNameText;
Component<MenuLabel>(parentMenu,itemNameLabelName)->Enable(true);
@ -179,4 +193,7 @@ public:
inline void SetCheckCraftingRequirements(bool check){
this->fadeOutIfMissingRequirements=check;
}
inline void SetHideLabelWhileLocked(bool hideWhileLocked){
hideLabelWhileLocked=hideWhileLocked;
}
};

@ -99,6 +99,9 @@ void State_OverworldMap::OnUserUpdate(Crawler*game){
if(game->GetKey(B).bPressed){
Menu::OpenMenu(BLACKSMITH);
}
if(game->GetKey(C).bPressed){
Menu::OpenMenu(CRAFT_CONSUMABLE);
}
#pragma region Handle Connection Point Clicking and Movement
for(ConnectionPoint&cp:connections){

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 0
#define VERSION_MINOR 2
#define VERSION_PATCH 1
#define VERSION_BUILD 5036
#define VERSION_BUILD 5056
#define stringify(a) stringify_(a)
#define stringify_(a) #a

@ -86,7 +86,7 @@ ItemDatabase
Crafting
{
# When this crafting recipe is available.
AvailableChapter = 1
AvailableChapter = 2
Item[0] = Bear Claw,1
Item[1] = Bear Blood,1

Loading…
Cancel
Save