213 lines
13 KiB
C++
213 lines
13 KiB
C++
#pragma region License
|
||
/*
|
||
License (OLC-3)
|
||
~~~~~~~~~~~~~~~
|
||
|
||
Copyright 2024 Joshua Sigona <sigonasr2@gmail.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 <20> 2023 The FreeType
|
||
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
|
||
All rights reserved.
|
||
*/
|
||
#pragma endregion
|
||
#include "InventoryCreator.h"
|
||
#include "RowInventoryScrollableWindowComponent.h"
|
||
|
||
#define DEFINE(SubName) InventoryCreator InventoryCreator::SubName##_InventoryUpdate(&InventoryCreator::SubName##_InventorySlotsUpdate,&InventoryCreator::SubName##_AddButtonOnSlotUpdate);
|
||
|
||
DEFINE(Player);
|
||
DEFINE(RowPlayer);
|
||
DEFINE(RowMerchant);
|
||
DEFINE(RowPlayerWeapons);
|
||
DEFINE(RowPlayerArmor);
|
||
|
||
#pragma region Player Inventory Updates
|
||
std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)> InventoryCreator::Player_InventorySlotsUpdate=
|
||
[](InventoryScrollableWindowComponent&component,ITCategory cat){
|
||
size_t invSize=Inventory::get(cat).size();
|
||
//We only want to refresh the inventory slots if the component count no longer matches what's actually in our inventory.
|
||
if(component.components.size()<invSize){//We need more space to display our items.
|
||
component.AddButtonOnSlotUpdate(cat);
|
||
}else
|
||
if(component.components.size()>invSize){ //There are empty spots, so let's clean up.
|
||
component.RemoveAllComponents();
|
||
for(std::weak_ptr<Item> item:Inventory::get(cat)){
|
||
component.AddButtonOnSlotUpdate(cat);
|
||
}
|
||
}
|
||
};
|
||
std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)> InventoryCreator::Player_AddButtonOnSlotUpdate=
|
||
[](InventoryScrollableWindowComponent&component,ITCategory cat){
|
||
size_t invSize=component.components.size()+1;
|
||
int invWidth=int((component.rect.size.x-12)/(float(component.options.size.x)+component.options.padding));
|
||
int x=int((invSize-1)%invWidth);
|
||
int y=int((invSize-1)/invWidth);
|
||
int itemIndex=y*invWidth+x;
|
||
|
||
vf2d buttonSize=component.options.size;
|
||
int totalSpacing=component.options.padding+buttonSize.x;
|
||
|
||
component.ADD("item_"+cat+"_"+std::to_string(itemIndex),MenuItemButton)(geom2d::rect<float>{{float(totalSpacing*x),float(totalSpacing*y)},buttonSize},Inventory::get(cat),itemIndex,component.inventoryButtonClickAction,component.inventoryButtonHoverAction,component.inventoryButtonMouseOutAction,component.parentMenu,component.itemNameLabelName,component.itemDescriptionLabelName,component.inventoryButtonsActive?IconButtonAttr::SELECTABLE:IconButtonAttr::NOT_SELECTABLE)END
|
||
->SetCompactDescriptions(component.compact);
|
||
};
|
||
#pragma endregion
|
||
|
||
#pragma region Row Inventory Player Updates
|
||
std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)> InventoryCreator::RowPlayer_InventorySlotsUpdate=Player_InventorySlotsUpdate;
|
||
std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)> InventoryCreator::RowPlayer_AddButtonOnSlotUpdate=
|
||
[](InventoryScrollableWindowComponent&component,ITCategory cat){
|
||
RowInventoryScrollableWindowComponent*c=DYNAMIC_CAST<RowInventoryScrollableWindowComponent*>(&component);
|
||
size_t invSize=c->components.size()+1;
|
||
int invWidth=int(c->rect.size.x/(float(c->options.size.x)+c->options.padding));
|
||
int x=int((invSize-1)%invWidth);
|
||
int y=int((invSize-1)/invWidth);
|
||
int itemIndex=y*invWidth+x;
|
||
|
||
vf2d buttonSize=c->options.size;
|
||
vf2d totalSpacing={c->options.padding+buttonSize.x,c->options.padding+buttonSize.y};
|
||
|
||
auto newItem=c->ADD("item_"+cat+"_"+std::to_string(itemIndex),RowItemDisplay)(geom2d::rect<float>{totalSpacing*vf2d{float(x),float(y)},buttonSize},Inventory::GetInventorySlot(cat,itemIndex),c->inventoryButtonClickAction,c->itemNameLabelName,c->itemDescriptionLabelName,c->inventoryButtonsActive?ButtonAttr::NONE:ButtonAttr::UNSELECTABLE)END;
|
||
newItem->SetCompactDescriptions(c->compact);
|
||
newItem->SetPriceLabelType(c->priceLabel);
|
||
newItem->SetHoverFunc(c->inventoryButtonHoverAction);
|
||
newItem->SetMouseOutFunc(c->inventoryButtonMouseOutAction);
|
||
};
|
||
#pragma endregion
|
||
|
||
#pragma region Row Merchant Updates
|
||
std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)> InventoryCreator::RowMerchant_InventorySlotsUpdate=
|
||
[](InventoryScrollableWindowComponent&component,ITCategory cat){
|
||
const std::vector<std::shared_ptr<Item>>&merchantInv=Merchant::GetCurrentTravelingMerchant().GetShopItems();
|
||
component.RemoveAllComponents();
|
||
for(std::shared_ptr<Item> item:merchantInv){
|
||
component.AddButtonOnSlotUpdate(cat);
|
||
}
|
||
};
|
||
std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)> InventoryCreator::RowMerchant_AddButtonOnSlotUpdate=
|
||
[](InventoryScrollableWindowComponent&component,ITCategory cat){
|
||
const std::vector<std::shared_ptr<Item>>&merchantInv=Merchant::GetCurrentTravelingMerchant().GetShopItems();
|
||
RowInventoryScrollableWindowComponent*c=DYNAMIC_CAST<RowInventoryScrollableWindowComponent*>(&component);
|
||
|
||
size_t invSize=c->components.size()+1;
|
||
int invWidth=int(c->rect.size.x/(float(c->options.size.x)+c->options.padding));
|
||
int x=int((invSize-1)%invWidth);
|
||
int y=int((invSize-1)/invWidth);
|
||
int itemIndex=y*invWidth+x;
|
||
|
||
vf2d buttonSize=c->options.size;
|
||
vf2d totalSpacing={c->options.padding+buttonSize.x,c->options.padding+buttonSize.y};
|
||
|
||
auto newItem=c->ADD("merchant_item_"+cat+"_"+std::to_string(itemIndex),RowItemDisplay)(geom2d::rect<float>{totalSpacing*vf2d{float(x),float(y)},buttonSize},Merchant::GetCurrentTravelingMerchant().GetShopItems()[itemIndex],c->inventoryButtonClickAction,c->itemNameLabelName,c->itemDescriptionLabelName,c->inventoryButtonsActive?ButtonAttr::NONE:ButtonAttr::UNSELECTABLE)END;
|
||
newItem->SetCompactDescriptions(c->compact);
|
||
newItem->SetPriceLabelType(c->priceLabel);
|
||
newItem->SetHoverFunc(c->inventoryButtonHoverAction);
|
||
newItem->SetMouseOutFunc(c->inventoryButtonMouseOutAction);
|
||
};
|
||
#pragma endregion
|
||
|
||
#pragma region Row Player Weapons Updates
|
||
std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)> InventoryCreator::RowPlayerWeapons_InventorySlotsUpdate=
|
||
[](InventoryScrollableWindowComponent&component,ITCategory cat){
|
||
component.RemoveAllComponents();
|
||
component.AddButtonOnSlotUpdate(cat);
|
||
};
|
||
std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)> InventoryCreator::RowPlayerWeapons_AddButtonOnSlotUpdate=
|
||
[](InventoryScrollableWindowComponent&component,ITCategory cat){
|
||
std::vector<std::weak_ptr<Item>>weapons;
|
||
std::copy_if(Inventory::get("Equipment").begin(),Inventory::get("Equipment").end(),std::back_inserter(weapons),[](std::shared_ptr<Item>item){return item->IsWeapon();});
|
||
std::copy_if(Inventory::blacksmithInventory.begin(),Inventory::blacksmithInventory.end(),std::back_inserter(weapons),[](std::shared_ptr<Item>item){return item->CanEnhanceItem()&&item->GetClass()==game->GetPlayer()->GetClassName()&&item->IsWeapon();});
|
||
|
||
std::sort(weapons.begin(),weapons.end(),[](const std::weak_ptr<Item>&it1,const std::weak_ptr<Item>&it2){
|
||
return ItemSortRules::GetItemSortRanking(it1)<ItemSortRules::GetItemSortRanking(it2);
|
||
});
|
||
|
||
RowInventoryScrollableWindowComponent*c=DYNAMIC_CAST<RowInventoryScrollableWindowComponent*>(&component);
|
||
|
||
vf2d buttonSize=c->options.size;
|
||
vf2d totalSpacing={c->options.padding+buttonSize.x,c->options.padding+buttonSize.y};
|
||
|
||
for(std::weak_ptr<Item> weapon:weapons){
|
||
size_t invSize=c->components.size()+1;
|
||
int invWidth=int(c->rect.size.x/(float(c->options.size.x)+c->options.padding));
|
||
int x=int((invSize-1)%invWidth);
|
||
int y=int((invSize-1)/invWidth);
|
||
int itemIndex=y*invWidth+x;
|
||
auto newItem=c->ADD("item_Weapon_"+std::to_string(itemIndex),RowItemDisplay)(geom2d::rect<float>{totalSpacing*vf2d{float(x),float(y)},buttonSize},weapon,c->inventoryButtonClickAction,c->itemNameLabelName,c->itemDescriptionLabelName,c->inventoryButtonsActive?ButtonAttr::NONE:ButtonAttr::UNSELECTABLE)END;
|
||
newItem->SetCompactDescriptions(c->compact);
|
||
if(Inventory::GetItemCount(weapon.lock()->ActualName())==0){ //An item that is not in our inventory is considered craftable..
|
||
newItem->SetPriceLabelType(PriceLabel::CRAFTABLE);
|
||
}else{ //Items that we do have are considered upgradeable.
|
||
newItem->SetPriceLabelType(PriceLabel::UPGRADEABLE);
|
||
}
|
||
newItem->SetHoverFunc(c->inventoryButtonHoverAction);
|
||
newItem->SetMouseOutFunc(c->inventoryButtonMouseOutAction);
|
||
newItem->SetCheckCraftingRequirements(true);
|
||
}
|
||
};
|
||
#pragma endregion
|
||
|
||
#pragma region Row Player Armor Updates
|
||
std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)> InventoryCreator::RowPlayerArmor_InventorySlotsUpdate=
|
||
[](InventoryScrollableWindowComponent&component,ITCategory cat){
|
||
component.RemoveAllComponents();
|
||
component.AddButtonOnSlotUpdate(cat);
|
||
};
|
||
std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)> InventoryCreator::RowPlayerArmor_AddButtonOnSlotUpdate=
|
||
[](InventoryScrollableWindowComponent&component,ITCategory cat){
|
||
std::vector<std::weak_ptr<Item>>armor;
|
||
std::copy_if(Inventory::get("Equipment").begin(),Inventory::get("Equipment").end(),std::back_inserter(armor),[](std::shared_ptr<Item>item){return item->IsArmor();});
|
||
std::copy_if(Inventory::blacksmithInventory.begin(),Inventory::blacksmithInventory.end(),std::back_inserter(armor),[](std::shared_ptr<Item>item){return item->CanEnhanceItem()&&item->GetClass()==game->GetPlayer()->GetClassName()&&item->IsArmor();});
|
||
|
||
std::sort(armor.begin(),armor.end(),[](const std::weak_ptr<Item>&it1,const std::weak_ptr<Item>&it2){
|
||
return ItemSortRules::GetItemSortRanking(it1)<ItemSortRules::GetItemSortRanking(it2);
|
||
});
|
||
|
||
RowInventoryScrollableWindowComponent*c=DYNAMIC_CAST<RowInventoryScrollableWindowComponent*>(&component);
|
||
|
||
vf2d buttonSize=c->options.size;
|
||
vf2d totalSpacing={c->options.padding+buttonSize.x,c->options.padding+buttonSize.y};
|
||
|
||
for(std::weak_ptr<Item> armor:armor){
|
||
size_t invSize=c->components.size()+1;
|
||
int invWidth=int(c->rect.size.x/(float(c->options.size.x)+c->options.padding));
|
||
int x=int((invSize-1)%invWidth);
|
||
int y=int((invSize-1)/invWidth);
|
||
int itemIndex=y*invWidth+x;
|
||
auto newItem=c->ADD("item_Armor_"+std::to_string(itemIndex),RowItemDisplay)(geom2d::rect<float>{totalSpacing*vf2d{float(x),float(y)},buttonSize},armor,c->inventoryButtonClickAction,c->itemNameLabelName,c->itemDescriptionLabelName,c->inventoryButtonsActive?ButtonAttr::NONE:ButtonAttr::UNSELECTABLE)END;
|
||
newItem->SetCompactDescriptions(c->compact);
|
||
if(Inventory::GetItemCount(armor.lock()->ActualName())==0){ //An item that is not in our inventory is considered craftable..
|
||
newItem->SetPriceLabelType(PriceLabel::CRAFTABLE);
|
||
}else{ //Items that we do have are considered upgradeable.
|
||
newItem->SetPriceLabelType(PriceLabel::UPGRADEABLE);
|
||
}
|
||
newItem->SetHoverFunc(c->inventoryButtonHoverAction);
|
||
newItem->SetMouseOutFunc(c->inventoryButtonMouseOutAction);
|
||
newItem->SetCheckCraftingRequirements(true);
|
||
}
|
||
};
|
||
#pragma endregion |