diff --git a/Crawler/CharacterMenuWindow.cpp b/Crawler/CharacterMenuWindow.cpp index 74bc510b..07bc5444 100644 --- a/Crawler/CharacterMenuWindow.cpp +++ b/Crawler/CharacterMenuWindow.cpp @@ -51,6 +51,8 @@ INCLUDE_game INCLUDE_GFX void Menu::InitializeCharacterMenuWindow(){ + static bool equipmentWindowOpened=false; + vf2d windowSize=game->GetScreenSize()-vf2d{52,52}; Menu*characterMenuWindow=CreateMenu(CHARACTER_MENU,CENTERED,windowSize); @@ -87,8 +89,10 @@ void Menu::InitializeCharacterMenuWindow(){ StatLabel*statDisplayLabel=Component(CHARACTER_MENU,"Attribute "+ItemAttributable::GetDisplayInfo(attribute).name+" Label"); statDisplayLabel->SetStatChangeAmt(0); } + equipmentWindowOpened=false; return true; }); + equipSelectionSelectButton->decal=true; equipSelectionOutline->Enable(false); equipmentList->Enable(false); @@ -190,6 +194,7 @@ void Menu::InitializeCharacterMenuWindow(){ if(Inventory::GetEquip(slot)==&itemInvRef){ equip->SetSelected(true); } + equip->SetCompactDescriptions(false); equipList->AddComponent(Menu::menus[CHARACTER_MENU],"Equip Item "+std::to_string(counter),equip); counter++; } @@ -199,12 +204,24 @@ void Menu::InitializeCharacterMenuWindow(){ Component(data.component->parentMenu,"Equip Selection Bottom Outline")->Enable(true); Component(data.component->parentMenu,"Equip Selection Select Button")->Enable(true); Component(data.component->parentMenu,"Character Rotating Display")->Enable(false); + equipmentWindowOpened=true; + return true; + },[](MenuFuncData data){//On Mouse Hover + if(Component(data.component->parentMenu,"Item Equip Description")->GetLabel()!=""){ + Component(data.component->parentMenu,"Character Rotating Display")->Enable(false); + } return true; - },DO_NOTHING,DO_NOTHING,"Item Name","Item Description"); + },[](MenuFuncData data){//On Mouse Out + if(Component(data.component->parentMenu,"Item Equip Description")->GetLabel()!=""&&!equipmentWindowOpened){ + Component(data.component->parentMenu,"Character Rotating Display")->Enable(true); + } + return true; + },"Item Equip Name","Item Equip Description"); PopupMenuLabel*equipmentLabel=NEW PopupMenuLabel(CHARACTER_MENU,{{labelX,labelY},{29,16}},slotNames[i],{0.5,1},ComponentAttr::SHADOW); equipmentSlot->I(Attribute::EQUIP_TYPE)=int(slot); equipmentSlot->I(Attribute::INDEXED_THEME)=i; equipmentSlot->SetShowQuantity(false); + equipmentSlot->SetCompactDescriptions(false); equipSlot<<=1; characterMenuWindow->AddComponent("Equip Slot "+slotNames[i],equipmentSlot); characterMenuWindow->AddComponent("Equip Label "+slotNames[i],equipmentLabel); @@ -229,10 +246,19 @@ void Menu::InitializeCharacterMenuWindow(){ backButton->decal=true; characterMenuWindow->AddComponent("Back button",backButton); - MenuLabel*itemNameDisplay=NEW MenuLabel(CHARACTER_MENU,{{32,windowSize.y-32},{windowSize.x-64,12}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW); + MenuLabel*itemNameDisplay=NEW MenuLabel(CHARACTER_MENU,{{0,28},{120,12}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW); + MenuLabel*itemDescriptionDisplay=NEW MenuLabel(CHARACTER_MENU,{{0,40},{120,windowSize.y-49}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW); + itemNameDisplay->decal=true; - MenuLabel*itemDescriptionDisplay=NEW MenuLabel(CHARACTER_MENU,{{32,windowSize.y-20},{windowSize.x-64,32}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW); itemDescriptionDisplay->decal=true; + itemNameDisplay->Enable(false); + itemDescriptionDisplay->Enable(false); + + MenuLabel*itemNameDisplayEquip=NEW MenuLabel(CHARACTER_MENU,{{123,28},{120,12}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW); + MenuLabel*itemDescriptionDisplayEquip=NEW MenuLabel(CHARACTER_MENU,{{123,40},{120,windowSize.y-49}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW); + characterMenuWindow->AddComponent("Item Name",itemNameDisplay); characterMenuWindow->AddComponent("Item Description",itemDescriptionDisplay); + characterMenuWindow->AddComponent("Item Equip Name",itemNameDisplayEquip); + characterMenuWindow->AddComponent("Item Equip Description",itemDescriptionDisplayEquip); } \ No newline at end of file diff --git a/Crawler/Item.cpp b/Crawler/Item.cpp index a1226197..829ab11d 100644 --- a/Crawler/Item.cpp +++ b/Crawler/Item.cpp @@ -383,21 +383,31 @@ std::string Item::Name(){ bool Item::IsEquippable()const{ return Category()=="Equipment"||Category()=="Accessories"; } -std::string Item::Description(){ +std::string Item::Description(CompactText compact){ std::string description=it->Description(); if(IsEquippable()){ description+='\n'; - description+=GetStats().GetStatsString(); + description+=GetStats().GetStatsString(compact); if(ItemSet()){ const ::ItemSet*const set=ItemSet().value(); - description+="\n"+set->GetSetName()+" Set - "; + if(compact==COMPACT){ + description+="\n"+set->GetSetName()+" Set - "; + }else{ + description+="\n\n"+set->GetSetName()+" Set\n"; + } const std::map<::ItemSet,int>&itemSetCounts=Inventory::GetEquippedItemSets(); for(bool first=true;const auto&[pieceCount,bonuses]:set->GetSetBonusBreakpoints()){ if(itemSetCounts.count(*set)&&pieceCount<=itemSetCounts.at(*set)){ description+="#56E346"; } - if(!first)description+=" "; - description+="("+std::to_string(pieceCount)+"): "+bonuses.GetStatsString()+"#FFFFFF"; + if(!first){ + if(compact==COMPACT){ + description+=" "; + }else{ + description+="\n"; + } + } + description+="("+std::to_string(pieceCount)+"): "+bonuses.GetStatsString(compact)+"#FFFFFF"; first=false; } } @@ -626,11 +636,15 @@ const std::mapInventory::GetEquippedItemSets(){ return setCounts; } -const std::string Stats::GetStatsString()const{ +const std::string Stats::GetStatsString(CompactText compact)const{ std::string description=""; for(bool first=true;const auto&[attr,val]:attributes){ if(!first){ - description+=" "; + if(compact==COMPACT){ + description+=" "; + }else{ + description+="\n"; + } } description+=ItemAttributable::GetAttributeName(attr)+": "+std::to_string(val)+(ItemAttributable::GetDisplayInfo(attr).displayAsPercent?"%":""); first=false; diff --git a/Crawler/Item.h b/Crawler/Item.h index 1b8c0b3a..666c3d02 100644 --- a/Crawler/Item.h +++ b/Crawler/Item.h @@ -65,6 +65,13 @@ enum class EquipSlot{ NONE= 0b0000'0000, }; +enum class CompactText{ + COMPACT, + NON_COMPACT +}; + +using enum CompactText; + struct Stats:ItemAttributable{ public: inline Stats&operator+=(Stats&rhs){ @@ -85,7 +92,7 @@ public: auto end()const{ return attributes.end(); } - const std::string GetStatsString()const; + const std::string GetStatsString(CompactText compact=NON_COMPACT)const; }; struct EnhancementInfo{ @@ -132,7 +139,7 @@ public: Item(uint32_t amt,IT item,uint8_t enhancementLevel=0); uint32_t Amt(); std::string Name(); - std::string Description(); + std::string Description(CompactText compact=COMPACT); const ITCategory Category()const; EquipSlot GetEquipSlot(); Decal*Decal(); diff --git a/Crawler/MenuItemItemButton.h b/Crawler/MenuItemItemButton.h index 0aa05928..6beb8b0d 100644 --- a/Crawler/MenuItemItemButton.h +++ b/Crawler/MenuItemItemButton.h @@ -60,6 +60,7 @@ private: bool hoverState=false; bool selected=false; bool hideQty=false; + CompactText compact=COMPACT; public: inline MenuItemItemButton(MenuType parent,geom2d::rectrect,Item&itemRef,MenuType menuDest,MenuFunc onClick,std::string itemNameLabelName,std::string itemDescriptionLabelName) :MenuIconButton(parent,rect,(!itemRef.IsBlank())?itemRef.Decal():nullptr,menuDest,onClick),itemRef(itemRef),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName),onHover(DO_NOTHING){ @@ -84,6 +85,10 @@ public: inline void SetShowQuantity(bool show){ this->hideQty=!show; } + inline void SetCompactDescriptions(bool compact){ + if(compact)this->compact=COMPACT; + else this->compact=NON_COMPACT; + } protected: virtual inline void BeforeUpdate(Crawler*game)override{ if(!hovered&&runHoverFunctions&&hoverState){ @@ -113,7 +118,7 @@ protected: if(valid){ icon=itemRef.get().Decal(); labelNameText=itemRef.get().Name(); - labelDescriptionText=itemRef.get().Description(); + labelDescriptionText=itemRef.get().Description(compact); }else{ icon=nullptr; labelNameText=""; diff --git a/Crawler/MenuLabel.h b/Crawler/MenuLabel.h index d8201130..86485031 100644 --- a/Crawler/MenuLabel.h +++ b/Crawler/MenuLabel.h @@ -64,16 +64,18 @@ protected: MenuComponent::Update(game); } virtual void inline Draw(Crawler*game,vf2d parentPos)override{ - MenuComponent::Draw(game,parentPos); - std::string wrappedText=util::WrapText(game,label,int(rect.size.x),true,{float(scale),float(scale)}); - vf2d drawPos=parentPos+rect.middle()-vf2d{game->GetTextSizeProp(wrappedText)}*float(scale)/2; //Assume centered. - if(!centered){ - drawPos=vf2d{rect.pos.x+2,rect.middle().y-game->GetTextSizeProp(wrappedText).y/2}+parentPos; //We should at least vertically align here. - } - if(shadow){ - game->DrawShadowStringProp(drawPos,wrappedText,WHITE,BLACK,{float(scale),float(scale)}); - }else{ - game->DrawStringProp(drawPos,wrappedText,WHITE,scale); + if(!decal){ + MenuComponent::Draw(game,parentPos); + std::string wrappedText=util::WrapText(game,label,int(rect.size.x),true,{float(scale),float(scale)}); + vf2d drawPos=parentPos+rect.middle()-vf2d{game->GetTextSizeProp(wrappedText)}*float(scale)/2; //Assume centered. + if(!centered){ + drawPos=vf2d{rect.pos.x+2,rect.middle().y-game->GetTextSizeProp(wrappedText).y/2}+parentPos; //We should at least vertically align here. + } + if(shadow){ + game->DrawShadowStringProp(drawPos,wrappedText,WHITE,BLACK,{float(scale),float(scale)}); + }else{ + game->DrawStringProp(drawPos,wrappedText,WHITE,scale); + } } } virtual void inline DrawDecal(Crawler*game,vf2d parentPos,bool focused)override{ diff --git a/Crawler/Version.h b/Crawler/Version.h index fb75816b..1408c2ce 100644 --- a/Crawler/Version.h +++ b/Crawler/Version.h @@ -39,7 +39,7 @@ All rights reserved. #define VERSION_MAJOR 0 #define VERSION_MINOR 2 #define VERSION_PATCH 1 -#define VERSION_BUILD 3669 +#define VERSION_BUILD 3692 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Crawler/olcPixelGameEngine.h b/Crawler/olcPixelGameEngine.h index ff262b42..da2d031d 100644 --- a/Crawler/olcPixelGameEngine.h +++ b/Crawler/olcPixelGameEngine.h @@ -3561,6 +3561,8 @@ namespace olc void PixelGameEngine::DrawShadowString(const olc::vi2d& pos, const std::string& sText, Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const float shadowSizeFactor){ std::string strippedText=sText; std::erase_if(strippedText,[](char chr){return chr<0;}); + int skip=0; + std::erase_if(strippedText,[&](char chr){if(skip>0){skip--;return true;}if(chr=='#'){skip=6;return true;}return false;}); for(float y=-shadowSizeFactor;y<=shadowSizeFactor+0.1;y+=shadowSizeFactor/2){ for(float x=-shadowSizeFactor;x<=shadowSizeFactor+0.1;x+=shadowSizeFactor/2){ if(x!=0||y!=0){ @@ -3574,6 +3576,8 @@ namespace olc void PixelGameEngine::DrawShadowStringProp(const olc::vi2d& pos, const std::string& sText, Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const float shadowSizeFactor){ std::string strippedText=sText; std::erase_if(strippedText,[](char chr){return chr<0;}); + int skip=0; + std::erase_if(strippedText,[&](char chr){if(skip>0){skip--;return true;}if(chr=='#'){skip=6;return true;}return false;}); for(float y=-shadowSizeFactor;y<=shadowSizeFactor+0.1;y+=shadowSizeFactor/2){ for(float x=-shadowSizeFactor;x<=shadowSizeFactor+0.1;x+=shadowSizeFactor/2){ if(x!=0||y!=0){