@ -164,6 +164,8 @@ void Menu::InitializeCharacterMenuWindow(){
return attrStr ;
} ;
const bool CanModifyEquipSlots { game - > GetCurrentMap ( ) . GetMapType ( ) = = Map : : MapType : : HUB | | game - > GetCurrentMap ( ) . GetMapType ( ) = = Map : : MapType : : WORLD_MAP } ;
int equipSlot = 1 ;
for ( int i = 0 ; i < 8 ; i + + ) {
float x = 31 + ( i % 2 ) * 33 ;
@ -177,137 +179,138 @@ void Menu::InitializeCharacterMenuWindow(){
EquipSlot slot = EquipSlot ( equipSlot ) ;
auto equipmentSlot = characterMenuWindow - > ADD ( " Equip Slot " + CharacterMenuWindow : : slotNames [ i ] , EquipSlotButton ) ( geom2d : : rect < float > { { x , y + 28 } , { 24 , 24 } } , slot ,
[ & ] ( MenuFuncData data ) {
if ( game - > GetCurrentMap ( ) . GetMapType ( ) ! = Map : : MapType : : HUB & & game - > GetCurrentMap ( ) . GetMapType ( ) ! = Map : : MapType : : WORLD_MAP ) {
game - > AddNotification ( AiL : : Notification { " Cannot change equipment in a stage! " , 5.f , YELLOW } ) ;
return false ;
}
EquipSlot slot = EquipSlot ( data . component . lock ( ) - > I ( Attribute : : EQUIP_TYPE ) ) ;
data . menu . I ( A : : EQUIP_TYPE ) = int ( slot ) ;
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 : : 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 ;
} ) ;
std : : copy_if ( accessories . begin ( ) , accessories . end ( ) , std : : back_inserter ( availableEquipment ) , [ & ] ( const std : : shared_ptr < Item > it ) {
return it - > GetEquipSlot ( ) & slot ;
} ) ;
std : : shared_ptr < ScrollableWindowComponent > equipList = Component < ScrollableWindowComponent > ( data . component . lock ( ) - > parentMenu , " Equip List " ) ;
equipList - > RemoveAllComponents ( ) ;
for ( int counter = 0 ; const std : : weak_ptr < Item > it : availableEquipment ) {
std : : shared_ptr < RowItemDisplay > equip ;
const bool isAccessorySlot = slot & ( EquipSlot : : RING1 | EquipSlot : : RING2 ) ;
if ( isAccessorySlot ) {
equip = CharacterMenuWindow : : GenerateItemDisplay < AccessoryRowItemDisplay > ( equipList , counter , it ) ;
} else {
equip = CharacterMenuWindow : : GenerateItemDisplay < RowItemDisplay > ( equipList , counter , it ) ;
}
if ( CanModifyEquipSlots ) {
EquipSlot slot = EquipSlot ( data . component . lock ( ) - > I ( Attribute : : EQUIP_TYPE ) ) ;
data . menu . I ( A : : EQUIP_TYPE ) = int ( slot ) ;
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 : : 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 ;
} ) ;
std : : copy_if ( accessories . begin ( ) , accessories . end ( ) , std : : back_inserter ( availableEquipment ) , [ & ] ( const std : : shared_ptr < Item > it ) {
return it - > GetEquipSlot ( ) & slot ;
} ) ;
std : : shared_ptr < ScrollableWindowComponent > equipList = Component < ScrollableWindowComponent > ( data . component . lock ( ) - > parentMenu , " Equip List " ) ;
equipList - > RemoveAllComponents ( ) ;
for ( int counter = 0 ; const std : : weak_ptr < Item > it : availableEquipment ) {
std : : shared_ptr < RowItemDisplay > equip ;
const bool isAccessorySlot = slot & ( EquipSlot : : RING1 | EquipSlot : : RING2 ) ;
if ( isAccessorySlot ) {
equip = CharacterMenuWindow : : GenerateItemDisplay < AccessoryRowItemDisplay > ( equipList , counter , it ) ;
} else {
equip = CharacterMenuWindow : : GenerateItemDisplay < RowItemDisplay > ( equipList , counter , it ) ;
}
equip - > SetHoverFunc (
[ & ] ( MenuFuncData data ) {
if ( ! data . component . lock ( ) - > GetSubcomponentParent ( ) . expired ( ) ) return true ;
std : : weak_ptr < RowItemDisplay > button = DYNAMIC_POINTER_CAST < RowItemDisplay > ( data . component . lock ( ) ) ;
if ( ! button . expired ( ) ) {
const std : : weak_ptr < Item > buttonItem = button . lock ( ) - > GetItem ( ) ;
std : : vector < float > statsBeforeEquip ;
EquipSlot slot = EquipSlot ( button . lock ( ) - > I ( Attribute : : EQUIP_TYPE ) ) ;
for ( const CharacterMenuWindow : : AttributeData & attribute : CharacterMenuWindow : : displayAttrs ) {
statsBeforeEquip . push_back ( attribute . calcFunc ( ) ) ;
}
int healthBeforeEquip = game - > GetPlayer ( ) - > GetHealth ( ) ;
int manaBeforeEquip = game - > GetPlayer ( ) - > GetMana ( ) ;
std : : weak_ptr < Item > equippedItem = Inventory : : GetEquip ( slot ) ;
std : : weak_ptr < Item > otherItem ;
if ( slot & EquipSlot : : RING1 ) otherItem = Inventory : : GetEquip ( EquipSlot : : RING2 ) ;
else
if ( slot & EquipSlot : : RING2 ) otherItem = Inventory : : GetEquip ( EquipSlot : : RING1 ) ;
if ( Item : : SelectedEquipIsDifferent ( button . lock ( ) - > GetItem ( ) , slot ) ) { //If we find that the opposite ring slot is equipped to us, this would be an item swap or the exact same ring, therefore no stat calculations apply.
Inventory : : EquipItem ( buttonItem , slot ) ;
for ( int counter = 0 ; const CharacterMenuWindow : : AttributeData & attribute : CharacterMenuWindow : : displayAttrs ) {
std : : weak_ptr < StatLabel > statDisplayLabel = Component < StatLabel > ( CHARACTER_MENU , " Attribute " + std : : string ( ItemAttribute : : Get ( attribute . attrName ) . Name ( ) ) + " Label " ) ;
int statChangeAmt = attribute . calcFunc ( ) - statsBeforeEquip [ counter ] ;
statDisplayLabel . lock ( ) - > SetStatChangeAmt ( statChangeAmt ) ;
counter + + ;
equip - > SetHoverFunc (
[ & ] ( MenuFuncData data ) {
if ( ! data . component . lock ( ) - > GetSubcomponentParent ( ) . expired ( ) ) return true ;
std : : weak_ptr < RowItemDisplay > button = DYNAMIC_POINTER_CAST < RowItemDisplay > ( data . component . lock ( ) ) ;
if ( ! button . expired ( ) ) {
const std : : weak_ptr < Item > buttonItem = button . lock ( ) - > GetItem ( ) ;
std : : vector < float > statsBeforeEquip ;
EquipSlot slot = EquipSlot ( button . lock ( ) - > I ( Attribute : : EQUIP_TYPE ) ) ;
for ( const CharacterMenuWindow : : AttributeData & attribute : CharacterMenuWindow : : displayAttrs ) {
statsBeforeEquip . push_back ( attribute . calcFunc ( ) ) ;
}
Inventory : : UnequipItem ( slot ) ;
if ( ! ISBLANK ( equippedItem ) ) {
Inventory : : EquipItem ( equippedItem , slot ) ;
game - > GetPlayer ( ) - > Heal ( healthBeforeEquip - game - > GetPlayer ( ) - > GetHealth ( ) , true ) ;
game - > GetPlayer ( ) - > RestoreMana ( manaBeforeEquip - game - > GetPlayer ( ) - > GetMana ( ) , true ) ;
}
if ( ! ISBLANK ( otherItem ) ) {
if ( slot & EquipSlot : : RING1 ) Inventory : : EquipItem ( otherItem , EquipSlot : : RING2 ) ;
else
if ( slot & EquipSlot : : RING2 ) Inventory : : EquipItem ( otherItem , EquipSlot : : RING1 ) ;
int healthBeforeEquip = game - > GetPlayer ( ) - > GetHealth ( ) ;
int manaBeforeEquip = game - > GetPlayer ( ) - > GetMana ( ) ;
std : : weak_ptr < Item > equippedItem = Inventory : : GetEquip ( slot ) ;
std : : weak_ptr < Item > otherItem ;
if ( slot & EquipSlot : : RING1 ) otherItem = Inventory : : GetEquip ( EquipSlot : : RING2 ) ;
else
if ( slot & EquipSlot : : RING2 ) otherItem = Inventory : : GetEquip ( EquipSlot : : RING1 ) ;
if ( Item : : SelectedEquipIsDifferent ( button . lock ( ) - > GetItem ( ) , slot ) ) { //If we find that the opposite ring slot is equipped to us, this would be an item swap or the exact same ring, therefore no stat calculations apply.
Inventory : : EquipItem ( buttonItem , slot ) ;
for ( int counter = 0 ; const CharacterMenuWindow : : AttributeData & attribute : CharacterMenuWindow : : displayAttrs ) {
std : : weak_ptr < StatLabel > statDisplayLabel = Component < StatLabel > ( CHARACTER_MENU , " Attribute " + std : : string ( ItemAttribute : : Get ( attribute . attrName ) . Name ( ) ) + " Label " ) ;
int statChangeAmt = attribute . calcFunc ( ) - statsBeforeEquip [ counter ] ;
statDisplayLabel . lock ( ) - > SetStatChangeAmt ( statChangeAmt ) ;
counter + + ;
}
Inventory : : UnequipItem ( slot ) ;
if ( ! ISBLANK ( equippedItem ) ) {
Inventory : : EquipItem ( equippedItem , slot ) ;
game - > GetPlayer ( ) - > Heal ( healthBeforeEquip - game - > GetPlayer ( ) - > GetHealth ( ) , true ) ;
game - > GetPlayer ( ) - > RestoreMana ( manaBeforeEquip - game - > GetPlayer ( ) - > GetMana ( ) , true ) ;
}
if ( ! ISBLANK ( otherItem ) ) {
if ( slot & EquipSlot : : RING1 ) Inventory : : EquipItem ( otherItem , EquipSlot : : RING2 ) ;
else
if ( slot & EquipSlot : : RING2 ) Inventory : : EquipItem ( otherItem , EquipSlot : : RING1 ) ;
}
}
Component < MenuItemLabel > ( data . menu . GetType ( ) , " Item Name " ) - > SetItem ( buttonItem ) ;
Component < MenuItemLabel > ( data . menu . GetType ( ) , " Item Description " ) - > SetItem ( buttonItem ) ;
Component < MenuItemLabel > ( data . menu . GetType ( ) , " Item Name " ) - > Enable ( ) ;
Component < MenuItemLabel > ( data . menu . GetType ( ) , " Item Description " ) - > Enable ( ) ;
} else {
ERR ( " WARNING! Attempting to cast a button that isn't a RowItemDisplay! " ) ;
}
Component < MenuItemLabel > ( data . menu . GetType ( ) , " Item Name " ) - > SetItem ( buttonItem ) ;
Component < MenuItemLabel > ( data . menu . GetType ( ) , " Item Description " ) - > SetItem ( buttonItem ) ;
Component < MenuItemLabel > ( data . menu . GetType ( ) , " Item Name " ) - > Enable ( ) ;
Component < MenuItemLabel > ( data . menu . GetType ( ) , " Item Description " ) - > Enable ( ) ;
} else {
ERR ( " WARNING! Attempting to cast a button that isn't a RowItemDisplay! " ) ;
}
return true ;
} ) ;
equip - > SetMouseOutFunc (
[ ] ( MenuFuncData data ) {
for ( int counter = 0 ; const CharacterMenuWindow : : AttributeData & attribute : CharacterMenuWindow : : displayAttrs ) {
std : : weak_ptr < StatLabel > statDisplayLabel = Component < StatLabel > ( CHARACTER_MENU , " Attribute " + std : : string ( ItemAttribute : : Get ( attribute . attrName ) . Name ( ) ) + " Label " ) ;
statDisplayLabel . lock ( ) - > SetStatChangeAmt ( 0 ) ;
counter + + ;
}
Component < MenuItemLabel > ( data . menu . GetType ( ) , " Item Name " ) - > Disable ( ) ;
Component < MenuItemLabel > ( data . menu . GetType ( ) , " Item Description " ) - > Disable ( ) ;
return true ;
} ) ;
equip - > SetShowQuantity ( false ) ;
equip - > SetSelectionType ( SelectionType : : NONE ) ;
equip - > I ( Attribute : : EQUIP_TYPE ) = int ( slot ) ;
if ( Inventory : : GetEquip ( slot ) = = it ) {
equip - > SetSelected ( true ) ;
}
equip - > SetCompactDescriptions ( NON_COMPACT ) ;
return true ;
} ) ;
equip - > SetMouseOutFunc (
[ ] ( MenuFuncData data ) {
for ( int counter = 0 ; const CharacterMenuWindow : : AttributeData & attribute : CharacterMenuWindow : : displayAttrs ) {
std : : weak_ptr < StatLabel > statDisplayLabel = Component < StatLabel > ( CHARACTER_MENU , " Attribute " + std : : string ( ItemAttribute : : Get ( attribute . attrName ) . Name ( ) ) + " Label " ) ;
statDisplayLabel . lock ( ) - > SetStatChangeAmt ( 0 ) ;
counter + + ;
}
Component < MenuItemLabel > ( data . menu . GetType ( ) , " Item Name " ) - > Disable ( ) ;
Component < MenuItemLabel > ( data . menu . GetType ( ) , " Item Description " ) - > Disable ( ) ;
return true ;
} ) ;
counter + + ;
}
equip - > SetShowQuantity ( false ) ;
equip - > SetSelectionType ( SelectionType : : NONE ) ;
equipList - > I ( Attribute : : INDEXED_THEME ) = data . component . lock ( ) - > I ( Attribute : : INDEXED_THEME ) ;
Component < MenuComponent > ( data . component . lock ( ) - > parentMenu , " Equip Selection Outline " ) - > Enable ( ) ;
equipList - > Enable ( ) ;
Component < MenuComponent > ( data . component . lock ( ) - > parentMenu , " Equip Selection Bottom Outline " ) - > Enable ( ) ;
Component < MenuComponent > ( data . component . lock ( ) - > parentMenu , " Equip Selection Select Button " ) - > Enable ( ) ;
Component < CharacterRotatingDisplay > ( data . component . lock ( ) - > parentMenu , " Character Rotating Display " ) - > Disable ( ) ;
equipmentWindowOpened = true ;
auto equipmentList = equipList - > GetComponents ( ) ;
auto itemEquipped = std : : find_if ( equipmentList . begin ( ) , equipmentList . end ( ) , [ & ] ( std : : weak_ptr < MenuComponent > & component ) {
return ! ISBLANK ( Inventory : : GetEquip ( slot ) ) & & component . lock ( ) - > GetSubcomponentParent ( ) . expired ( ) & & & * DYNAMIC_POINTER_CAST < RowItemDisplay > ( component ) - > GetItem ( ) . lock ( ) = = & * Inventory : : GetEquip ( slot ) . lock ( ) ;
} ) ;
if ( itemEquipped ! = equipmentList . end ( ) ) {
data . menu . SetSelection ( * itemEquipped , true , true ) ;
if ( Menu : : UsingMouseNavigation ( ) ) {
equipList - > HandleOutsideDisabledButtonSelection ( * itemEquipped ) ;
equip - > I ( Attribute : : EQUIP_TYPE ) = int ( slot ) ;
if ( Inventory : : GetEquip ( slot ) = = it ) {
equip - > SetSelected ( true ) ;
}
equip - > SetCompactDescriptions ( NON_COMPACT ) ;
counter + + ;
}
data . menu . I ( A : : ITEM_SLOT ) = equipList - > GetComponentIndex ( * itemEquipped ) ;
} else
if ( equipmentList . size ( ) > 0 ) {
data . menu . SetSelection ( equipmentList [ 0 ] , true , true ) ;
if ( Menu : : UsingMouseNavigation ( ) ) {
equipList - > HandleOutsideDisabledButtonSelection ( equipmentList [ 0 ] ) ;
equipList - > I ( Attribute : : INDEXED_THEME ) = data . component . lock ( ) - > I ( Attribute : : INDEXED_THEME ) ;
Component < MenuComponent > ( data . component . lock ( ) - > parentMenu , " Equip Selection Outline " ) - > Enable ( ) ;
equipList - > Enable ( ) ;
Component < MenuComponent > ( data . component . lock ( ) - > parentMenu , " Equip Selection Bottom Outline " ) - > Enable ( ) ;
Component < MenuComponent > ( data . component . lock ( ) - > parentMenu , " Equip Selection Select Button " ) - > Enable ( ) ;
Component < CharacterRotatingDisplay > ( data . component . lock ( ) - > parentMenu , " Character Rotating Display " ) - > Disable ( ) ;
equipmentWindowOpened = true ;
auto equipmentList = equipList - > GetComponents ( ) ;
auto itemEquipped = std : : find_if ( equipmentList . begin ( ) , equipmentList . end ( ) , [ & ] ( std : : weak_ptr < MenuComponent > & component ) {
return ! ISBLANK ( Inventory : : GetEquip ( slot ) ) & & component . lock ( ) - > GetSubcomponentParent ( ) . expired ( ) & & & * DYNAMIC_POINTER_CAST < RowItemDisplay > ( component ) - > GetItem ( ) . lock ( ) = = & * Inventory : : GetEquip ( slot ) . lock ( ) ;
} ) ;
if ( itemEquipped ! = equipmentList . end ( ) ) {
data . menu . SetSelection ( * itemEquipped , true , true ) ;
if ( Menu : : UsingMouseNavigation ( ) ) {
equipList - > HandleOutsideDisabledButtonSelection ( * itemEquipped ) ;
}
data . menu . I ( A : : ITEM_SLOT ) = equipList - > GetComponentIndex ( * itemEquipped ) ;
} else
if ( equipmentList . size ( ) > 0 ) {
data . menu . SetSelection ( equipmentList [ 0 ] , true , true ) ;
if ( Menu : : UsingMouseNavigation ( ) ) {
equipList - > HandleOutsideDisabledButtonSelection ( equipmentList [ 0 ] ) ;
}
data . menu . I ( A : : ITEM_SLOT ) = 0 ;
} else {
data . menu . SetSelection ( " Equip Selection Select Button " sv ) ;
}
data . menu . I ( A : : ITEM_SLOT ) = 0 ;
return true ;
} else {
data . menu . SetSelection ( " Equip Selection Select Button " sv ) ;
game - > AddNotification ( AiL : : Notification { " Cannot change equipment in a stage! " , 5.f , YELLOW } ) ;
return false ;
}
return true ;
} , [ ] ( MenuFuncData data ) { //On Mouse Hover
EquipSlot slot = DYNAMIC_POINTER_CAST < EquipSlotButton > ( data . component . lock ( ) ) - > GetSlot ( ) ;
const std : : weak_ptr < Item > equip = Inventory : : GetEquip ( slot ) ;
@ -372,18 +375,20 @@ void Menu::InitializeCharacterMenuWindow(){
}
}
return " " ;
} , [ ] ( MenuType type ) {
} , [ & CanModifyEquipSlots ] ( MenuType type ) {
if ( ! Menu : : menus [ type ] - > GetSelection ( ) . expired ( ) & &
Menu : : menus [ type ] - > GetSelection ( ) . lock ( ) - > GetName ( ) . starts_with ( " Equip Slot " ) ) {
EquipSlot slot = EquipSlot ( Menu : : menus [ type ] - > GetSelection ( ) . lock ( ) - > I ( Attribute : : EQUIP_TYPE ) ) ;
if ( ! ISBLANK ( Inventory : : GetEquip ( slot ) ) ) {
Inventory : : UnequipItem ( slot ) ;
if ( slot & EquipSlot : : RING1 | | slot & EquipSlot : : RING2 ) {
SoundEffect : : PlaySFX ( " Unequip Accessory " , SoundEffect : : CENTERED ) ;
} else {
SoundEffect : : PlaySFX ( " Unequip Armor " , SoundEffect : : CENTERED ) ;
if ( CanModifyEquipSlots ) {
EquipSlot slot = EquipSlot ( Menu : : menus [ type ] - > GetSelection ( ) . lock ( ) - > I ( Attribute : : EQUIP_TYPE ) ) ;
if ( ! ISBLANK ( Inventory : : GetEquip ( slot ) ) ) {
Inventory : : UnequipItem ( slot ) ;
if ( slot & EquipSlot : : RING1 | | slot & EquipSlot : : RING2 ) {
SoundEffect : : PlaySFX ( " Unequip Accessory " , SoundEffect : : CENTERED ) ;
} else {
SoundEffect : : PlaySFX ( " Unequip Armor " , SoundEffect : : CENTERED ) ;
}
}
}
} else game - > AddNotification ( AiL : : Notification { " Cannot change equipment in a stage! " , 5.f , YELLOW } ) ;
}
} } } ,
{ { game - > KEY_FACELEFT , Pressed } , { [ ] ( MenuFuncData data ) {
@ -395,18 +400,20 @@ void Menu::InitializeCharacterMenuWindow(){
}
}
return " " ;
} , [ ] ( MenuType type ) {
} , [ & CanModifyEquipSlots ] ( MenuType type ) {
if ( ! Menu : : menus [ type ] - > GetSelection ( ) . expired ( ) & &
Menu : : menus [ type ] - > GetSelection ( ) . lock ( ) - > GetName ( ) . starts_with ( " Equip Slot " ) ) {
EquipSlot slot = EquipSlot ( Menu : : menus [ type ] - > GetSelection ( ) . lock ( ) - > I ( Attribute : : EQUIP_TYPE ) ) ;
if ( ! ISBLANK ( Inventory : : GetEquip ( slot ) ) ) {
Inventory : : UnequipItem ( slot ) ;
if ( slot & EquipSlot : : RING1 | | slot & EquipSlot : : RING2 ) {
SoundEffect : : PlaySFX ( " Unequip Accessory " , SoundEffect : : CENTERED ) ;
} else {
SoundEffect : : PlaySFX ( " Unequip Armor " , SoundEffect : : CENTERED ) ;
if ( CanModifyEquipSlots ) {
EquipSlot slot = EquipSlot ( Menu : : menus [ type ] - > GetSelection ( ) . lock ( ) - > I ( Attribute : : EQUIP_TYPE ) ) ;
if ( ! ISBLANK ( Inventory : : GetEquip ( slot ) ) ) {
Inventory : : UnequipItem ( slot ) ;
if ( slot & EquipSlot : : RING1 | | slot & EquipSlot : : RING2 ) {
SoundEffect : : PlaySFX ( " Unequip Accessory " , SoundEffect : : CENTERED ) ;
} else {
SoundEffect : : PlaySFX ( " Unequip Armor " , SoundEffect : : CENTERED ) ;
}
}
}
} else game - > AddNotification ( AiL : : Notification { " Cannot change equipment in a stage! " , 5.f , YELLOW } ) ;
}
} } } ,
{ game - > KEY_BACK , { " Back " , [ ] ( MenuType type ) {