# 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 © 2023 The FreeType
Project ( www . freetype . org ) . Please see LICENSE_FT . txt for more information .
All rights reserved .
*/
# pragma endregion
# include "AdventuresInLestoria.h"
# include "DEFINES.h"
# include "Menu.h"
# include "MenuLabel.h"
# include "MenuAnimatedIconToggleButton.h"
# include "GameState.h"
# include "ClassInfo.h"
INCLUDE_game
using A = Attribute ;
void Menu : : InitializeClassSelectionWindow ( ) {
Menu * classSelectionWindow = CreateMenu ( CLASS_SELECTION , CENTERED , game - > GetScreenSize ( ) - vi2d { 24 , 24 } ) ;
classSelectionWindow - > S ( A : : CLASS_SELECTION ) = " Warrior " ; //Default selected class.
vf2d outlineSize = classSelectionWindow - > size - vf2d { 13 , 13 } ;
classSelectionWindow - > ADD ( " Class Selection Title Label " , MenuLabel ) ( geom2d : : rect < float > { { 4 , 20 } , { outlineSize . x , 32 } } , " Choose a Character Class " , 2 , ComponentAttr : : SHADOW | ComponentAttr : : OUTLINE | ComponentAttr : : BACKGROUND ) END ;
auto outline = classSelectionWindow - > ADD ( " Outline Border " , MenuLabel ) ( geom2d : : rect < float > { { 4 , 4 } , outlineSize } , " " , 1 , ComponentAttr : : OUTLINE ) END ;
vf2d navigationButtonSize = { 24 * 2.5f , 16 } ;
classSelectionWindow - > ADD ( " Back Button " , MenuComponent ) ( geom2d : : rect < float > { { 4 + 2 , outlineSize . y + 4 - navigationButtonSize . y - 2 } , navigationButtonSize } , " Back " , [ ] ( MenuFuncData data ) { Menu : : CloseMenu ( ) ; return true ; } ) END ;
classSelectionWindow - > ADD ( " Confirm " , MenuComponent ) ( geom2d : : rect < float > { { outlineSize . x + 4 - navigationButtonSize . x - 2 , outlineSize . y + 4 - navigationButtonSize . y - 2 } , navigationButtonSize } , " Confirm " , [ ] ( MenuFuncData data ) {
std : : string selectedClass = data . component . lock ( ) - > S ( A : : CLASS_SELECTION ) ;
data . game - > ChangePlayerClass ( classutils : : StringToClass ( selectedClass ) ) ;
GameState : : ChangeState ( States : : OVERWORLD_MAP ) ;
return true ;
} ) END
- > disabled = true ;
vf2d buttonPadding = { 2 , 2 } ;
vf2d buttonSize = { floor ( outlineSize . y / 3 - buttonPadding . y * 3 ) , outlineSize . y / 9 - buttonPadding . y * 3 } ; //The floor is for fixing a small pixel rounding bug.
float buttonTotalWidth = ( buttonSize . x + buttonPadding . x ) * 3 ;
vf2d buttonStartPos = outline - > GetPos ( ) + vf2d { outlineSize . x / 2 , outlineSize . y / 3 } - vf2d { buttonTotalWidth / 2 , 0 } ;
std : : array < std : : string , 6 > classNames = {
Warrior : : name ,
Ranger : : name ,
Wizard : : name ,
Thief : : name ,
Trapper : : name ,
Witch : : name ,
} ;
std : : array < std : : string , 6 > classAnimationNames = {
Warrior : : walk_s ,
Ranger : : walk_s ,
Wizard : : walk_s ,
Thief : : walk_s ,
Trapper : : walk_s ,
Witch : : walk_s ,
} ;
std : : vector < std : : weak_ptr < IToggleable > > toggleGroup ;
for ( int i = 0 ; i < 6 ; i + + ) {
std : : string className = classNames [ i ] ;
std : : string classAnimationName = classAnimationNames [ i ] ;
vf2d offsetPos = {
buttonStartPos . x + ( buttonSize . x + buttonPadding . x ) * float ( i % 3 ) ,
buttonStartPos . y + ( buttonSize . y + buttonPadding . y + 2 * outlineSize . y / 9 ) * float ( i / 3 ) + 2 * outlineSize . y / 9 ,
} ;
vf2d backgroundOffsetPos = {
buttonStartPos . x + ( buttonSize . x + buttonPadding . x ) * float ( i % 3 ) ,
buttonStartPos . y + ( buttonSize . y + buttonPadding . y + 2 * outlineSize . y / 9 ) * float ( i / 3 ) ,
} ;
vf2d backgroundSize = { floor ( outlineSize . y / 3 - buttonPadding . y * 3 ) , outlineSize . y / 3 - buttonPadding . y * 3 } ; //The floor is for fixing a small pixel rounding bug.
classSelectionWindow - > ADD ( className + " Background " , MenuLabel ) ( geom2d : : rect < float > { backgroundOffsetPos , backgroundSize } , " " , 1 , ComponentAttr : : OUTLINE | ComponentAttr : : BACKGROUND ) END ;
classSelectionWindow - > ADD ( className + " Button " , MenuComponent ) ( geom2d : : rect < float > { offsetPos , buttonSize } , " Info " , CLASS_INFO ,
[ ] ( MenuFuncData data ) {
data . menu . S ( A : : CLASS_SELECTION ) = data . component . lock ( ) - > S ( A : : CLASS_SELECTION ) ;
delete Menu : : menus [ CLASS_INFO ] ;
Menu : : InitializeClassInfoWindow ( ) ;
return true ;
} ) END
- > S ( A : : CLASS_SELECTION ) = className ;
classSelectionWindow - > ADD ( className + " Label " , MenuLabel ) ( geom2d : : rect < float > { backgroundOffsetPos , buttonSize } , className , 1 , ComponentAttr : : SHADOW ) END ;
auto classSprite = classSelectionWindow - > ADD ( className + " Icon " , MenuAnimatedIconToggleButton ) ( geom2d : : rect < float > { backgroundOffsetPos + vf2d { 0 , 12 } , backgroundSize + vf2d { 0 , - buttonSize . y - 12 } } , classAnimationName , [ ] ( MenuFuncData data ) {
data . menu . components [ " Confirm " ] - > Enable ( true ) ;
data . menu . components [ " Confirm " ] - > S ( A : : CLASS_SELECTION ) = data . component . lock ( ) - > S ( A : : CLASS_SELECTION ) ;
return true ;
} ) END ;
classSprite - > S ( A : : CLASS_SELECTION ) = className ;
toggleGroup . push_back ( classSprite ) ;
}
for ( std : : weak_ptr < IToggleable > item : toggleGroup ) {
item . lock ( ) - > SetToggleGroup ( toggleGroup ) ;
}
}