# 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 <EFBFBD> 2023 The FreeType
Project ( www . freetype . org ) . Please see LICENSE_FT . txt for more information .
All rights reserved .
*/
# pragma endregion
# include "Menu.h"
# include "Crawler.h"
# include "RowMerchantInventoryScrollableWindowComponent.h"
# include "MenuItemItemButton.h"
# include "MenuComponent.h"
# include "PlayerMoneyLabel.h"
INCLUDE_game
INCLUDE_ITEM_CATEGORIES
INCLUDE_DATA
INCLUDE_GFX
void Menu : : InitializeMerchantWindow ( ) {
Menu * merchantWindow = CreateMenu ( MERCHANT , CENTERED , game - > GetScreenSize ( ) - vi2d { 52 , 52 } ) ;
static std : : string lastInventoryTypeOpened = " " ;
std : : vector < std : : pair < std : : string , int > > categories ;
for ( auto & [ category , items ] : ITEM_CATEGORIES ) {
if ( DATA [ " ItemCategory " ] [ category ] . GetString ( 0 ) = = " !HIDE " ) continue ; //This category is meant to be hidden!
categories . push_back ( { category , DATA [ " ItemCategory " ] [ category ] . GetInt ( 0 ) } ) ; //We assume the first value becomes the sort order we wish to use.
}
std : : sort ( categories . begin ( ) , categories . end ( ) , [ ] ( std : : pair < std : : string , int > & cat1 , std : : pair < std : : string , int > & cat2 ) { return cat1 . second < cat2 . second ; } ) ;
auto inventoryDisplay = merchantWindow - > ADD ( " Merchant Inventory Display " , RowMerchantInventoryScrollableWindowComponent ) ( { { 2 , 28 } , { 220 , merchantWindow - > size . y - 44 } } , " Item Name Label " , " Item Description Label " ,
[ ] ( MenuFuncData data ) {
RowItemDisplay * item = dynamic_cast < RowItemDisplay * > ( data . component ) ;
Component < MenuLabel > ( BUY_ITEM , " Item Purchase Header " ) - > S ( A : : ITEM_NAME ) = item - > GetItem ( ) . lock ( ) - > ActualName ( ) ;
Component < MenuLabel > ( BUY_ITEM , " Price per item Amount Label " ) - > SetLabel ( std : : to_string ( item - > GetItem ( ) . lock ( ) - > BuyValue ( ) ) ) ;
Component < MenuLabel > ( BUY_ITEM , " Amount to buy Amount Label " ) - > SetLabel ( " 1 " ) ;
Component < MenuLabel > ( BUY_ITEM , " Total Price Amount Label " ) - > SetLabel ( std : : to_string ( item - > GetItem ( ) . lock ( ) - > BuyValue ( ) ) ) ;
Merchant & merchant = Merchant : : GetCurrentTravelingMerchant ( ) ;
bool canPurchase = merchant . CanPurchaseItem ( item - > GetItem ( ) . lock ( ) - > ActualName ( ) , 1 ) ;
std : : string colorCode = " " ;
if ( ! canPurchase ) colorCode = " #FF0000 " ;
Component < MenuLabel > ( BUY_ITEM , " Total Price Amount Label " ) - > SetLabel ( colorCode + std : : to_string ( item - > GetItem ( ) . lock ( ) - > BuyValue ( ) ) ) ;
Component < MenuLabel > ( BUY_ITEM , " Item Purchase Header " ) - > SetLabel ( " Buying " + item - > GetItem ( ) . lock ( ) - > DisplayName ( ) ) ;
Component < MenuComponent > ( BUY_ITEM , " Purchase Button " ) - > SetGrayedOut ( ! merchant . CanPurchaseItem ( item - > GetItem ( ) . lock ( ) - > ActualName ( ) , 1 ) ) ;
Menu : : OpenMenu ( BUY_ITEM ) ;
return true ;
} ,
[ ] ( MenuFuncData data ) {
Component < MenuItemItemButton > ( data . menu . GetType ( ) , " Item Icon " ) - > SetItem ( dynamic_cast < RowItemDisplay * > ( data . component ) - > GetItem ( ) ) ;
Component < MenuItemItemButton > ( data . menu . GetType ( ) , " Item Icon " ) - > UpdateIcon ( ) ;
return true ;
} ,
[ ] ( MenuFuncData data ) {
Component < MenuItemItemButton > ( data . menu . GetType ( ) , " Item Icon " ) - > SetItem ( Item : : BLANK ) ;
Component < MenuItemItemButton > ( data . menu . GetType ( ) , " Item Icon " ) - > UpdateIcon ( ) ;
return true ;
} , { . padding = 1 , . size = { 220 - 13 , 28 } } ) END ;
for ( auto & [ category , items ] : ITEM_CATEGORIES ) {
Menu : : AddMerchantInventoryListener ( inventoryDisplay , category ) ;
}
# pragma region Inventory Description
float inventoryDescriptionWidth = merchantWindow - > pos . x + merchantWindow - > size . x - 26 - 224 ;
merchantWindow - > ADD ( " Item Description Outline " , MenuLabel ) ( { { 224 , 28 } , { inventoryDescriptionWidth , merchantWindow - > size . y - 44 } } , " " , 1 , ComponentAttr : : LEFT_ALIGN | ComponentAttr : : OUTLINE | ComponentAttr : : BACKGROUND ) END ;
merchantWindow - > ADD ( " Item Icon " , MenuItemItemButton ) ( { { 226 + inventoryDescriptionWidth / 2 - 24 , 30 } , { 48 , 48 } } , Item : : BLANK , MenuType : : ENUM_END , DO_NOTHING , " " , " " , IconButtonAttr : : NOT_SELECTABLE ) END ;
merchantWindow - > ADD ( " Item Name Label " , MenuLabel ) ( { { 226 , 84 } , { inventoryDescriptionWidth - 6 , 12 } } , " " , 0.75f , ComponentAttr : : LEFT_ALIGN | ComponentAttr : : SHADOW ) END ;
merchantWindow - > ADD ( " Item Description Label " , MenuLabel ) ( { { 226 , 94 } , { inventoryDescriptionWidth - 6 , merchantWindow - > size . y - 44 - 66 } } , " " , 0.5f , ComponentAttr : : LEFT_ALIGN | ComponentAttr : : SHADOW ) END ;
# pragma endregion
# pragma region Money Display
vf2d moneyIconPos = { 224 + inventoryDescriptionWidth - 24 , 28 + merchantWindow - > size . y - 44 + 6 } ;
auto moneyIcon = merchantWindow - > ADD ( " Money Icon " , MenuIconButton ) ( { moneyIconPos , { 24 , 24 } } , GFX [ " money.png " ] . Decal ( ) , DO_NOTHING , IconButtonAttr : : NOT_SELECTABLE | IconButtonAttr : : NO_OUTLINE | IconButtonAttr : : NO_BACKGROUND ) END ;
std : : string moneyText = std : : to_string ( game - > GetPlayer ( ) - > GetMoney ( ) ) ;
vf2d moneyTextSize = game - > GetTextSizeProp ( moneyText ) * 2 ;
auto moneyDisplay = merchantWindow - > ADD ( " Money Label " , PlayerMoneyLabel ) ( { moneyIconPos - vf2d { 2 + moneyTextSize . x , - 2 } , moneyTextSize } , 2 , ComponentAttr : : SHADOW | ComponentAttr : : LEFT_ALIGN ) END ;
moneyDisplay - > SetRightAlignment ( true ) ;
Player : : AddMoneyListener ( moneyDisplay ) ;
# pragma endregion
merchantWindow - > ADD ( " Leave Button " , MenuComponent ) ( { { merchantWindow - > size . x / 2 - 48 , 28 + merchantWindow - > size . y - 44 + 6 } , { 96 , 24 } } , " Leave " , MenuType : : ENUM_END ,
[ ] ( MenuFuncData data ) {
Menu : : CloseMenu ( ) ;
return true ;
} , { 2 , 2 } ) END ;
}