Make gear appear unstackable in inventories while other items remain stackable. Each individual piece of gear can now have its own stats.
This commit is contained in:
parent
f987e51324
commit
c528d89b85
@ -57,8 +57,8 @@ void Menu::InitializeBlacksmithCraftingWindow(){
|
||||
std::vector<std::weak_ptr<Item>>armorInventory;
|
||||
|
||||
#pragma region Build Equipment Lists
|
||||
std::for_each(Inventory::get("Equipment").begin(),Inventory::get("Equipment").end(),[&](const std::shared_ptr<Item> item){
|
||||
switch(item.get()->GetEquipSlot()){
|
||||
std::for_each(Inventory::get("Equipment").begin(),Inventory::get("Equipment").end(),[&](const std::weak_ptr<Item> item){
|
||||
switch(item.lock()->GetEquipSlot()){
|
||||
case EquipSlot::WEAPON:{
|
||||
weaponInventory.push_back(item);
|
||||
}break;
|
||||
|
@ -122,7 +122,7 @@ void Menu::InitializeCharacterMenuWindow(){
|
||||
|
||||
const std::vector<std::shared_ptr<Item>>&equips=Inventory::get("Equipment");
|
||||
const std::vector<std::shared_ptr<Item>>&accessories=Inventory::get("Accessories");
|
||||
std::vector<std::shared_ptr<Item>>availableEquipment;
|
||||
std::vector<std::weak_ptr<Item>>availableEquipment;
|
||||
std::copy_if(equips.begin(),equips.end(),std::back_inserter(availableEquipment),[&](const std::shared_ptr<Item>it){
|
||||
return it->GetEquipSlot()&slot;
|
||||
});
|
||||
@ -132,9 +132,8 @@ void Menu::InitializeCharacterMenuWindow(){
|
||||
|
||||
ScrollableWindowComponent*equipList=Component<ScrollableWindowComponent>(data.component->parentMenu,"Equip List");
|
||||
equipList->RemoveAllComponents();
|
||||
for(int counter=0;const std::shared_ptr<Item>it:availableEquipment){
|
||||
std::weak_ptr<Item>itemInvRef=Inventory::GetItem(it->ActualName());
|
||||
auto equip=equipList->ADD("Equip Item "+std::to_string(counter),RowItemDisplay)({{2,2+counter*29.f},{120-15,28}},itemInvRef,
|
||||
for(int counter=0;const std::weak_ptr<Item>it:availableEquipment){
|
||||
auto equip=equipList->ADD("Equip Item "+std::to_string(counter),RowItemDisplay)({{2,2+counter*29.f},{120-15,28}},it,
|
||||
[](MenuFuncData data){
|
||||
RowItemDisplay*comp=DYNAMIC_CAST<RowItemDisplay*>(data.component);
|
||||
if(comp!=nullptr){
|
||||
@ -201,7 +200,7 @@ void Menu::InitializeCharacterMenuWindow(){
|
||||
equip->SetSelectionType(SelectionType::NONE);
|
||||
|
||||
equip->I(Attribute::EQUIP_TYPE)=int(slot);
|
||||
if(Inventory::GetEquip(slot)==itemInvRef){
|
||||
if(Inventory::GetEquip(slot)==it){
|
||||
equip->SetSelected(true);
|
||||
}
|
||||
equip->SetCompactDescriptions(NON_COMPACT);
|
||||
|
@ -200,8 +200,11 @@ bool Crawler::OnUserCreate(){
|
||||
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");
|
||||
@ -2350,7 +2353,7 @@ const std::weak_ptr<Item>Crawler::GetLoadoutItem(int slot){
|
||||
void Crawler::SetLoadoutItem(int slot,std::string itemName){
|
||||
if(slot<0||slot>loadout.size()-1)ERR("Invalid inventory slot "+std::to_string(slot)+", please choose a slot in range (0-"+std::to_string(loadout.size()-1)+").");
|
||||
if(Inventory::GetItemCount(itemName)>0){
|
||||
loadout[slot]=Inventory::CopyItem(itemName);
|
||||
loadout[slot]=Inventory::CopyItem(itemName)[0];
|
||||
GetLoadoutItem(slot).lock()->amt=std::min((uint32_t)"Player.Item Loadout Limit"_I,GetLoadoutItem(slot).lock()->Amt()); //We are only allowed to have up to 10 maximum of an item on a journey.
|
||||
InputGroup*inputGroup=nullptr;
|
||||
switch(slot){
|
||||
|
@ -351,6 +351,10 @@
|
||||
<SubType>
|
||||
</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ItemMenuLabel.h">
|
||||
<SubType>
|
||||
</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PlayerMoneyLabel.h">
|
||||
<SubType>
|
||||
</SubType>
|
||||
|
@ -387,6 +387,9 @@
|
||||
<ClInclude Include="RequiredMaterialsList.h">
|
||||
<Filter>Header Files\Interface</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ItemMenuLabel.h">
|
||||
<Filter>Header Files\Interface</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Player.cpp">
|
||||
|
@ -139,22 +139,22 @@ std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)>
|
||||
#pragma region Row Player Weapons Updates
|
||||
std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)> InventoryCreator::RowPlayerWeapons_InventorySlotsUpdate=
|
||||
[](InventoryScrollableWindowComponent&component,ITCategory cat){
|
||||
std::vector<std::shared_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.get()->IsWeapon();});
|
||||
std::vector<std::weak_ptr<Item>>weapons;
|
||||
std::copy_if(Inventory::get("Equipment").begin(),Inventory::get("Equipment").end(),std::back_inserter(weapons),[](std::weak_ptr<Item> item){return item.lock()->IsWeapon();});
|
||||
component.RemoveAllComponents();
|
||||
component.AddButtonOnSlotUpdate(cat);
|
||||
};
|
||||
std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)> InventoryCreator::RowPlayerWeapons_AddButtonOnSlotUpdate=
|
||||
[](InventoryScrollableWindowComponent&component,ITCategory cat){
|
||||
std::vector<std::shared_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.get()->IsWeapon();});
|
||||
std::vector<std::weak_ptr<Item>>weapons;
|
||||
std::copy_if(Inventory::get("Equipment").begin(),Inventory::get("Equipment").end(),std::back_inserter(weapons),[](std::weak_ptr<Item> item){return item.lock()->IsWeapon();});
|
||||
|
||||
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::shared_ptr<Item> weapon:weapons){
|
||||
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);
|
||||
@ -173,22 +173,22 @@ std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)>
|
||||
#pragma region Row Player Armor Updates
|
||||
std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)> InventoryCreator::RowPlayerArmor_InventorySlotsUpdate=
|
||||
[](InventoryScrollableWindowComponent&component,ITCategory cat){
|
||||
std::vector<std::shared_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.get()->IsArmor();});
|
||||
std::vector<std::weak_ptr<Item>>armor;
|
||||
std::copy_if(Inventory::get("Equipment").begin(),Inventory::get("Equipment").end(),std::back_inserter(armor),[](std::weak_ptr<Item> item){return item.lock()->IsArmor();});
|
||||
component.RemoveAllComponents();
|
||||
component.AddButtonOnSlotUpdate(cat);
|
||||
};
|
||||
std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)> InventoryCreator::RowPlayerArmor_AddButtonOnSlotUpdate=
|
||||
[](InventoryScrollableWindowComponent&component,ITCategory cat){
|
||||
std::vector<std::shared_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.get()->IsArmor();});
|
||||
std::vector<std::weak_ptr<Item>>armor;
|
||||
std::copy_if(Inventory::get("Equipment").begin(),Inventory::get("Equipment").end(),std::back_inserter(armor),[](std::weak_ptr<Item> item){return item.lock()->IsArmor();});
|
||||
|
||||
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::shared_ptr<Item> armor:armor){
|
||||
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);
|
||||
|
@ -42,6 +42,7 @@ All rights reserved.
|
||||
#include "Menu.h"
|
||||
#include "Ability.h"
|
||||
#include "AttributableStat.h"
|
||||
#include <numeric>
|
||||
|
||||
INCLUDE_game
|
||||
INCLUDE_DATA
|
||||
@ -51,7 +52,7 @@ safemap<std::string,ItemInfo>ITEM_DATA;
|
||||
safemap<std::string,ItemScript>ITEM_SCRIPTS;
|
||||
safemap<std::string,std::set<std::string>>ITEM_CATEGORIES;
|
||||
std::shared_ptr<Item>Item::BLANK=std::make_shared<Item>();
|
||||
std::map<IT,std::shared_ptr<Item>>Inventory::_inventory;
|
||||
std::multimap<IT,std::shared_ptr<Item>>Inventory::_inventory;
|
||||
std::map<ITCategory,std::vector<std::shared_ptr<Item>>>Inventory::sortedInv;
|
||||
std::vector<ItemOverlay>ItemOverlay::items;
|
||||
std::map<std::string,ItemSet>ItemSet::sets;
|
||||
@ -358,31 +359,52 @@ Item::Item(uint32_t amt,IT item,uint8_t enhancementLevel)
|
||||
|
||||
void Inventory::AddItem(IT it,uint32_t amt,bool monsterDrop){
|
||||
if(!ITEM_DATA.count(it))ERR("Item "<<std::quoted(it)<<" does not exist in Item Database!");
|
||||
|
||||
if(ITEM_DATA[it].IsEquippable()){ //Do not stack equips!
|
||||
for(uint32_t i=0;i<amt;i++){
|
||||
InsertIntoSortedInv((*_inventory.insert({it,std::make_shared<Item>(amt,it)})).second);
|
||||
}
|
||||
goto SkipAddingStackableItem;
|
||||
}
|
||||
else
|
||||
//There are two places to manipulate items in (Both the sorted inventory and the actual inventory)
|
||||
if(!_inventory.count(it)){
|
||||
_inventory[it]=std::make_shared<Item>(amt,it);
|
||||
InsertIntoSortedInv(it);
|
||||
InsertIntoSortedInv((*_inventory.insert({it,std::make_shared<Item>(amt,it)})).second);
|
||||
}else{
|
||||
_inventory.at(it)->amt+=amt;
|
||||
auto inventory=_inventory.equal_range(it);
|
||||
std::accumulate(inventory.first,inventory.second,0,[&](int counter,std::pair<IT,std::shared_ptr<Item>>item){
|
||||
(*item.second).amt+=amt;
|
||||
if(counter>=1)ERR("WARNING! We should not have more than 1 instance of a stackable item!");
|
||||
return counter+1;
|
||||
});
|
||||
}
|
||||
|
||||
SkipAddingStackableItem:
|
||||
InsertIntoStageInventoryCategory(it,amt,monsterDrop);
|
||||
}
|
||||
|
||||
std::shared_ptr<Item>Inventory::CopyItem(IT it){
|
||||
if(!_inventory.count(it))return std::make_shared<Item>(*Item::BLANK);
|
||||
return std::make_shared<Item>(*_inventory.at(it));
|
||||
std::vector<std::shared_ptr<Item>>Inventory::CopyItem(IT it){
|
||||
if(!_inventory.count(it))return{};
|
||||
std::vector<std::shared_ptr<Item>>copiedItems;
|
||||
auto inventory=_inventory.equal_range(it);
|
||||
std::for_each(inventory.first,inventory.second,[&](std::pair<IT,std::shared_ptr<Item>>it){copiedItems.push_back(std::make_shared<Item>(*it.second));});
|
||||
return copiedItems;
|
||||
}
|
||||
|
||||
std::weak_ptr<Item>Inventory::GetItem(IT it){
|
||||
if(!_inventory.count(it))return Item::BLANK;
|
||||
return _inventory.at(it);
|
||||
std::vector<std::weak_ptr<Item>>Inventory::GetItem(IT it){
|
||||
if(!_inventory.count(it))return{};
|
||||
std::vector<std::weak_ptr<Item>>items;
|
||||
auto inventory=_inventory.equal_range(it);
|
||||
std::for_each(inventory.first,inventory.second,[&](std::pair<IT,std::shared_ptr<Item>>it){items.push_back(it.second);});
|
||||
return items;
|
||||
}
|
||||
|
||||
uint32_t Inventory::GetItemCount(IT it){
|
||||
if(!_inventory.count(it)){
|
||||
return 0;
|
||||
}else{
|
||||
return _inventory.at(it)->Amt();
|
||||
auto inventory=_inventory.equal_range(it);
|
||||
return std::accumulate(inventory.first,inventory.second,0,[](int val,std::pair<IT,std::shared_ptr<Item>>it){return val+(*it.second).Amt();});
|
||||
}
|
||||
}
|
||||
|
||||
@ -392,14 +414,14 @@ bool Inventory::UseItem(IT it,uint32_t amt){
|
||||
//There are two places to manipulate items in (Both the sorted inventory and the actual inventory)
|
||||
for(uint32_t i=0;i<amt;i++){
|
||||
if(ExecuteAction(it)){
|
||||
return RemoveItem(it);
|
||||
return RemoveItem(GetItem(it)[0]);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//Returns true if the item has been consumed completely and there are 0 remaining of that type in our inventory.
|
||||
bool Inventory::RemoveItem(IT it,ITCategory inventory,uint32_t amt){
|
||||
bool Inventory::RemoveItem(std::weak_ptr<Item>itemRef,ITCategory inventory,uint32_t amt){
|
||||
#pragma region Calculate Inventory to Manipulate
|
||||
std::vector<std::shared_ptr<Item>>&inv=sortedInv.at(inventory);
|
||||
bool eraseFromLootWindow=false;
|
||||
@ -412,13 +434,13 @@ bool Inventory::RemoveItem(IT it,ITCategory inventory,uint32_t amt){
|
||||
eraseFromLootWindow=true;
|
||||
}
|
||||
int count=0;
|
||||
for(std::shared_ptr<Item>item:inv){
|
||||
if(item==it)break;
|
||||
for(std::weak_ptr<Item>item:inv){
|
||||
if(item==itemRef)break;
|
||||
count++;
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
uint32_t itemAmt=GetItemCount(it);
|
||||
uint32_t itemAmt=GetItemCount(itemRef.lock()->ActualName());
|
||||
if(inventory=="Monster Loot"||inventory=="Stage Loot"){
|
||||
itemAmt=inv.at(count)->Amt();
|
||||
}
|
||||
@ -429,7 +451,7 @@ bool Inventory::RemoveItem(IT it,ITCategory inventory,uint32_t amt){
|
||||
if (amt>=itemAmt){
|
||||
inv.erase(inv.begin()+count); //Clears it from the detected sorted inventory as well!
|
||||
if(!eraseFromLootWindow){ //We must clear out the item AFTER we've updated context-sensitive inventories because they may be borrowing a ref from this structure!!!
|
||||
_inventory.erase(it);
|
||||
_inventory.erase(itemRef.lock()->ActualName());
|
||||
}
|
||||
|
||||
//Callback for GUI inventories.
|
||||
@ -437,28 +459,28 @@ bool Inventory::RemoveItem(IT it,ITCategory inventory,uint32_t amt){
|
||||
return true;
|
||||
}else{
|
||||
if(!eraseFromLootWindow){
|
||||
_inventory.at(it)->amt-=amt;
|
||||
itemRef.lock()->amt-=amt;
|
||||
}else{
|
||||
inv.at(count)->amt-=amt; //Don't touch the sorted inventory unless this is monster loot or stage loot because there's only "1" of this item in the entry list.
|
||||
itemRef.lock()->amt-=amt; //Don't touch the sorted inventory unless this is monster loot or stage loot because there's only "1" of this item in the entry list.
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//Returns true if the item has been consumed completely and there are 0 remaining of that type in our inventory.
|
||||
bool Inventory::RemoveItem(IT it,uint32_t amt){
|
||||
ITCategory cat = ITEM_DATA[it].category;
|
||||
return RemoveItem(it, cat, amt);
|
||||
bool Inventory::RemoveItem(std::weak_ptr<Item>itemRef,uint32_t amt){
|
||||
ITCategory cat = itemRef.lock()->Category();
|
||||
return RemoveItem(itemRef, cat, amt);
|
||||
}
|
||||
|
||||
const std::vector<std::shared_ptr<Item>>&Inventory::get(ITCategory itemCategory){
|
||||
return sortedInv.at(itemCategory);
|
||||
}
|
||||
|
||||
void Inventory::InsertIntoSortedInv(IT item){
|
||||
sortedInv.at(ITEM_DATA[item].category).push_back(_inventory[item]);
|
||||
void Inventory::InsertIntoSortedInv(std::shared_ptr<Item>itemRef){
|
||||
sortedInv.at(itemRef->Category()).push_back(itemRef);
|
||||
//This should be a callback to menus that we need to update the interface with another item slot since a new one has appeared.
|
||||
Menu::InventorySlotsUpdated(ITEM_DATA[item].category);
|
||||
Menu::InventorySlotsUpdated(itemRef->Category());
|
||||
}
|
||||
|
||||
void Inventory::InsertIntoStageInventoryCategory(IT item,uint32_t amt,bool monsterDrop){
|
||||
@ -467,7 +489,7 @@ void Inventory::InsertIntoStageInventoryCategory(IT item,uint32_t amt,bool monst
|
||||
stageInventoryCategory="Monster Loot";
|
||||
}
|
||||
std::vector<std::shared_ptr<Item>>&inv=sortedInv.at(stageInventoryCategory);
|
||||
std::vector<std::shared_ptr<Item>>::iterator it=std::find(inv.begin(),inv.end(),std::make_shared<Item>(amt,item));
|
||||
std::vector<std::shared_ptr<Item>>::iterator it=std::find(inv.begin(),inv.end(),std::make_shared<Item>(amt,item)); //Uses operator== to compare if this item does exist in a stage/monster loot inventory already. We just make an in-place shared pointer of an item to compare with.
|
||||
if(it!=inv.end()){
|
||||
(*it)->amt+=amt;
|
||||
}else{
|
||||
@ -491,8 +513,8 @@ bool Inventory::SwapItems(ITCategory itemCategory,uint32_t slot1,uint32_t slot2)
|
||||
//The inventory is too small, so expand out blank slots to accomodate.
|
||||
inv.resize(largestSlot+size_t(1));
|
||||
}
|
||||
std::shared_ptr<Item>item1=inv.at(slot1);
|
||||
std::shared_ptr<Item>item2=inv.at(slot2);
|
||||
std::weak_ptr<Item>item1=inv.at(slot1);
|
||||
std::weak_ptr<Item>item2=inv.at(slot2);
|
||||
std::swap(item1,item2);
|
||||
return true;
|
||||
}
|
||||
@ -609,7 +631,7 @@ void Inventory::Clear(ITCategory itemCategory){
|
||||
if(itemCategory=="Monster Loot"||itemCategory=="Stage Loot"){//These do not affect the actual inventory, we just clear the lists.
|
||||
itemQuantity=item->Amt();
|
||||
}
|
||||
RemoveItem(item->ActualName(),itemCategory,uint32_t(itemQuantity));
|
||||
RemoveItem(item,itemCategory,uint32_t(itemQuantity));
|
||||
}
|
||||
}
|
||||
|
||||
@ -707,7 +729,7 @@ EquipSlot Inventory::GetSlotEquippedIn(const std::weak_ptr<Item>it){
|
||||
EquipSlot slot=EquipSlot(i);
|
||||
std::weak_ptr<Item>equip=GetEquip(slot);
|
||||
if(equip.expired())continue;
|
||||
if(equip.lock()->ActualName()==it.lock()->ActualName())return slot;
|
||||
if(&*equip.lock()==&*it.lock())return slot;
|
||||
}
|
||||
return EquipSlot::NONE;
|
||||
};
|
||||
@ -782,7 +804,7 @@ void Item::EnhanceItem(uint8_t qty){
|
||||
const CraftingRequirement&consumedResources=GetEnhancementInfo()[EnhancementLevel()].craftingRequirement;
|
||||
|
||||
for(const auto&[name,amt]:consumedResources.GetItems()){
|
||||
Inventory::RemoveItem(name,amt);
|
||||
Inventory::RemoveItem(Inventory::GetItem(name)[0],amt);
|
||||
}
|
||||
game->GetPlayer()->SetMoney(game->GetPlayer()->GetMoney()-consumedResources.GetCost());
|
||||
}else{ //This is a craftable, so we have to give the player the item they crafted.
|
||||
@ -791,7 +813,7 @@ void Item::EnhanceItem(uint8_t qty){
|
||||
const CraftingRequirement&consumedResources=GetEnhancementInfo()[1].craftingRequirement;
|
||||
|
||||
for(const auto&[name,amt]:consumedResources.GetItems()){
|
||||
Inventory::RemoveItem(name,amt);
|
||||
Inventory::RemoveItem(Inventory::GetItem(name)[0],amt);
|
||||
}
|
||||
game->GetPlayer()->SetMoney(game->GetPlayer()->GetMoney()-consumedResources.GetCost());
|
||||
}
|
||||
@ -871,7 +893,7 @@ void Item::SetAmt(uint32_t newAmt){
|
||||
}
|
||||
|
||||
const std::weak_ptr<Item>Inventory::GetInventorySlot(ITCategory itemCategory,size_t slot){
|
||||
return GetItem(get(itemCategory).at(slot)->ActualName());
|
||||
return GetItem(get(itemCategory).at(slot)->ActualName())[0];
|
||||
}
|
||||
|
||||
bool Item::IsBlank(std::shared_ptr<Item>item){
|
||||
|
@ -153,7 +153,7 @@ class Item{
|
||||
friend class Crawler;
|
||||
friend class Menu;
|
||||
friend void Merchant::PurchaseItem(IT item,uint32_t amt);
|
||||
friend void Merchant::SellItem(IT item,uint32_t amt);
|
||||
friend void Merchant::SellItem(std::weak_ptr<Item>,uint32_t amt);
|
||||
private:
|
||||
//The amount in the current item stack.
|
||||
uint32_t amt;
|
||||
@ -220,12 +220,12 @@ public:
|
||||
static void AddItem(IT it,uint32_t amt=1,bool monsterDrop=false);
|
||||
//Returns the actual amount available in your main inventory.
|
||||
static uint32_t GetItemCount(IT it);
|
||||
static std::shared_ptr<Item>CopyItem(IT it);
|
||||
static std::weak_ptr<Item>GetItem(IT it);
|
||||
static std::vector<std::shared_ptr<Item>>CopyItem(IT it);
|
||||
static std::vector<std::weak_ptr<Item>>GetItem(IT it);
|
||||
//Auto-executes its use function and removes the amt specified from the inventory. Multiple amounts will cause the item to execute its useFunc multiple times.
|
||||
static bool UseItem(IT it,uint32_t amt=1);
|
||||
static bool RemoveItem(IT it,ITCategory inventory,uint32_t amt = 1);
|
||||
static bool RemoveItem(IT it,uint32_t amt=1);
|
||||
static bool RemoveItem(std::weak_ptr<Item>itemRef,ITCategory inventory,uint32_t amt = 1);
|
||||
static bool RemoveItem(std::weak_ptr<Item>itemRef,uint32_t amt=1);
|
||||
static const std::vector<std::shared_ptr<Item>>&get(ITCategory itemCategory);
|
||||
static const std::weak_ptr<Item>GetInventorySlot(ITCategory itemCategory,size_t slot);
|
||||
static void Clear(ITCategory itemCategory);
|
||||
@ -242,10 +242,10 @@ public:
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
static void InsertIntoSortedInv(IT item);
|
||||
static void InsertIntoSortedInv(std::shared_ptr<Item>itemRef);
|
||||
static void InsertIntoStageInventoryCategory(IT item,uint32_t amt,bool monsterDrop);
|
||||
static bool ExecuteAction(IT item);
|
||||
static std::map<IT,std::shared_ptr<Item>>_inventory;
|
||||
static std::multimap<IT,std::shared_ptr<Item>>_inventory;
|
||||
static std::map<EquipSlot,std::weak_ptr<Item>>equipment;
|
||||
//Only contains "1" of every item, as this is a map to index items and not the actual storage of items!
|
||||
static std::map<ITCategory,std::vector<std::shared_ptr<Item>>>sortedInv;
|
||||
|
58
Crawler/ItemMenuLabel.h
Normal file
58
Crawler/ItemMenuLabel.h
Normal file
@ -0,0 +1,58 @@
|
||||
#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
|
||||
#pragma once
|
||||
|
||||
#include "MenuLabel.h"
|
||||
#include "Item.h"
|
||||
|
||||
class ItemMenuLabel:public MenuLabel{
|
||||
private:
|
||||
std::weak_ptr<Item>itemRef;
|
||||
public:
|
||||
inline ItemMenuLabel(geom2d::rect<float>rect,std::string label,std::weak_ptr<Item>itemRef,std::function<void(std::string_view newLabel)>onLabelChangeFunc,float scale=1,ComponentAttr attributes=ComponentAttr::NONE)
|
||||
:MenuLabel(rect,label,onLabelChangeFunc,scale,attributes),itemRef(itemRef){}
|
||||
inline ItemMenuLabel(geom2d::rect<float>rect,std::string label,std::weak_ptr<Item>itemRef,float scale=1,ComponentAttr attributes=ComponentAttr::NONE)
|
||||
:MenuLabel(rect,label,scale,attributes),itemRef(itemRef){}
|
||||
|
||||
inline const std::weak_ptr<Item>GetItem()const{
|
||||
return itemRef;
|
||||
}
|
||||
inline void SetItem(std::weak_ptr<Item>itemRef){
|
||||
this->itemRef=itemRef;
|
||||
}
|
||||
};
|
@ -74,7 +74,7 @@ public:
|
||||
SetMouseOutFunc(onMouseOut);
|
||||
}
|
||||
inline std::weak_ptr<Item>GetItem(){
|
||||
return Inventory::GetItem(invRef.at(inventoryIndex)->ActualName());
|
||||
return invRef.at(inventoryIndex);
|
||||
}
|
||||
//Returns true if the item has been consumed completely and there are 0 remaining of that type in our inventory.
|
||||
inline bool UseItem(uint32_t amt=1){
|
||||
|
@ -153,7 +153,7 @@ protected:
|
||||
virtual inline void DrawDecal(ViewPort&window,bool focused)override{
|
||||
MenuIconButton::DrawDecal(window,focused);
|
||||
if(valid&&!hideQty){
|
||||
if(!ISBLANK(itemRef)){
|
||||
if(!ISBLANK(itemRef)&&!itemRef.lock()->IsEquippable()){
|
||||
std::string quantityText="x"+std::to_string(itemRef.lock()->Amt());
|
||||
vf2d quantityTextScale=rect.size/48.f;
|
||||
vf2d textSize=vf2d(game->GetTextSizeProp(quantityText))*quantityTextScale;
|
||||
|
@ -185,8 +185,8 @@ void Merchant::PurchaseItem(IT item,uint32_t amt){
|
||||
Inventory::AddItem(item,amt);
|
||||
game->GetPlayer()->SetMoney(game->GetPlayer()->GetMoney()-totalCost);
|
||||
};
|
||||
void Merchant::SellItem(IT item,uint32_t amt){
|
||||
sellFunctionPrimed.Validate(item,amt);
|
||||
void Merchant::SellItem(std::weak_ptr<Item>item,uint32_t amt){
|
||||
sellFunctionPrimed.Validate(item.lock()->ActualName(),amt);
|
||||
|
||||
uint32_t totalCost=0U;
|
||||
bool itemFound=false;
|
||||
@ -199,10 +199,10 @@ void Merchant::SellItem(IT item,uint32_t amt){
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!itemFound&&ITEM_DATA[item].CanBePurchased()){
|
||||
AddItem(item,amt); //This may not be a feature we include in future versions of the game. For now let's allow it.
|
||||
if(!itemFound&&item.lock()->CanBePurchased()){
|
||||
AddItem(item.lock()->ActualName(),amt); //This may not be a feature we include in future versions of the game. For now let's allow it.
|
||||
}
|
||||
totalCost=ITEM_DATA[item].GetSellValue()*amt;
|
||||
totalCost=item.lock()->SellValue()*amt;
|
||||
|
||||
Inventory::RemoveItem(item,amt);
|
||||
game->GetPlayer()->SetMoney(game->GetPlayer()->GetMoney()+totalCost);
|
||||
|
@ -55,7 +55,7 @@ public:
|
||||
bool CanPurchaseItem(IT item,uint32_t amt=1U)const;
|
||||
bool CanSellItem(IT item,uint32_t amt=1U)const;
|
||||
void PurchaseItem(IT item,uint32_t amt=1U);
|
||||
void SellItem(IT item,uint32_t amt=1U);
|
||||
void SellItem(std::weak_ptr<Item>,uint32_t amt=1U);
|
||||
public:
|
||||
static void Initialize();
|
||||
static Merchant&AddMerchant(Chapter chapter);
|
||||
|
@ -42,6 +42,7 @@ All rights reserved.
|
||||
#include "MenuItemItemButton.h"
|
||||
#include "MenuComponent.h"
|
||||
#include "PlayerMoneyLabel.h"
|
||||
#include "ItemMenuLabel.h"
|
||||
|
||||
INCLUDE_game
|
||||
INCLUDE_ITEM_CATEGORIES
|
||||
@ -153,7 +154,7 @@ void Menu::InitializeMerchantWindow(){
|
||||
[](MenuFuncData data){
|
||||
RowItemDisplay*item=DYNAMIC_CAST<RowItemDisplay*>(data.component);
|
||||
if(item->GetItem().lock()->CanBeSold()){
|
||||
Component<MenuLabel>(SELL_ITEM,"Item Sell Header")->S(A::ITEM_NAME)=item->GetItem().lock()->ActualName();
|
||||
Component<ItemMenuLabel>(SELL_ITEM,"Item Sell Header")->SetItem(item->GetItem());
|
||||
Component<MenuLabel>(SELL_ITEM,"Price per item Amount Label")->SetLabel(std::to_string(item->GetItem().lock()->SellValue()));
|
||||
Component<MenuLabel>(SELL_ITEM,"Amount to sell Amount Label")->SetLabel("1");
|
||||
Component<MenuLabel>(SELL_ITEM,"Total Price Amount Label")->SetLabel(std::to_string(item->GetItem().lock()->SellValue()));
|
||||
|
@ -37,7 +37,7 @@ All rights reserved.
|
||||
#pragma endregion
|
||||
|
||||
#include "Menu.h"
|
||||
#include "MenuLabel.h"
|
||||
#include "ItemMenuLabel.h"
|
||||
|
||||
using A=Attribute;
|
||||
|
||||
@ -52,8 +52,8 @@ void Menu::InitializeSellItemWindow(){
|
||||
Component<MenuLabel>(SELL_ITEM,"Amount to sell Amount Label")->SetLabel(std::to_string(qty));
|
||||
|
||||
Merchant&merchant=Merchant::GetCurrentTravelingMerchant();
|
||||
const std::string&item=Component<MenuLabel>(SELL_ITEM,"Item Sell Header")->GetString(A::ITEM_NAME);
|
||||
bool canSell=merchant.CanSellItem(item,GetQuantity());
|
||||
const std::weak_ptr<Item>item=Component<ItemMenuLabel>(SELL_ITEM,"Item Sell Header")->GetItem();
|
||||
bool canSell=merchant.CanSellItem(item.lock()->ActualName(),GetQuantity());
|
||||
|
||||
std::string colorCode="";
|
||||
if(!canSell)colorCode="#FF0000";
|
||||
@ -61,7 +61,7 @@ void Menu::InitializeSellItemWindow(){
|
||||
Component<MenuComponent>(SELL_ITEM,"Sell Button")->SetGrayedOut(!canSell);
|
||||
};
|
||||
|
||||
sellItemWindow->ADD("Item Sell Header",MenuLabel)({{2,2},{188,12}},"Selling ",1,ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND|ComponentAttr::SHADOW|ComponentAttr::FIT_TO_LABEL)END;
|
||||
sellItemWindow->ADD("Item Sell Header",ItemMenuLabel)({{2,2},{188,12}},"Selling {}",Item::BLANK,1,ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND|ComponentAttr::SHADOW|ComponentAttr::FIT_TO_LABEL)END;
|
||||
|
||||
sellItemWindow->ADD("Price Per Item Label",MenuLabel)({{4,18},{188,12}},"Price Per Item",1.0f,ComponentAttr::LEFT_ALIGN|ComponentAttr::SHADOW)END;
|
||||
sellItemWindow->ADD("Amount to Sell Label",MenuLabel)({{4,34},{188,12}},"Amount to Sell",1.0f,ComponentAttr::LEFT_ALIGN|ComponentAttr::SHADOW)END;
|
||||
@ -83,8 +83,7 @@ void Menu::InitializeSellItemWindow(){
|
||||
|
||||
sellItemWindow->ADD("Sell Button",MenuComponent)({{sellItemWindow->size.x/2+18,70},{64,12}},"Sell",[&](MenuFuncData data){
|
||||
Merchant&merchant=Merchant::GetCurrentTravelingMerchant();
|
||||
const std::string&item=Component<MenuLabel>(SELL_ITEM,"Item Sell Header")->GetString(A::ITEM_NAME);
|
||||
merchant.SellItem(item,GetQuantity());
|
||||
merchant.SellItem(Component<ItemMenuLabel>(SELL_ITEM,"Item Sell Header")->GetItem(),GetQuantity());
|
||||
Menu::CloseMenu();
|
||||
return true;
|
||||
})END;
|
||||
|
@ -1,6 +1,5 @@
|
||||
January 1st
|
||||
===========
|
||||
Blacksmith Item Crafting Screen
|
||||
Randomized Item Stats
|
||||
- Get Item may return multiples of the same item.
|
||||
- Removing an item with multiples require a specific item to be selected.
|
||||
|
@ -39,7 +39,7 @@ All rights reserved.
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 2
|
||||
#define VERSION_PATCH 1
|
||||
#define VERSION_BUILD 5079
|
||||
#define VERSION_BUILD 5110
|
||||
|
||||
#define stringify(a) stringify_(a)
|
||||
#define stringify_(a) #a
|
||||
|
Loading…
x
Reference in New Issue
Block a user