diff --git a/Adventures in Lestoria/AdventuresInLestoria.cpp b/Adventures in Lestoria/AdventuresInLestoria.cpp index aec06d78..e924af43 100644 --- a/Adventures in Lestoria/AdventuresInLestoria.cpp +++ b/Adventures in Lestoria/AdventuresInLestoria.cpp @@ -3578,10 +3578,6 @@ void AiL::InitializeGraphics(){ GFX.Reset(); Menu::themes.Reset(); - //These two create item graphics, so they should be after the GFX structure gets reset! - ItemAttribute::Initialize(); - ItemInfo::InitializeItems(); - circleCooldownPoints.push_back({0,0}); squareCircleCooldownPoints.push_back({0,0}); for(int i=0;i<=360;i+=4){ @@ -3657,6 +3653,10 @@ void AiL::InitializeGraphics(){ } } + //These two create item graphics, so they should be after the GFX structure gets reset! + ItemAttribute::Initialize(); + ItemInfo::InitializeItems(); + for(std::string img:VisualNovel::graphicsToLoad){ Renderable&image=GFX[img]; LoadResource(image,"GFX_Prefix"_S+img); diff --git a/Adventures in Lestoria/ArtificerRefineWindow.cpp b/Adventures in Lestoria/ArtificerRefineWindow.cpp index 84a5b3cc..17008616 100644 --- a/Adventures in Lestoria/ArtificerRefineWindow.cpp +++ b/Adventures in Lestoria/ArtificerRefineWindow.cpp @@ -38,12 +38,29 @@ All rights reserved. #include "Menu.h" #include "AdventuresInLestoria.h" +#include "RowInventoryScrollableWindowComponent.h" +#include "MenuLabel.h" INCLUDE_game void Menu::InitializeArtificerRefineWindow(){ - Menu*artificerRefineWindow=CreateMenu(ARTIFICER_REFINE,CENTERED,vi2d{144,144}); + Menu*artificerRefineWindow=CreateMenu(ARTIFICER_REFINE,CENTERED,game->GetScreenSize()-vi2d{52,52}); + auto inventoryLabel=artificerRefineWindow->ADD("Accessory List Label",MenuLabel)(geom2d::rect{{},{180.f,12.f}},"Choose Accessory:",1.f,ComponentAttr::SHADOW|ComponentAttr::LEFT_ALIGN)END; + + auto inventoryDisplay=artificerRefineWindow->ADD("Accessory List",RowInventoryScrollableWindowComponent)(geom2d::rect{{0.f,16.f},{artificerRefineWindow->size.x/2-4.f,artificerRefineWindow->size.y-32}},"","",[](MenuFuncData data){ + return true; + },DO_NOTHING,DO_NOTHING, + InventoryCreator::RowPlayer_InventoryUpdate, + InventoryWindowOptions{.padding=1,.size={137,28}})END; + + auto backButton=artificerRefineWindow->ADD("Back",MenuComponent)(geom2d::rect{{0.f,artificerRefineWindow->size.y-12.f},{120.f,12.f}},"Back",[](MenuFuncData data){ + Menu::CloseMenu(); + return true; + })END; + + Menu::AddInventoryListener(inventoryDisplay,"Accessories"); + artificerRefineWindow->SetupKeyboardNavigation( [](MenuType type,Data&returnData){ //On Open returnData=""; diff --git a/Adventures in Lestoria/BearTrap.cpp b/Adventures in Lestoria/BearTrap.cpp index 866800ba..9c6e829e 100644 --- a/Adventures in Lestoria/BearTrap.cpp +++ b/Adventures in Lestoria/BearTrap.cpp @@ -67,7 +67,7 @@ BulletDestroyState BearTrap::MonsterHit(Monster&monster,const uint8_t markStacks const float timeBetweenTicks{"Trapper.Ability 2.Marked Target Bleed"_f[2]}; if(markStacksBeforeHit>0){ - const uint8_t resetStackCount{uint8_t("Trapper.Ability 2.Marked Target Stack Count Reset"_I)+1U}; //Add an additional stack because we know the target hit is about to lose one stack. + const uint8_t resetStackCount{uint8_t("Trapper.Ability 2.Marked Target Stack Count Reset"_I+1U)}; //Add an additional stack because we know the target hit is about to lose one stack. const uint8_t numberOfStacksToReplenish{uint8_t(resetStackCount-monster.GetMarkStacks())}; monster.ApplyMark("Trapper.Ability 2.Marked Target Reset Time"_F,numberOfStacksToReplenish); monster.ApplyDot(bleedDuration,bleedDamage,timeBetweenTicks); diff --git a/Adventures in Lestoria/Item.cpp b/Adventures in Lestoria/Item.cpp index a362f5ea..ea9f4144 100644 --- a/Adventures in Lestoria/Item.cpp +++ b/Adventures in Lestoria/Item.cpp @@ -151,6 +151,7 @@ void ItemInfo::InitializeItems(){ bool useDuringCast=false; std::unordered_setequippableClass; EventName useSound; + std::optionalfragmentName; for(auto&[itemKey,itemValue]:data[key].GetKeys()){ std::string keyName=itemKey; if(keyName=="Description"){ @@ -199,6 +200,9 @@ void ItemInfo::InitializeItems(){ if(keyName.starts_with("Alternative Name")){ if(ITEM_CONVERSIONS.count(data[key][keyName].GetString()))ERR(std::format("Item {} already exists in Item Conversion database! Cannot add a duplicate entry!",data[key][keyName].GetString())); ITEM_CONVERSIONS[data[key][keyName].GetString()]=key; + }else + if(keyName.starts_with("Fragment Name")){ + fragmentName=data[key][keyName].GetString(); }else{ //THis is a custom override modifier for a script. NO-OP } } @@ -320,6 +324,7 @@ void ItemInfo::InitializeItems(){ it.useFunc=scriptName; it.minStats=minStats; it.maxStats=maxStats; + it.fragmentName=fragmentName; #pragma region Equipment Category Verification Tests int equipmentCategories=0; @@ -334,6 +339,7 @@ void ItemInfo::InitializeItems(){ if(it.Category()=="Accessories"&&it.IsWeapon())ERR(std::format("WARNING! {} is in the Accessories Category, but is considered a Weapon!",it.Name())) 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())) + if(it.IsAccessory()&&!it.fragmentName.has_value())ERR(std::format("WARNING! Accessory {} does not have a \"Fragment Name\" set!",it.Name())); #pragma endregion #pragma region Equipment Sort Rules Verification Tests @@ -342,23 +348,54 @@ void ItemInfo::InitializeItems(){ 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 - } + } }; ReadItems(DATA["ItemDatabase"]); ReadItems(DATA["Equipment"]); std::sort(craftableConsumables.begin(),craftableConsumables.end(),[](std::shared_ptr&item1,std::shared_ptr&item2){return item1.get()->GetEnhancementInfo()[0].chapterAvailableGetEnhancementInfo()[0].chapterAvailable;}); - - ITEM_DATA.SetInitialized(); - ITEM_CATEGORIES.SetInitialized(); - ITEM_CONVERSIONS.SetInitialized(); - Menu::LockInListeners(); for(auto&[name,info]:ITEM_DATA){ Item tempItem{1,name}; if(tempItem.Description().length()==0)ERR("WARNING! Item "<SetDrawTarget(GFX.at(fragmentName).Sprite()); + std::setcolors; + for(int y=0;y<24;y++){ + for(int x=0;x<24;x++){ + colors.insert(ITEM_DATA.at(itemName).img->sprite->GetPixel(x,y)); + } + } + colors.erase(BLANK); + game->DrawSprite({},GFX.at("items/Fragment.png").Sprite(),1U,0U,[colors](const Pixel&in){ + if(in==BLANK)return in; + for(const Pixel&p:colors){ + if(util::random()%colors.size()==0)return PixelLerp(in,{p.r,p.g,p.b},0.5f); + } + return in; + }); + game->SetDrawTarget(nullptr); + GFX.at(fragmentName).Decal()->Update(); + it.img=GFX.at(fragmentName).Decal(); + it.name=fragmentName; + it.description="Fragment Description"_S; + it.category="Materials"; + LOG(std::format("Item Fragment {} generated...",fragmentName)); + } + } + + ITEM_DATA.SetInitialized(); + ITEM_CATEGORIES.SetInitialized(); + ITEM_CONVERSIONS.SetInitialized(); + Menu::LockInListeners(); LOG(ITEM_DATA.size()<<" items have been loaded."); LOG(ITEM_CATEGORIES.size()<<" item categories have been loaded."); diff --git a/Adventures in Lestoria/Item.h b/Adventures in Lestoria/Item.h index e6940ce8..b40cd0df 100644 --- a/Adventures in Lestoria/Item.h +++ b/Adventures in Lestoria/Item.h @@ -335,6 +335,7 @@ class ItemInfo{ std::unordered_setequippableClass; Stats minStats; Stats maxStats; + std::optionalfragmentName; private: static void InitializeScripts(); static void InitializeSets(); diff --git a/Adventures in Lestoria/Pixel.cpp b/Adventures in Lestoria/Pixel.cpp index 71a9e6ef..230c9f77 100644 --- a/Adventures in Lestoria/Pixel.cpp +++ b/Adventures in Lestoria/Pixel.cpp @@ -154,6 +154,11 @@ namespace olc{ return *this; } + bool Pixel::operator< (const Pixel& p) const + { + return n