Implemented Crafting enhancement window, item enhancement checks, and enhancement implementation done.

pull/28/head
sigonasr2 11 months ago
parent 8f41870b46
commit 64694e1b63
  1. 28
      Crawler/BlacksmithCraftingWindow.cpp
  2. 71
      Crawler/CraftItemWindow.cpp
  3. 12
      Crawler/Crawler.vcxproj
  4. 9
      Crawler/Crawler.vcxproj.filters
  5. 106
      Crawler/EnhancementStatsLabel.h
  6. 9
      Crawler/Item.cpp
  7. 4
      Crawler/Item.h
  8. 1
      Crawler/Menu.cpp
  9. 2
      Crawler/Menu.h
  10. 13
      Crawler/MenuComponent.h
  11. 25
      Crawler/MenuLabel.h
  12. 93
      Crawler/RequiredMaterialsList.h
  13. 2
      Crawler/Version.h
  14. 3
      Crawler/assets/config/items/Weapons.txt
  15. 2
      Crawler/assets/config/items/items.txt

@ -41,6 +41,8 @@ All rights reserved.
#include "MenuItemItemButton.h"
#include "PlayerMoneyLabel.h"
#include "RowInventoryScrollableWindowComponent.h"
#include "EnhancementStatsLabel.h"
#include "RequiredMaterialsList.h"
INCLUDE_game
INCLUDE_ITEM_CATEGORIES
@ -90,6 +92,19 @@ void Menu::InitializeBlacksmithCraftingWindow(){
auto weaponsDisplay=blacksmithWindow->ADD("Weapon Inventory Display",RowInventoryScrollableWindowComponent)({{2,28},{220,blacksmithWindow->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();
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());
Menu::OpenMenu(CRAFT_ITEM);
return true;
},
[](MenuFuncData data){
@ -109,6 +124,19 @@ void Menu::InitializeBlacksmithCraftingWindow(){
auto armorDisplay=blacksmithWindow->ADD("Armor Inventory Display",RowInventoryScrollableWindowComponent)({{2,28},{220,blacksmithWindow->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();
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){

@ -0,0 +1,71 @@
#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 "Menu.h"
#include "EnhancementStatsLabel.h"
#include "RequiredMaterialsList.h"
void Menu::InitializeCraftItemWindow(){
Menu*craftItemWindow=CreateMenu(CRAFT_ITEM,CENTERED,{240,120});
craftItemWindow->ADD("Item Name Header",MenuLabel)({{2,-16},{craftItemWindow->size.x-4,12}},"Item Name",1.0f,ComponentAttr::SHADOW|ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND)END;
craftItemWindow->ADD("Enhancement Level Header",MenuLabel)({{2,0},{craftItemWindow->size.x-4,12}},"Level X ->#00AA00 Y",1.f,ComponentAttr::SHADOW|ComponentAttr::FIXED_WIDTH_FONT)END;
craftItemWindow->ADD("Enhancement Stats Label",EnhancementStatsLabel)({{2,16},{craftItemWindow->size.x-4,72}},Item::BLANK,1.f)END;
craftItemWindow->ADD("Materials Requirement Outline",MenuComponent)({{2,86},{craftItemWindow->size.x-4,26}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)END;
craftItemWindow->ADD("Required Materials Label",MenuLabel)({{4,80},{craftItemWindow->size.x-8,0}},"Required Materials",1.0f,ComponentAttr::SHADOW)END;
craftItemWindow->ADD("Required Materials List",RequiredMaterialsList)({{4,88},{craftItemWindow->size.x-8,22}},Item::BLANK)END;
craftItemWindow->ADD("Back Button",MenuComponent)({{36,116},{48,12}},"Back",[](MenuFuncData data){Menu::CloseMenu();return true;})END;
craftItemWindow->ADD("Craft Button",MenuComponent)({{craftItemWindow->size.x-84,116},{48,12}},"Craft",[](MenuFuncData data){
const std::weak_ptr<Item>item=Component<EnhancementStatsLabel>(data.menu.GetType(),"Enhancement Stats Label")->GetItem();
if(item.lock()->CanEnhanceItem()){
item.lock()->EnhanceItem();
}
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>(data.menu.GetType(),"Enhancement Level Header")->SetLabel(label);
data.component->SetGrayedOut(!item.lock()->CanEnhanceItem());
return true;
})END;
}

@ -333,6 +333,10 @@
<ClInclude Include="Effect.h" />
<ClInclude Include="Emitter.h" />
<ClInclude Include="EncountersSpawnListScrollableWindowComponent.h" />
<ClInclude Include="EnhancementStatsLabel.h">
<SubType>
</SubType>
</ClInclude>
<ClInclude Include="EquipSlotButton.h">
<SubType>
</SubType>
@ -401,6 +405,10 @@
<SubType>
</SubType>
</ClInclude>
<ClInclude Include="RequiredMaterialsList.h">
<SubType>
</SubType>
</ClInclude>
<ClInclude Include="resource.h" />
<ClInclude Include="resource1.h" />
<ClInclude Include="RowInventoryScrollableWindowComponent.h">
@ -467,6 +475,10 @@
<SubType>
</SubType>
</ClCompile>
<ClCompile Include="CraftItemWindow.cpp">
<SubType>
</SubType>
</ClCompile>
<ClCompile Include="Crawler.cpp" />
<ClCompile Include="DamageNumber.cpp" />
<ClCompile Include="discord-files\achievement_manager.cpp" />

@ -381,6 +381,12 @@
<ClInclude Include="InventoryCreator.h">
<Filter>Header Files\Interface</Filter>
</ClInclude>
<ClInclude Include="EnhancementStatsLabel.h">
<Filter>Header Files\Interface</Filter>
</ClInclude>
<ClInclude Include="RequiredMaterialsList.h">
<Filter>Header Files\Interface</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Player.cpp">
@ -635,6 +641,9 @@
<ClCompile Include="InventoryCreator.cpp">
<Filter>Source Files\Interface</Filter>
</ClCompile>
<ClCompile Include="CraftItemWindow.cpp">
<Filter>Source Files\Interface</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="cpp.hint" />

@ -0,0 +1,106 @@
#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
#pragma once
#include "MenuLabel.h"
#include "Item.h"
class EnhancementStatsLabel:public MenuLabel{
std::weak_ptr<Item>itemRef;
public:
inline EnhancementStatsLabel(geom2d::rect<float>rect,const std::weak_ptr<Item>itemRef,float scale=1,ComponentAttr attributes=ComponentAttr::SHADOW|ComponentAttr::LEFT_ALIGN)
:MenuLabel(rect,"",scale,attributes),itemRef(itemRef){}
inline void SetItem(const std::weak_ptr<Item>itemRef){
this->itemRef=itemRef;
}
inline const std::weak_ptr<Item>GetItem()const{
return itemRef;
}
protected:
inline virtual void DrawDecal(ViewPort&window,bool focused)override final{
MenuComponent::DrawDecal(window,focused);
vf2d adjustedScale={scale,scale};
vf2d labelTextSize=vf2d(game->GetWrappedTextSizeProp(label,rect.size.x,adjustedScale));
if(fitToLabel){
float sizeRatio=((labelTextSize*adjustedScale).x)/(rect.size.x-2);
if(sizeRatio>1){
adjustedScale.x/=sizeRatio;
}
labelTextSize=vf2d(game->GetTextSizeProp(label)*adjustedScale);
}
vf2d drawPos=rect.middle()-vf2d{labelTextSize}/2; //Assume centered.
if(!centered){
drawPos=vf2d{rect.pos.x+2,rect.pos.y};
}
if(itemRef.lock()->EnhancementIsPossible()){
float maxAttributeLabelSize=0;
std::for_each(itemRef.lock()->GetEnhancementInfo()[1].stats.begin(),itemRef.lock()->GetEnhancementInfo()[1].stats.end(),[&](const auto&data){
auto&attr=data.first;
maxAttributeLabelSize=std::max(maxAttributeLabelSize,float(game->GetWrappedTextSizeProp(std::format("{}",attr.Name()),rect.size.x,adjustedScale).x));
});
for(float yOffset=0;const auto&[attr,value]:itemRef.lock()->GetEnhancementInfo()[itemRef.lock()->EnhancementLevel()].stats){
std::string attributeLabel=std::format("{}",attr.Name());
float attributeLabelWidth=game->GetTextSizeProp(attributeLabel).x;
window.DrawShadowStringPropDecal(drawPos+vf2d{maxAttributeLabelSize/2+24,yOffset}-vf2d{attributeLabelWidth/2,0},attributeLabel,WHITE,BLACK,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x,1.0f);
uint8_t nextEnhanceLevel=itemRef.lock()->EnhancementLevel()+1;
float nextStageValue=0;
if(itemRef.lock()->GetEnhancementInfo().size()>nextEnhanceLevel){
nextStageValue=itemRef.lock()->GetEnhancementInfo()[nextEnhanceLevel].stats.get_readOnly(attr);
}
std::string percentageSign=attr.DisplayAsPercent()?"%":"";
window.DrawShadowStringDecal(drawPos+vf2d{maxAttributeLabelSize+4+24,yOffset},std::format("{:>5} ->#00AA00 {:<5}",
attr.ShowAsDecimal()?std::format("{:>4.1f}{}",value,percentageSign):std::format("{}{}",value,percentageSign),
nextStageValue!=0?
attr.ShowAsDecimal()?std::format("{:<4.1f}{}",nextStageValue,percentageSign):std::format("{}{}",nextStageValue,percentageSign)
:"MAX"),
WHITE,BLACK,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x,1.0f);
yOffset+=16;
}
}else{
std::string text="Cannot be enhanced.";
float textWidth=game->GetTextSizeProp(text).x;
window.DrawShadowStringPropDecal(rect.middle()-vf2d{textWidth,0}/2,text,RED,BLACK,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x,1.0f);
}
}
};

@ -901,12 +901,13 @@ EnhancementLevelInfo::EnhancementLevelInfo(const Stats&stats,const CraftingRequi
:stats(stats),craftingRequirement(craftingRequirement){}
const bool Item::CanEnhanceItem()const{
if(ISBLANK(std::make_shared<Item>(*this)))return false;
if(!GetEnhancementInfo().CanBeEnhanced())return false;
const EnhancementLevelInfo&enhanceInfo=GetEnhancementInfo()[EnhancementLevel()+1];
if(EnhancementLevel()>="Item.Item Max Enhancement Level"_I)return false;
if(game->GetPlayer()->GetMoney()<enhanceInfo.craftingRequirement.GetCost())return false;
for(const Item&it:enhanceInfo.craftingRequirement.GetItems()){
if(Inventory::GetItemCount(ActualName())<it.Amt()){
if(Inventory::GetItemCount(it.ActualName())<it.Amt()){
return false;
}
}
@ -954,5 +955,9 @@ const bool Item::IsCraftable()const{
return it->IsCraftable();
}
const bool ItemInfo::IsCraftable()const{
return GetEnhancementInfo().CanBeEnhanced();
return GetEnhancementInfo().CanBeEnhanced();
}
const bool Item::EnhancementIsPossible()const{
return it->IsCraftable();
}

@ -181,7 +181,11 @@ public:
//Use ISBLANK macro instead!! This should not be called directly!!
const bool IsBlank()const;
const uint8_t EnhancementLevel()const;
//NOTE: This function must be primed with CanEnhanceItem()! Otherwise it will cause a runtime error.
void EnhanceItem();
//Whether or not this item can be enhanced/crafted.
const bool EnhancementIsPossible()const;
//A verification function that confirms if we are allowed to perform an enhancement. MUST BE CALLED to prime EnhanceItem() function!!
const bool CanEnhanceItem()const;
static std::shared_ptr<Item>BLANK;
const std::optional<const::ItemSet*const>ItemSet()const;

@ -107,6 +107,7 @@ void Menu::InitializeMenus(){
InitializeBuyItemWindow();
InitializeSellItemWindow();
InitializeBlacksmithCraftingWindow();
InitializeCraftItemWindow();
for(MenuType type=MenuType(int(MenuType::ENUM_START)+1);type<MenuType::ENUM_END;type=MenuType(int(type+1))){
if(menus.count(type)==0){

@ -76,6 +76,7 @@ enum MenuType{
BUY_ITEM,
SELL_ITEM,
BLACKSMITH,
CRAFT_ITEM,
#pragma region Enum End //DO NOT REMOVE
///////////////////////////////////////////////////////////
/*DO NOT REMOVE!!*/ENUM_END////////////////////////////////
@ -98,6 +99,7 @@ class Menu:public IAttributable{
static void InitializeBuyItemWindow();
static void InitializeSellItemWindow();
static void InitializeBlacksmithCraftingWindow();
static void InitializeCraftItemWindow();
friend class Crawler;
friend struct Player;

@ -47,12 +47,13 @@ enum class ButtonAttr{
};
enum class ComponentAttr{
NONE= 0b000000,
LEFT_ALIGN= 0b000001, //Labels are centered by default.
SHADOW= 0b000010, //Adds shadows to the label text.
OUTLINE= 0b000100, //Adds an outline around the component.
BACKGROUND= 0b001000, //Renders the background of the menu theme for this component.
FIT_TO_LABEL= 0b010000, //Scales the text horizontally to fit the label if the text takes up more space rather than wrapping.
NONE= 0b0'0000'0000,
LEFT_ALIGN= 0b0'0000'0001, //Labels are centered by default.
SHADOW= 0b0'0000'0010, //Adds shadows to the label text.
OUTLINE= 0b0'0000'0100, //Adds an outline around the component.
BACKGROUND= 0b0'0000'1000, //Renders the background of the menu theme for this component.
FIT_TO_LABEL= 0b0'0001'0000, //Scales the text horizontally to fit the label if the text takes up more space rather than wrapping.
FIXED_WIDTH_FONT= 0b0'0010'0000, //Uses a fixed-width font (instead of a proportional one) for text rendering.
};
enum class SelectionType{

@ -49,9 +49,10 @@ protected:
float scale=1;
bool shadow=false;
bool centered=true;
bool proportional=true;
public:
inline MenuLabel(geom2d::rect<float>rect,std::string label,float scale=1,ComponentAttr attributes=ComponentAttr::NONE)
:MenuComponent(rect,label,MenuFunc{},ButtonAttr::UNSELECTABLE|ButtonAttr::UNSELECTABLE_VIA_KEYBOARD),scale(scale),centered(!(attributes&ComponentAttr::LEFT_ALIGN)),shadow(attributes&ComponentAttr::SHADOW){
:MenuComponent(rect,label,MenuFunc{},ButtonAttr::UNSELECTABLE|ButtonAttr::UNSELECTABLE_VIA_KEYBOARD),scale(scale),centered(!(attributes&ComponentAttr::LEFT_ALIGN)),shadow(attributes&ComponentAttr::SHADOW),proportional(!(attributes&ComponentAttr::FIXED_WIDTH_FONT)){
border=attributes&ComponentAttr::OUTLINE;
this->background=attributes&ComponentAttr::BACKGROUND;
showDefaultLabel=false;
@ -67,14 +68,20 @@ protected:
inline virtual void DrawDecal(ViewPort&window,bool focused)override{
MenuComponent::DrawDecal(window,focused);
vf2d adjustedScale={scale,scale};
vf2d labelTextSize=vf2d(game->GetWrappedTextSizeProp(label,rect.size.x,adjustedScale));
vf2d labelTextSize=
proportional?
vf2d(game->GetWrappedTextSizeProp(label,rect.size.x,adjustedScale)):
vf2d(game->GetWrappedTextSize(label,rect.size.x,adjustedScale));
if(fitToLabel){
float sizeRatio=((labelTextSize*adjustedScale).x)/(rect.size.x-2);
if(sizeRatio>1){
adjustedScale.x/=sizeRatio;
}
labelTextSize=vf2d(game->GetTextSizeProp(label)*adjustedScale);
labelTextSize=
proportional?
vf2d(game->GetTextSizeProp(label)*adjustedScale):
vf2d(game->GetTextSize(label)*adjustedScale);
}
vf2d drawPos=rect.middle()-vf2d{labelTextSize}/2; //Assume centered.
@ -83,9 +90,17 @@ protected:
}
if(shadow){
window.DrawShadowStringPropDecal(drawPos,label,WHITE,BLACK,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x,1.0f);
if(proportional){
window.DrawShadowStringPropDecal(drawPos,label,WHITE,BLACK,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x,1.0f);
}else{
window.DrawShadowStringDecal(drawPos,label,WHITE,BLACK,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x,1.0f);
}
}else{
window.DrawStringPropDecal(drawPos,label,WHITE,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x,1.0f);
if(proportional){
window.DrawStringPropDecal(drawPos,label,WHITE,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x,1.0f);
}else{
window.DrawStringDecal(drawPos,label,WHITE,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x,1.0f);
}
}
}
};

@ -0,0 +1,93 @@
#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
#pragma once
#include "MenuLabel.h"
#include "Item.h"
class RequiredMaterialsList:public MenuLabel{
std::weak_ptr<Item>itemRef;
public:
inline RequiredMaterialsList(geom2d::rect<float>rect,const std::weak_ptr<Item>itemRef,ComponentAttr attributes=ComponentAttr::SHADOW|ComponentAttr::LEFT_ALIGN)
:MenuLabel(rect,"",1.f,attributes),itemRef(itemRef){}
inline void SetItem(const std::weak_ptr<Item>itemRef){
this->itemRef=itemRef;
}
inline const std::weak_ptr<Item>GetItem()const{
return itemRef;
}
protected:
inline virtual void DrawDecal(ViewPort&window,bool focused)override final{
MenuComponent::DrawDecal(window,focused);
vf2d adjustedScale={scale,scale};
vf2d labelTextSize=vf2d(game->GetWrappedTextSizeProp(label,rect.size.x,adjustedScale));
if(fitToLabel){
float sizeRatio=((labelTextSize*adjustedScale).x)/(rect.size.x-2);
if(sizeRatio>1){
adjustedScale.x/=sizeRatio;
}
labelTextSize=vf2d(game->GetTextSizeProp(label)*adjustedScale);
}
if(itemRef.lock()->EnhancementIsPossible()&&itemRef.lock()->GetEnhancementInfo().size()>itemRef.lock()->EnhancementLevel()+1){
float drawWidth=rect.size.x/3;
int index=0;
for(const auto&item:itemRef.lock()->GetEnhancementInfo()[itemRef.lock()->EnhancementLevel()+1].craftingRequirement.GetItems()){
Pixel textCol=WHITE;
if(Inventory::GetItemCount(item.ActualName())<item.Amt())textCol=RED;
vf2d drawPos=rect.pos+vf2d{drawWidth*(index%3),12.f*(index/3)};
std::string labelText=std::format("{}",item.DisplayName());
float labelWidth=game->GetTextSizeProp(labelText).x;
window.DrawShadowStringDecal(drawPos,std::format("{:>3}",item.Amt()),textCol,BLACK);
window.DrawShadowStringPropDecal(drawPos+vf2d{26,0},labelText,textCol,BLACK,{std::min(1.f,(drawWidth-26-2)/labelWidth),1.f});
index++;
}
Pixel textCol=WHITE;
uint32_t goldAmt=itemRef.lock()->GetEnhancementInfo()[itemRef.lock()->EnhancementLevel()+1].craftingRequirement.GetCost();
if(game->GetPlayer()->GetMoney()<goldAmt)textCol=RED;
vf2d drawPos=rect.pos+vf2d{drawWidth*(index%3),12.f*(index/3)};
std::string goldAmtText=std::format("{:>3}",goldAmt);
std::string labelText=std::format("{}","Item.Currency Name"_S);
float goldAmtWidth=game->GetTextSize(goldAmtText).x;
window.DrawShadowStringDecal(drawPos,goldAmtText,textCol,BLACK);
window.DrawShadowStringPropDecal(drawPos+vf2d{goldAmtWidth+2,0},labelText,textCol,BLACK);
index++;
}
}
};

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

@ -26,6 +26,9 @@ Equipment
{
Item[0] = Green Slime Remains,10
Item[1] = Logs,2
Item[2] = Blue Slime Remains,4
Item[3] = Red Slime Remains,3
Item[4] = Flower Petals,1
Gold = 50
}

@ -12,6 +12,8 @@ Item
Item Cooldown Time = 5.0
# The maximum enhancement level of equipment.
Item Max Enhancement Level = 10
# The name of the currency in the game.
Currency Name = Gold
}
ItemDrop
{

Loading…
Cancel
Save