Implemented Merchant Selling Screen

pull/28/head
sigonasr2 11 months ago
parent 25dd39b60a
commit 6412f34dce
  1. 4
      Crawler/BuyItemWindow.cpp
  2. 8
      Crawler/Crawler.cpp
  3. 5
      Crawler/Crawler.vcxproj
  4. 4
      Crawler/Crawler.vcxproj.filters
  5. 2
      Crawler/InventoryConsumableWindow.cpp
  6. 16
      Crawler/InventoryScrollableWindowComponent.h
  7. 8
      Crawler/InventoryWindow.cpp
  8. 4
      Crawler/LevelCompleteWindow.cpp
  9. 2
      Crawler/Menu.cpp
  10. 14
      Crawler/MenuItemItemButton.h
  11. 4
      Crawler/MenuLabel.h
  12. 17
      Crawler/Merchant.cpp
  13. 34
      Crawler/MerchantWindow.cpp
  14. 21
      Crawler/RowInventoryScrollableWindowComponent.h
  15. 35
      Crawler/RowItemDisplay.h
  16. 24
      Crawler/RowMerchantInventoryScrollableWindowComponent.h
  17. 4
      Crawler/ScrollableWindowComponent.h
  18. 52
      Crawler/SellItemWindow.cpp
  19. 4
      Crawler/TODO.txt
  20. 2
      Crawler/Version.h
  21. 1
      Crawler/assets/config/gfx/gfx.txt
  22. 8
      Crawler/olcPGEX_ViewPort.h
  23. 8
      Crawler/olcPixelGameEngine.h

@ -43,10 +43,10 @@ using A=Attribute;
void Menu::InitializeBuyItemWindow(){ void Menu::InitializeBuyItemWindow(){
Menu*buyItemWindow=CreateMenu(BUY_ITEM,CENTERED,{192,72}); Menu*buyItemWindow=CreateMenu(BUY_ITEM,CENTERED,{192,72});
static auto GetQuantity = [&](){ static auto GetQuantity=[&](){
return std::stoi(Component<MenuLabel>(BUY_ITEM,"Amount to buy Amount Label")->GetLabel()); return std::stoi(Component<MenuLabel>(BUY_ITEM,"Amount to buy Amount Label")->GetLabel());
}; };
static auto UpdateMenu = [&](int32_t qty){ static auto UpdateMenu=[&](int32_t qty){
qty=std::clamp(qty,1,99); qty=std::clamp(qty,1,99);
int pricePerItem=std::stoi(Component<MenuLabel>(BUY_ITEM,"Price per item Amount Label")->GetLabel()); int pricePerItem=std::stoi(Component<MenuLabel>(BUY_ITEM,"Price per item Amount Label")->GetLabel());
Component<MenuLabel>(BUY_ITEM,"Amount to buy Amount Label")->SetLabel(std::to_string(qty)); Component<MenuLabel>(BUY_ITEM,"Amount to buy Amount Label")->SetLabel(std::to_string(qty));

@ -1244,7 +1244,7 @@ void Crawler::RenderHud(){
std::stringstream castTimeDisplay; std::stringstream castTimeDisplay;
castTimeDisplay<<std::fixed<<std::setprecision(1)<<timer; castTimeDisplay<<std::fixed<<std::setprecision(1)<<timer;
DrawShadowStringPropDecal(vf2d{ScreenWidth()/2+90.f,ScreenHeight()-80.f}-vf2d{float(GetTextSizeProp(castTimeDisplay.str()).x),0},castTimeDisplay.str(),WHITE,BLACK); DrawShadowStringPropDecal(vf2d{ScreenWidth()/2+90.f,ScreenHeight()-80.f}-vf2d{float(GetTextSizeProp(castTimeDisplay.str()).x),0},castTimeDisplay.str(),WHITE,BLACK);
DrawShadowStringPropDecal(vf2d{ScreenWidth()/2.f-GetTextSizeProp(castText).x*2/2,ScreenHeight()-64.f},castText,WHITE,BLACK,{2,3},std::numeric_limits<float>::max(),0.75f); DrawShadowStringPropDecal(vf2d{ScreenWidth()/2.f-GetTextSizeProp(castText).x*2/2,ScreenHeight()-64.f},castText,WHITE,BLACK,{2,3},std::numeric_limits<float>::max(),2.f);
}; };
if(GetPlayer()->GetCastInfo().castTimer>0){ if(GetPlayer()->GetCastInfo().castTimer>0){
@ -1258,8 +1258,8 @@ void Crawler::RenderHud(){
DrawDecal({2,20},GFX["mana.png"].Decal()); DrawDecal({2,20},GFX["mana.png"].Decal());
std::string text=player->GetHealth()>0?std::to_string(player->GetHealth()):"X"; std::string text=player->GetHealth()>0?std::to_string(player->GetHealth()):"X";
std::string text_mana=std::to_string(player->GetMana()); std::string text_mana=std::to_string(player->GetMana());
DrawShadowStringPropDecal({20,3},text,WHITE,BLACK,{2,2},INFINITE,0.5f); DrawShadowStringPropDecal({20,3},text,WHITE,BLACK,{2,2},INFINITE);
DrawShadowStringPropDecal({24,23},text_mana,{192,192,255},BLACK,{1.5f,1.5f},INFINITE,0.6f); DrawShadowStringPropDecal({24,23},text_mana,{192,192,255},BLACK,{1.5f,1.5f},INFINITE);
if(player->notEnoughManaDisplay.second>0){ if(player->notEnoughManaDisplay.second>0){
std::string displayText="Not enough mana for "+player->notEnoughManaDisplay.first+"!"; std::string displayText="Not enough mana for "+player->notEnoughManaDisplay.first+"!";
DrawShadowStringPropDecal(vf2d{float(ScreenWidth()/2),float(ScreenHeight()/4)}-GetTextSizeProp(displayText)/2,displayText,DARK_RED,VERY_DARK_RED); DrawShadowStringPropDecal(vf2d{float(ScreenWidth()/2),float(ScreenHeight()/4)}-GetTextSizeProp(displayText)/2,displayText,DARK_RED,VERY_DARK_RED);
@ -1362,7 +1362,7 @@ void Crawler::RenderCooldowns(){
DrawShadowStringDecal(pos+vf2d{12,-2}-keyDisplaySize/2,a.input->GetDisplayName(),keyDisplayCol,BLACK,{0.5f,0.5f},std::numeric_limits<float>::max(),1); DrawShadowStringDecal(pos+vf2d{12,-2}-keyDisplaySize/2,a.input->GetDisplayName(),keyDisplayCol,BLACK,{0.5f,0.5f},std::numeric_limits<float>::max(),1);
vf2d shortNameSize=vf2d{GetTextSize(a.shortName)}*vf2d{0.5f,0.75f}; vf2d shortNameSize=vf2d{GetTextSize(a.shortName)}*vf2d{0.5f,0.75f};
DrawShadowStringDecal(pos+vf2d{13,24}-shortNameSize/2,a.shortName,shortNameCol,WHITE,{0.5f,0.75f}); DrawShadowStringDecal(pos+vf2d{13,24}-shortNameSize/2,a.shortName,shortNameCol,{255,255,255,230},{0.5f,0.75f});
} }
}; };

@ -407,10 +407,7 @@
<SubType> <SubType>
</SubType> </SubType>
</ClInclude> </ClInclude>
<ClInclude Include="RowMerchantInventoryScrollableWindowComponent.h"> <ClInclude Include="RowMerchantInventoryScrollableWindowComponent.h" />
<SubType>
</SubType>
</ClInclude>
<ClInclude Include="safemap.h" /> <ClInclude Include="safemap.h" />
<ClInclude Include="ScrollableWindowComponent.h" /> <ClInclude Include="ScrollableWindowComponent.h" />
<ClInclude Include="InventoryScrollableWindowComponent.h" /> <ClInclude Include="InventoryScrollableWindowComponent.h" />

@ -375,10 +375,10 @@
<ClInclude Include="discord-files\types.h"> <ClInclude Include="discord-files\types.h">
<Filter>Header Files\discord-files</Filter> <Filter>Header Files\discord-files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="RowMerchantInventoryScrollableWindowComponent.h"> <ClInclude Include="PlayerMoneyLabel.h">
<Filter>Header Files\Interface</Filter> <Filter>Header Files\Interface</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="PlayerMoneyLabel.h"> <ClInclude Include="RowMerchantInventoryScrollableWindowComponent.h">
<Filter>Header Files\Interface</Filter> <Filter>Header Files\Interface</Filter>
</ClInclude> </ClInclude>
</ItemGroup> </ItemGroup>

@ -55,7 +55,7 @@ void Menu::InitializeConsumableInventoryWindow(){
inventoryWindow->I(A::LOADOUT_SLOT)=0; inventoryWindow->I(A::LOADOUT_SLOT)=0;
auto consumableWindow=inventoryWindow->ADD("inventory",InventoryScrollableWindowComponent)({{0,15},{windowSize.x,96.f}},"Consumables","itemName","itemDescription", auto consumableWindow=inventoryWindow->ADD("inventory",InventoryScrollableWindowComponent)({{0,15},{windowSize.x,96.f}},"itemName","itemDescription",
[&](MenuFuncData data){ [&](MenuFuncData data){
MenuItemButton*button=(MenuItemButton*)data.component; MenuItemButton*button=(MenuItemButton*)data.component;
data.game->ClearLoadoutItem(data.menu.I(A::LOADOUT_SLOT)); data.game->ClearLoadoutItem(data.menu.I(A::LOADOUT_SLOT));

@ -57,7 +57,6 @@ struct InventoryWindowOptions{
// Please ensure these are overwritten, otherwise you will get errors complaining about dynamic casts unable to convert classes successfully. // Please ensure these are overwritten, otherwise you will get errors complaining about dynamic casts unable to convert classes successfully.
class InventoryScrollableWindowComponent:public ScrollableWindowComponent{ class InventoryScrollableWindowComponent:public ScrollableWindowComponent{
protected: protected:
ITCategory inventoryType;
std::function<bool(MenuFuncData)>inventoryButtonClickAction; std::function<bool(MenuFuncData)>inventoryButtonClickAction;
std::function<bool(MenuFuncData)>inventoryButtonHoverAction; std::function<bool(MenuFuncData)>inventoryButtonHoverAction;
std::function<bool(MenuFuncData)>inventoryButtonMouseOutAction; std::function<bool(MenuFuncData)>inventoryButtonMouseOutAction;
@ -67,11 +66,11 @@ protected:
std::string itemDescriptionLabelName; std::string itemDescriptionLabelName;
bool inventoryButtonsActive=true; bool inventoryButtonsActive=true;
public: public:
inline InventoryScrollableWindowComponent(geom2d::rect<float>rect,ITCategory invType,std::string itemNameLabelName,std::string itemDescriptionLabelName,std::function<bool(MenuFuncData)>inventoryButtonClickAction,InventoryWindowOptions options={.padding=8,.size={24,24}},bool inventoryButtonsActive=true,ComponentAttr attributes=ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE) inline InventoryScrollableWindowComponent(geom2d::rect<float>rect,std::string itemNameLabelName,std::string itemDescriptionLabelName,std::function<bool(MenuFuncData)>inventoryButtonClickAction,InventoryWindowOptions options={.padding=8,.size={24,24}},bool inventoryButtonsActive=true,ComponentAttr attributes=ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE)
:InventoryScrollableWindowComponent(rect,invType,itemNameLabelName,itemDescriptionLabelName,inventoryButtonClickAction,DO_NOTHING,DO_NOTHING,options,inventoryButtonsActive,attributes){ :InventoryScrollableWindowComponent(rect,itemNameLabelName,itemDescriptionLabelName,inventoryButtonClickAction,DO_NOTHING,DO_NOTHING,options,inventoryButtonsActive,attributes){
} }
inline InventoryScrollableWindowComponent(geom2d::rect<float>rect,ITCategory invType,std::string itemNameLabelName,std::string itemDescriptionLabelName,std::function<bool(MenuFuncData)>inventoryButtonClickAction,std::function<bool(MenuFuncData)>inventoryButtonHoverAction,std::function<bool(MenuFuncData)>inventoryButtonMouseOutAction,InventoryWindowOptions options={.padding=8,.size={24,24}},bool inventoryButtonsActive=true,ComponentAttr attributes=ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE) inline InventoryScrollableWindowComponent(geom2d::rect<float>rect,std::string itemNameLabelName,std::string itemDescriptionLabelName,std::function<bool(MenuFuncData)>inventoryButtonClickAction,std::function<bool(MenuFuncData)>inventoryButtonHoverAction,std::function<bool(MenuFuncData)>inventoryButtonMouseOutAction,InventoryWindowOptions options={.padding=8,.size={24,24}},bool inventoryButtonsActive=true,ComponentAttr attributes=ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE)
:ScrollableWindowComponent(rect,attributes),inventoryButtonHoverAction(inventoryButtonHoverAction),inventoryButtonMouseOutAction(inventoryButtonMouseOutAction),inventoryType(invType),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName), :ScrollableWindowComponent(rect,attributes),inventoryButtonHoverAction(inventoryButtonHoverAction),inventoryButtonMouseOutAction(inventoryButtonMouseOutAction),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName),
options(options),inventoryButtonClickAction(inventoryButtonClickAction),inventoryButtonsActive(inventoryButtonsActive){} options(options),inventoryButtonClickAction(inventoryButtonClickAction),inventoryButtonsActive(inventoryButtonsActive){}
virtual inline void Update(Crawler*game)override{ virtual inline void Update(Crawler*game)override{
ScrollableWindowComponent::Update(game); ScrollableWindowComponent::Update(game);
@ -128,7 +127,10 @@ protected:
AddButtonOnSlotUpdate(cat); AddButtonOnSlotUpdate(cat);
}else }else
if(components.size()>invSize){ //There are empty spots, so let's clean up. if(components.size()>invSize){ //There are empty spots, so let's clean up.
RemoveEmptySlots(); RemoveAllComponents();
for(std::weak_ptr<Item> item:Inventory::get(cat)){
AddButtonOnSlotUpdate(cat);
}
} }
} }
@ -137,7 +139,7 @@ protected:
} }
virtual inline void AddButtonOnSlotUpdate(ITCategory cat){ virtual inline void AddButtonOnSlotUpdate(ITCategory cat){
size_t invSize=Inventory::get(cat).size(); size_t invSize=components.size()+1;
int invWidth=int(rect.size.x/(float(options.size.x)+options.padding)); int invWidth=int(rect.size.x/(float(options.size.x)+options.padding));
int x=int((invSize-1)%invWidth); int x=int((invSize-1)%invWidth);
int y=int((invSize-1)/invWidth); int y=int((invSize-1)/invWidth);

@ -88,7 +88,7 @@ void Menu::InitializeInventoryWindow(){
button->SetSelectionType(HIGHLIGHT); button->SetSelectionType(HIGHLIGHT);
button->S(A::CATEGORY_NAME)=category; button->S(A::CATEGORY_NAME)=category;
auto inventoryDisplay=inventoryWindow->ADD("Inventory Display - "+category,RowInventoryScrollableWindowComponent)({{72,28},{150,inventoryWindow->size.y-44}},category,"Item Name Label","Item Description Label",DO_NOTHING, auto inventoryDisplay=inventoryWindow->ADD("Inventory Display - "+category,RowInventoryScrollableWindowComponent)({{72,28},{150,inventoryWindow->size.y-44}},"Item Name Label","Item Description Label",DO_NOTHING,
[](MenuFuncData data){ [](MenuFuncData data){
Component<MenuItemItemButton>(data.menu.GetType(),"Item Icon")->SetItem(dynamic_cast<RowItemDisplay*>(data.component)->GetItem()); Component<MenuItemItemButton>(data.menu.GetType(),"Item Icon")->SetItem(dynamic_cast<RowItemDisplay*>(data.component)->GetItem());
Component<MenuItemItemButton>(data.menu.GetType(),"Item Icon")->UpdateIcon(); Component<MenuItemItemButton>(data.menu.GetType(),"Item Icon")->UpdateIcon();
@ -131,4 +131,10 @@ void Menu::InitializeInventoryWindow(){
moneyDisplay->SetRightAlignment(true); moneyDisplay->SetRightAlignment(true);
Player::AddMoneyListener(moneyDisplay); Player::AddMoneyListener(moneyDisplay);
#pragma endregion #pragma endregion
inventoryWindow->ADD("Back Button",MenuComponent)({{inventoryWindow->size.x/2-48,28+inventoryWindow->size.y-44+6},{96,24}},"Back",MenuType::ENUM_END,
[](MenuFuncData data){
Menu::CloseMenu();
return true;
},{2,2})END;
} }

@ -55,12 +55,12 @@ void Menu::InitializeLevelCompleteWindow(){
levelCompleteWindow->ADD("Monster Loot Outline",MenuComponent)({{0,32},{windowSize.size.x-80.f,72}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)END; levelCompleteWindow->ADD("Monster Loot Outline",MenuComponent)({{0,32},{windowSize.size.x-80.f,72}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)END;
levelCompleteWindow->ADD("Monster Loot Label",MenuLabel)({{0,32},{windowSize.size.x-80.f,12}},"Monster Loot",1,ComponentAttr::LEFT_ALIGN|ComponentAttr::SHADOW|ComponentAttr::OUTLINE)END; levelCompleteWindow->ADD("Monster Loot Label",MenuLabel)({{0,32},{windowSize.size.x-80.f,12}},"Monster Loot",1,ComponentAttr::LEFT_ALIGN|ComponentAttr::SHADOW|ComponentAttr::OUTLINE)END;
auto monsterLootWindow=levelCompleteWindow->ADD("Monster Loot Window",InventoryScrollableWindowComponent)({{0,44},{windowSize.size.x-80.f,60}},"Monster Loot","Monster Loot Popup Item Name","Monster Loot Popup Item Description",DO_NOTHING)END; auto monsterLootWindow=levelCompleteWindow->ADD("Monster Loot Window",InventoryScrollableWindowComponent)({{0,44},{windowSize.size.x-80.f,60}},"Monster Loot Popup Item Name","Monster Loot Popup Item Description",DO_NOTHING)END;
Menu::AddInventoryListener(monsterLootWindow,"Monster Loot"); Menu::AddInventoryListener(monsterLootWindow,"Monster Loot");
levelCompleteWindow->ADD("Stage Loot Outline",MenuComponent)({{0,108},{windowSize.size.x-80.f,72}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)END; levelCompleteWindow->ADD("Stage Loot Outline",MenuComponent)({{0,108},{windowSize.size.x-80.f,72}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)END;
levelCompleteWindow->ADD("Stage Loot Label",MenuLabel)({{0,108},{windowSize.size.x-80.f,12}},"Stage Loot",1,ComponentAttr::LEFT_ALIGN|ComponentAttr::SHADOW|ComponentAttr::OUTLINE)END; levelCompleteWindow->ADD("Stage Loot Label",MenuLabel)({{0,108},{windowSize.size.x-80.f,12}},"Stage Loot",1,ComponentAttr::LEFT_ALIGN|ComponentAttr::SHADOW|ComponentAttr::OUTLINE)END;
auto stageLootWindow=levelCompleteWindow->ADD("Stage Loot Window",InventoryScrollableWindowComponent)({{0,120},{windowSize.size.x-80.f,60}},"Stage Loot","Stage Loot Popup Item Name","Stage Loot Popup Item Description",DO_NOTHING)END; auto stageLootWindow=levelCompleteWindow->ADD("Stage Loot Window",InventoryScrollableWindowComponent)({{0,120},{windowSize.size.x-80.f,60}},"Stage Loot Popup Item Name","Stage Loot Popup Item Description",DO_NOTHING)END;
Menu::AddInventoryListener(stageLootWindow,"Stage Loot"); Menu::AddInventoryListener(stageLootWindow,"Stage Loot");
auto nextButtonAction=[](MenuFuncData data){ auto nextButtonAction=[](MenuFuncData data){

@ -177,6 +177,8 @@ void Menu::MenuSelect(Crawler*game){
} }
void Menu::Update(Crawler*game){ void Menu::Update(Crawler*game){
if(selection.x<0||selection.x>=buttons[selection.y].size()){selection={-1,-1};}
if(draggingComponent==nullptr){ if(draggingComponent==nullptr){
HoverMenuSelect(game); HoverMenuSelect(game);
} }

@ -138,12 +138,14 @@ protected:
virtual inline void DrawDecal(ViewPort&window,bool focused)override{ virtual inline void DrawDecal(ViewPort&window,bool focused)override{
MenuIconButton::DrawDecal(window,focused); MenuIconButton::DrawDecal(window,focused);
if(valid&&!hideQty){ if(valid&&!hideQty){
std::string quantityText="x"+std::to_string(itemRef.lock()->Amt()); if(!ISBLANK(itemRef)){
vf2d quantityTextScale=rect.size/48.f; std::string quantityText="x"+std::to_string(itemRef.lock()->Amt());
vf2d textSize=vf2d(game->GetTextSizeProp(quantityText))*quantityTextScale; vf2d quantityTextScale=rect.size/48.f;
vf2d drawPos=rect.pos+rect.size-textSize; vf2d textSize=vf2d(game->GetTextSizeProp(quantityText))*quantityTextScale;
if(itemRef.lock()->Amt()!=INFINITE){ vf2d drawPos=rect.pos+rect.size-textSize;
window.DrawShadowStringDecal(drawPos,quantityText,WHITE,BLACK,quantityTextScale); if(itemRef.lock()->Amt()!=INFINITE){
window.DrawShadowStringDecal(drawPos,quantityText,WHITE,BLACK,quantityTextScale);
}
} }
} }
} }

@ -83,9 +83,9 @@ protected:
} }
if(shadow){ if(shadow){
window.DrawShadowStringPropDecal(drawPos,label,WHITE,BLACK,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x); window.DrawShadowStringPropDecal(drawPos,label,WHITE,BLACK,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x,1.0f);
}else{ }else{
window.DrawStringPropDecal(drawPos,label,WHITE,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x); window.DrawStringPropDecal(drawPos,label,WHITE,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x,1.0f);
} }
} }
}; };

@ -73,8 +73,8 @@ Merchant&Merchant::AddMerchant(Chapter chapter){
void Merchant::AddItem(IT item,uint32_t amt,uint8_t enhancementLevel){ void Merchant::AddItem(IT item,uint32_t amt,uint8_t enhancementLevel){
shopItems.push_back(std::make_shared<Item>(amt,item,enhancementLevel)); shopItems.push_back(std::make_shared<Item>(amt,item,enhancementLevel));
UpdateSortedItemsList();
if(&GetCurrentTravelingMerchant()==this){ if(&GetCurrentTravelingMerchant()==this){
UpdateSortedItemsList();
Menu::MerchantInventorySlotsUpdated(ITEM_DATA[item].Category()); Menu::MerchantInventorySlotsUpdated(ITEM_DATA[item].Category());
} }
} }
@ -161,16 +161,27 @@ void Merchant::PurchaseItem(IT item,uint32_t amt){
purchaseFunctionPrimed.Validate(item,amt); purchaseFunctionPrimed.Validate(item,amt);
uint32_t totalCost=0U; uint32_t totalCost=0U;
bool finiteItemPurchased=false;
for(std::shared_ptr<Item>it:shopItems){ for(std::shared_ptr<Item>it:shopItems){
if(it==item){ if(it==item){
if(it->Amt()!=INFINITE){ if(it->Amt()!=INFINITE){
it->SetAmt(it->Amt()-amt); it->SetAmt(it->Amt()-amt);
finiteItemPurchased=true;
} }
totalCost=it->BuyValue()*amt; totalCost=it->BuyValue()*amt;
break; break;
} }
} }
if(finiteItemPurchased){
size_t removeCount=std::erase_if(shopItems,[](std::shared_ptr<Item> it){return it->Amt()==0;});
if(removeCount>1)ERR("WARNING! Somehow we sold more than one item???")
if(removeCount){
UpdateSortedItemsList();
Menu::MerchantInventorySlotsUpdated(ITEM_DATA[item].Category());
}
}
Inventory::AddItem(item,amt); Inventory::AddItem(item,amt);
game->GetPlayer()->SetMoney(game->GetPlayer()->GetMoney()-totalCost); game->GetPlayer()->SetMoney(game->GetPlayer()->GetMoney()-totalCost);
@ -190,8 +201,8 @@ void Merchant::SellItem(IT item,uint32_t amt){
break; break;
} }
} }
if(!itemFound){ if(!itemFound&&ITEM_DATA[item].CanBePurchased()){
AddItem(item); //This may not be a feature we include in future versions of the game. For now let's allow it. AddItem(item,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_DATA[item].GetSellValue()*amt;

@ -77,7 +77,7 @@ void Menu::InitializeMerchantWindow(){
buyTab->selectionType=SelectionType::HIGHLIGHT; buyTab->selectionType=SelectionType::HIGHLIGHT;
auto sellTab=merchantWindow->ADD("Sell Tab",MenuComponent)({{merchantWindow->size.x/2+2,0},{merchantWindow->size.x/2-4,24}},"Sell",[](MenuFuncData data){ auto sellTab=merchantWindow->ADD("Sell Tab",MenuComponent)({{merchantWindow->size.x/2+2,0},{merchantWindow->size.x/2-4,24}},"Sell",[](MenuFuncData data){
Component<RowMerchantInventoryScrollableWindowComponent>(MERCHANT,"Merchant Inventory Display")->Enable(false); Component<RowInventoryScrollableWindowComponent>(MERCHANT,"Merchant Inventory Display")->Enable(false);
Component<MenuComponent>(MERCHANT,"Buy Tab")->selected=false; Component<MenuComponent>(MERCHANT,"Buy Tab")->selected=false;
Component<MenuComponent>(MERCHANT,"Inventory Tabs Outline")->Enable(true); Component<MenuComponent>(MERCHANT,"Inventory Tabs Outline")->Enable(true);
for(auto&[category,items]:ITEM_CATEGORIES){ for(auto&[category,items]:ITEM_CATEGORIES){
@ -119,6 +119,7 @@ void Menu::InitializeMerchantWindow(){
Component<MenuItemItemButton>(data.menu.GetType(),"Item Icon")->UpdateIcon(); Component<MenuItemItemButton>(data.menu.GetType(),"Item Icon")->UpdateIcon();
return true; return true;
},{.padding=1,.size={220-13,28}})END; },{.padding=1,.size={220-13,28}})END;
inventoryDisplay->SetPriceLabelType(PriceLabel::BUY_LABEL);
for(auto&[category,items]:ITEM_CATEGORIES){ for(auto&[category,items]:ITEM_CATEGORIES){
Menu::AddMerchantInventoryListener(inventoryDisplay,category); Menu::AddMerchantInventoryListener(inventoryDisplay,category);
@ -148,22 +149,24 @@ void Menu::InitializeMerchantWindow(){
button->SetSelectionType(HIGHLIGHT); button->SetSelectionType(HIGHLIGHT);
button->S(A::CATEGORY_NAME)=category; button->S(A::CATEGORY_NAME)=category;
auto inventoryDisplay=merchantWindow->ADD("Inventory Display - "+category,RowInventoryScrollableWindowComponent)({{72,28},{150,merchantWindow->size.y-44}},category,"Item Name Label","Item Description Label", auto inventoryDisplay=merchantWindow->ADD("Inventory Display - "+category,RowInventoryScrollableWindowComponent)({{72,28},{150,merchantWindow->size.y-44}},"Item Name Label","Item Description Label",
[](MenuFuncData data){ [](MenuFuncData data){
RowItemDisplay*item=dynamic_cast<RowItemDisplay*>(data.component); RowItemDisplay*item=dynamic_cast<RowItemDisplay*>(data.component);
Component<MenuLabel>(SELL_ITEM,"Item Sell Header")->S(A::ITEM_NAME)=item->GetItem().lock()->ActualName(); if(item->GetItem().lock()->CanBeSold()){
Component<MenuLabel>(SELL_ITEM,"Price per item Amount Label")->SetLabel(std::to_string(item->GetItem().lock()->BuyValue())); Component<MenuLabel>(SELL_ITEM,"Item Sell Header")->S(A::ITEM_NAME)=item->GetItem().lock()->ActualName();
Component<MenuLabel>(SELL_ITEM,"Amount to sell Amount Label")->SetLabel("1"); Component<MenuLabel>(SELL_ITEM,"Price per item Amount Label")->SetLabel(std::to_string(item->GetItem().lock()->SellValue()));
Component<MenuLabel>(SELL_ITEM,"Total Price Amount Label")->SetLabel(std::to_string(item->GetItem().lock()->BuyValue())); Component<MenuLabel>(SELL_ITEM,"Amount to sell Amount Label")->SetLabel("1");
Merchant&merchant=Merchant::GetCurrentTravelingMerchant(); Component<MenuLabel>(SELL_ITEM,"Total Price Amount Label")->SetLabel(std::to_string(item->GetItem().lock()->SellValue()));
bool canPurchase=merchant.CanPurchaseItem(item->GetItem().lock()->ActualName(),1); Merchant&merchant=Merchant::GetCurrentTravelingMerchant();
bool canPurchase=merchant.CanSellItem(item->GetItem().lock()->ActualName(),1);
std::string colorCode="";
if(!canPurchase)colorCode="#FF0000"; std::string colorCode="";
Component<MenuLabel>(SELL_ITEM,"Total Price Amount Label")->SetLabel(colorCode+std::to_string(item->GetItem().lock()->BuyValue())); if(!canPurchase)colorCode="#FF0000";
Component<MenuLabel>(SELL_ITEM,"Item Purchase Header")->SetLabel("Buying "+item->GetItem().lock()->DisplayName()); Component<MenuLabel>(SELL_ITEM,"Total Price Amount Label")->SetLabel(colorCode+std::to_string(item->GetItem().lock()->SellValue()));
Component<MenuComponent>(SELL_ITEM,"Purchase Button")->SetGrayedOut(!merchant.CanPurchaseItem(item->GetItem().lock()->ActualName(),1)); Component<MenuLabel>(SELL_ITEM,"Item Sell Header")->SetLabel("Selling "+item->GetItem().lock()->DisplayName());
Menu::OpenMenu(SELL_ITEM); Component<MenuComponent>(SELL_ITEM,"Sell Button")->SetGrayedOut(!merchant.CanSellItem(item->GetItem().lock()->ActualName(),1));
Menu::OpenMenu(SELL_ITEM);
}
return true; return true;
}, },
[](MenuFuncData data){ [](MenuFuncData data){
@ -176,6 +179,7 @@ void Menu::InitializeMerchantWindow(){
Component<MenuItemItemButton>(data.menu.GetType(),"Item Icon")->UpdateIcon(); Component<MenuItemItemButton>(data.menu.GetType(),"Item Icon")->UpdateIcon();
return true; return true;
},{.padding=1,.size={137,28}})END; },{.padding=1,.size={137,28}})END;
inventoryDisplay->SetPriceLabelType(PriceLabel::SELL_LABEL);
if(first){ if(first){
merchantWindow->S(A::LAST_INVENTORY_TYPE_OPENED)=category; merchantWindow->S(A::LAST_INVENTORY_TYPE_OPENED)=category;

@ -40,9 +40,11 @@ All rights reserved.
#include "RowItemDisplay.h" #include "RowItemDisplay.h"
class RowInventoryScrollableWindowComponent:public InventoryScrollableWindowComponent{ class RowInventoryScrollableWindowComponent:public InventoryScrollableWindowComponent{
protected:
PriceLabel::PriceLabel priceLabel=PriceLabel::NONE;
public: public:
inline RowInventoryScrollableWindowComponent(geom2d::rect<float>rect,ITCategory invType,std::string itemNameLabelName,std::string itemDescriptionLabelName,std::function<bool(MenuFuncData)>inventoryButtonClickAction,std::function<bool(MenuFuncData)>inventoryButtonHoverAction,std::function<bool(MenuFuncData)>inventoryButtonMouseOutAction,InventoryWindowOptions options={.padding=8,.size={24,24}},bool inventoryButtonsActive=true,ComponentAttr attributes=ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE) inline RowInventoryScrollableWindowComponent(geom2d::rect<float>rect,std::string itemNameLabelName,std::string itemDescriptionLabelName,std::function<bool(MenuFuncData)>inventoryButtonClickAction,std::function<bool(MenuFuncData)>inventoryButtonHoverAction,std::function<bool(MenuFuncData)>inventoryButtonMouseOutAction,InventoryWindowOptions options={.padding=8,.size={24,24}},bool inventoryButtonsActive=true,ComponentAttr attributes=ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE)
:InventoryScrollableWindowComponent(rect,invType,itemNameLabelName,itemDescriptionLabelName,inventoryButtonClickAction,inventoryButtonHoverAction,inventoryButtonMouseOutAction,options,inventoryButtonsActive,attributes){} :InventoryScrollableWindowComponent(rect,itemNameLabelName,itemDescriptionLabelName,inventoryButtonClickAction,inventoryButtonHoverAction,inventoryButtonMouseOutAction,options,inventoryButtonsActive,attributes){}
virtual inline void SetCompactDescriptions(bool compact)override final{ virtual inline void SetCompactDescriptions(bool compact)override final{
if(compact)this->compact=COMPACT; if(compact)this->compact=COMPACT;
@ -57,8 +59,20 @@ public:
} }
} }
virtual inline void SetPriceLabelType(PriceLabel::PriceLabel labelType)final{
this->priceLabel=labelType;
for(MenuComponent*component:components){
RowItemDisplay*itemButton=dynamic_cast<RowItemDisplay*>(component);
if(itemButton){
itemButton->SetPriceLabelType(labelType);
}else{
ERR("WARNING! Attempting to cast a button that isn't a MenuItemButton!");
}
}
}
virtual inline void AddButtonOnSlotUpdate(ITCategory cat)override{ virtual inline void AddButtonOnSlotUpdate(ITCategory cat)override{
size_t invSize=Inventory::get(cat).size(); size_t invSize=components.size()+1;
int invWidth=int(rect.size.x/(float(options.size.x)+options.padding)); int invWidth=int(rect.size.x/(float(options.size.x)+options.padding));
int x=int((invSize-1)%invWidth); int x=int((invSize-1)%invWidth);
int y=int((invSize-1)/invWidth); int y=int((invSize-1)/invWidth);
@ -69,6 +83,7 @@ public:
auto newItem=ADD("item_"+cat+"_"+std::to_string(itemIndex),RowItemDisplay)({totalSpacing*vf2d{float(x),float(y)},buttonSize},Inventory::GetInventorySlot(cat,itemIndex),inventoryButtonClickAction,itemNameLabelName,itemDescriptionLabelName,inventoryButtonsActive?ButtonAttr::NONE:ButtonAttr::UNSELECTABLE)END; auto newItem=ADD("item_"+cat+"_"+std::to_string(itemIndex),RowItemDisplay)({totalSpacing*vf2d{float(x),float(y)},buttonSize},Inventory::GetInventorySlot(cat,itemIndex),inventoryButtonClickAction,itemNameLabelName,itemDescriptionLabelName,inventoryButtonsActive?ButtonAttr::NONE:ButtonAttr::UNSELECTABLE)END;
newItem->SetCompactDescriptions(compact==COMPACT); newItem->SetCompactDescriptions(compact==COMPACT);
newItem->SetPriceLabelType(priceLabel);
newItem->SetHoverFunc(inventoryButtonHoverAction); newItem->SetHoverFunc(inventoryButtonHoverAction);
newItem->SetMouseOutFunc(inventoryButtonMouseOutAction); newItem->SetMouseOutFunc(inventoryButtonMouseOutAction);

@ -41,6 +41,15 @@ All rights reserved.
#include "MenuLabel.h" #include "MenuLabel.h"
INCLUDE_game INCLUDE_game
INCLUDE_GFX
namespace PriceLabel{
enum PriceLabel{
NONE,
BUY_LABEL,
SELL_LABEL,
};
}
class RowItemDisplay:public MenuComponent{ class RowItemDisplay:public MenuComponent{
std::weak_ptr<Item>itemRef; std::weak_ptr<Item>itemRef;
@ -48,6 +57,7 @@ class RowItemDisplay:public MenuComponent{
std::string itemDescriptionLabelName; std::string itemDescriptionLabelName;
CompactText compact=NON_COMPACT; CompactText compact=NON_COMPACT;
bool showQuantity=true; bool showQuantity=true;
PriceLabel::PriceLabel priceLabel=PriceLabel::NONE;
public: public:
inline RowItemDisplay(geom2d::rect<float>rect,const std::weak_ptr<Item>itemRef,MenuFunc onClick,std::string itemNameLabelName,std::string itemDescriptionLabelName,ButtonAttr attributes=ButtonAttr::NONE) inline RowItemDisplay(geom2d::rect<float>rect,const std::weak_ptr<Item>itemRef,MenuFunc onClick,std::string itemNameLabelName,std::string itemDescriptionLabelName,ButtonAttr attributes=ButtonAttr::NONE)
:MenuComponent(rect,"",onClick,attributes),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName),itemRef(itemRef){ :MenuComponent(rect,"",onClick,attributes),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName),itemRef(itemRef){
@ -71,6 +81,28 @@ public:
vf2d qtyTextSize=vf2d(game->GetTextSizeProp(quantityText))*qtyTextScale; vf2d qtyTextSize=vf2d(game->GetTextSizeProp(quantityText))*qtyTextScale;
window.DrawShadowStringPropDecal(rect.pos+rect.size-vf2d{1,1}+vf2d{-qtyTextSize.x,-qtyTextSize.y},quantityText,WHITE,BLACK,{qtyTextScale,qtyTextScale}); window.DrawShadowStringPropDecal(rect.pos+rect.size-vf2d{1,1}+vf2d{-qtyTextSize.x,-qtyTextSize.y},quantityText,WHITE,BLACK,{qtyTextScale,qtyTextScale});
} }
if(priceLabel!=PriceLabel::NONE){
if(priceLabel==PriceLabel::SELL_LABEL){
std::string priceText=std::to_string(itemRef.lock()->SellValue());
if(itemRef.lock()->SellValue()==0)priceText="Cannot Sell";
vf2d priceTextSize=vf2d(game->GetTextSize(priceText));
if(itemRef.lock()->SellValue()!=0){
window.DrawShadowStringDecal(rect.pos+vf2d{rect.size.x-priceTextSize.x-15,3},priceText);
window.DrawDecal(rect.pos+vf2d{rect.size.x-14,1},GFX["currency_coin.png"].Decal(),{0.5f,0.5f});
}else{
vf2d priceTextSize=vf2d(game->GetTextSizeProp(priceText))*vf2d{0.5f,0.85f};
window.DrawShadowStringPropDecal(rect.pos+vf2d{rect.size.x-priceTextSize.x-1,3},priceText,WHITE,BLACK,{0.5f,0.85f});
}
}else{
std::string priceText=std::to_string(itemRef.lock()->BuyValue());
vf2d priceTextSize=vf2d(game->GetTextSize(priceText));
window.DrawShadowStringDecal(rect.pos+vf2d{rect.size.x-priceTextSize.x-15,3},priceText);
window.DrawDecal(rect.pos+vf2d{rect.size.x-14,1},GFX["currency_coin.png"].Decal(),{0.5f,0.5f});
}
}
if(Inventory::GetSlotEquippedIn(itemRef)!=EquipSlot::NONE){ if(Inventory::GetSlotEquippedIn(itemRef)!=EquipSlot::NONE){
window.DrawShadowStringDecal(rect.pos+vf2d{2,2}+iconSize-vf2d{8,8},"E",GREEN,VERY_DARK_GREEN); window.DrawShadowStringDecal(rect.pos+vf2d{2,2}+iconSize-vf2d{8,8},"E",GREEN,VERY_DARK_GREEN);
@ -128,4 +160,7 @@ public:
virtual inline void OnHover()override{ virtual inline void OnHover()override{
UpdateLabel(); UpdateLabel();
} }
inline void SetPriceLabelType(PriceLabel::PriceLabel labelType){
this->priceLabel=labelType;
}
}; };

@ -41,7 +41,7 @@ All rights reserved.
class RowMerchantInventoryScrollableWindowComponent:public RowInventoryScrollableWindowComponent{ class RowMerchantInventoryScrollableWindowComponent:public RowInventoryScrollableWindowComponent{
public: public:
inline RowMerchantInventoryScrollableWindowComponent(geom2d::rect<float>rect,std::string itemNameLabelName,std::string itemDescriptionLabelName,std::function<bool(MenuFuncData)>inventoryButtonClickAction,std::function<bool(MenuFuncData)>inventoryButtonHoverAction,std::function<bool(MenuFuncData)>inventoryButtonMouseOutAction,InventoryWindowOptions options={.padding=8,.size={24,24}},bool inventoryButtonsActive=true,ComponentAttr attributes=ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE) inline RowMerchantInventoryScrollableWindowComponent(geom2d::rect<float>rect,std::string itemNameLabelName,std::string itemDescriptionLabelName,std::function<bool(MenuFuncData)>inventoryButtonClickAction,std::function<bool(MenuFuncData)>inventoryButtonHoverAction,std::function<bool(MenuFuncData)>inventoryButtonMouseOutAction,InventoryWindowOptions options={.padding=8,.size={24,24}},bool inventoryButtonsActive=true,ComponentAttr attributes=ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE)
:RowInventoryScrollableWindowComponent(rect,"",itemNameLabelName,itemDescriptionLabelName,inventoryButtonClickAction,inventoryButtonHoverAction,inventoryButtonMouseOutAction,options,inventoryButtonsActive,attributes){} :RowInventoryScrollableWindowComponent(rect,itemNameLabelName,itemDescriptionLabelName,inventoryButtonClickAction,inventoryButtonHoverAction,inventoryButtonMouseOutAction,options,inventoryButtonsActive,attributes){}
virtual inline void OnInventorySlotsUpdate(ITCategory cat)override{ virtual inline void OnInventorySlotsUpdate(ITCategory cat)override{
@ -51,13 +51,16 @@ public:
AddButtonOnSlotUpdate(cat); AddButtonOnSlotUpdate(cat);
}else }else
if(components.size()>merchantInv.size()){ //There are empty spots, so let's clean up. if(components.size()>merchantInv.size()){ //There are empty spots, so let's clean up.
RemoveEmptySlots(); RemoveAllComponents();
for(std::shared_ptr<Item> item:merchantInv){
AddButtonOnSlotUpdate(cat);
}
} }
} }
virtual inline void AddButtonOnSlotUpdate(ITCategory cat)override{ virtual inline void AddButtonOnSlotUpdate(ITCategory cat)override{
const std::vector<std::shared_ptr<Item>>&merchantInv=Merchant::GetCurrentTravelingMerchant().GetShopItems(); const std::vector<std::shared_ptr<Item>>&merchantInv=Merchant::GetCurrentTravelingMerchant().GetShopItems();
size_t invSize=merchantInv.size(); size_t invSize=components.size()+1;
int invWidth=int(rect.size.x/(float(options.size.x)+options.padding)); int invWidth=int(rect.size.x/(float(options.size.x)+options.padding));
int x=int((invSize-1)%invWidth); int x=int((invSize-1)%invWidth);
int y=int((invSize-1)/invWidth); int y=int((invSize-1)/invWidth);
@ -66,21 +69,10 @@ public:
vf2d buttonSize=options.size; vf2d buttonSize=options.size;
vf2d totalSpacing={options.padding+buttonSize.x,options.padding+buttonSize.y}; vf2d totalSpacing={options.padding+buttonSize.x,options.padding+buttonSize.y};
auto newItem=ADD("item_"+cat+"_"+std::to_string(itemIndex),RowItemDisplay)({totalSpacing*vf2d{float(x),float(y)},buttonSize},Merchant::GetCurrentTravelingMerchant().GetShopItems()[itemIndex],inventoryButtonClickAction,itemNameLabelName,itemDescriptionLabelName,inventoryButtonsActive?ButtonAttr::NONE:ButtonAttr::UNSELECTABLE)END; auto newItem=ADD("merchant_item_"+cat+"_"+std::to_string(itemIndex),RowItemDisplay)({totalSpacing*vf2d{float(x),float(y)},buttonSize},Merchant::GetCurrentTravelingMerchant().GetShopItems()[itemIndex],inventoryButtonClickAction,itemNameLabelName,itemDescriptionLabelName,inventoryButtonsActive?ButtonAttr::NONE:ButtonAttr::UNSELECTABLE)END;
newItem->SetCompactDescriptions(compact==COMPACT); newItem->SetCompactDescriptions(compact==COMPACT);
newItem->SetPriceLabelType(priceLabel);
newItem->SetHoverFunc(inventoryButtonHoverAction); newItem->SetHoverFunc(inventoryButtonHoverAction);
newItem->SetMouseOutFunc(inventoryButtonMouseOutAction); newItem->SetMouseOutFunc(inventoryButtonMouseOutAction);
//Since we are indexing into a vector reference which is inevitably going to get erased as we add more items,
//we must update all previous menu component references in case that memory has been overwritten!
for(int counter=0;MenuComponent*component:components){
RowItemDisplay*item=dynamic_cast<RowItemDisplay*>(component);
if(item!=nullptr){
item->SetItem(merchantInv[itemIndex]);
}else{
ERR("WARNING! Could not properly cast item to RowItemDisplay* type!");
}
counter++;
}
} }
}; };

@ -236,6 +236,7 @@ public:
components.push_back(button); components.push_back(button);
button->renderInMain=false; //Now we are in control! button->renderInMain=false; //Now we are in control!
button->parentComponent=this; button->parentComponent=this;
button->disabled=disabled;
CalculateBounds(); CalculateBounds();
@ -259,6 +260,9 @@ public:
} }
virtual inline void Enable(bool enabled)override final{ virtual inline void Enable(bool enabled)override final{
disabled=!enabled; disabled=!enabled;
for(MenuComponent*component:components){
component->Enable(enabled);
}
if(upButton){upButton->Enable(enabled);} if(upButton){upButton->Enable(enabled);}
if(downButton){downButton->Enable(enabled);} if(downButton){downButton->Enable(enabled);}
}; };

@ -39,7 +39,57 @@ All rights reserved.
#include "Menu.h" #include "Menu.h"
#include "MenuLabel.h" #include "MenuLabel.h"
using A=Attribute;
void Menu::InitializeSellItemWindow(){ void Menu::InitializeSellItemWindow(){
Menu*sellItemWindow=CreateMenu(SELL_ITEM,CENTERED,{120,72}); Menu*sellItemWindow=CreateMenu(SELL_ITEM,CENTERED,{192,72});
static auto GetQuantity=[&](){
return std::stoi(Component<MenuLabel>(SELL_ITEM,"Amount to sell Amount Label")->GetLabel());
};
static auto UpdateMenu=[&](int32_t qty){
qty=std::clamp(qty,1,99);
int pricePerItem=std::stoi(Component<MenuLabel>(SELL_ITEM,"Price per item Amount Label")->GetLabel());
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());
std::string colorCode="";
if(!canSell)colorCode="#FF0000";
Component<MenuLabel>(SELL_ITEM,"Total Price Amount Label")->SetLabel(colorCode+std::to_string(qty*pricePerItem));
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("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;
sellItemWindow->ADD("Price Label",MenuLabel)({{4,50},{188,12}},"Total Price",1.0f,ComponentAttr::LEFT_ALIGN|ComponentAttr::SHADOW)END;
sellItemWindow->ADD("Price per item Amount Label",MenuLabel)({{sellItemWindow->size.x/2+28,18},{72,12}},"0",1.0f,ComponentAttr::SHADOW|ComponentAttr::FIT_TO_LABEL)END;
sellItemWindow->ADD("Amount to sell Amount Label",MenuLabel)({{sellItemWindow->size.x/2+48,34},{32,12}},"0",1.0f,ComponentAttr::SHADOW|ComponentAttr::OUTLINE|ComponentAttr::FIT_TO_LABEL)END;
sellItemWindow->ADD("Increase sell amount Button",MenuComponent)({{sellItemWindow->size.x/2+80+2,34},{12,12}},"+",[&](MenuFuncData data){
UpdateMenu(GetQuantity()+1);
return true;
})END;
sellItemWindow->ADD("Decrease sell amount Button",MenuComponent)({{sellItemWindow->size.x/2+48-14,34},{12,12}},"-",[](MenuFuncData data){
UpdateMenu(GetQuantity()-1);
return true;
})END;
sellItemWindow->ADD("Total Price Amount Label",MenuLabel)({{sellItemWindow->size.x/2+28,50},{72,12}},"0",1.0f,ComponentAttr::SHADOW|ComponentAttr::FIT_TO_LABEL)END;
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());
Menu::CloseMenu();
return true;
})END;
sellItemWindow->ADD("Cancel Button",MenuComponent)({{sellItemWindow->size.x/2-82,70},{64,12}},"Cancel",[](MenuFuncData data){
Menu::CloseMenu();
return true;
})END;
} }

@ -1,6 +1,5 @@
January 1st January 1st
=========== ===========
Sell Item Merchant Screen
Blacksmith Item Crafting Screen Blacksmith Item Crafting Screen
Randomized Item Stats Randomized Item Stats
- Get Item may return multiples of the same item. - Get Item may return multiples of the same item.
@ -9,9 +8,10 @@ Randomized Item Stats
The Hub / NPC Interactions The Hub / NPC Interactions
Save/Load Game Save/Load Game
- Save Inventory Items/Equips - Save Inventory Items/Equips
- Player Base Level/Stats - Player Base Level/Stats/Accumulated Exp
- Unlock Progress - Unlock Progress
- World Map Location - World Map Location
- Chapter #
Audio Engine Audio Engine
- Audio Ambience Zones - Audio Ambience Zones
- Menu Sound Effects - Menu Sound Effects

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 0 #define VERSION_MAJOR 0
#define VERSION_MINOR 2 #define VERSION_MINOR 2
#define VERSION_PATCH 1 #define VERSION_PATCH 1
#define VERSION_BUILD 4798 #define VERSION_BUILD 4854
#define stringify(a) stringify_(a) #define stringify(a) stringify_(a)
#define stringify_(a) #a #define stringify_(a) #a

@ -43,6 +43,7 @@ Images
GFX_SqareSkillIcon = square_skill_overlay_icon.png GFX_SqareSkillIcon = square_skill_overlay_icon.png
GFX_SqareSkillIconEmpty = square_skill_overlay_icon_empty.png GFX_SqareSkillIconEmpty = square_skill_overlay_icon_empty.png
GFX_Money = money.png GFX_Money = money.png
GFX_CurrencyCoin = currency_coin.png
# Ability Icons # Ability Icons
GFX_Warrior_BattleCry_Icon = Ability Icons/battlecry.png GFX_Warrior_BattleCry_Icon = Ability Icons/battlecry.png

@ -736,7 +736,7 @@ void olc::ViewPort::DrawShadowStringDecal(const olc::vf2d& pos, std::string_view
pge->Clear(BLANK); pge->Clear(BLANK);
pge->DrawString({0,0},sText,WHITE,1U,width/scale.x); pge->DrawString({0,0},sText,WHITE,1U,width/scale.x);
newDecal->Update(); newDecal->Update();
float adjustedShadowSizeFactor=shadowSizeFactor*4; float adjustedShadowSizeFactor=shadowSizeFactor*4/std::max(scale.x,scale.y);
Decal*newShadowDecal=new Decal(new Sprite((imageSize.x/scale.x*4)+adjustedShadowSizeFactor*2,(imageSize.y/scale.x*4)+adjustedShadowSizeFactor*2)); Decal*newShadowDecal=new Decal(new Sprite((imageSize.x/scale.x*4)+adjustedShadowSizeFactor*2,(imageSize.y/scale.x*4)+adjustedShadowSizeFactor*2));
garbageCollector[key+"_SHADOW"].decal=newShadowDecal; garbageCollector[key+"_SHADOW"].decal=newShadowDecal;
pge->SetDrawTarget(newShadowDecal->sprite); pge->SetDrawTarget(newShadowDecal->sprite);
@ -760,7 +760,7 @@ void olc::ViewPort::DrawShadowStringDecal(const olc::vf2d& pos, std::string_view
} }
return false; return false;
}); });
DrawDecal(pos-vf2d{shadowSizeFactor,shadowSizeFactor}*scale,garbageCollector[key+"_SHADOW"].decal,scale/4,shadowCol); DrawDecal(pos-vf2d{shadowSizeFactor,shadowSizeFactor},garbageCollector[key+"_SHADOW"].decal,scale/4,shadowCol);
DrawDecal(pos,garbageCollector[key].decal,scale,col); DrawDecal(pos,garbageCollector[key].decal,scale,col);
} }
@ -784,7 +784,7 @@ void olc::ViewPort::DrawShadowStringPropDecal(const olc::vf2d& pos, std::string_
pge->Clear(BLANK); pge->Clear(BLANK);
pge->DrawStringProp({0,0},sText,WHITE,1U,width/scale.x); pge->DrawStringProp({0,0},sText,WHITE,1U,width/scale.x);
newDecal->Update(); newDecal->Update();
float adjustedShadowSizeFactor=shadowSizeFactor*4; float adjustedShadowSizeFactor=shadowSizeFactor*4/std::max(scale.x,scale.y);
Decal*newShadowDecal=new Decal(new Sprite((imageSize.x/scale.x*4)+adjustedShadowSizeFactor*2,(imageSize.y/scale.x*4)+adjustedShadowSizeFactor*2)); Decal*newShadowDecal=new Decal(new Sprite((imageSize.x/scale.x*4)+adjustedShadowSizeFactor*2,(imageSize.y/scale.x*4)+adjustedShadowSizeFactor*2));
garbageCollector[key+"_SHADOW"].decal=newShadowDecal; garbageCollector[key+"_SHADOW"].decal=newShadowDecal;
pge->SetDrawTarget(newShadowDecal->sprite); pge->SetDrawTarget(newShadowDecal->sprite);
@ -808,7 +808,7 @@ void olc::ViewPort::DrawShadowStringPropDecal(const olc::vf2d& pos, std::string_
} }
return false; return false;
}); });
DrawDecal(pos-vf2d{shadowSizeFactor,shadowSizeFactor}*scale,garbageCollector[key+"_SHADOW"].decal,scale/4,shadowCol); DrawDecal(pos-vf2d{shadowSizeFactor,shadowSizeFactor},garbageCollector[key+"_SHADOW"].decal,scale/4,shadowCol);
DrawDecal(pos,garbageCollector[key].decal,scale,col); DrawDecal(pos,garbageCollector[key].decal,scale,col);
} }

@ -3440,7 +3440,7 @@ namespace olc
Clear(BLANK); Clear(BLANK);
DrawString({0,0},sText,WHITE,1U,width/scale.x); DrawString({0,0},sText,WHITE,1U,width/scale.x);
newDecal->Update(); newDecal->Update();
float adjustedShadowSizeFactor=shadowSizeFactor*4; float adjustedShadowSizeFactor=shadowSizeFactor*4/std::max(scale.x,scale.y);
Decal*newShadowDecal=new Decal(new Sprite((imageSize.x/scale.x*4)+adjustedShadowSizeFactor*2,(imageSize.y/scale.x*4)+adjustedShadowSizeFactor*2)); Decal*newShadowDecal=new Decal(new Sprite((imageSize.x/scale.x*4)+adjustedShadowSizeFactor*2,(imageSize.y/scale.x*4)+adjustedShadowSizeFactor*2));
garbageCollector[key+"_SHADOW"].decal=newShadowDecal; garbageCollector[key+"_SHADOW"].decal=newShadowDecal;
SetDrawTarget(newShadowDecal->sprite); SetDrawTarget(newShadowDecal->sprite);
@ -3464,7 +3464,7 @@ namespace olc
} }
return false; return false;
}); });
DrawDecal(pos-vf2d{shadowSizeFactor,shadowSizeFactor}*scale,garbageCollector[key+"_SHADOW"].decal,scale/4,shadowCol); DrawDecal(pos-vf2d{shadowSizeFactor,shadowSizeFactor},garbageCollector[key+"_SHADOW"].decal,scale/4,shadowCol);
DrawDecal(pos,garbageCollector[key].decal,scale,col); DrawDecal(pos,garbageCollector[key].decal,scale,col);
} }
@ -3564,7 +3564,7 @@ namespace olc
Clear(BLANK); Clear(BLANK);
DrawStringProp({0,0},sText,WHITE,1U,width/scale.x); DrawStringProp({0,0},sText,WHITE,1U,width/scale.x);
newDecal->Update(); newDecal->Update();
float adjustedShadowSizeFactor=shadowSizeFactor*4; float adjustedShadowSizeFactor=shadowSizeFactor*4/std::max(scale.x,scale.y);
Decal*newShadowDecal=new Decal(new Sprite((imageSize.x/scale.x*4)+adjustedShadowSizeFactor*2,(imageSize.y/scale.x*4)+adjustedShadowSizeFactor*2)); Decal*newShadowDecal=new Decal(new Sprite((imageSize.x/scale.x*4)+adjustedShadowSizeFactor*2,(imageSize.y/scale.x*4)+adjustedShadowSizeFactor*2));
garbageCollector[key+"_SHADOW"].decal=newShadowDecal; garbageCollector[key+"_SHADOW"].decal=newShadowDecal;
SetDrawTarget(newShadowDecal->sprite); SetDrawTarget(newShadowDecal->sprite);
@ -3588,7 +3588,7 @@ namespace olc
} }
return false; return false;
}); });
DrawDecal(pos-vf2d{shadowSizeFactor,shadowSizeFactor}*scale,garbageCollector[key+"_SHADOW"].decal,scale/4,shadowCol); DrawDecal(pos-vf2d{shadowSizeFactor,shadowSizeFactor},garbageCollector[key+"_SHADOW"].decal,scale/4,shadowCol);
DrawDecal(pos,garbageCollector[key].decal,scale,col); DrawDecal(pos,garbageCollector[key].decal,scale,col);
} }

Loading…
Cancel
Save