Added operator< for Pixel class to allow sets of pixels to be used. Add fragment item default description. Generate fragment images that randomly sample from the source ring's colors. Add base fragment item icon. Release Build 10443.

removeExposedPackKey
sigonasr2 4 months ago
parent 47530d4822
commit 13eeb46000
  1. 8
      Adventures in Lestoria/AdventuresInLestoria.cpp
  2. 19
      Adventures in Lestoria/ArtificerRefineWindow.cpp
  3. 2
      Adventures in Lestoria/BearTrap.cpp
  4. 47
      Adventures in Lestoria/Item.cpp
  5. 1
      Adventures in Lestoria/Item.h
  6. 5
      Adventures in Lestoria/Pixel.cpp
  7. 1
      Adventures in Lestoria/Pixel.h
  8. 2
      Adventures in Lestoria/Version.h
  9. 1
      Adventures in Lestoria/assets/config/gfx/gfx.txt
  10. 12
      Adventures in Lestoria/assets/config/items/Accessories.txt
  11. BIN
      Adventures in Lestoria/assets/gamepack.pak
  12. BIN
      Adventures in Lestoria/assets/items/Fragment.png
  13. 2
      Adventures in Lestoria/safemap.h
  14. BIN
      x64/Release/Adventures in Lestoria.exe

@ -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);

@ -38,11 +38,28 @@ 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<float>{{},{180.f,12.f}},"Choose Accessory:",1.f,ComponentAttr::SHADOW|ComponentAttr::LEFT_ALIGN)END;
auto inventoryDisplay=artificerRefineWindow->ADD("Accessory List",RowInventoryScrollableWindowComponent)(geom2d::rect<float>{{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<float>{{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

@ -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);

@ -151,6 +151,7 @@ void ItemInfo::InitializeItems(){
bool useDuringCast=false;
std::unordered_set<std::string>equippableClass;
EventName useSound;
std::optional<std::string>fragmentName;
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
@ -350,16 +356,47 @@ void ItemInfo::InitializeItems(){
std::sort(craftableConsumables.begin(),craftableConsumables.end(),[](std::shared_ptr<Item>&item1,std::shared_ptr<Item>&item2){return item1.get()->GetEnhancementInfo()[0].chapterAvailable<item2.get()->GetEnhancementInfo()[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 "<<info.name<<" does not have a description!");
}
CreateAccessoryFragments:{
for(const auto&itemName:ITEM_CATEGORIES.at("Accessories")){
const std::string fragmentName{ITEM_DATA.at(itemName).fragmentName.value()};
ItemInfo&it{ITEM_DATA[fragmentName]};
//olc::Decal*generatedFragmentImage{new olc::Decal(new Sprite(24,24))};
GFX[fragmentName].Create(24,24);
game->SetDrawTarget(GFX.at(fragmentName).Sprite());
std::set<Pixel>colors;
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.");
}

@ -335,6 +335,7 @@ class ItemInfo{
std::unordered_set<std::string>equippableClass;
Stats minStats;
Stats maxStats;
std::optional<std::string>fragmentName;
private:
static void InitializeScripts();
static void InitializeSets();

@ -154,6 +154,11 @@ namespace olc{
return *this;
}
bool Pixel::operator< (const Pixel& p) const
{
return n<p.n;
}
Pixel Pixel::inv() const
{
uint8_t nR = uint8_t(std::min(255, std::max(0, 255 - int(r))));

@ -87,6 +87,7 @@ namespace olc{
Pixel& operator -=(const Pixel& p);
Pixel operator * (const Pixel& p) const;
Pixel& operator *=(const Pixel& p);
bool operator < (const Pixel& p)const;
Pixel inv() const;
};

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 1
#define VERSION_MINOR 2
#define VERSION_PATCH 3
#define VERSION_BUILD 10424
#define VERSION_BUILD 10443
#define stringify(a) stringify_(a)
#define stringify_(a) #a

@ -117,6 +117,7 @@ Images
GFX_PurpleEnergyBallHit = purpleenergyball_hit.png
GFX_PoisonPool = poison_pool.png
GFX_PoisonBottle = poison_bottle.png
GFX_Fragment = items/Fragment.png
GFX_Thief_Sheet = nico-thief.png
GFX_Trapper_Sheet = nico-trapper.png

@ -1,3 +1,5 @@
Fragment Description = "A small piece of concentrated material from broken down jewelry."
Equipment
{
Ring of the Slime King
@ -5,6 +7,10 @@ Equipment
Slot = Ring1,Ring2
ItemCategory = Accessories
Fragment Name = Slime King Ring Fragment
# Uncomment to specify a custom icon for this fragment. Otherwise uses the default fragment icon with auto-detected color sampling.
#Fragment Icon = MyIcon.png
# See ItemStats.txt for valid stat names
StatValues = Health,Mana,Move Spd %
MinStats = 5,1,1
@ -18,6 +24,8 @@ Equipment
Slot = Ring1,Ring2
ItemCategory = Accessories
Fragment Name = Bear Ring Fragment
# See ItemStats.txt for valid stat names
StatValues = Health,Attack,Mana
MinStats = 4,1,1
@ -31,6 +39,8 @@ Equipment
Slot = Ring1,Ring2
ItemCategory = Accessories
Fragment Name = Stone Ring Fragment
# See ItemStats.txt for valid stat names
StatValues = Defense,Health,Health %
MinStats = 5,10,1
@ -44,6 +54,8 @@ Equipment
Slot = Ring1,Ring2
ItemCategory = Accessories
Fragment Name = Bird's Treasure Fragment
# See ItemStats.txt for valid stat names
StatValues = Move Spd %,Crit Rate,Mana
MinStats = 1,1,2

Binary file not shown.

After

Width:  |  Height:  |  Size: 736 B

@ -63,7 +63,7 @@ public:
}
}
O&at(T key){
return map.at(key);
return map.at(key);
}
auto insert(T key,O obj){
return map.insert({key,obj});

Loading…
Cancel
Save