Add in consumable crafting. Allow specifying a quantity for item crafts. Add Flower Petals to Flower Turret drop table.

pull/28/head
sigonasr2 1 year ago
parent c876f8a6ea
commit 9fef977a3a
  1. 101
      Crawler/ConsumableCraftItemWindow.cpp
  2. 17
      Crawler/ConsumableCraftingWindow.cpp
  3. 2
      Crawler/Crawler.cpp
  4. 4
      Crawler/Crawler.vcxproj
  5. 3
      Crawler/Crawler.vcxproj.filters
  6. 4
      Crawler/FunctionPriming.h
  7. 36
      Crawler/Item.cpp
  8. 4
      Crawler/Item.h
  9. 1
      Crawler/Menu.cpp
  10. 2
      Crawler/Menu.h
  11. 8
      Crawler/MenuLabel.h
  12. 14
      Crawler/RequiredMaterialsList.h
  13. 2
      Crawler/Version.h
  14. 1
      Crawler/assets/config/Monsters.txt
  15. 6
      Crawler/assets/config/items/ItemDatabase.txt
  16. 3
      Crawler/loc.sh

@ -0,0 +1,101 @@
#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"
#include "Item.h"
INCLUDE_ITEM_DATA
using A=Attribute;
void Menu::InitializeConsumableCraftItemWindow(){
Menu*consumableCraftItemWindow=CreateMenu(CONSUMABLE_CRAFT_ITEM,CENTERED,{240,96});
consumableCraftItemWindow->ADD("Item Name Header",MenuLabel)({{2,-4},{consumableCraftItemWindow->size.x-4,12}},"Item Name",1.0f,ComponentAttr::SHADOW|ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND)END;
static auto GetQuantity=[&](){
return std::stoi(Component<MenuLabel>(CONSUMABLE_CRAFT_ITEM,"Amount to Craft Amount Label")->GetLabel());
};
static auto UpdateMenu=[&](std::string_view label){
uint8_t qty=std::stoi(std::string(label));
const std::string&item=Component<MenuLabel>(CONSUMABLE_CRAFT_ITEM,"Item Name Header")->GetString(A::ITEM_NAME);
bool canCraft=Item(qty,item).CanEnhanceItem(qty);
std::string colorCode="";
if(!canCraft)colorCode="#FF0000";
Component<RequiredMaterialsList>(CONSUMABLE_CRAFT_ITEM,"Required Materials List")->SetQuantity(qty);
Component<MenuComponent>(CONSUMABLE_CRAFT_ITEM,"Craft Button")->SetGrayedOut(!canCraft);
};
consumableCraftItemWindow->ADD("Amount to Craft Label",MenuLabel)({{4,34},{188,12}},"Craft Amount",1.0f,ComponentAttr::LEFT_ALIGN|ComponentAttr::SHADOW)END;
consumableCraftItemWindow->ADD("Amount to Craft Amount Label",MenuLabel)({{consumableCraftItemWindow->size.x/2+48,34},{32,12}},"1"
,UpdateMenu,1.0f,ComponentAttr::SHADOW|ComponentAttr::OUTLINE|ComponentAttr::FIT_TO_LABEL)END;
consumableCraftItemWindow->ADD("Increase Craft amount Button",MenuComponent)({{consumableCraftItemWindow->size.x/2+80+2,34},{12,12}},"+",[&](MenuFuncData data){
uint8_t qty=std::clamp(GetQuantity()+1,1,99);
Component<MenuLabel>(CONSUMABLE_CRAFT_ITEM,"Amount to Craft Amount Label")->SetLabel(std::to_string(qty));
return true;
})END;
consumableCraftItemWindow->ADD("Decrease Craft amount Button",MenuComponent)({{consumableCraftItemWindow->size.x/2+48-14,34},{12,12}},"-",[](MenuFuncData data){
uint8_t qty=std::clamp(GetQuantity()-1,1,99);
Component<MenuLabel>(CONSUMABLE_CRAFT_ITEM,"Amount to Craft Amount Label")->SetLabel(std::to_string(qty));
return true;
})END;
consumableCraftItemWindow->ADD("Materials Requirement Outline",MenuComponent)({{2,86-18},{consumableCraftItemWindow->size.x-4,26}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)END;
consumableCraftItemWindow->ADD("Required Materials Label",MenuLabel)({{4,80-18},{consumableCraftItemWindow->size.x-8,0}},"Required Materials",1.0f,ComponentAttr::SHADOW)END;
consumableCraftItemWindow->ADD("Required Materials List",RequiredMaterialsList)({{4,88-18},{consumableCraftItemWindow->size.x-8,22}},Item::BLANK)END;
consumableCraftItemWindow->ADD("Back Button",MenuComponent)({{36,116-18},{48,12}},"Back",[](MenuFuncData data){Menu::CloseMenu();return true;})END;
consumableCraftItemWindow->ADD("Craft Button",MenuComponent)({{consumableCraftItemWindow->size.x-84,116-18},{48,12}},"Craft",[](MenuFuncData data){
const std::weak_ptr<Item>item=Component<RequiredMaterialsList>(CONSUMABLE_CRAFT_ITEM,"Required Materials List")->GetItem();
uint8_t qty=stoi(Component<MenuLabel>(CONSUMABLE_CRAFT_ITEM,"Amount to Craft Amount Label")->GetLabel());
for(uint8_t i=0;i<qty;i++){
if(item.lock()->CanEnhanceItem(qty)){
item.lock()->EnhanceItem(qty);
}
}
data.component->SetGrayedOut(!item.lock()->CanEnhanceItem(qty));
return true;
})END;
}

@ -57,17 +57,12 @@ void Menu::InitializeConsumableCraftingWindow(){
[](MenuFuncData data){ [](MenuFuncData data){
RowItemDisplay*comp=DYNAMIC_CAST<RowItemDisplay*>(data.component); RowItemDisplay*comp=DYNAMIC_CAST<RowItemDisplay*>(data.component);
const std::weak_ptr<Item>item=comp->GetItem(); const std::weak_ptr<Item>item=comp->GetItem();
Component<MenuLabel>(CONSUMABLE_CRAFT_ITEM,"Item Name Header")->GetString(A::ITEM_NAME)=item.lock()->ActualName();
std::string label=""; Component<MenuLabel>(CONSUMABLE_CRAFT_ITEM,"Amount to Craft Amount Label")->SetLabel("1");
if(item.lock()->EnhancementIsPossible()&&item.lock()->GetEnhancementInfo().size()>item.lock()->EnhancementLevel()+1){ Component<MenuLabel>(CONSUMABLE_CRAFT_ITEM,"Item Name Header")->SetLabel(std::format("Crafting {}",item.lock()->DisplayName()));
label=std::format("Level {} ->#00AA00 {}",item.lock()->EnhancementLevel(),item.lock()->EnhancementLevel()+1); Component<RequiredMaterialsList>(CONSUMABLE_CRAFT_ITEM,"Required Materials List")->SetItem(item);
} Component<MenuComponent>(CONSUMABLE_CRAFT_ITEM,"Craft Button")->SetGrayedOut(!item.lock()->CanEnhanceItem());
Component<MenuLabel>(CRAFT_ITEM,"Enhancement Level Header")->SetLabel(label); Menu::OpenMenu(CONSUMABLE_CRAFT_ITEM);
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; return true;
}, },
[](MenuFuncData data){ [](MenuFuncData data){

@ -192,7 +192,7 @@ bool Crawler::OnUserCreate(){
Inventory::AddItem("Minor Health Potion",16); Inventory::AddItem("Minor Health Potion",16);
Inventory::AddItem("Bandages",10); Inventory::AddItem("Bandages",10);
Inventory::AddItem("Green Slime Remains",1); Inventory::AddItem("Green Slime Remains",40);
Inventory::AddItem("Blue Slime Remains",22); Inventory::AddItem("Blue Slime Remains",22);
Inventory::AddItem("Copper Armor"); Inventory::AddItem("Copper Armor");
Inventory::AddItem("Copper Pants"); Inventory::AddItem("Copper Pants");

@ -472,6 +472,10 @@
<ClCompile Include="ClassSelectionWindow.cpp" /> <ClCompile Include="ClassSelectionWindow.cpp" />
<ClCompile Include="ConnectionPoint.cpp" /> <ClCompile Include="ConnectionPoint.cpp" />
<ClCompile Include="ConsumableCraftingWindow.cpp" /> <ClCompile Include="ConsumableCraftingWindow.cpp" />
<ClCompile Include="ConsumableCraftItemWindow.cpp">
<SubType>
</SubType>
</ClCompile>
<ClCompile Include="CraftingRequirement.cpp"> <ClCompile Include="CraftingRequirement.cpp">
<SubType> <SubType>
</SubType> </SubType>

@ -647,6 +647,9 @@
<ClCompile Include="ConsumableCraftingWindow.cpp"> <ClCompile Include="ConsumableCraftingWindow.cpp">
<Filter>Source Files\Interface</Filter> <Filter>Source Files\Interface</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="ConsumableCraftItemWindow.cpp">
<Filter>Source Files\Interface</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="cpp.hint" /> <None Include="cpp.hint" />

@ -69,11 +69,13 @@ struct MerchantFunctionPrimingData:public FunctionPrimingData{
struct ItemEnhancementFunctionPrimingData:public FunctionPrimingData{ struct ItemEnhancementFunctionPrimingData:public FunctionPrimingData{
IT item=""; IT item="";
uint8_t enhancementLevel=0; uint8_t enhancementLevel=0;
uint8_t qty=0;
inline ItemEnhancementFunctionPrimingData(std::string dependentFunction) inline ItemEnhancementFunctionPrimingData(std::string dependentFunction)
:FunctionPrimingData(dependentFunction){} :FunctionPrimingData(dependentFunction){}
virtual inline void Validate(IT item,uint8_t enhancementLevel){ virtual inline void Validate(IT item,uint8_t enhancementLevel,uint8_t qty){
if(!primed)ERR(std::format("WARNING! {} should be called before running this function! Priming Requirement!",dependentFunction)); if(!primed)ERR(std::format("WARNING! {} should be called before running this function! Priming Requirement!",dependentFunction));
if(this->item!=item)ERR(std::format("WARNING! Primed items are not matching! {}!={}",this->item,item)); if(this->item!=item)ERR(std::format("WARNING! Primed items are not matching! {}!={}",this->item,item));
if(this->qty!=qty)ERR(std::format("WARNING! Primed items do not have the same quantity! {}!={}",this->qty,qty));
if(this->enhancementLevel!=enhancementLevel)ERR(std::format("WARNING! Primed enhancement levels are not matching! {}!={}",this->enhancementLevel,enhancementLevel)); if(this->enhancementLevel!=enhancementLevel)ERR(std::format("WARNING! Primed enhancement levels are not matching! {}!={}",this->enhancementLevel,enhancementLevel));
primed=false; primed=false;
} }

@ -248,6 +248,8 @@ void ItemInfo::InitializeItems(){
ReadItems(DATA["ItemDatabase"]); ReadItems(DATA["ItemDatabase"]);
ReadItems(DATA["Equipment"]); ReadItems(DATA["Equipment"]);
std::sort(craftableConsumables.begin(),craftableConsumables.end(),[](std::shared_ptr<Item>&item1,std::shared_ptr<Item>&item2){return item1.get()->GetEnhancementInfo().AvailableChapter()<item2.get()->GetEnhancementInfo().AvailableChapter();});
ITEM_DATA.SetInitialized(); ITEM_DATA.SetInitialized();
ITEM_CATEGORIES.SetInitialized(); ITEM_CATEGORIES.SetInitialized();
Menu::LockInListeners(); Menu::LockInListeners();
@ -557,12 +559,15 @@ const std::string Item::Description(CompactText compact)const{
Inventory::GetItemCount(name)); Inventory::GetItemCount(name));
} }
description+="\n"; description+="\n";
uint32_t goldCost=info.craftingRequirement.GetCost();
if(goldCost>0){
description+=std::format("{}Crafting Cost: {} {}", description+=std::format("{}Crafting Cost: {} {}",
game->GetPlayer()->GetMoney()<info.craftingRequirement.GetCost()?"#FF0000":"#FFFFFF", game->GetPlayer()->GetMoney()<goldCost?"#FF0000":"#FFFFFF",
info.craftingRequirement.GetCost(), goldCost,
"Item.Currency Name"_S); "Item.Currency Name"_S);
} }
} }
}
return description; return description;
} }
const ITCategory Item::Category()const{ const ITCategory Item::Category()const{
@ -765,9 +770,11 @@ const std::optional<const ItemSet*const>Item::ItemSet()const{
const uint8_t Item::EnhancementLevel()const{ const uint8_t Item::EnhancementLevel()const{
return enhancementLevel; return enhancementLevel;
}; };
void Item::EnhanceItem(){ void Item::EnhanceItem(uint8_t qty){
enhanceFunctionPrimed.Validate(ActualName(),EnhancementLevel()); if(qty==0)ERR("WARNING! You must specify at least 1 item to be enhanced!")
enhanceFunctionPrimed.Validate(ActualName(),EnhancementLevel(),qty);
for(uint8_t i=0;i<qty;i++){
if(GetEnhancementInfo().size()!=2){
if(enhancementLevel+1>"Item.Item Max Enhancement Level"_I)ERR("WARNING! Attempted to enhance "<<DisplayName()<<" beyond the cap of "<<"Item.Item Max Enhancement Level"_I); if(enhancementLevel+1>"Item.Item Max Enhancement Level"_I)ERR("WARNING! Attempted to enhance "<<DisplayName()<<" beyond the cap of "<<"Item.Item Max Enhancement Level"_I);
enhancementLevel++; enhancementLevel++;
@ -778,6 +785,17 @@ void Item::EnhanceItem(){
Inventory::RemoveItem(name,amt); Inventory::RemoveItem(name,amt);
} }
game->GetPlayer()->SetMoney(game->GetPlayer()->GetMoney()-consumedResources.GetCost()); game->GetPlayer()->SetMoney(game->GetPlayer()->GetMoney()-consumedResources.GetCost());
}else{ //This is a craftable, so we have to give the player the item they crafted.
Inventory::AddItem(ActualName());
const CraftingRequirement&consumedResources=GetEnhancementInfo()[1].craftingRequirement;
for(const auto&[name,amt]:consumedResources.GetItems()){
Inventory::RemoveItem(name,amt);
}
game->GetPlayer()->SetMoney(game->GetPlayer()->GetMoney()-consumedResources.GetCost());
}
}
}; };
const std::vector<std::pair<int,Stats>>&ItemSet::GetSetBonusBreakpoints()const{ const std::vector<std::pair<int,Stats>>&ItemSet::GetSetBonusBreakpoints()const{
@ -917,7 +935,8 @@ void EnhancementInfo::SetCraftingRequirements(const int enhanceLevel,const std::
EnhancementLevelInfo::EnhancementLevelInfo(const Stats&stats,const CraftingRequirement&craftingRequirement) EnhancementLevelInfo::EnhancementLevelInfo(const Stats&stats,const CraftingRequirement&craftingRequirement)
:stats(stats),craftingRequirement(craftingRequirement){} :stats(stats),craftingRequirement(craftingRequirement){}
const bool Item::CanEnhanceItem()const{ const bool Item::CanEnhanceItem(uint8_t qty)const{
if(qty==0)ERR("WARNING! Must specify at least 1 for the quantity!")
if(ISBLANK(std::make_shared<Item>(*this)))return false; if(ISBLANK(std::make_shared<Item>(*this)))return false;
if(!GetEnhancementInfo().CanBeEnhanced())return false; if(!GetEnhancementInfo().CanBeEnhanced())return false;
if(GetEnhancementInfo().AvailableChapter()<game->GetCurrentChapter())return false; if(GetEnhancementInfo().AvailableChapter()<game->GetCurrentChapter())return false;
@ -925,15 +944,16 @@ const bool Item::CanEnhanceItem()const{
if(GetEnhancementInfo().size()>2){ //If the item has exactly 2 enhancement levels, then it's an item that can only simply be crafted. Therefore, don't do the max enhancement level check. if(GetEnhancementInfo().size()>2){ //If the item has exactly 2 enhancement levels, then it's an item that can only simply be crafted. Therefore, don't do the max enhancement level check.
if(EnhancementLevel()>="Item.Item Max Enhancement Level"_I)return false; if(EnhancementLevel()>="Item.Item Max Enhancement Level"_I)return false;
} }
if(game->GetPlayer()->GetMoney()<enhanceInfo.craftingRequirement.GetCost())return false; if(game->GetPlayer()->GetMoney()<enhanceInfo.craftingRequirement.GetCost()*qty)return false;
for(const auto&[name,amt]:enhanceInfo.craftingRequirement.GetItems()){ for(const auto&[name,amt]:enhanceInfo.craftingRequirement.GetItems()){
if(Inventory::GetItemCount(name)<amt){ if(Inventory::GetItemCount(name)<amt*qty){
return false; return false;
} }
} }
enhanceFunctionPrimed.enhancementLevel=EnhancementLevel(); enhanceFunctionPrimed.enhancementLevel=EnhancementLevel();
enhanceFunctionPrimed.item=ActualName(); enhanceFunctionPrimed.item=ActualName();
enhanceFunctionPrimed.qty=qty;
return enhanceFunctionPrimed=true; return enhanceFunctionPrimed=true;
} }

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

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

@ -78,6 +78,7 @@ enum MenuType{
BLACKSMITH, BLACKSMITH,
CRAFT_ITEM, CRAFT_ITEM,
CRAFT_CONSUMABLE, CRAFT_CONSUMABLE,
CONSUMABLE_CRAFT_ITEM,
#pragma region Enum End //DO NOT REMOVE #pragma region Enum End //DO NOT REMOVE
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
/*DO NOT REMOVE!!*/ENUM_END//////////////////////////////// /*DO NOT REMOVE!!*/ENUM_END////////////////////////////////
@ -102,6 +103,7 @@ class Menu:public IAttributable{
static void InitializeBlacksmithCraftingWindow(); static void InitializeBlacksmithCraftingWindow();
static void InitializeCraftItemWindow(); static void InitializeCraftItemWindow();
static void InitializeConsumableCraftingWindow(); static void InitializeConsumableCraftingWindow();
static void InitializeConsumableCraftItemWindow();
friend class Crawler; friend class Crawler;
friend struct Player; friend struct Player;

@ -50,7 +50,14 @@ protected:
bool shadow=false; bool shadow=false;
bool centered=true; bool centered=true;
bool proportional=true; bool proportional=true;
bool runOnLabelChangeFunc=false;
std::function<void(std::string_view newLabel)>onLabelChangeFunc;
public: public:
inline MenuLabel(geom2d::rect<float>rect,std::string label,std::function<void(std::string_view newLabel)>onLabelChangeFunc,float scale=1,ComponentAttr attributes=ComponentAttr::NONE)
:MenuLabel(rect,label,scale,attributes){
runOnLabelChangeFunc=true;
this->onLabelChangeFunc=onLabelChangeFunc;
}
inline MenuLabel(geom2d::rect<float>rect,std::string label,float scale=1,ComponentAttr attributes=ComponentAttr::NONE) 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),proportional(!(attributes&ComponentAttr::FIXED_WIDTH_FONT)){ :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; border=attributes&ComponentAttr::OUTLINE;
@ -60,6 +67,7 @@ public:
} }
inline virtual void SetLabel(std::string text){ inline virtual void SetLabel(std::string text){
label=text; label=text;
if(runOnLabelChangeFunc)onLabelChangeFunc(text);
} }
protected: protected:
inline virtual void Update(Crawler*game)override{ inline virtual void Update(Crawler*game)override{

@ -42,6 +42,7 @@ All rights reserved.
class RequiredMaterialsList:public MenuLabel{ class RequiredMaterialsList:public MenuLabel{
std::weak_ptr<Item>itemRef; std::weak_ptr<Item>itemRef;
uint8_t qty=1;
public: public:
inline RequiredMaterialsList(geom2d::rect<float>rect,const std::weak_ptr<Item>itemRef,ComponentAttr attributes=ComponentAttr::SHADOW|ComponentAttr::LEFT_ALIGN) 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){} :MenuLabel(rect,"",1.f,attributes),itemRef(itemRef){}
@ -51,6 +52,9 @@ public:
inline const std::weak_ptr<Item>GetItem()const{ inline const std::weak_ptr<Item>GetItem()const{
return itemRef; return itemRef;
} }
inline void SetQuantity(uint8_t quantity){
this->qty=quantity;
}
protected: protected:
inline virtual void DrawDecal(ViewPort&window,bool focused)override final{ inline virtual void DrawDecal(ViewPort&window,bool focused)override final{
MenuComponent::DrawDecal(window,focused); MenuComponent::DrawDecal(window,focused);
@ -70,23 +74,25 @@ protected:
int index=0; int index=0;
for(const auto&[name,amt]:itemRef.lock()->GetEnhancementInfo()[itemRef.lock()->EnhancementLevel()+1].craftingRequirement.GetItems()){ for(const auto&[name,amt]:itemRef.lock()->GetEnhancementInfo()[itemRef.lock()->EnhancementLevel()+1].craftingRequirement.GetItems()){
Pixel textCol=WHITE; Pixel textCol=WHITE;
if(Inventory::GetItemCount(name)<amt)textCol=RED; if(Inventory::GetItemCount(name)<amt*qty)textCol=RED;
vf2d drawPos=rect.pos+vf2d{drawWidth*(index%3),12.f*(index/3)}; vf2d drawPos=rect.pos+vf2d{drawWidth*(index%3),12.f*(index/3)};
std::string labelText=std::format("{}",name); std::string labelText=std::format("{}",name);
float labelWidth=game->GetTextSizeProp(labelText).x; float labelWidth=game->GetTextSizeProp(labelText).x;
window.DrawShadowStringDecal(drawPos,std::format("{:>3}",amt),textCol,BLACK); window.DrawShadowStringDecal(drawPos,std::format("{:>3}",amt*qty),textCol,BLACK);
window.DrawShadowStringPropDecal(drawPos+vf2d{26,0},labelText,textCol,BLACK,{std::min(1.f,(drawWidth-26-2)/labelWidth),1.f}); window.DrawShadowStringPropDecal(drawPos+vf2d{26,0},labelText,textCol,BLACK,{std::min(1.f,(drawWidth-26-2)/labelWidth),1.f});
index++; index++;
} }
Pixel textCol=WHITE; Pixel textCol=WHITE;
uint32_t goldAmt=itemRef.lock()->GetEnhancementInfo()[itemRef.lock()->EnhancementLevel()+1].craftingRequirement.GetCost(); uint32_t goldAmt=itemRef.lock()->GetEnhancementInfo()[itemRef.lock()->EnhancementLevel()+1].craftingRequirement.GetCost();
if(game->GetPlayer()->GetMoney()<goldAmt)textCol=RED; if(goldAmt>0){
if(game->GetPlayer()->GetMoney()<goldAmt*qty)textCol=RED;
vf2d drawPos=rect.pos+vf2d{drawWidth*(index%3),12.f*(index/3)}; vf2d drawPos=rect.pos+vf2d{drawWidth*(index%3),12.f*(index/3)};
std::string goldAmtText=std::format("{:>3}",goldAmt); std::string goldAmtText=std::format("{:>3}",goldAmt*qty);
std::string labelText=std::format("{}","Item.Currency Name"_S); std::string labelText=std::format("{}","Item.Currency Name"_S);
float goldAmtWidth=game->GetTextSize(goldAmtText).x; float goldAmtWidth=game->GetTextSize(goldAmtText).x;
window.DrawShadowStringDecal(drawPos,goldAmtText,textCol,BLACK); window.DrawShadowStringDecal(drawPos,goldAmtText,textCol,BLACK);
window.DrawShadowStringPropDecal(drawPos+vf2d{goldAmtWidth+2,0},labelText,textCol,BLACK); window.DrawShadowStringPropDecal(drawPos+vf2d{goldAmtWidth+2,0},labelText,textCol,BLACK);
}
index++; index++;
} }
} }

@ -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 5056 #define VERSION_BUILD 5077
#define stringify(a) stringify_(a) #define stringify(a) stringify_(a)
#define stringify_(a) #a #define stringify_(a) #a

@ -150,6 +150,7 @@ Monsters
# Drop Item Name, Drop Percentage(0-100%), Drop Min Quantity, Drop Max Quantity # Drop Item Name, Drop Percentage(0-100%), Drop Min Quantity, Drop Max Quantity
DROP[0] = Bandages,30%,1,1 DROP[0] = Bandages,30%,1,1
DROP[1] = Berries,5%,1,1 DROP[1] = Berries,5%,1,1
DROP[2] = Flower Petals,10%,1,1
#Additional custom animations go down below. Start with ANIMATION[0] #Additional custom animations go down below. Start with ANIMATION[0]
#ANIMATION[0] = MY_NEW_ANIMATION #ANIMATION[0] = MY_NEW_ANIMATION

@ -29,7 +29,7 @@ ItemDatabase
Item[0] = Green Slime Remains,3 Item[0] = Green Slime Remains,3
Item[1] = Blue Slime Remains,1 Item[1] = Blue Slime Remains,1
Gold = 0 Gold = 10
} }
} }
Minor Mana Potion Minor Mana Potion
@ -45,7 +45,7 @@ ItemDatabase
Crafting Crafting
{ {
# When this crafting recipe is available. # When this crafting recipe is available.
AvailableChapter = 1 AvailableChapter = 2
Item[0] = Red Slime Remains,1 Item[0] = Red Slime Remains,1
Item[1] = Yellow Slime Remains,1 Item[1] = Yellow Slime Remains,1
@ -86,7 +86,7 @@ ItemDatabase
Crafting Crafting
{ {
# When this crafting recipe is available. # When this crafting recipe is available.
AvailableChapter = 2 AvailableChapter = 1
Item[0] = Bear Claw,1 Item[0] = Bear Claw,1
Item[1] = Bear Blood,1 Item[1] = Bear Blood,1

@ -1,3 +1,6 @@
ALLTOTAL=$(wc -l $(find *.cpp *.h)|grep "total"|awk '{print $1}')
TOTAL=$(wc -l $(find *.cpp *.h -not -name "miniaudio.h" -not -name "olc*.h")|grep "total"|awk '{print $1}') TOTAL=$(wc -l $(find *.cpp *.h -not -name "miniaudio.h" -not -name "olc*.h")|grep "total"|awk '{print $1}')
FILECOUNT=$(find *.cpp *.h -not -name "miniaudio.h" -not -name "olc*.h"|wc -l) FILECOUNT=$(find *.cpp *.h -not -name "miniaudio.h" -not -name "olc*.h"|wc -l)
echo "ALL: $[ALLTOTAL]"
echo "$[TOTAL-FILECOUNT*37] (License lines Excluded)" echo "$[TOTAL-FILECOUNT*37] (License lines Excluded)"

Loading…
Cancel
Save