2023-11-20 22:56:35 -06:00
# pragma region License
2023-11-14 18:11:32 -06:00
/*
License ( OLC - 3 )
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
2024-01-02 00:46:32 -06:00
Copyright 2024 Joshua Sigona < sigonasr2 @ gmail . com >
2023-11-14 18:11:32 -06:00
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 .
2023-11-29 00:50:00 -06:00
2024-01-30 14:48:49 +00:00
Portions of this software are copyright © 2024 The FreeType
2023-11-29 00:50:00 -06:00
Project ( www . freetype . org ) . Please see LICENSE_FT . txt for more information .
All rights reserved .
2023-11-14 18:11:32 -06:00
*/
2023-11-20 22:56:35 -06:00
# pragma endregion
2023-10-07 13:33:27 -05:00
# pragma once
2023-11-13 21:26:34 -06:00
# include "Menu.h"
2023-10-07 13:33:27 -05:00
# include "MenuIconButton.h"
2024-02-29 03:55:15 -06:00
# include "MenuLabel.h"
2023-10-07 13:33:27 -05:00
# include "DEFINES.h"
2024-01-04 05:21:56 -06:00
# include "AdventuresInLestoria.h"
2023-10-07 13:33:27 -05:00
# include "Item.h"
2023-10-07 15:47:26 -05:00
# include "safemap.h"
2023-11-13 21:26:34 -06:00
# include "drawutil.h"
2023-10-07 13:33:27 -05:00
INCLUDE_game
2023-10-07 15:47:26 -05:00
INCLUDE_ITEM_DATA
2023-10-07 13:33:27 -05:00
class MenuItemButton : public MenuIconButton {
2023-12-22 06:14:37 -06:00
friend class InventoryScrollableWindowComponent ;
2023-10-07 13:33:27 -05:00
private :
2023-12-27 17:00:52 -06:00
const std : : vector < std : : shared_ptr < Item > > & invRef ;
2023-11-16 17:36:36 -06:00
MenuType itemDescriptionMenu ;
std : : string itemNameLabelName ;
std : : string itemDescriptionLabelName ;
2023-12-12 05:20:51 -06:00
CompactText compact = COMPACT ;
2023-10-07 13:33:27 -05:00
public :
2023-11-13 21:26:34 -06:00
int selected = - 1 ; //0-2 representing which loadout slot this item consumes. -1 means not selected.
2023-12-27 17:00:52 -06:00
inline MenuItemButton ( geom2d : : rect < float > rect , const std : : vector < std : : shared_ptr < Item > > & invRef , int invIndex , MenuFunc onClick , MenuType itemDescriptionMenu , std : : string itemNameLabelName , std : : string itemDescriptionLabelName , IconButtonAttr attributes = IconButtonAttr : : SELECTABLE )
2023-12-22 06:14:37 -06:00
: MenuIconButton ( rect , invRef . size ( ) > invIndex ? const_cast < Decal * > ( invRef [ invIndex ] - > Decal ( ) ) : nullptr , onClick , attributes ) , invRef ( invRef ) , itemDescriptionMenu ( itemDescriptionMenu ) , itemNameLabelName ( itemNameLabelName ) , itemDescriptionLabelName ( itemDescriptionLabelName ) {
2023-11-13 21:26:34 -06:00
draggable = false ;
2023-12-22 06:14:37 -06:00
inventoryIndex = invIndex ;
2023-10-07 18:28:19 -05:00
valid = invRef . size ( ) > invIndex ;
2023-10-07 16:26:03 -05:00
}
2023-12-27 17:00:52 -06:00
inline MenuItemButton ( geom2d : : rect < float > rect , const std : : vector < std : : shared_ptr < Item > > & invRef , int invIndex , MenuFunc onClick , MenuFunc onHover , MenuFunc onMouseOut , MenuType itemDescriptionMenu , std : : string itemNameLabelName , std : : string itemDescriptionLabelName , IconButtonAttr attributes = IconButtonAttr : : SELECTABLE )
2023-12-22 06:14:37 -06:00
: MenuIconButton ( rect , invRef . size ( ) > invIndex ? const_cast < Decal * > ( invRef [ invIndex ] - > Decal ( ) ) : nullptr , onClick , attributes ) , invRef ( invRef ) , itemDescriptionMenu ( itemDescriptionMenu ) , itemNameLabelName ( itemNameLabelName ) , itemDescriptionLabelName ( itemDescriptionLabelName ) {
2023-12-12 05:20:51 -06:00
draggable = false ;
2023-12-22 06:14:37 -06:00
inventoryIndex = invIndex ;
2023-12-12 05:20:51 -06:00
runHoverFunctions = true ;
valid = invRef . size ( ) > invIndex ;
2023-12-16 21:28:41 -06:00
SetHoverFunc ( onHover ) ;
SetMouseOutFunc ( onMouseOut ) ;
2023-12-12 05:20:51 -06:00
}
2023-12-22 06:14:37 -06:00
inline std : : weak_ptr < Item > GetItem ( ) {
2023-12-29 06:25:54 -06:00
return invRef . at ( inventoryIndex ) ;
2023-10-07 16:26:03 -05:00
}
2023-11-11 17:31:53 -06:00
//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 ) {
if ( invRef . size ( ) < = inventoryIndex ) return false ;
2023-12-22 06:14:37 -06:00
return Inventory : : UseItem ( invRef . at ( inventoryIndex ) - > ActualName ( ) , amt ) ;
2023-10-07 16:26:03 -05:00
}
2023-12-28 02:55:59 -06:00
inline void SetCompactDescriptions ( CompactText compact ) {
this - > compact = compact ;
2023-12-12 05:20:51 -06:00
}
2024-01-04 05:21:56 -06:00
inline virtual void Update ( AiL * game ) override {
2023-12-22 06:14:37 -06:00
MenuIconButton : : Update ( game ) ;
valid = invRef . size ( ) > inventoryIndex & & ITEM_DATA . count ( invRef [ inventoryIndex ] - > ActualName ( ) ) & & invRef [ inventoryIndex ] - > Amt ( ) > 0 ;
if ( ! valid ) {
icon = nullptr ;
}
if ( hovered ) {
UpdateLabel ( ) ;
}
}
2023-10-07 13:33:27 -05:00
protected :
2023-12-16 21:28:41 -06:00
virtual inline void OnMouseOut ( ) override {
if ( itemNameLabelName ! = " " ) {
2024-02-11 18:31:30 -06:00
Component < MenuLabel > ( parentMenu , itemNameLabelName ) - > Disable ( ) ;
2023-12-16 21:28:41 -06:00
}
if ( itemDescriptionLabelName ! = " " ) {
2024-02-11 18:31:30 -06:00
Component < MenuLabel > ( parentMenu , itemDescriptionLabelName ) - > Disable ( ) ;
2023-12-12 05:20:51 -06:00
}
}
2023-12-16 21:28:41 -06:00
void UpdateLabel ( ) {
2023-12-22 06:14:37 -06:00
if ( ISBLANK ( invRef [ inventoryIndex ] ) ) return ;
2023-12-12 05:20:51 -06:00
std : : string labelNameText ;
std : : string labelDescriptionText ;
2023-11-14 23:20:13 -06:00
if ( valid ) {
2023-12-22 06:14:37 -06:00
icon = const_cast < Decal * > ( invRef [ inventoryIndex ] - > Decal ( ) ) ;
labelNameText = invRef [ inventoryIndex ] - > DisplayName ( ) ;
labelDescriptionText = invRef [ inventoryIndex ] - > Description ( compact ) ;
2023-11-14 23:20:13 -06:00
} else {
icon = nullptr ;
2023-12-12 05:20:51 -06:00
labelNameText = " " ;
labelDescriptionText = " " ;
}
2023-12-16 21:28:41 -06:00
if ( itemNameLabelName ! = " " ) {
2024-02-17 15:30:56 -06:00
Component < MenuLabel > ( parentMenu , itemNameLabelName ) - > SetLabel ( labelNameText ) ;
2024-02-11 18:31:30 -06:00
Component < MenuLabel > ( parentMenu , itemNameLabelName ) - > Enable ( ) ;
2023-12-16 21:28:41 -06:00
}
if ( itemDescriptionLabelName ! = " " ) {
2024-02-17 15:30:56 -06:00
Component < MenuLabel > ( parentMenu , itemDescriptionLabelName ) - > SetLabel ( labelDescriptionText ) ;
2024-02-11 18:31:30 -06:00
Component < MenuLabel > ( parentMenu , itemDescriptionLabelName ) - > Enable ( ) ;
2023-12-16 21:28:41 -06:00
}
}
virtual inline void OnHover ( ) override {
UpdateLabel ( ) ;
}
2023-12-15 23:57:09 -06:00
virtual inline void DrawDecal ( ViewPort & window , bool focused ) override {
MenuIconButton : : DrawDecal ( window , focused ) ;
2023-12-14 04:18:05 -06:00
if ( selected ! = - 1 ) {
2023-12-15 23:57:09 -06:00
drawutil : : DrawCrosshairDecalViewPort ( window , { rect . pos , rect . size } , 0 ) ;
2023-12-12 05:41:44 -06:00
}
if ( valid ) {
2023-12-22 06:14:37 -06:00
int itemQuantity = Inventory : : GetItemCount ( invRef . at ( inventoryIndex ) - > ActualName ( ) ) ; //Normally we'd retrieve how many of this item we have from our inventory...However Monster Loot and Stage Loot inventories are special and hold their own inventory counts...
2023-12-12 05:41:44 -06:00
if ( & invRef = = & Inventory : : get ( " Monster Loot " ) | | & invRef = = & Inventory : : get ( " Stage Loot " ) ) {
2023-12-22 06:14:37 -06:00
itemQuantity = invRef . at ( inventoryIndex ) - > Amt ( ) ; //So the item quantity comes from the stack itself and not our main inventory.
2023-12-12 05:41:44 -06:00
}
std : : string quantityText = " x " + std : : to_string ( itemQuantity ) ;
2023-12-13 04:03:17 -06:00
vf2d quantityTextScale = rect . size / 48.f ;
vf2d textSize = vf2d ( game - > GetTextSizeProp ( quantityText ) ) * quantityTextScale ;
2023-12-15 23:57:09 -06:00
vf2d drawPos = rect . pos + rect . size - textSize ;
2023-12-19 18:46:59 -06:00
if ( itemQuantity ! = INFINITE ) {
2023-12-21 10:26:18 -06:00
window . DrawShadowStringDecal ( drawPos , quantityText , WHITE , BLACK , quantityTextScale ) ;
2023-12-19 18:46:59 -06:00
}
2023-10-07 19:06:56 -05:00
}
2023-10-07 13:33:27 -05:00
}
2024-01-16 00:20:30 -06:00
inline std : : unique_ptr < MenuComponent > PickUpDraggableItem ( ) override final {
2023-10-07 18:28:19 -05:00
if ( valid ) {
2024-01-16 00:20:30 -06:00
std : : unique_ptr < MenuItemButton > pickUp = std : : make_unique < MenuItemButton > ( rect , invRef , inventoryIndex , onClick , itemDescriptionMenu , itemNameLabelName , itemDescriptionLabelName ) ;
2023-10-07 18:28:19 -05:00
valid = false ;
return pickUp ;
} else {
return nullptr ;
}
}
2024-01-16 00:20:30 -06:00
inline bool DropDraggableItem ( std : : unique_ptr < MenuComponent > draggable ) override final {
2023-10-07 18:28:19 -05:00
//HACK Warning! We're making a bold assumption that every component that is draggable is of the same type! This may change in the future....
2024-01-16 00:20:30 -06:00
MenuItemButton * draggedItem = DYNAMIC_CAST < MenuItemButton * > ( draggable . get ( ) ) ;
2023-12-22 06:14:37 -06:00
ITCategory cat = draggedItem - > invRef . at ( draggedItem - > inventoryIndex ) - > Category ( ) ;
2023-10-07 18:28:19 -05:00
return Inventory : : SwapItems ( cat , draggedItem - > inventoryIndex , inventoryIndex ) ;
}
2023-11-15 07:53:55 -06:00
} ;