# pragma region License
/*
License ( OLC - 3 )
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
Copyright 2018 - 2023 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 .
*/
# pragma endregion
# include "Crawler.h"
# include "DEFINES.h"
# include "Menu.h"
# include "MenuLabel.h"
# include "MenuAnimatedIconToggleButton.h"
# include "GameState.h"
# include "ClassInfo.h"
INCLUDE_game
typedef Attribute A ;
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 } ;
MenuLabel * classSelectionLabel = NEW MenuLabel ( CLASS_SELECTION , { { 4 , 20 } , { outlineSize . x , 32 } } , " Choose a Character Class " , 2 , ComponentAttr : : SHADOW | ComponentAttr : : OUTLINE | ComponentAttr : : BACKGROUND ) ;
classSelectionWindow - > AddComponent ( " Class Selection Title Label " , classSelectionLabel ) ;
MenuLabel * outline = NEW MenuLabel ( CLASS_SELECTION , { { 4 , 4 } , outlineSize } , " " , 1 , ComponentAttr : : OUTLINE ) ;
classSelectionWindow - > AddComponent ( " Outline Border " , outline ) ;
vf2d navigationButtonSize = { 24 * 2.5f , 16 } ;
MenuComponent * backButton = NEW MenuComponent ( CLASS_SELECTION , { { 4 + 2 , outlineSize . y + 4 - navigationButtonSize . y - 2 } , navigationButtonSize } , " Back " , [ ] ( MenuFuncData data ) { Menu : : CloseMenu ( ) ; return true ; } ) ;
classSelectionWindow - > AddComponent ( " Back Button " , backButton ) ;
MenuComponent * confirmButton = NEW MenuComponent ( CLASS_SELECTION , { { outlineSize . x + 4 - navigationButtonSize . x - 2 , outlineSize . y + 4 - navigationButtonSize . y - 2 } , navigationButtonSize } , " Confirm " , [ ] ( MenuFuncData data ) {
std : : string selectedClass = data . component - > S ( A : : CLASS_SELECTION ) ;
data . game - > ChangePlayerClass ( classutils : : StringToClass ( selectedClass ) ) ;
GameState : : ChangeState ( States : : OVERWORLD_MAP ) ;
return true ;
} ) ;
confirmButton - > disabled = true ;
classSelectionWindow - > AddComponent ( " Confirm " , confirmButton ) ;
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 < 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.
MenuLabel * backgroundOutline = NEW MenuLabel ( CLASS_SELECTION , { backgroundOffsetPos , backgroundSize } , " " , 1 , ComponentAttr : : OUTLINE | ComponentAttr : : BACKGROUND ) ;
MenuLabel * classLabel = NEW MenuLabel ( CLASS_SELECTION , { backgroundOffsetPos , buttonSize } , className , 1 , ComponentAttr : : SHADOW ) ;
MenuAnimatedIconToggleButton * classSprite = NEW MenuAnimatedIconToggleButton ( CLASS_SELECTION , { 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 - > S ( A : : CLASS_SELECTION ) ;
return true ;
} ) ;
toggleGroup . push_back ( classSprite ) ;
MenuComponent * classButton = NEW MenuComponent ( CLASS_SELECTION , { offsetPos , buttonSize } , " Info " , CLASS_INFO ,
[ ] ( MenuFuncData data ) {
data . menu . S ( A : : CLASS_SELECTION ) = data . component - > S ( A : : CLASS_SELECTION ) ;
delete Menu : : menus [ CLASS_INFO ] ;
Menu : : InitializeClassInfoWindow ( ) ;
return true ;
} ) ;
classSprite - > S ( A : : CLASS_SELECTION ) = classButton - > S ( A : : CLASS_SELECTION ) = className ;
classSelectionWindow - > AddComponent ( className + " Button " , classButton ) ;
classSelectionWindow - > AddComponent ( className + " Background " , backgroundOutline ) ;
classSelectionWindow - > AddComponent ( className + " Label " , classLabel ) ;
classSelectionWindow - > AddComponent ( className + " Icon " , classSprite ) ;
}
for ( IToggleable * item : toggleGroup ) {
item - > SetToggleGroup ( toggleGroup ) ;
}
}