Fixed menu label updates for row item displays. Added a row scrollable inventory window component. Made InventoryScrollableWindowComponent more modular with a couple overrideable functions.

pull/28/head
sigonasr2 12 months ago
parent e656dc95b2
commit 57377823c5
  1. 4
      Crawler/Crawler.cpp
  2. 4
      Crawler/Crawler.vcxproj
  3. 3
      Crawler/Crawler.vcxproj.filters
  4. 2
      Crawler/InventoryConsumableWindow.cpp
  5. 67
      Crawler/InventoryScrollableWindowComponent.h
  6. 13
      Crawler/InventoryWindow.cpp
  7. 5
      Crawler/Item.cpp
  8. 2
      Crawler/Item.h
  9. 16
      Crawler/MenuItemItemButton.h
  10. 87
      Crawler/RowInventoryScrollableWindowComponent.h
  11. 37
      Crawler/RowItemDisplay.h
  12. 2
      Crawler/Version.h

@ -65,6 +65,7 @@ All rights reserved.
#include "VisualNovel.h" #include "VisualNovel.h"
#include "util.h" #include "util.h"
#include "olcPGEX_TTF.h" #include "olcPGEX_TTF.h"
#include "MenuItemItemButton.h"
INCLUDE_EMITTER_LIST INCLUDE_EMITTER_LIST
@ -2222,18 +2223,21 @@ void Crawler::SetLoadoutItem(int slot,std::string itemName){
return itemUsed; return itemUsed;
}; };
game->GetPlayer()->SetItem1UseFunc(itemAbility); game->GetPlayer()->SetItem1UseFunc(itemAbility);
Component<MenuItemItemButton>(MenuType::ITEM_LOADOUT,"Loadout Item 1")->UpdateIcon();
}break; }break;
case 1:{ case 1:{
itemAbility.action=[&](Player*p,vf2d pos={}){ itemAbility.action=[&](Player*p,vf2d pos={}){
return game->UseLoadoutItem(1); return game->UseLoadoutItem(1);
}; };
game->GetPlayer()->SetItem2UseFunc(itemAbility); game->GetPlayer()->SetItem2UseFunc(itemAbility);
Component<MenuItemItemButton>(MenuType::ITEM_LOADOUT,"Loadout Item 2")->UpdateIcon();
}break; }break;
case 2:{ case 2:{
itemAbility.action=[&](Player*p,vf2d pos={}){ itemAbility.action=[&](Player*p,vf2d pos={}){
return game->UseLoadoutItem(2); return game->UseLoadoutItem(2);
}; };
game->GetPlayer()->SetItem3UseFunc(itemAbility); game->GetPlayer()->SetItem3UseFunc(itemAbility);
Component<MenuItemItemButton>(MenuType::ITEM_LOADOUT,"Loadout Item 3")->UpdateIcon();
}break; }break;
} }

@ -366,6 +366,10 @@
</ClInclude> </ClInclude>
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />
<ClInclude Include="resource1.h" /> <ClInclude Include="resource1.h" />
<ClInclude Include="RowInventoryScrollableWindowComponent.h">
<SubType>
</SubType>
</ClInclude>
<ClInclude Include="RowItemDisplay.h"> <ClInclude Include="RowItemDisplay.h">
<SubType> <SubType>
</SubType> </SubType>

@ -303,6 +303,9 @@
<ClInclude Include="RowItemDisplay.h"> <ClInclude Include="RowItemDisplay.h">
<Filter>Header Files\Interface</Filter> <Filter>Header Files\Interface</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="RowInventoryScrollableWindowComponent.h">
<Filter>Header Files\Interface</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="Player.cpp"> <ClCompile Include="Player.cpp">

@ -62,7 +62,7 @@ void Menu::InitializeConsumableInventoryWindow(){
for(MenuComponent*component:data.parentComponent->GetComponents()){ //HACK ALERT! If we are accessing a parent component, it's because we are dealing with a scrolling window component, which has sub-components. So this should be a safe cast to make. for(MenuComponent*component:data.parentComponent->GetComponents()){ //HACK ALERT! If we are accessing a parent component, it's because we are dealing with a scrolling window component, which has sub-components. So this should be a safe cast to make.
if(component->GetName().starts_with("item")){ if(component->GetName().starts_with("item")){
MenuItemButton*button2=dynamic_cast<MenuItemButton*>(component);//HACK ALERT! This is probably an item since we populated item lists using this name for the components. So we assume these are MenuItemButton classes. MenuItemButton*button2=dynamic_cast<MenuItemButton*>(component);//HACK ALERT! This is probably an item since we populated item lists using this name for the components. So we assume these are MenuItemButton classes.
if(button2==nullptr)continue; if(button2==nullptr)ERR("Could not cast item to a MenuItemButton*!");
if(button2==button){ if(button2==button){
if(button2->selected!=-1){ if(button2->selected!=-1){
data.game->ClearLoadoutItem(button2->selected); data.game->ClearLoadoutItem(button2->selected);

@ -46,34 +46,35 @@ using A=Attribute;
struct InventoryWindowOptions{ struct InventoryWindowOptions{
int padding=8; int padding=8;
int size=24; vf2d size={24,24};
}; };
//This class can easily be derived with different component types by overriding non-final virtual functions in this class.
//Functions currently include:
// virtual inline void AddButtonOnSlotUpdate(ITCategory cat)
// virtual inline void SetCompactDescriptions(bool compact)
//
// Please ensure these are overwritten, otherwise you will get errors complaining about dynamic casts unable to convert classes successfully.
class InventoryScrollableWindowComponent:public ScrollableWindowComponent{ class InventoryScrollableWindowComponent:public ScrollableWindowComponent{
private: protected:
std::string itemNameLabelName; ITCategory inventoryType;
std::string itemDescriptionLabelName;
bool inventoryButtonsActive=true;
std::function<bool(MenuFuncData)>inventoryButtonClickAction; std::function<bool(MenuFuncData)>inventoryButtonClickAction;
std::function<bool(MenuFuncData)>inventoryButtonHoverAction; std::function<bool(MenuFuncData)>inventoryButtonHoverAction;
std::function<bool(MenuFuncData)>inventoryButtonMouseOutAction; std::function<bool(MenuFuncData)>inventoryButtonMouseOutAction;
InventoryWindowOptions options;
CompactText compact=COMPACT; CompactText compact=COMPACT;
protected: InventoryWindowOptions options;
ITCategory inventoryType; std::string itemNameLabelName;
std::string itemDescriptionLabelName;
bool inventoryButtonsActive=true;
public: public:
inline InventoryScrollableWindowComponent(geom2d::rect<float>rect,ITCategory invType,std::string itemNameLabelName,std::string itemDescriptionLabelName,std::function<bool(MenuFuncData)>inventoryButtonClickAction,InventoryWindowOptions options={.padding=8,.size=24},bool inventoryButtonsActive=true,ComponentAttr attributes=ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE) inline InventoryScrollableWindowComponent(geom2d::rect<float>rect,ITCategory invType,std::string itemNameLabelName,std::string itemDescriptionLabelName,std::function<bool(MenuFuncData)>inventoryButtonClickAction,InventoryWindowOptions options={.padding=8,.size={24,24}},bool inventoryButtonsActive=true,ComponentAttr attributes=ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE)
:ScrollableWindowComponent(rect,attributes),inventoryType(invType),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName), :InventoryScrollableWindowComponent(rect,invType,itemNameLabelName,itemDescriptionLabelName,inventoryButtonClickAction,DO_NOTHING,DO_NOTHING,options,inventoryButtonsActive,attributes){
}
inline InventoryScrollableWindowComponent(geom2d::rect<float>rect,ITCategory invType,std::string itemNameLabelName,std::string itemDescriptionLabelName,std::function<bool(MenuFuncData)>inventoryButtonClickAction,std::function<bool(MenuFuncData)>inventoryButtonHoverAction,std::function<bool(MenuFuncData)>inventoryButtonMouseOutAction,InventoryWindowOptions options={.padding=8,.size={24,24}},bool inventoryButtonsActive=true,ComponentAttr attributes=ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE)
:ScrollableWindowComponent(rect,attributes),inventoryButtonHoverAction(inventoryButtonHoverAction),inventoryButtonMouseOutAction(inventoryButtonMouseOutAction),inventoryType(invType),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName),
options(options),inventoryButtonClickAction(inventoryButtonClickAction),inventoryButtonsActive(inventoryButtonsActive){ options(options),inventoryButtonClickAction(inventoryButtonClickAction),inventoryButtonsActive(inventoryButtonsActive){
this->inventoryButtonHoverAction=DO_NOTHING;
this->inventoryButtonMouseOutAction=DO_NOTHING;
Menu::AddInventoryListener(this,invType); Menu::AddInventoryListener(this,invType);
} }
inline InventoryScrollableWindowComponent(geom2d::rect<float>rect,ITCategory invType,std::string itemNameLabelName,std::string itemDescriptionLabelName,std::function<bool(MenuFuncData)>inventoryButtonClickAction,std::function<bool(MenuFuncData)>inventoryButtonHoverAction,std::function<bool(MenuFuncData)>inventoryButtonMouseOutAction,InventoryWindowOptions options={.padding=8,.size=24},bool inventoryButtonsActive=true,ComponentAttr attributes=ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE)
:InventoryScrollableWindowComponent(rect,invType,itemNameLabelName,itemDescriptionLabelName,inventoryButtonClickAction,options,inventoryButtonsActive,attributes){
this->inventoryButtonHoverAction=inventoryButtonHoverAction;
this->inventoryButtonMouseOutAction=inventoryButtonMouseOutAction;
}
virtual inline void Update(Crawler*game)override{ virtual inline void Update(Crawler*game)override{
ScrollableWindowComponent::Update(game); ScrollableWindowComponent::Update(game);
bool noneHovered=true; bool noneHovered=true;
@ -88,7 +89,7 @@ public:
if(itemDescriptionLabelName.length()>0)Component<MenuLabel>(parentMenu,itemDescriptionLabelName)->SetLabel(""); if(itemDescriptionLabelName.length()>0)Component<MenuLabel>(parentMenu,itemDescriptionLabelName)->SetLabel("");
} }
} }
inline void SetCompactDescriptions(bool compact){ virtual inline void SetCompactDescriptions(bool compact){
if(compact)this->compact=COMPACT; if(compact)this->compact=COMPACT;
else this->compact=NON_COMPACT; else this->compact=NON_COMPACT;
for(MenuComponent*component:components){ for(MenuComponent*component:components){
@ -121,26 +122,32 @@ protected:
} }
CalculateBounds(); //Recalculate the bounds as it's possible the width/height of the component has changed. CalculateBounds(); //Recalculate the bounds as it's possible the width/height of the component has changed.
} }
virtual inline void OnInventorySlotsUpdate(ITCategory cat)override{ virtual inline void OnInventorySlotsUpdate(ITCategory cat)override final{
size_t invSize=Inventory::get(cat).size(); size_t invSize=Inventory::get(cat).size();
//We only want to refresh the inventory slots if the component count no longer matches what's actually in our inventory. //We only want to refresh the inventory slots if the component count no longer matches what's actually in our inventory.
if(components.size()<invSize){//We need more space to display our items. if(components.size()<invSize){//We need more space to display our items.
int invWidth=int(rect.size.x/(float(options.size)+options.padding)); AddButtonOnSlotUpdate(cat);
int x=int((invSize-1)%invWidth);
int y=int((invSize-1)/invWidth);
int itemIndex=y*invWidth+x;
int buttonSize=options.size;
int totalSpacing=options.padding+buttonSize;
ADD("item_"+cat+"_"+std::to_string(itemIndex),MenuItemButton)({{float(totalSpacing*x),float(totalSpacing*y)},{float(buttonSize),float(buttonSize)}},Inventory::get(cat),itemIndex,inventoryButtonClickAction,inventoryButtonHoverAction,inventoryButtonMouseOutAction,parentMenu,itemNameLabelName,itemDescriptionLabelName,inventoryButtonsActive?IconButtonAttr::SELECTABLE:IconButtonAttr::NOT_SELECTABLE)END
->SetCompactDescriptions(compact==COMPACT);
}else }else
if(components.size()>invSize){ //There are empty spots, so let's clean up. if(components.size()>invSize){ //There are empty spots, so let's clean up.
RemoveEmptySlots(); RemoveEmptySlots();
} }
} }
virtual inline void Cleanup()override{
virtual inline void Cleanup()override final{
}
virtual inline void AddButtonOnSlotUpdate(ITCategory cat){
size_t invSize=Inventory::get(cat).size();
int invWidth=int(rect.size.x/(float(options.size.x)+options.padding));
int x=int((invSize-1)%invWidth);
int y=int((invSize-1)/invWidth);
int itemIndex=y*invWidth+x;
vf2d buttonSize=options.size;
int totalSpacing=options.padding+buttonSize.x;
ADD("item_"+cat+"_"+std::to_string(itemIndex),MenuItemButton)({{float(totalSpacing*x),float(totalSpacing*y)},buttonSize},Inventory::get(cat),itemIndex,inventoryButtonClickAction,inventoryButtonHoverAction,inventoryButtonMouseOutAction,parentMenu,itemNameLabelName,itemDescriptionLabelName,inventoryButtonsActive?IconButtonAttr::SELECTABLE:IconButtonAttr::NOT_SELECTABLE)END
->SetCompactDescriptions(compact==COMPACT);
} }
}; };

@ -39,10 +39,11 @@ All rights reserved.
#include "DEFINES.h" #include "DEFINES.h"
#include "Menu.h" #include "Menu.h"
#include "MenuLabel.h" #include "MenuLabel.h"
#include "InventoryScrollableWindowComponent.h" #include "RowInventoryScrollableWindowComponent.h"
#include "MenuIconButton.h" #include "MenuIconButton.h"
#include "MenuItemButton.h" #include "MenuItemButton.h"
#include "MenuItemItemButton.h" #include "MenuItemItemButton.h"
#include "RowItemDisplay.h"
INCLUDE_game INCLUDE_game
INCLUDE_ITEM_CATEGORIES INCLUDE_ITEM_CATEGORIES
@ -77,7 +78,7 @@ void Menu::InitializeInventoryWindow(){
auto button=inventoryWindow->ADD(category+" Inventory Tab",MenuComponent)({{2,30+yOffset},{68,16}},category,MenuType::ENUM_END, auto button=inventoryWindow->ADD(category+" Inventory Tab",MenuComponent)({{2,30+yOffset},{68,16}},category,MenuType::ENUM_END,
[&](MenuFuncData data){ [&](MenuFuncData data){
//Close the old inventory window and show the proper one. //Close the old inventory window and show the proper one.
Component<InventoryScrollableWindowComponent>(data.menu.GetType(),"Inventory Display - "+lastInventoryTypeOpened)->Enable(false); Component<RowInventoryScrollableWindowComponent>(data.menu.GetType(),"Inventory Display - "+lastInventoryTypeOpened)->Enable(false);
Component<MenuComponent>(data.menu.GetType(),lastInventoryTypeOpened+" Inventory Tab")->SetSelected(false); Component<MenuComponent>(data.menu.GetType(),lastInventoryTypeOpened+" Inventory Tab")->SetSelected(false);
Component<InventoryScrollableWindowComponent>(data.menu.GetType(),"Inventory Display - "+data.component->S(A::CATEGORY_NAME))->Enable(true); Component<InventoryScrollableWindowComponent>(data.menu.GetType(),"Inventory Display - "+data.component->S(A::CATEGORY_NAME))->Enable(true);
Component<MenuComponent>(data.menu.GetType(),data.component->S(A::CATEGORY_NAME)+" Inventory Tab")->SetSelected(true); Component<MenuComponent>(data.menu.GetType(),data.component->S(A::CATEGORY_NAME)+" Inventory Tab")->SetSelected(true);
@ -87,15 +88,17 @@ void Menu::InitializeInventoryWindow(){
button->SetSelectionType(HIGHLIGHT); button->SetSelectionType(HIGHLIGHT);
button->S(A::CATEGORY_NAME)=category; button->S(A::CATEGORY_NAME)=category;
auto inventoryDisplay=inventoryWindow->ADD("Inventory Display - "+category,InventoryScrollableWindowComponent)({{72,28},{150,inventoryWindow->size.y-44}},category,"Item Name Label","Item Description Label",DO_NOTHING, auto inventoryDisplay=inventoryWindow->ADD("Inventory Display - "+category,RowInventoryScrollableWindowComponent)({{72,28},{150,inventoryWindow->size.y-44}},category,"Item Name Label","Item Description Label",DO_NOTHING,
[](MenuFuncData data){ [](MenuFuncData data){
Component<MenuItemItemButton>(data.menu.GetType(),"Item Icon")->SetItem(dynamic_cast<MenuItemButton*>(data.component)->GetItem()); Component<MenuItemItemButton>(data.menu.GetType(),"Item Icon")->SetItem(dynamic_cast<RowItemDisplay*>(data.component)->GetItem());
Component<MenuItemItemButton>(data.menu.GetType(),"Item Icon")->UpdateIcon();
return true; return true;
}, },
[](MenuFuncData data){ [](MenuFuncData data){
Component<MenuItemItemButton>(data.menu.GetType(),"Item Icon")->SetItem(Item::BLANK); Component<MenuItemItemButton>(data.menu.GetType(),"Item Icon")->SetItem(Item::BLANK);
Component<MenuItemItemButton>(data.menu.GetType(),"Item Icon")->UpdateIcon();
return true; return true;
})END; },{.padding=1,.size={136,28}})END;
if(first){ if(first){
lastInventoryTypeOpened=category; lastInventoryTypeOpened=category;

@ -375,6 +375,7 @@ uint32_t Item::Amt(){
return amt; return amt;
}; };
std::string Item::Name(){ std::string Item::Name(){
if(IsBlank())return "";
std::string name=it->Name(); std::string name=it->Name();
if(IsEquippable()&&EnhancementLevel()>0){ if(IsEquippable()&&EnhancementLevel()>0){
name+=" [+"+std::to_string(EnhancementLevel())+"]"; name+=" [+"+std::to_string(EnhancementLevel())+"]";
@ -552,7 +553,9 @@ void Inventory::UnequipItem(EquipSlot slot){
EquipSlot Inventory::GetSlotEquippedIn(Item&it){ EquipSlot Inventory::GetSlotEquippedIn(Item&it){
for(int i=int(EquipSlot::HELMET);i<=int(EquipSlot::RING2);i<<=1){ for(int i=int(EquipSlot::HELMET);i<=int(EquipSlot::RING2);i<<=1){
EquipSlot slot=EquipSlot(i); EquipSlot slot=EquipSlot(i);
if(GetEquip(slot)==&it)return slot; Item*equip=GetEquip(slot);
if(equip==nullptr)continue;
if(equip->Name()==it.Name())return slot;
} }
return EquipSlot::NONE; return EquipSlot::NONE;
}; };

@ -134,7 +134,6 @@ private:
uint32_t amt; uint32_t amt;
uint8_t enhancementLevel; uint8_t enhancementLevel;
ItemInfo*it; ItemInfo*it;
bool IsEquippable()const;
public: public:
Item(); Item();
Item(uint32_t amt,IT item,uint8_t enhancementLevel=0); Item(uint32_t amt,IT item,uint8_t enhancementLevel=0);
@ -154,6 +153,7 @@ public:
static Item BLANK; static Item BLANK;
bool operator==(const Item&rhs)const; bool operator==(const Item&rhs)const;
const std::optional<const ::ItemSet *const>ItemSet()const; const std::optional<const ::ItemSet *const>ItemSet()const;
bool IsEquippable()const;
}; };
class Inventory{ class Inventory{

@ -73,7 +73,6 @@ public:
return itemRef.get(); return itemRef.get();
} }
inline Item&SetItem(Item&newItem){ inline Item&SetItem(Item&newItem){
UpdateIcon();
return itemRef=std::reference_wrapper<Item>(newItem); return itemRef=std::reference_wrapper<Item>(newItem);
} }
inline void SetShowQuantity(bool show){ inline void SetShowQuantity(bool show){
@ -83,6 +82,13 @@ public:
if(compact)this->compact=COMPACT; if(compact)this->compact=COMPACT;
else this->compact=NON_COMPACT; else this->compact=NON_COMPACT;
} }
inline void UpdateIcon(){
if(itemRef.get().IsBlank()){
icon=nullptr;
return;
}
icon=itemRef.get().Decal();
}
protected: protected:
virtual inline void OnMouseOut()override{ virtual inline void OnMouseOut()override{
if(itemNameLabelName!=""){ if(itemNameLabelName!=""){
@ -137,12 +143,4 @@ protected:
window.DrawShadowStringDecal(drawPos,quantityText,WHITE,BLACK,quantityTextScale,quantityTextScale.x); window.DrawShadowStringDecal(drawPos,quantityText,WHITE,BLACK,quantityTextScale,quantityTextScale.x);
} }
} }
private:
inline void UpdateIcon(){
if(itemRef.get().IsBlank()){
icon=nullptr;
return;
}
icon=itemRef.get().Decal();
}
}; };

@ -0,0 +1,87 @@
#pragma region License
/*
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2022 OneLoneCoder.com
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions or derivations of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions or derivative works in binary form must reproduce the above
copyright notice. This list of conditions and the following disclaimer must be
reproduced in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may
be used to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
Portions of this software are copyright © 2023 The FreeType
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
All rights reserved.
*/
#pragma endregion
#include "InventoryScrollableWindowComponent.h"
#include "RowItemDisplay.h"
class RowInventoryScrollableWindowComponent:public InventoryScrollableWindowComponent{
public:
inline RowInventoryScrollableWindowComponent(geom2d::rect<float>rect,ITCategory invType,std::string itemNameLabelName,std::string itemDescriptionLabelName,std::function<bool(MenuFuncData)>inventoryButtonClickAction,std::function<bool(MenuFuncData)>inventoryButtonHoverAction,std::function<bool(MenuFuncData)>inventoryButtonMouseOutAction,InventoryWindowOptions options={.padding=8,.size={24,24}},bool inventoryButtonsActive=true,ComponentAttr attributes=ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE)
:InventoryScrollableWindowComponent(rect,invType,itemNameLabelName,itemDescriptionLabelName,inventoryButtonClickAction,inventoryButtonHoverAction,inventoryButtonMouseOutAction,options,inventoryButtonsActive,attributes){}
virtual inline void SetCompactDescriptions(bool compact)override{
if(compact)this->compact=COMPACT;
else this->compact=NON_COMPACT;
for(MenuComponent*component:components){
RowItemDisplay*itemButton=dynamic_cast<RowItemDisplay*>(component);
if(itemButton){
itemButton->SetCompactDescriptions(compact);
}else{
ERR("WARNING! Attempting to cast a button that isn't a MenuItemButton!");
}
}
}
virtual inline void AddButtonOnSlotUpdate(ITCategory cat)override{
size_t invSize=Inventory::get(cat).size();
int invWidth=int(rect.size.x/(float(options.size.x)+options.padding));
int x=int((invSize-1)%invWidth);
int y=int((invSize-1)/invWidth);
int itemIndex=y*invWidth+x;
vf2d buttonSize=options.size;
vf2d totalSpacing={options.padding+buttonSize.x,options.padding+buttonSize.y};
auto newItem=ADD("item_"+cat+"_"+std::to_string(itemIndex),RowItemDisplay)({totalSpacing*vf2d{float(x),float(y)},buttonSize},Inventory::get(cat)[itemIndex],inventoryButtonClickAction,itemNameLabelName,itemDescriptionLabelName,inventoryButtonsActive?ButtonAttr::NONE:ButtonAttr::UNSELECTABLE)END;
newItem->SetCompactDescriptions(compact==COMPACT);
newItem->SetHoverFunc(inventoryButtonHoverAction);
newItem->SetMouseOutFunc(inventoryButtonMouseOutAction);
//Since we are indexing into a vector reference which is inevitably going to get erased as we add more items,
//we must update all previous menu component references in case that memory has been overwritten!
for(int counter=0;MenuComponent*component:components){
RowItemDisplay*item=dynamic_cast<RowItemDisplay*>(component);
if(item!=nullptr){
item->SetItem(Inventory::get(cat)[counter]);
}else{
ERR("WARNING! Could not properly cast item to RowItemDisplay* type!");
}
counter++;
}
}
};

@ -35,7 +35,7 @@ Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
All rights reserved. All rights reserved.
*/ */
#pragma endregion #pragma endregion
#pragma once
#include "Item.h" #include "Item.h"
#include "Crawler.h" #include "Crawler.h"
#include "MenuLabel.h" #include "MenuLabel.h"
@ -43,36 +43,46 @@ All rights reserved.
INCLUDE_game INCLUDE_game
class RowItemDisplay:public MenuComponent{ class RowItemDisplay:public MenuComponent{
Item&itemRef; std::reference_wrapper<Item>itemRef;
std::string itemNameLabelName; std::string itemNameLabelName;
std::string itemDescriptionLabelName; std::string itemDescriptionLabelName;
CompactText compact=NON_COMPACT; CompactText compact=NON_COMPACT;
bool showQuantity=true; bool showQuantity=true;
public: public:
inline RowItemDisplay(geom2d::rect<float>rect,Item&itemRef,MenuFunc onClick,std::string itemNameLabelName,std::string itemDescriptionLabelName,ButtonAttr attributes=ButtonAttr::NONE) inline RowItemDisplay(geom2d::rect<float>rect,Item&itemRef,MenuFunc onClick,std::string itemNameLabelName,std::string itemDescriptionLabelName,ButtonAttr attributes=ButtonAttr::NONE)
:MenuComponent(rect,"",onClick,attributes),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName),itemRef(itemRef){} :MenuComponent(rect,"",onClick,attributes),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName),itemRef(itemRef){
if(itemRef.IsEquippable())SetShowQuantity(false);
}
virtual inline void DrawDecal(ViewPort&window,bool focused)final{ virtual inline void DrawDecal(ViewPort&window,bool focused)final{
MenuComponent::DrawDecal(window,focused); MenuComponent::DrawDecal(window,focused);
float scaleFactor=(rect.size.y-4)/24; float scaleFactor=(rect.size.y-4)/24;
vf2d iconSize=vf2d{scaleFactor,scaleFactor}*24.f; vf2d iconSize=vf2d{scaleFactor,scaleFactor}*24.f;
window.DrawDecal(rect.pos+vf2d{2,2},itemRef.Decal(),{scaleFactor,scaleFactor}); window.DrawDecal(rect.pos+vf2d{2,2},itemRef.get().Decal(),{scaleFactor,scaleFactor});
window.DrawRectDecal(rect.pos+vf2d{2,2},iconSize); window.DrawRectDecal(rect.pos+vf2d{2,2},iconSize);
std::string itemName=itemRef.Name(); std::string itemName=itemRef.get().Name();
vf2d scaledSize={std::min(1.f,(rect.size.x-6-iconSize.x)/game->GetTextSizeProp(itemName).x),1}; vf2d scaledSize={std::min(1.f,(rect.size.x-6-iconSize.x)/game->GetTextSizeProp(itemName).x),1};
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);
if(showQuantity){ if(showQuantity){
std::string quantityText=std::format("x{}",itemRef.Amt()); std::string quantityText=std::format("x{}",itemRef.get().Amt());
vf2d qtyTextSize=game->GetTextSizeProp(quantityText); float qtyTextScale=0.75f;
window.DrawShadowStringPropDecal(rect.pos+rect.size-vf2d{2,2}+vf2d{-qtyTextSize.x,0},quantityText); vf2d qtyTextSize=vf2d(game->GetTextSizeProp(quantityText))*qtyTextScale;
window.DrawShadowStringPropDecal(rect.pos+rect.size-vf2d{1,1}+vf2d{-qtyTextSize.x,-qtyTextSize.y},quantityText,WHITE,BLACK,{qtyTextScale,qtyTextScale});
} }
if(selected){ if(Inventory::GetSlotEquippedIn(itemRef)!=EquipSlot::NONE){
window.DrawShadowStringDecal(rect.pos+vf2d{2,2}+iconSize-vf2d{8,8},"E",GREEN,VERY_DARK_GREEN); window.DrawShadowStringDecal(rect.pos+vf2d{2,2}+iconSize-vf2d{8,8},"E",GREEN,VERY_DARK_GREEN);
} }
} }
virtual inline void Update(Crawler*game)override{
MenuComponent::Update(game);
if(hovered){
UpdateLabel();
}
}
inline void SetCompactDescriptions(bool compact){ inline void SetCompactDescriptions(bool compact){
if(compact)this->compact=COMPACT; if(compact)this->compact=COMPACT;
else this->compact=NON_COMPACT; else this->compact=NON_COMPACT;
@ -91,13 +101,16 @@ public:
virtual inline Item&GetItem(){ virtual inline Item&GetItem(){
return itemRef; return itemRef;
} }
virtual inline void SetItem(Item&itemRef){
this->itemRef=std::reference_wrapper<Item>(itemRef);
}
void UpdateLabel(){ void UpdateLabel(){
if(itemRef.IsBlank())return; if(itemRef.get().IsBlank())return;
std::string labelNameText; std::string labelNameText;
std::string labelDescriptionText; std::string labelDescriptionText;
if(valid){ if(valid){
labelNameText=itemRef.Name(); labelNameText=itemRef.get().Name();
labelDescriptionText=itemRef.Description(compact); labelDescriptionText=itemRef.get().Description(compact);
}else{ }else{
labelNameText=""; labelNameText="";
labelDescriptionText=""; labelDescriptionText="";

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

Loading…
Cancel
Save