# 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 <EFBFBD> 2024 The FreeType
Project ( www . freetype . org ) . Please see LICENSE_FT . txt for more information .
All rights reserved .
*/
# pragma endregion
# include "Menu.h"
# include "AdventuresInLestoria.h"
# include "RowInventoryScrollableWindowComponent.h"
# include "MenuItemItemButton.h"
# include "MenuRefineLabel.h"
# include "PlayerMoneyLabel.h"
# include "MenuDecal.h"
# include "SoundEffect.h"
# include "DynamicMenuLabel.h"
INCLUDE_game
void Menu : : InitializeArtificerRefineWindow ( ) {
Menu * const artificerRefineWindow { CreateMenu ( ARTIFICER_REFINE , CENTERED , game - > GetScreenSize ( ) - vi2d { 52 , 52 } ) } ;
auto refiningTitleLabel { artificerRefineWindow - > ADD ( " Refining Title Label " , MenuLabel ) ( geom2d : : rect < float > { { 0.f , - 16.f } , { artificerRefineWindow - > size . x , 24.f } } , " Accessory Refinement " , 2.f , ComponentAttr : : SHADOW | ComponentAttr : : OUTLINE | ComponentAttr : : BACKGROUND ) END } ;
auto inventoryLabel { artificerRefineWindow - > ADD ( " Accessory List Label " , MenuLabel ) ( geom2d : : rect < float > { { 0.f , 12.f } , { 180.f , 12.f } } , " Choose Accessory: " , 1.f , ComponentAttr : : SHADOW | ComponentAttr : : LEFT_ALIGN ) END } ;
auto itemIcon { artificerRefineWindow - > ADD ( " Item Icon " , MenuItemItemButton ) ( geom2d : : rect < float > ( { artificerRefineWindow - > size . x / 2 + 4.f , 28.f } , { 48 , 48 } ) , Item : : BLANK , DO_NOTHING , " " , " Item Description " , IconButtonAttr : : NOT_SELECTABLE ) END } ;
itemIcon - > SetIconScale ( { 2.f , 2.f } ) ;
itemIcon - > SetCompactDescriptions ( true ) ;
auto accessoryDescription { artificerRefineWindow - > ADD ( " Item Description " , MenuLabel ) ( geom2d : : rect < float > { { artificerRefineWindow - > size . x / 2 + 56.f , 28.f } , { artificerRefineWindow - > size . x / 2 - 40.f , 72.f } } , " " , 0.5f , ComponentAttr : : BACKGROUND | ComponentAttr : : OUTLINE | ComponentAttr : : SHADOW | ComponentAttr : : LEFT_ALIGN ) END } ;
const auto ResetRefineDisplay { [ artificerRefineWindow ] ( ) {
MenuType menuType { artificerRefineWindow - > GetType ( ) } ;
Component < MenuItemItemButton > ( menuType , " Item Icon " ) - > SetItem ( Item : : BLANK ) ;
Component < MenuRefineLabel > ( menuType , " Stats Block " ) - > Disable ( ) ;
Component < MenuLabel > ( menuType , " Refine Cost Label " ) - > Disable ( ) ;
Component < MenuDecal > ( menuType , " Fragment Cost Icon " ) - > Disable ( ) ;
Component < MenuLabel > ( menuType , " Fragment Label " ) - > Disable ( ) ;
Component < MenuLabel > ( menuType , " Fragment Money Cost Label " ) - > Disable ( ) ;
Component < MenuComponent > ( menuType , " Fragment Refine Button " ) - > Disable ( ) ;
} } ;
const auto EnableRefineDisplay { [ artificerRefineWindow ] ( ) {
MenuType menuType { artificerRefineWindow - > GetType ( ) } ;
const std : : weak_ptr < Item > & selectedItem { Component < MenuItemItemButton > ( menuType , " Item Icon " ) - > GetItem ( ) } ;
Component < MenuRefineLabel > ( menuType , " Stats Block " ) - > SetItem ( selectedItem ) ;
Component < MenuRefineLabel > ( menuType , " Stats Block " ) - > Enable ( ) ;
Component < MenuLabel > ( menuType , " Refine Cost Label " ) - > Enable ( ) ;
Component < MenuDecal > ( menuType , " Fragment Cost Icon " ) - > Enable ( ) ;
Component < MenuDecal > ( menuType , " Fragment Cost Icon " ) - > SetImage ( GFX . at ( selectedItem . lock ( ) - > FragmentIcon ( ) . value ( ) ) ) ;
Component < MenuLabel > ( menuType , " Fragment Label " ) - > Enable ( ) ;
Component < MenuLabel > ( menuType , " Fragment Money Cost Label " ) - > Enable ( ) ;
Component < MenuComponent > ( menuType , " Fragment Refine Button " ) - > Enable ( ) ;
Component < MenuComponent > ( menuType , " Fragment Refine Button " ) - > SetGrayedOut ( ! selectedItem . lock ( ) - > CanBeRefined ( ) ) ;
const std : : string_view fragmentName { selectedItem . lock ( ) - > FragmentName ( ) } ;
const Pixel fragmentItemDisplayCol { Inventory : : GetItemCount ( fragmentName ) > = " Fragment Refine Cost " _i [ 0 ] ? WHITE : RED } ;
const Pixel moneyCostDisplayCol { game - > GetPlayer ( ) - > GetMoney ( ) > = " Fragment Refine Cost " _i [ 1 ] ? WHITE : RED } ;
Component < MenuLabel > ( menuType , " Fragment Label " ) - > SetLabel ( std : : format ( " {}{} x{} ({}) " , fragmentItemDisplayCol . toHTMLColorCode ( ) , fragmentName , " Fragment Refine Cost " _i [ 0 ] , Inventory : : GetItemCount ( fragmentName ) ) ) ;
Component < MenuLabel > ( menuType , " Fragment Money Cost Label " ) - > SetLabel ( std : : format ( " {}{} gold " , moneyCostDisplayCol . toHTMLColorCode ( ) , " Fragment Refine Cost " _i [ 1 ] ) ) ;
} } ;
auto inventoryDisplay { artificerRefineWindow - > ADD ( " Accessory List " , RowInventoryScrollableWindowComponent ) ( geom2d : : rect < float > { { 0.f , 28.f } , { artificerRefineWindow - > size . x / 2 - 4.f , artificerRefineWindow - > size . y - 44 } } , " " , " " , [ ] ( MenuFuncData data ) {
OnClick :
RowItemDisplay & item { * DYNAMIC_POINTER_CAST < RowItemDisplay > ( data . component ) } ;
DYNAMIC_POINTER_CAST < RowInventoryScrollableWindowComponent > ( data . parentComponent . lock ( ) ) - > SelectChild ( DYNAMIC_POINTER_CAST < RowItemDisplay > ( data . component ) ) ;
return true ;
} , [ EnableRefineDisplay ] ( MenuFuncData data ) { OnHover :
RowItemDisplay & item { * DYNAMIC_POINTER_CAST < RowItemDisplay > ( data . component ) } ;
Component < MenuItemItemButton > ( data . menu . type , " Item Icon " ) - > SetItem ( item . GetItem ( ) ) ;
EnableRefineDisplay ( ) ;
return true ;
} , [ ResetRefineDisplay , EnableRefineDisplay ] ( MenuFuncData data ) { OnMouseOut :
ResetRefineDisplay ( ) ;
auto childComponent { DYNAMIC_POINTER_CAST < RowInventoryScrollableWindowComponent > ( data . parentComponent . lock ( ) ) - > GetSelectedChild ( ) } ;
if ( childComponent ) {
RowItemDisplay & item { childComponent . value ( ) . get ( ) } ;
Component < MenuItemItemButton > ( data . menu . type , " Item Icon " ) - > SetItem ( item . GetItem ( ) ) ;
EnableRefineDisplay ( ) ;
}
return true ;
} ,
InventoryCreator : : RowPlayer_InventoryUpdate ,
InventoryWindowOptions { . padding = 1 , . size = { artificerRefineWindow - > size . x / 2 - 5.f - 12.f , 28 } } ) END } ;
auto statsBlock { artificerRefineWindow - > ADD ( " Stats Block " , MenuRefineLabel ) ( geom2d : : rect < float > { { artificerRefineWindow - > size . x / 2 + 4.f , 104.f } , { artificerRefineWindow - > size . x / 2 + 12.f , 44.f } } , Item : : BLANK , 1.f , ComponentAttr : : BACKGROUND | ComponentAttr : : SHADOW | ComponentAttr : : OUTLINE | ComponentAttr : : FIXED_WIDTH_FONT | ComponentAttr : : FIT_TO_LABEL | ComponentAttr : : LEFT_ALIGN ) END } ;
auto refineCostLabel { artificerRefineWindow - > ADD ( " Refine Cost Label " , MenuLabel ) ( geom2d : : rect < float > { { artificerRefineWindow - > size . x / 2 + 4.f , 152.f } , { 64.f , 20.f } } , " Refine Cost: " , 1.f , ComponentAttr : : SHADOW | ComponentAttr : : BACKGROUND | ComponentAttr : : OUTLINE ) END } ;
auto fragmentCostIcon { artificerRefineWindow - > ADD ( " Fragment Cost Icon " , MenuDecal ) ( geom2d : : rect < float > { { artificerRefineWindow - > size . x / 2 + 68.f , 152.f } , { 12.f , 12.f } } ) END } ;
auto fragmentDisplayLabel { artificerRefineWindow - > ADD ( " Fragment Label " , MenuLabel ) ( geom2d : : rect < float > { { artificerRefineWindow - > size . x / 2 + 80.f , 152.f } , { artificerRefineWindow - > size . x / 2 - 60.f , 12.f } } , " " , 1.f , ComponentAttr : : SHADOW | ComponentAttr : : FIT_TO_LABEL | ComponentAttr : : LEFT_ALIGN ) END } ;
auto fragmentMoneyCostLabel { artificerRefineWindow - > ADD ( " Fragment Money Cost Label " , MenuLabel ) ( geom2d : : rect < float > { { artificerRefineWindow - > size . x / 2 + 80.f , 164.f } , { artificerRefineWindow - > size . x / 2 - 60.f , 12.f } } , " " , 1.f , ComponentAttr : : SHADOW | ComponentAttr : : LEFT_ALIGN ) END } ;
auto fragmentRefineButton { artificerRefineWindow - > ADD ( " Fragment Refine Button " , MenuComponent ) ( geom2d : : rect < float > { { artificerRefineWindow - > size . x / 2 + 96.f , 180.f } , { artificerRefineWindow - > size . x / 2 - 80.f , 12.f } } , " Refine " , [ EnableRefineDisplay ] ( MenuFuncData data ) {
onClick :
SoundEffect : : PlaySFX ( " Sprint " , SoundEffect : : CENTERED ) ;
std : : weak_ptr < Item > item { Component < MenuItemItemButton > ( data . menu . type , " Item Icon " ) - > GetItem ( ) } ;
RefineResult result { item . lock ( ) - > Refine ( ) } ;
Component < MenuItemItemButton > ( ARTIFICER_REFINE_RESULT , " Item Icon " ) - > SetItem ( item ) ;
Component < DynamicMenuLabel > ( ARTIFICER_REFINE_RESULT , " Refine Result " ) - > SetLabelUpdateFunction ( [ result ] ( ) {
const Pixel shimmeringColor { PixelLerp ( WHITE , { 220 , 220 , 220 } , sin ( ( 70 * game - > GetRunTime ( ) ) / 2.f + 0.5f ) ) } ;
return std : : format ( " {} -> {}+{}{} #FFFF00UP! " , result . first . Name ( ) , shimmeringColor . toHTMLColorCode ( ) , result . second , result . first . DisplayAsPercent ( ) ? " % " : " " ) ;
} ) ;
Component < MenuLabel > ( ARTIFICER_REFINE_RESULT , " Refine Item Text Display " ) - > SetLabel ( std : : format ( " #FFFF00{} has been refined! " , item . lock ( ) - > DisplayName ( ) ) ) ;
EnableRefineDisplay ( ) ; //Refresh the current display contents.
Menu : : OpenMenu ( ARTIFICER_REFINE_RESULT , true ) ;
return true ;
} ) END } ;
# pragma region Money Display
vf2d moneyIconPos { artificerRefineWindow - > size . x / 2 - 28.f , artificerRefineWindow - > size . y - 12.f } ;
auto moneyIcon = artificerRefineWindow - > ADD ( " Money Icon " , MenuIconButton ) ( geom2d : : rect < float > { 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 = artificerRefineWindow - > ADD ( " Money Label " , PlayerMoneyLabel ) ( geom2d : : rect < float > { moneyIconPos + vf2d { 26.f , 4.f } , moneyTextSize } , 2 , 1.85f , ComponentAttr : : SHADOW | ComponentAttr : : LEFT_ALIGN | ComponentAttr : : FIT_TO_LABEL ) END ;
Player : : AddMoneyListener ( moneyDisplay ) ;
# pragma endregion
auto backButton { artificerRefineWindow - > ADD ( " Back " , MenuComponent ) ( geom2d : : rect < float > { { 0.f , artificerRefineWindow - > size . y - 12.f } , { 96.f , 16.f } } , " Back " , [ ] ( MenuFuncData data ) {
Menu : : CloseMenu ( ) ;
return true ;
} ) END } ;
Menu : : AddInventoryListener ( inventoryDisplay , " Accessories " ) ;
artificerRefineWindow - > SetupKeyboardNavigation (
[ ] ( MenuType type , Data & returnData ) { //On Open
returnData = " " ;
} ,
{ //Button Key
{ game - > KEY_SCROLL , { " Navigate " , [ ] ( MenuType type ) { } } } ,
{ game - > KEY_BACK , { " Stay " , [ ] ( MenuType type ) {
Menu : : CloseMenu ( ) ;
} } } ,
{ game - > KEY_CONFIRM , { " Select " , [ ] ( MenuType type ) { } } } ,
}
, { //Button Navigation Rules
{ " Sample Button " , {
. up = " " ,
. down = " " ,
. left = " " ,
. right = " " , } } ,
} ) ;
}