diff --git a/Adventures in Lestoria/Adventures in Lestoria.vcxproj b/Adventures in Lestoria/Adventures in Lestoria.vcxproj
index 67d911ca..21190f13 100644
--- a/Adventures in Lestoria/Adventures in Lestoria.vcxproj
+++ b/Adventures in Lestoria/Adventures in Lestoria.vcxproj
@@ -359,15 +359,15 @@
-
+
-
+
-
+
@@ -599,6 +599,10 @@
+
+
+
+
diff --git a/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters b/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters
index 8eb713fc..a4884c87 100644
--- a/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters
+++ b/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters
@@ -423,9 +423,6 @@
Header Files\Interface
-
- Header Files
-
Header Files
@@ -447,6 +444,9 @@
Header Files\State
+
+ Header Files
+
@@ -776,6 +776,9 @@
Source Files\Interface
+
+ Source Files
+
diff --git a/Adventures in Lestoria/AdventuresInLestoria.cpp b/Adventures in Lestoria/AdventuresInLestoria.cpp
index 61c5442a..c64bfa79 100644
--- a/Adventures in Lestoria/AdventuresInLestoria.cpp
+++ b/Adventures in Lestoria/AdventuresInLestoria.cpp
@@ -243,33 +243,8 @@ bool AiL::OnUserCreate(){
Menu::InitializeMenus();
- Inventory::AddItem("Minor Health Potion",16);
- Inventory::AddItem("Bandages",10);
- Inventory::AddItem("Green Slime Remains",40);
- Inventory::AddItem("Blue Slime Remains",22);
- Inventory::AddItem("Copper Armor");
- Inventory::AddItem("Copper Pants");
- Inventory::AddItem("Copper Helmet");
- Inventory::AddItem("Copper Shoes");
- Inventory::AddItem("Shell Helmet");
- Inventory::AddItem("Shell Armor");
- Inventory::AddItem("Shell Armor");
- Inventory::AddItem("Shell Armor");
- Inventory::AddItem("Bone Armor");
- Inventory::AddItem("Shell Gloves");
- Inventory::AddItem("Shell Gloves",3);
- Inventory::AddItem("Shell Shoes");
- Inventory::AddItem("Bone Pants");
- Inventory::AddItem("Bone Gloves");
- Inventory::AddItem("Elixir of Bear Strength",3);
- Inventory::AddItem("Leather Helmet");
- Inventory::AddItem("Leather Pants");
- Inventory::AddItem("Leather Gloves");
- Inventory::AddItem("Leather Shoes");
- Inventory::AddItem("Wooden Sword");
- Inventory::AddItem("Laser Sword");
- Inventory::AddItem("Shell Sword");
- Inventory::AddItem("Ring of the Slime King",3);
+ Inventory::AddItem("Minor Health Potion"s,3);
+ Inventory::AddItem("Bandages"s,10);
Audio::Initialize();
EnvironmentalAudio::Initialize();
diff --git a/Adventures in Lestoria/BlacksmithCraftingWindow.cpp b/Adventures in Lestoria/BlacksmithCraftingWindow.cpp
index d0902d97..15d73bca 100644
--- a/Adventures in Lestoria/BlacksmithCraftingWindow.cpp
+++ b/Adventures in Lestoria/BlacksmithCraftingWindow.cpp
@@ -142,14 +142,25 @@ void Menu::InitializeBlacksmithCraftingWindow(){
const std::weak_ptr- item=comp.lock()->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);
+ if(Inventory::GetItemCount(item.lock()->ActualName())==0){ //If we don't own the item we have to create it first.
+ if(item.lock()->EnhancementIsPossible()&&item.lock()->GetEnhancementInfo().size()>item.lock()->EnhancementLevel()+1){
+ label="";
+ }
+ Component(CRAFT_ITEM,"Enhancement Level Header")->SetLabel(label);
+ Component(CRAFT_ITEM,"Item Name Header")->SetLabel(std::format("Crafting {}",item.lock()->DisplayName()));
+ Component(CRAFT_ITEM,"Enhancement Stats Label")->SetItem(item);
+ Component(CRAFT_ITEM,"Required Materials List")->SetItem(item);
+ Component(CRAFT_ITEM,"Craft Button")->SetGrayedOut(!item.lock()->CanEnhanceItem());
+ }else{ //We will open the menu that lets us enhance by one level.
+ 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(CRAFT_ITEM,"Enhancement Level Header")->SetLabel(label);
+ Component(CRAFT_ITEM,"Item Name Header")->SetLabel(std::format("Enhancing {}",item.lock()->DisplayName()));
+ Component(CRAFT_ITEM,"Enhancement Stats Label")->SetItem(item);
+ Component(CRAFT_ITEM,"Required Materials List")->SetItem(item);
+ Component(CRAFT_ITEM,"Craft Button")->SetGrayedOut(!item.lock()->CanEnhanceItem());
}
- Component(CRAFT_ITEM,"Enhancement Level Header")->SetLabel(label);
- Component(CRAFT_ITEM,"Item Name Header")->SetLabel(std::format("Crafting {}",item.lock()->DisplayName()));
- Component(CRAFT_ITEM,"Enhancement Stats Label")->SetItem(item);
- Component(CRAFT_ITEM,"Required Materials List")->SetItem(item);
- Component(CRAFT_ITEM,"Craft Button")->SetGrayedOut(!item.lock()->CanEnhanceItem());
return true;
},
[](MenuFuncData data){
diff --git a/Adventures in Lestoria/CraftItemWindow.cpp b/Adventures in Lestoria/CraftItemWindow.cpp
index f1546f14..1629a62e 100644
--- a/Adventures in Lestoria/CraftItemWindow.cpp
+++ b/Adventures in Lestoria/CraftItemWindow.cpp
@@ -56,10 +56,12 @@ void Menu::InitializeCraftItemWindow(){
craftItemWindow->ADD("Back Button",MenuComponent)(geom2d::rect{{36,116},{48,12}},"Back",[](MenuFuncData data){Menu::CloseMenu();return true;})END;
craftItemWindow->ADD("Craft Button",MenuComponent)(geom2d::rect{{craftItemWindow->size.x-84,116},{48,12}},"Craft",[](MenuFuncData data){
- const std::weak_ptr
- item=Component(data.menu.GetType(),"Enhancement Stats Label")->GetItem();
+ std::weak_ptr
- item=Component(data.menu.GetType(),"Enhancement Stats Label")->GetItem();
if(item.lock()->CanEnhanceItem()){
if(Inventory::GetItemCount(item.lock()->ActualName())==0){ //We don't own this item, so we need to give the player this item and refresh the blacksmith's inventory.
- Inventory::AddItem(item.lock()->ActualName());
+ item=Inventory::AddItem(item.lock()->ActualName());
+ Component(CRAFT_ITEM,"Enhancement Stats Label")->SetItem(item);
+ Component(CRAFT_ITEM,"Required Materials List")->SetItem(item); //Update the item refs in the enhancement level screen to now display the correct item.
Inventory::UpdateBlacksmithInventoryLists();
}else{ //Since we already own this equipment, just enhance it.
item.lock()->EnhanceItem();
diff --git a/Adventures in Lestoria/DEFINES.h b/Adventures in Lestoria/DEFINES.h
index df972138..6dd69956 100644
--- a/Adventures in Lestoria/DEFINES.h
+++ b/Adventures in Lestoria/DEFINES.h
@@ -57,6 +57,7 @@ using BackdropName=std::string;
#define INCLUDE_ITEM_CATEGORIES extern safemap>ITEM_CATEGORIES;
#define DO_NOTHING [](MenuFuncData data){return true;}
#define INCLUDE_WINDOW_SIZE extern vi2d WINDOW_SIZE;
+#define INCLUDE_ITEM_CONVERSIONS extern safemapITEM_CONVERSIONS;
#define INCLUDE_BACKDROP_DATA extern std::mapBACKDROP_DATA;
@@ -75,7 +76,7 @@ class::class() \
class::class(Player*player) \
:Player::Player(player){} \
Class class::GetClass(){return cl;} \
-std::string class::GetClassName(){return name;} \
+const std::string&class::GetClassName(){return name;} \
Ability&class::GetRightClickAbility(){return rightClickAbility;}; \
Ability&class::GetAbility1(){return ability1;}; \
Ability&class::GetAbility2(){return ability2;}; \
diff --git a/Adventures in Lestoria/EnhancementStatsLabel.h b/Adventures in Lestoria/EnhancementStatsLabel.h
index eda66391..c2fdd9c5 100644
--- a/Adventures in Lestoria/EnhancementStatsLabel.h
+++ b/Adventures in Lestoria/EnhancementStatsLabel.h
@@ -90,16 +90,13 @@ protected:
std::string percentageSign=attr.DisplayAsPercent()?"%":"";
if(Inventory::GetItemCount(itemRef.lock()->ActualName())==0){ //This item hasn't been created yet, so just show that we are developing the item first.
- window.DrawShadowStringDecal(drawPos+vf2d{maxAttributeLabelSize+4+24,yOffset},std::format("{:<5}",
- attr.ShowAsDecimal()?std::format("{:>4.2f}{}",value,percentageSign):std::format("{}{}",value,percentageSign),
- nextStageValue!=0?
- attr.ShowAsDecimal()?std::format("{:<4.2f}{}",nextStageValue,percentageSign):std::format("{}{}",nextStageValue,percentageSign)
- :"MAX"),
+ window.DrawShadowStringDecal(drawPos+vf2d{maxAttributeLabelSize+4+24,yOffset},std::format("{:<5}",(
+ (attr.ShowAsDecimal()?std::format("{:>4.2f}{}",value,percentageSign):std::format("{}{}",value,percentageSign)))),
WHITE,BLACK,adjustedScale,fitToLabel?std::numeric_limits::max():rect.size.x,1.0f);
}else{ //This item is getting enhanced to the next level.
window.DrawShadowStringDecal(drawPos+vf2d{maxAttributeLabelSize+4+24,yOffset},std::format("{:>5} ->#00AA00 {:<5}",
attr.ShowAsDecimal()?std::format("{:>4.2f}{}",value,percentageSign):std::format("{}{}",value,percentageSign),
- nextStageValue!=0?
+ nextEnhanceLevel!="Item.Item Max Enhancement Level"_I?
attr.ShowAsDecimal()?std::format("{:<4.2f}{}",nextStageValue,percentageSign):std::format("{}{}",nextStageValue,percentageSign)
:"MAX"),
WHITE,BLACK,adjustedScale,fitToLabel?std::numeric_limits::max():rect.size.x,1.0f);
diff --git a/Adventures in Lestoria/FunctionPriming.h b/Adventures in Lestoria/FunctionPriming.h
index ecd653b5..e64c8df2 100644
--- a/Adventures in Lestoria/FunctionPriming.h
+++ b/Adventures in Lestoria/FunctionPriming.h
@@ -38,7 +38,9 @@ All rights reserved.
#pragma once
#include "Error.h"
#include
-using IT=std::string;
+#include "IT.h"
+
+using namespace std::literals;
struct FunctionPrimingData{
bool primed=false;
@@ -51,7 +53,7 @@ struct FunctionPrimingData{
};
struct MerchantFunctionPrimingData:public FunctionPrimingData{
- IT item="";
+ IT item=""s;
uint32_t amt=0;
inline MerchantFunctionPrimingData(std::string dependentFunction)
:FunctionPrimingData(dependentFunction){}
@@ -67,7 +69,7 @@ struct MerchantFunctionPrimingData:public FunctionPrimingData{
};
struct ItemEnhancementFunctionPrimingData:public FunctionPrimingData{
- IT item="";
+ IT item=""s;
uint8_t enhancementLevel=0;
uint8_t qty=0;
inline ItemEnhancementFunctionPrimingData(std::string dependentFunction)
diff --git a/Adventures in Lestoria/IT.cpp b/Adventures in Lestoria/IT.cpp
new file mode 100644
index 00000000..728a000d
--- /dev/null
+++ b/Adventures in Lestoria/IT.cpp
@@ -0,0 +1,70 @@
+#pragma region License
+/*
+License (OLC-3)
+~~~~~~~~~~~~~~~
+
+Copyright 2024 Joshua Sigona
+
+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 "DEFINES.h"
+#include "IT.h"
+#include "Item.h"
+
+INCLUDE_ITEM_CONVERSIONS
+
+IT::IT():itemName(""){}
+IT::IT(std::string name)
+ :itemName(name){
+ if(ITEM_CONVERSIONS.count(name)){
+ itemName=ITEM_CONVERSIONS.at(name); //Convert the item if it's using an old name.
+ }
+}
+IT::operator std::string(){
+ return itemName;
+}
+std::ostream&operator<<(std::ostream&rhs,IT&item){
+ rhs<&rhs){
+ return itemName==rhs->ActualName();
+}
+const bool IT::operator==(const std::weak_ptr
- &rhs){
+ return !rhs.expired()&&itemName==rhs.lock()->ActualName();
+}
+const bool operator==(const IT&lhs,const IT&rhs){
+ return lhs.itemName==rhs.itemName;
+}
+const bool operator<(const IT&lhs,const IT&rhs){
+ return lhs.itemName
+#include
+#include
+
+class Item;
+
+class IT{
+ friend struct std::formatter;
+ std::string itemName="";
+public:
+ IT();
+ IT(std::string name);
+ operator std::string();
+ const bool operator==(const std::shared_ptr
- &rhs);
+ const bool operator==(const std::weak_ptr
- &rhs);
+ friend std::ostream&operator<<(std::ostream&rhs,IT&item);
+ friend const bool operator==(const IT&lhs,const IT&rhs);
+ friend const bool operator<(const IT&lhs,const IT&rhs);
+};
+template <>
+struct std::formatter {
+ constexpr auto parse(std::format_parse_context&ctx) {
+ return ctx.begin();
+ }
+
+ auto format(const IT&item,std::format_context&ctx) const {
+ return std::format_to(ctx.out(),"{}",item.itemName);
+ }
+};
\ No newline at end of file
diff --git a/Adventures in Lestoria/InventoryCreator.cpp b/Adventures in Lestoria/InventoryCreator.cpp
index 6c65e452..9564aabf 100644
--- a/Adventures in Lestoria/InventoryCreator.cpp
+++ b/Adventures in Lestoria/InventoryCreator.cpp
@@ -146,7 +146,11 @@ std::function
[](InventoryScrollableWindowComponent&component,ITCategory cat){
std::vector>weapons;
std::copy_if(Inventory::get("Equipment").begin(),Inventory::get("Equipment").end(),std::back_inserter(weapons),[](std::shared_ptr
- item){return item->IsWeapon();});
- std::copy_if(Inventory::blacksmithInventory.begin(),Inventory::blacksmithInventory.end(),std::back_inserter(weapons),[](std::shared_ptr
- item){return item->IsWeapon();});
+ std::copy_if(Inventory::blacksmithInventory.begin(),Inventory::blacksmithInventory.end(),std::back_inserter(weapons),[](std::shared_ptr
- item){return game->GetCurrentChapter()>=item->GetEnhancementInfo().AvailableChapter()&&item->GetClass()==game->GetPlayer()->GetClassName()&&item->IsWeapon();});
+
+ std::sort(weapons.begin(),weapons.end(),[](const std::weak_ptr
- &it1,const std::weak_ptr
- &it2){
+ return ItemSortRules::GetItemSortRanking(it1)(&component);
@@ -183,7 +187,11 @@ std::function
[](InventoryScrollableWindowComponent&component,ITCategory cat){
std::vector>armor;
std::copy_if(Inventory::get("Equipment").begin(),Inventory::get("Equipment").end(),std::back_inserter(armor),[](std::shared_ptr
- item){return item->IsArmor();});
- std::copy_if(Inventory::blacksmithInventory.begin(),Inventory::blacksmithInventory.end(),std::back_inserter(armor),[](std::shared_ptr
- item){return item->IsArmor();});
+ std::copy_if(Inventory::blacksmithInventory.begin(),Inventory::blacksmithInventory.end(),std::back_inserter(armor),[](std::shared_ptr
- item){return game->GetCurrentChapter()>=item->GetEnhancementInfo().AvailableChapter()&&item->GetClass()==game->GetPlayer()->GetClassName()&&item->IsArmor();});
+
+ std::sort(armor.begin(),armor.end(),[](const std::weak_ptr
- &it1,const std::weak_ptr
- &it2){
+ return ItemSortRules::GetItemSortRanking(it1)(&component);
diff --git a/Adventures in Lestoria/Item.cpp b/Adventures in Lestoria/Item.cpp
index 8518893e..94001a44 100644
--- a/Adventures in Lestoria/Item.cpp
+++ b/Adventures in Lestoria/Item.cpp
@@ -69,11 +69,20 @@ int Item::IsBlankStaticCallCounter=0;
safemapStats::maxDamageReductionTable;
ItemEnhancementFunctionPrimingData Item::enhanceFunctionPrimed("CanEnhanceItem()");
std::vector>ItemInfo::craftableConsumables;
+std::vectorItemSortRules::primarySort;
+std::vectorItemSortRules::secondarySort;
ItemInfo::ItemInfo()
:customProps({nullptr,nullptr}),img(nullptr){}
void ItemInfo::InitializeItems(){
+ for(const std::string&data:DATA.GetProperty("Item.Equipment Sort Order Primary").GetValues()){
+ ItemSortRules::primarySort.push_back(data);
+ }
+ for(const std::string&data:DATA.GetProperty("Item.Equipment Sort Order Secondary").GetValues()){
+ ItemSortRules::secondarySort.push_back(data);
+ }
+
for(int i=int(EquipSlot::HELMET);i<=int(EquipSlot::RING2);i<<=1){
Inventory::equipment[EquipSlot(i)]=Item::BLANK;
}
@@ -171,8 +180,8 @@ void ItemInfo::InitializeItems(){
if(data[key].HasProperty("StatValues[0]")){ //This means this has enhancement levels.
EnhancementInfo enhancementStats;
+ uint8_t availableChapter=1;
for(int enhancementLevel=0;enhancementLevel<=10;enhancementLevel++){
- uint8_t availableChapter=1;
datafile&dat=data[key]["StatValues["+std::to_string(enhancementLevel)+"]"];
for(int attrIndex=0;ItemAttribute&attr:statValueList){
enhancementStats.SetAttribute(enhancementLevel,attr,dat.GetReal(attrIndex));
@@ -295,6 +304,13 @@ void ItemInfo::InitializeItems(){
if(it.Category()=="Accessories"&&it.IsArmor())ERR(std::format("WARNING! {} is in the Accessories Category, but is considered Armor!",it.Name()))
if(it.Category()=="Accessories"&&!it.IsAccessory())ERR(std::format("WARNING! {} is in the Accessories Category, but not considered an Accessory!",it.Name()))
#pragma endregion
+
+ #pragma region Equipment Sort Rules Verification Tests
+ if(category=="Equipment"){
+ if(std::find_if(ItemSortRules::primarySort.begin(),ItemSortRules::primarySort.end(),[&](const std::string&sort){return key.find(sort)!=std::string::npos;})==ItemSortRules::primarySort.end())ERR(std::format("WARNING! Item {} does not have valid equipment sorting primary rule! Check items.txt config key: 'Equipment Sort Order Primary'!",key))
+ if(std::find_if(ItemSortRules::secondarySort.begin(),ItemSortRules::secondarySort.end(),[&](const std::string&sort){return key.find(sort)!=std::string::npos;})==ItemSortRules::secondarySort.end())ERR(std::format("WARNING! Item {} does not have valid equipment sorting secondary rule! Check items.txt config key: 'Equipment Sort Order Secondary'!",key))
+ }
+ #pragma endregion
}
};
@@ -408,28 +424,19 @@ Item::Item()
:amt(0),it(nullptr),enhancementLevel(0){}
Item::Item(uint32_t amt,IT item,uint8_t enhancementLevel)
- :amt(amt),enhancementLevel(enhancementLevel){
- if(ITEM_CONVERSIONS.count(item)){
- it=&ITEM_DATA.at(ITEM_CONVERSIONS[item]); //Convert the item if it's using an old name.
- }else{
- it=&ITEM_DATA.at(item);
- }
-}
+ :amt(amt),enhancementLevel(enhancementLevel),it(&ITEM_DATA.at(item)){}
std::weak_ptr
- Inventory::AddItem(IT it,uint32_t amt,bool monsterDrop){
- if(ITEM_CONVERSIONS.count(it)){
- it=ITEM_CONVERSIONS[it]; //Convert the item if it's using an old name.
- }
- if(!ITEM_DATA.count(it))ERR("Item "<itemPtr;
+ std::shared_ptr
- newItem;
if(ITEM_DATA[it].IsEquippable()){ //Do not stack equips!
for(uint32_t i=0;inewItem=(*_inventory.insert({it,std::make_shared
- (1,it)})).second;
+ newItem=(*_inventory.insert({it,std::make_shared
- (1,it)})).second;
newItem->RandomizeStats();
InsertIntoSortedInv(newItem);
- InsertIntoStageInventoryCategory(newItem,monsterDrop);
itemPtr=newItem;
}
goto SkipAddingStackableItem;
@@ -437,9 +444,8 @@ std::weak_ptr
- Inventory::AddItem(IT it,uint32_t amt,bool monsterDrop){
else
//There are two places to manipulate items in (Both the sorted inventory and the actual inventory)
if(!_inventory.count(it)){
- std::shared_ptr
- newItem=(*_inventory.insert({it,std::make_shared
- (amt,it)})).second;
+ newItem=(*_inventory.insert({it,std::make_shared
- (amt,it)})).second;
InsertIntoSortedInv(newItem);
- InsertIntoStageInventoryCategory(newItem,monsterDrop);
itemPtr=newItem;
}else{
auto inventory=_inventory.equal_range(it);
@@ -447,10 +453,12 @@ std::weak_ptr
- Inventory::AddItem(IT it,uint32_t amt,bool monsterDrop){
[&](int counter,std::pair>item){
(*item.second).amt+=amt;
itemPtr=item.second;
+ newItem=std::make_shared
- (amt,it);
return counter+1;})>1)ERR("WARNING! We should not have more than 1 instance of a stackable item!");
}
SkipAddingStackableItem:
+ InsertIntoStageInventoryCategory(newItem,monsterDrop);
return itemPtr;
}
@@ -671,7 +679,10 @@ const std::string Item::Description(CompactText compact)const{
if(compact==CRAFTING_INFO){
description+="\n\nCrafting Requirements:\n---------\n";
if(IsCraftable()){
- const EnhancementLevelInfo&info=GetEnhancementInfo()[EnhancementLevel()+1];
+ size_t enhanceIndex=EnhancementLevel()+1;
+ if(IsEquippable()&&Inventory::GetItemCount(ActualName())==0)enhanceIndex=0;
+
+ const EnhancementLevelInfo&info=GetEnhancementInfo()[enhanceIndex];
for(const auto&[name,amt]:info.craftingRequirement.GetItems()){
description+=std::format("{}{} x{} ({})\n",
Inventory::GetItemCount(name)(item)))ERR("Item "<(item)<<" does not exist in the item database!");
+ return ITEM_DATA[const_cast(item)];
}
const uint32_t ItemInfo::GetBuyValue()const{
@@ -1069,7 +1080,7 @@ const bool Item::CanEnhanceItem(uint8_t qty)const{
if(!GetEnhancementInfo().CanBeEnhanced())return false;
if(GetEnhancementInfo().AvailableChapter()GetCurrentChapter())return false;
size_t enhanceIndex=EnhancementLevel()+1;
- if(Inventory::GetItemCount(ActualName())==0)enhanceIndex=0;
+ if(IsEquippable()&&Inventory::GetItemCount(ActualName())==0)enhanceIndex=0;//Equipment we don't have we need to first craft.
const EnhancementLevelInfo&enhanceInfo=GetEnhancementInfo()[enhanceIndex];
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;
@@ -1181,7 +1192,7 @@ const std::vector>Inventory::GetInventory(){
}
const std::string&ItemInfo::GetClass()const{
- return equippableClass;
+ return equippableClass.length()==0?game->GetPlayer()->GetClassName():equippableClass;
}
const std::string&Item::GetClass()const{
@@ -1203,4 +1214,27 @@ void Inventory::UpdateBlacksmithInventoryLists(){
InventoryCreator::RowPlayerWeapons_InventorySlotsUpdate(*DYNAMIC_POINTER_CAST(weaponsList),"Equipment");
InventoryCreator::RowPlayerArmor_InventorySlotsUpdate(*DYNAMIC_POINTER_CAST(armorList),"Equipment");
+}
+
+uint16_t ItemSortRules::GetItemSortRanking(const std::weak_ptr
- &it){
+ uint16_t sortRank=0;
+ auto secondaryFind=std::find_if(secondarySort.begin(),secondarySort.end(),[&](const std::string&sort){
+ if(it.lock()->DisplayName().find(sort)!=std::string::npos){
+ return true;
+ }
+ return false;
+ });
+ sortRank+=std::distance(secondarySort.begin(),secondaryFind);
+ auto primaryFind=std::find_if(primarySort.begin(),primarySort.end(),[&](const std::string&sort){
+ if(it.lock()->DisplayName().find(sort)!=std::string::npos){
+ return true;
+ }
+ return false;
+ });
+ sortRank+=std::distance(primarySort.begin(),primaryFind)*(secondarySort.size()+1);
+ return sortRank;
+}
+
+uint16_t ItemSortRules::MaxSortRanking(){
+ return primarySort.size()*(secondarySort.size()+1)+secondarySort.size();
}
\ No newline at end of file
diff --git a/Adventures in Lestoria/Item.h b/Adventures in Lestoria/Item.h
index 926b7d9f..dd66fb4e 100644
--- a/Adventures in Lestoria/Item.h
+++ b/Adventures in Lestoria/Item.h
@@ -46,12 +46,12 @@ All rights reserved.
#include "Merchant.h"
#include "CraftingRequirement.h"
#include "FunctionPriming.h"
+#include "IT.h"
class AiL;
class ItemInfo;
class ItemProps;
-using IT=std::string;
using ITCategory=std::string;
using EventName=std::string;
@@ -132,6 +132,16 @@ public:
const size_t size()const;
};
+class ItemSortRules{
+ friend class ItemInfo;
+public:
+ static std::vectorprimarySort;
+ static std::vectorsecondarySort;
+ //Returns a number based on what the equipment type of an item is. The lower the number, the earlier it should appear in the list.
+ static uint16_t GetItemSortRanking(const std::weak_ptr
- &it);
+ static uint16_t MaxSortRanking();
+};
+
//You cannot create instances of this class, access sets from ItemSet::sets and add the appropriate set bonuses.
class ItemSet{
friend class ItemInfo;
@@ -219,9 +229,9 @@ public:
//Use ISBLANK macro instead!! This should not be called directly!!
static bool IsBlank(std::weak_ptr
- item);
friend const bool operator==(std::shared_ptr
- lhs,std::shared_ptr
- rhs){return lhs->it==rhs->it&&lhs->randomizedStats==rhs->randomizedStats;};
- friend const bool operator==(std::shared_ptr
- lhs,const IT&rhs){return lhs->ActualName()==rhs;};
+ friend const bool operator==(std::shared_ptr
- lhs,const IT&rhs){return lhs->ActualName()==const_cast(rhs);};
friend const bool operator==(std::weak_ptr
- lhs,std::weak_ptr
- rhs){return !lhs.expired()&&!rhs.expired()&&lhs.lock()->it==rhs.lock()->it&&lhs.lock()->randomizedStats==rhs.lock()->randomizedStats;};
- friend const bool operator==(std::weak_ptr
- lhs,const IT&rhs){return !lhs.expired()&&lhs.lock()->ActualName()==rhs;};
+ friend const bool operator==(std::weak_ptr
- lhs,const IT&rhs){return !lhs.expired()&&lhs.lock()->ActualName()==const_cast(rhs);};
friend const bool operator==(const IT&lhs,std::weak_ptr
- rhs){return operator==(rhs,lhs);};
friend const bool operator==(const IT&lhs,std::shared_ptr
- rhs){return operator==(rhs,lhs);};
};
diff --git a/Adventures in Lestoria/LevelCompleteWindow.cpp b/Adventures in Lestoria/LevelCompleteWindow.cpp
index 6dbb2e36..295b7111 100644
--- a/Adventures in Lestoria/LevelCompleteWindow.cpp
+++ b/Adventures in Lestoria/LevelCompleteWindow.cpp
@@ -65,7 +65,6 @@ void Menu::InitializeLevelCompleteWindow(){
auto nextButtonAction=[](MenuFuncData data){
Unlock::UnlockArea(State_OverworldMap::GetCurrentConnectionPoint().map);
- game->UpdateDiscordStatus("Hub Area",game->GetPlayer()->GetClassName());
Merchant::RandomizeTravelingMerchant();
GameState::ChangeState(States::GAME_HUB,0.25f);
return true;
diff --git a/Adventures in Lestoria/Merchant.h b/Adventures in Lestoria/Merchant.h
index c87effd8..7ecb5992 100644
--- a/Adventures in Lestoria/Merchant.h
+++ b/Adventures in Lestoria/Merchant.h
@@ -40,7 +40,6 @@ All rights reserved.
class Item;
using Chapter=int;
-using IT=std::string;
using ITCategory=std::string;
class Merchant{
diff --git a/Adventures in Lestoria/Player.h b/Adventures in Lestoria/Player.h
index 4ee071a0..daa86038 100644
--- a/Adventures in Lestoria/Player.h
+++ b/Adventures in Lestoria/Player.h
@@ -189,7 +189,7 @@ public:
virtual Class GetClass()=0;
virtual bool AutoAttack()=0;
virtual void OnUpdate(float fElapsedTime)=0;
- virtual std::string GetClassName()=0;
+ virtual const std::string&GetClassName()=0;
virtual Ability&GetRightClickAbility()=0;
virtual Ability&GetAbility1()=0;
virtual Ability&GetAbility2()=0;
@@ -354,7 +354,7 @@ struct Warrior:Player{
//Include only WARRIOR-specific implementations!
void OnUpdate(float fElapsedTime)override;
static void InitializeClassAbilities();
- std::string GetClassName()override;
+ const std::string&GetClassName()override;
Ability&GetRightClickAbility()override;
Ability&GetAbility1()override;
Ability&GetAbility2()override;
@@ -385,7 +385,7 @@ struct Thief:Player{
//Include only THIEF-specific implementations!
void OnUpdate(float fElapsedTime)override;
static void InitializeClassAbilities();
- std::string GetClassName()override;
+ const std::string&GetClassName()override;
Ability&GetRightClickAbility()override;
Ability&GetAbility1()override;
Ability&GetAbility2()override;
@@ -416,7 +416,7 @@ struct Ranger:Player{
//Include only RANGER-specific implementations!
void OnUpdate(float fElapsedTime)override;
static void InitializeClassAbilities();
- std::string GetClassName()override;
+ const std::string&GetClassName()override;
Ability&GetRightClickAbility()override;
Ability&GetAbility1()override;
Ability&GetAbility2()override;
@@ -447,7 +447,7 @@ struct Trapper:Player{
//Include only TRAPPER-specific implementations!
void OnUpdate(float fElapsedTime)override;
static void InitializeClassAbilities();
- std::string GetClassName()override;
+ const std::string&GetClassName()override;
Ability&GetRightClickAbility()override;
Ability&GetAbility1()override;
Ability&GetAbility2()override;
@@ -478,7 +478,7 @@ struct Wizard:Player{
//Include only WIZARD-specific implementations!
void OnUpdate(float fElapsedTime)override;
static void InitializeClassAbilities();
- std::string GetClassName()override;
+ const std::string&GetClassName()override;
Ability&GetRightClickAbility()override;
Ability&GetAbility1()override;
Ability&GetAbility2()override;
@@ -509,7 +509,7 @@ struct Witch:Player{
//Include only WITCHs-specific implementations!
void OnUpdate(float fElapsedTime)override;
static void InitializeClassAbilities();
- std::string GetClassName()override;
+ const std::string&GetClassName()override;
Ability&GetRightClickAbility()override;
Ability&GetAbility1()override;
Ability&GetAbility2()override;
diff --git a/Adventures in Lestoria/RequiredMaterialsList.h b/Adventures in Lestoria/RequiredMaterialsList.h
index fecbe09b..71699be2 100644
--- a/Adventures in Lestoria/RequiredMaterialsList.h
+++ b/Adventures in Lestoria/RequiredMaterialsList.h
@@ -71,9 +71,7 @@ protected:
if(itemRef.lock()->EnhancementIsPossible()){
size_t enhancementIndex=itemRef.lock()->EnhancementLevel()+1;
- if(Inventory::GetItemCount(itemRef.lock()->ActualName())==0){ //If we don't have the item, use the initial crafting list instead.
- enhancementIndex=0;
- }
+ if(itemRef.lock()->IsEquippable()&&Inventory::GetItemCount(itemRef.lock()->ActualName())==0)enhancementIndex=0;//If we don't have the item, use the initial crafting list instead. But only for equipment!
float drawWidth=rect.size.x/3;
int index=0;
for(const auto&[name,amt]:itemRef.lock()->GetEnhancementInfo()[enhancementIndex].craftingRequirement.GetItems()){
diff --git a/Adventures in Lestoria/State_GameHub.cpp b/Adventures in Lestoria/State_GameHub.cpp
index 98e93938..a992748b 100644
--- a/Adventures in Lestoria/State_GameHub.cpp
+++ b/Adventures in Lestoria/State_GameHub.cpp
@@ -43,6 +43,7 @@ All rights reserved.
#include "VisualNovel.h"
#include "State_OverworldMap.h"
#include "GameEvent.h"
+#include "SaveFile.h"
INCLUDE_MONSTER_LIST
INCLUDE_game
@@ -51,9 +52,12 @@ void State_GameHub::OnStateChange(GameState*prevState){
if(Menu::IsMenuOpen()){
Menu::CloseAllMenus();
}
+ SaveFile::SaveGame();
+
game->GetPlayer()->SetState(State::NORMAL);
game->LoadLevel("HUB");
+ game->UpdateDiscordStatus("Hub Area",game->GetPlayer()->GetClassName());
}
void State_GameHub::OnUserUpdate(AiL*game){
State_GameRun::OnUserUpdate(game);
diff --git a/Adventures in Lestoria/TODO.txt b/Adventures in Lestoria/TODO.txt
index 5e1a87a7..3b2b562c 100644
--- a/Adventures in Lestoria/TODO.txt
+++ b/Adventures in Lestoria/TODO.txt
@@ -4,6 +4,7 @@ Settings Menu
- Any settings should be saved to the save file!
- Volume Controls
- Play Sound in Background
+ - Keyboard aim assist (When playing w/keyboard, have the game auto fire for players that don't want to use mouse or cannot)
- Key Configuration
-Upon pressing a key, check if the key is bound to another option, if so,
remove that bind from the list. Up to two keys may be binded per action.
diff --git a/Adventures in Lestoria/Version.h b/Adventures in Lestoria/Version.h
index 3c71e7d2..4f9cd8a1 100644
--- a/Adventures in Lestoria/Version.h
+++ b/Adventures in Lestoria/Version.h
@@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 0
#define VERSION_MINOR 3
#define VERSION_PATCH 0
-#define VERSION_BUILD 6616
+#define VERSION_BUILD 6677
#define stringify(a) stringify_(a)
#define stringify_(a) #a
diff --git a/Adventures in Lestoria/assets/config/items/Weapons.txt b/Adventures in Lestoria/assets/config/items/Weapons.txt
index ec1bba19..09e94707 100644
--- a/Adventures in Lestoria/assets/config/items/Weapons.txt
+++ b/Adventures in Lestoria/assets/config/items/Weapons.txt
@@ -1383,7 +1383,7 @@ Equipment
Crafting
{
# When this crafting recipe is available.
- AvailableChapter = 1
+ AvailableChapter = 4
Item[0] = Wolf Skin,1
Gold = 5
diff --git a/Adventures in Lestoria/assets/config/items/items.txt b/Adventures in Lestoria/assets/config/items/items.txt
index 9df79b19..5bf6e1e3 100644
--- a/Adventures in Lestoria/assets/config/items/items.txt
+++ b/Adventures in Lestoria/assets/config/items/items.txt
@@ -27,6 +27,11 @@ Item
Missing Upgradeable Item Text = Missing Materials
# Color of the text that displays when items can be upgraded in the Blacksmith but the player doesn't have enough material.
Missing Upgradeable Item Text Color = 192,0,0,255
+
+ # The names of items to be sorted for equipment lists.
+ Equipment Sort Order Primary = Wooden, Leather, Steel, Copper, Shell, Bone, Laser, Plasma, Unknown
+ # The types of the items to be sorted for equipment lists if they have the same primary type.
+ Equipment Sort Order Secondary = Helmet, Armor, Pants, Gloves, Shoes, Sword, Bow, Staff
}
ItemDrop
{
diff --git a/x64/Release/Adventures in Lestoria.exe b/x64/Release/Adventures in Lestoria.exe
index 220fc908..622d3117 100644
Binary files a/x64/Release/Adventures in Lestoria.exe and b/x64/Release/Adventures in Lestoria.exe differ