Implement Crafting requirements display on equipment crafting window. Add in crafting requirement sample data for non-equipment items.

pull/28/head
sigonasr2 1 year ago
parent 3410b5b92b
commit 8f41870b46
  1. 8
      Crawler/BlacksmithCraftingWindow.cpp
  2. 2
      Crawler/CharacterMenuWindow.cpp
  3. 3
      Crawler/Crawler.cpp
  4. 12
      Crawler/InventoryCreator.cpp
  5. 4
      Crawler/InventoryCreator.h
  6. 5
      Crawler/InventoryScrollableWindowComponent.h
  7. 4
      Crawler/InventoryWindow.cpp
  8. 54
      Crawler/Item.cpp
  9. 5
      Crawler/Item.h
  10. 5
      Crawler/MenuItemButton.h
  11. 4
      Crawler/MenuItemItemButton.h
  12. 6
      Crawler/MerchantWindow.cpp
  13. 5
      Crawler/RowInventoryScrollableWindowComponent.h
  14. 21
      Crawler/RowItemDisplay.h
  15. 2
      Crawler/Version.h
  16. 6
      Crawler/assets/config/items/ItemDatabase.txt

@ -93,24 +93,31 @@ void Menu::InitializeBlacksmithCraftingWindow(){
return true;
},
[](MenuFuncData data){
RowItemDisplay*rowItem=DYNAMIC_CAST<RowItemDisplay*>(data.component);
Component<MenuItemItemButton>(BLACKSMITH,"Item Icon")->SetItem(rowItem->GetItem());
return true;
},
[](MenuFuncData data){
Component<MenuItemItemButton>(BLACKSMITH,"Item Icon")->SetItem(Item::BLANK);
return true;
},
InventoryCreator::RowPlayerWeapons_InventoryUpdate,
{.padding=1,.size={207,28}}
)END;
AddInventoryListener(weaponsDisplay,"Equipment");
weaponsDisplay->SetCompactDescriptions(CRAFTING_INFO);
auto armorDisplay=blacksmithWindow->ADD("Armor Inventory Display",RowInventoryScrollableWindowComponent)({{2,28},{220,blacksmithWindow->size.y-44}},"Item Name Label","Item Description Label",
[](MenuFuncData data){
return true;
},
[](MenuFuncData data){
RowItemDisplay*rowItem=DYNAMIC_CAST<RowItemDisplay*>(data.component);
Component<MenuItemItemButton>(BLACKSMITH,"Item Icon")->SetItem(rowItem->GetItem());
return true;
},
[](MenuFuncData data){
Component<MenuItemItemButton>(BLACKSMITH,"Item Icon")->SetItem(Item::BLANK);
return true;
},
InventoryCreator::RowPlayerArmor_InventoryUpdate,
@ -118,6 +125,7 @@ void Menu::InitializeBlacksmithCraftingWindow(){
)END;
AddInventoryListener(armorDisplay,"Equipment");
armorDisplay->Enable(false);
armorDisplay->SetCompactDescriptions(CRAFTING_INFO);
#pragma region Inventory Description
float inventoryDescriptionWidth=blacksmithWindow->pos.x+blacksmithWindow->size.x-26-224;

@ -204,7 +204,7 @@ void Menu::InitializeCharacterMenuWindow(){
if(Inventory::GetEquip(slot)==itemInvRef){
equip->SetSelected(true);
}
equip->SetCompactDescriptions(false);
equip->SetCompactDescriptions(NON_COMPACT);
counter++;
}

@ -2371,7 +2371,6 @@ void Crawler::SetLoadoutItem(int slot,std::string itemName){
};
game->GetPlayer()->SetItem1UseFunc(itemAbility);
Component<MenuItemItemButton>(MenuType::ITEM_LOADOUT,"Loadout Item 1")->SetItem(loadout[slot]);
Component<MenuItemItemButton>(MenuType::ITEM_LOADOUT,"Loadout Item 1")->UpdateIcon();
}break;
case 1:{
itemAbility.action=[&](Player*p,vf2d pos={}){
@ -2379,7 +2378,6 @@ void Crawler::SetLoadoutItem(int slot,std::string itemName){
};
game->GetPlayer()->SetItem2UseFunc(itemAbility);
Component<MenuItemItemButton>(MenuType::ITEM_LOADOUT,"Loadout Item 2")->SetItem(loadout[slot]);
Component<MenuItemItemButton>(MenuType::ITEM_LOADOUT,"Loadout Item 2")->UpdateIcon();
}break;
case 2:{
itemAbility.action=[&](Player*p,vf2d pos={}){
@ -2387,7 +2385,6 @@ void Crawler::SetLoadoutItem(int slot,std::string itemName){
};
game->GetPlayer()->SetItem3UseFunc(itemAbility);
Component<MenuItemItemButton>(MenuType::ITEM_LOADOUT,"Loadout Item 3")->SetItem(loadout[slot]);
Component<MenuItemItemButton>(MenuType::ITEM_LOADOUT,"Loadout Item 3")->UpdateIcon();
}break;
}

@ -73,7 +73,7 @@ std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)>
int totalSpacing=component.options.padding+buttonSize.x;
component.ADD("item_"+cat+"_"+std::to_string(itemIndex),MenuItemButton)({{float(totalSpacing*x),float(totalSpacing*y)},buttonSize},Inventory::get(cat),itemIndex,component.inventoryButtonClickAction,component.inventoryButtonHoverAction,component.inventoryButtonMouseOutAction,component.parentMenu,component.itemNameLabelName,component.itemDescriptionLabelName,component.inventoryButtonsActive?IconButtonAttr::SELECTABLE:IconButtonAttr::NOT_SELECTABLE)END
->SetCompactDescriptions(component.compact==COMPACT);
->SetCompactDescriptions(component.compact);
};
#pragma endregion
@ -92,7 +92,7 @@ std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)>
vf2d totalSpacing={c->options.padding+buttonSize.x,c->options.padding+buttonSize.y};
auto newItem=c->ADD("item_"+cat+"_"+std::to_string(itemIndex),RowItemDisplay)({totalSpacing*vf2d{float(x),float(y)},buttonSize},Inventory::GetInventorySlot(cat,itemIndex),c->inventoryButtonClickAction,c->itemNameLabelName,c->itemDescriptionLabelName,c->inventoryButtonsActive?ButtonAttr::NONE:ButtonAttr::UNSELECTABLE)END;
newItem->SetCompactDescriptions(c->compact==COMPACT);
newItem->SetCompactDescriptions(c->compact);
newItem->SetPriceLabelType(c->priceLabel);
newItem->SetHoverFunc(c->inventoryButtonHoverAction);
newItem->SetMouseOutFunc(c->inventoryButtonMouseOutAction);
@ -129,7 +129,7 @@ std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)>
vf2d totalSpacing={c->options.padding+buttonSize.x,c->options.padding+buttonSize.y};
auto newItem=c->ADD("merchant_item_"+cat+"_"+std::to_string(itemIndex),RowItemDisplay)({totalSpacing*vf2d{float(x),float(y)},buttonSize},Merchant::GetCurrentTravelingMerchant().GetShopItems()[itemIndex],c->inventoryButtonClickAction,c->itemNameLabelName,c->itemDescriptionLabelName,c->inventoryButtonsActive?ButtonAttr::NONE:ButtonAttr::UNSELECTABLE)END;
newItem->SetCompactDescriptions(c->compact==COMPACT);
newItem->SetCompactDescriptions(c->compact);
newItem->SetPriceLabelType(c->priceLabel);
newItem->SetHoverFunc(c->inventoryButtonHoverAction);
newItem->SetMouseOutFunc(c->inventoryButtonMouseOutAction);
@ -161,10 +161,11 @@ std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)>
int y=int((invSize-1)/invWidth);
int itemIndex=y*invWidth+x;
auto newItem=c->ADD("item_Weapon_"+std::to_string(itemIndex),RowItemDisplay)({totalSpacing*vf2d{float(x),float(y)},buttonSize},weapon,c->inventoryButtonClickAction,c->itemNameLabelName,c->itemDescriptionLabelName,c->inventoryButtonsActive?ButtonAttr::NONE:ButtonAttr::UNSELECTABLE)END;
newItem->SetCompactDescriptions(c->compact==COMPACT);
newItem->SetCompactDescriptions(c->compact);
newItem->SetPriceLabelType(c->priceLabel);
newItem->SetHoverFunc(c->inventoryButtonHoverAction);
newItem->SetMouseOutFunc(c->inventoryButtonMouseOutAction);
newItem->SetCheckCraftingRequirements(true);
}
};
#pragma endregion
@ -194,10 +195,11 @@ std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)>
int y=int((invSize-1)/invWidth);
int itemIndex=y*invWidth+x;
auto newItem=c->ADD("item_Armor_"+std::to_string(itemIndex),RowItemDisplay)({totalSpacing*vf2d{float(x),float(y)},buttonSize},armor,c->inventoryButtonClickAction,c->itemNameLabelName,c->itemDescriptionLabelName,c->inventoryButtonsActive?ButtonAttr::NONE:ButtonAttr::UNSELECTABLE)END;
newItem->SetCompactDescriptions(c->compact==COMPACT);
newItem->SetCompactDescriptions(c->compact);
newItem->SetPriceLabelType(c->priceLabel);
newItem->SetHoverFunc(c->inventoryButtonHoverAction);
newItem->SetMouseOutFunc(c->inventoryButtonMouseOutAction);
newItem->SetCheckCraftingRequirements(true);
}
};
#pragma endregion

@ -62,4 +62,6 @@ public:
std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)>*const InventorySlotsUpdate,
std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)>*const AddButtonOnSlotUpdate)
:InventorySlotsUpdate(InventorySlotsUpdate),AddButtonOnSlotUpdate(AddButtonOnSlotUpdate){};
};
};
#undef _SETUP

@ -91,9 +91,8 @@ public:
if(itemDescriptionLabelName.length()>0)Component<MenuLabel>(parentMenu,itemDescriptionLabelName)->SetLabel("");
}
}
virtual inline void SetCompactDescriptions(bool compact){
if(compact)this->compact=COMPACT;
else this->compact=NON_COMPACT;
virtual inline void SetCompactDescriptions(CompactText compact){
this->compact=compact;
for(MenuComponent*component:components){
MenuItemButton*itemButton=DYNAMIC_CAST<MenuItemButton*>(component);
itemButton->SetCompactDescriptions(compact);

@ -91,12 +91,10 @@ void Menu::InitializeInventoryWindow(){
auto inventoryDisplay=inventoryWindow->ADD("Inventory Display - "+category,RowInventoryScrollableWindowComponent)({{72,28},{150,inventoryWindow->size.y-44}},"Item Name Label","Item Description Label",DO_NOTHING,
[](MenuFuncData data){
Component<MenuItemItemButton>(data.menu.GetType(),"Item Icon")->SetItem(DYNAMIC_CAST<RowItemDisplay*>(data.component)->GetItem());
Component<MenuItemItemButton>(data.menu.GetType(),"Item Icon")->UpdateIcon();
return true;
},
[](MenuFuncData data){
Component<MenuItemItemButton>(data.menu.GetType(),"Item Icon")->SetItem(Item::BLANK);
Component<MenuItemItemButton>(data.menu.GetType(),"Item Icon")->UpdateIcon();
return true;
},
InventoryCreator::RowPlayer_InventoryUpdate,
@ -109,7 +107,7 @@ void Menu::InitializeInventoryWindow(){
Menu::AddInventoryListener(inventoryDisplay,category);
inventoryDisplay->Enable(first);
inventoryDisplay->SetCompactDescriptions(false);
inventoryDisplay->SetCompactDescriptions(NON_COMPACT);
yOffset+=20;
first=false;

@ -162,6 +162,15 @@ void ItemInfo::InitializeItems(){
itemsRequired.push_back(Item(item.GetInt(1),item.GetString(0)));
}
goldCost=data[key]["Crafting"][std::format("Level[{}]",enhancementLevel)]["Gold"].GetInt();
}else
if(data[key].HasProperty("Crafting")&&!data[key]["Crafting"].HasProperty("Level[1]")){
//If the item has a key called "Crafting" but did not specify a level number, then we assume this item just has one base level for normal crafting and thus we will add the requirements to craft this item under enhancement level 1.
while(data[key]["Crafting"].HasProperty(std::format("Item[{}]",itemsRequired.size()))){
datafile&item=data[key]["Crafting"][std::format("Item[{}]",itemsRequired.size())];
itemsRequired.push_back(Item(item.GetInt(1),item.GetString(0)));
}
goldCost=data[key]["Crafting"]["Gold"].GetInt();
enhancementLevel=1;
}
enhancementStats.SetCraftingRequirements(enhancementLevel,itemsRequired,goldCost);
}
@ -520,34 +529,51 @@ 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 Item&itemRequirement:info.craftingRequirement.GetItems()){
description+=std::format("{}{} x{} ({})\n",
Inventory::GetItemCount(itemRequirement.ActualName())<itemRequirement.Amt()?"#FF0000":"#FFFFFF",
itemRequirement.DisplayName(),
itemRequirement.Amt(),
Inventory::GetItemCount(itemRequirement.ActualName()));
}
description+="\n";
description+=std::format("{}Crafting Cost: {}",
game->GetPlayer()->GetMoney()<info.craftingRequirement.GetCost()?"#FF0000":"#FFFFFF",
info.craftingRequirement.GetCost());
}
}
}
return description;
};
}
const ITCategory Item::Category()const{
return it->Category();
};
}
const::Decal*const Item::Decal()const{
return it->Decal();
};
}
const ItemScript&Item::OnUseAction()const{
return it->OnUseAction();
};
}
const std::string&ItemInfo::Name()const{
return name;
};
}
const std::string&ItemInfo::Description()const{
return description;
};
}
const ITCategory ItemInfo::Category()const{
return category;
};
}
const::Decal*const ItemInfo::Decal()const{
return img;
};
}
const ItemScript&ItemInfo::OnUseAction()const{
return ITEM_SCRIPTS.at(useFunc);
};
}
const bool Item::IsBlank()const{
if(Item::IsBlankStaticCallCounter!=1)ERR("WARNING! You should not call the IsBlank() function directly! Use ISBLANK() macro instead!")
@ -899,7 +925,7 @@ const EnhancementInfo&Item::GetEnhancementInfo()const{
}
const bool EnhancementInfo::CanBeEnhanced()const{
return enhancementStats.size()=="Item.Item Max Enhancement Level"_I+1&&craftingRequirements.size()=="Item.Item Max Enhancement Level"_I+1;
return enhancementStats.size()>0&&craftingRequirements.size()>0;
};
@ -921,4 +947,12 @@ const bool Item::IsArmor()const{
}
const bool Item::IsAccessory()const{
return it->IsAccessory();
}
const bool Item::IsCraftable()const{
return it->IsCraftable();
}
const bool ItemInfo::IsCraftable()const{
return GetEnhancementInfo().CanBeEnhanced();
}

@ -71,7 +71,8 @@ enum class EquipSlot{
enum class CompactText{
COMPACT,
NON_COMPACT
NON_COMPACT,
CRAFTING_INFO
};
using enum CompactText;
@ -185,6 +186,7 @@ public:
static std::shared_ptr<Item>BLANK;
const std::optional<const::ItemSet*const>ItemSet()const;
const bool IsEquippable()const;
const bool IsCraftable()const;
const bool IsWeapon()const;
const bool IsArmor()const;
const bool IsAccessory()const;
@ -303,6 +305,7 @@ public:
const bool UseDuringCast()const;
const EnhancementInfo&GetEnhancementInfo()const;
const bool IsEquippable()const;
const bool IsCraftable()const;
const bool IsWeapon()const;
const bool IsArmor()const;
const bool IsAccessory()const;

@ -81,9 +81,8 @@ public:
if(invRef.size()<=inventoryIndex)return false;
return Inventory::UseItem(invRef.at(inventoryIndex)->ActualName(),amt);
}
inline void SetCompactDescriptions(bool compact){
if(compact)this->compact=COMPACT;
else this->compact=NON_COMPACT;
inline void SetCompactDescriptions(CompactText compact){
this->compact=compact;
}
inline virtual void Update(Crawler*game)override{
MenuIconButton::Update(game);

@ -72,7 +72,9 @@ public:
return itemRef;
}
inline const std::weak_ptr<Item>SetItem(const std::weak_ptr<Item>newItem){
return itemRef=newItem;
itemRef=newItem;
UpdateIcon();
return itemRef;
}
inline void SetShowQuantity(bool show){
this->hideQty=!show;

@ -111,12 +111,10 @@ void Menu::InitializeMerchantWindow(){
},
[](MenuFuncData data){
Component<MenuItemItemButton>(data.menu.GetType(),"Item Icon")->SetItem(DYNAMIC_CAST<RowItemDisplay*>(data.component)->GetItem());
Component<MenuItemItemButton>(data.menu.GetType(),"Item Icon")->UpdateIcon();
return true;
},
[](MenuFuncData data){
Component<MenuItemItemButton>(data.menu.GetType(),"Item Icon")->SetItem(Item::BLANK);
Component<MenuItemItemButton>(data.menu.GetType(),"Item Icon")->UpdateIcon();
return true;
},
InventoryCreator::RowMerchant_InventoryUpdate,
@ -173,12 +171,10 @@ void Menu::InitializeMerchantWindow(){
},
[](MenuFuncData data){
Component<MenuItemItemButton>(data.menu.GetType(),"Item Icon")->SetItem(DYNAMIC_CAST<RowItemDisplay*>(data.component)->GetItem());
Component<MenuItemItemButton>(data.menu.GetType(),"Item Icon")->UpdateIcon();
return true;
},
[](MenuFuncData data){
Component<MenuItemItemButton>(data.menu.GetType(),"Item Icon")->SetItem(Item::BLANK);
Component<MenuItemItemButton>(data.menu.GetType(),"Item Icon")->UpdateIcon();
return true;
},
InventoryCreator::RowPlayer_InventoryUpdate,
@ -192,7 +188,7 @@ void Menu::InitializeMerchantWindow(){
Menu::AddInventoryListener(inventoryDisplay,category);
inventoryDisplay->Enable(first);
inventoryDisplay->SetCompactDescriptions(false);
inventoryDisplay->SetCompactDescriptions(NON_COMPACT);
yOffset+=20;
first=false;

@ -48,9 +48,8 @@ public:
inline RowInventoryScrollableWindowComponent(geom2d::rect<float>rect,std::string itemNameLabelName,std::string itemDescriptionLabelName,std::function<bool(MenuFuncData)>inventoryButtonClickAction,std::function<bool(MenuFuncData)>inventoryButtonHoverAction,std::function<bool(MenuFuncData)>inventoryButtonMouseOutAction,const InventoryCreator&creator,InventoryWindowOptions options={.padding=8,.size={24,24}},bool inventoryButtonsActive=true,ComponentAttr attributes=ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE)
:InventoryScrollableWindowComponent(rect,itemNameLabelName,itemDescriptionLabelName,inventoryButtonClickAction,inventoryButtonHoverAction,inventoryButtonMouseOutAction,creator,options,inventoryButtonsActive,attributes){}
virtual inline void SetCompactDescriptions(bool compact)override final{
if(compact)this->compact=COMPACT;
else this->compact=NON_COMPACT;
virtual inline void SetCompactDescriptions(CompactText compact)override final{
this->compact=compact;
for(MenuComponent*component:components){
RowItemDisplay*itemButton=DYNAMIC_CAST<RowItemDisplay*>(component);
itemButton->SetCompactDescriptions(compact);

@ -58,20 +58,33 @@ class RowItemDisplay:public MenuComponent{
CompactText compact=NON_COMPACT;
bool showQuantity=true;
PriceLabel::PriceLabel priceLabel=PriceLabel::NONE;
bool fadeOutIfMissingRequirements=false;
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{
bool canEnhance=itemRef.lock()->CanEnhanceItem();
MenuComponent::DrawDecal(window,focused);
if(!canEnhance&&fadeOutIfMissingRequirements){
window.FillRectDecal(rect.pos+vf2d{1,1},rect.size-vf2d{1,1},VERY_DARK_GREY);
}
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});
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};
if(!canEnhance&&fadeOutIfMissingRequirements){
itemName="#666666"+itemName;
}
window.DrawShadowStringPropDecal(rect.pos+vf2d{4,4}+vf2d{iconSize.x,iconSize.y/2-4},itemName,WHITE,BLACK,scaledSize);
@ -116,9 +129,8 @@ public:
UpdateLabel();
}
}
inline void SetCompactDescriptions(bool compact){
if(compact)this->compact=COMPACT;
else this->compact=NON_COMPACT;
inline void SetCompactDescriptions(CompactText compact){
this->compact=compact;
}
virtual inline void OnMouseOut()override{
if(itemNameLabelName!=""){
@ -163,4 +175,7 @@ public:
inline void SetPriceLabelType(PriceLabel::PriceLabel labelType){
this->priceLabel=labelType;
}
inline void SetCheckCraftingRequirements(bool check){
this->fadeOutIfMissingRequirements=check;
}
};

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

@ -10,6 +10,12 @@ ItemDatabase
Cooldown Time = 5.0
Cast Time = 0.0
SellValue = 8
Crafting
{
Item[0] = Green Slime Remains,2
Gold = 8
}
}
Minor Health Potion
{

Loading…
Cancel
Save