5656#include "event.h"
5757#include "config.h"
5858#include "save.h"
59+ #include "text_input.h"
5960
6061#ifdef DEBUG
6162#include "debug/debug.h"
@@ -104,6 +105,7 @@ static SDL_Rect statsGuiViewport;
104105static SDL_Rect minimapViewport ;
105106static SDL_Rect menuViewport ;
106107static Input input ;
108+ static unsigned int gCustomSeed = 0 ;
107109
108110#ifdef DEBUG
109111static Sprite * fpsSprite = NULL ;
@@ -260,10 +262,16 @@ startGame(void)
260262 else
261263 cLevel = 1 ;
262264
263- if (weeklyGame )
265+ if (weeklyGame ) {
266+ debug ("Using weekly game seed" );
264267 set_random_seed ((unsigned int )time_get_weekly_seed ());
265- else
266- set_random_seed (0 );
268+ } else if (gCustomSeed ) {
269+ debug ("Using custom game seed" );
270+ set_random_seed (gCustomSeed );
271+ } else {
272+ debug ("Setting random seed" );
273+ set_random_seed (0 ); // 0 will trigger a random seed later on.
274+ }
267275
268276 gGameState = PLAYING ;
269277 if (gPlayer )
@@ -471,6 +479,18 @@ goToGameSelectMenu(void *unused)
471479 gGameState = GAME_SELECT ;
472480}
473481
482+ static void
483+ openSeedEntry (void * unused )
484+ {
485+ (void )unused ;
486+ char seed_str [16 ] = {0 };
487+ if (gCustomSeed > 0 ) {
488+ SDL_snprintf (seed_str , sizeof (seed_str ), "%u" , gCustomSeed );
489+ }
490+ text_input_init (gWindow , gRenderer , "Enter game seed:" , seed_str );
491+ gGameState = SEED_ENTRY ;
492+ }
493+
474494static void
475495showHowToTooltip (void * unused )
476496{
@@ -479,33 +499,66 @@ showHowToTooltip(void *unused)
479499 gGui -> activeTooltip = tooltip_manager_get_tooltip (TOOLTIP_TYPE_HOWTO );
480500}
481501
502+ static void
503+ copySeedToClipboard (void * unused )
504+ {
505+ (void )unused ;
506+ char seed_str [16 ];
507+ SDL_snprintf (seed_str , sizeof (seed_str ), "%u" , get_random_seed ());
508+ SDL_SetClipboardText (seed_str );
509+ gui_event_message ("Seed copied to clipboard" );
510+ toggleInGameMenu (NULL );
511+ }
512+
513+ static void
514+ buildSeedLabel (char * buf , size_t size )
515+ {
516+ SDL_snprintf (buf , size , "SEED:%u" , get_random_seed ());
517+ }
518+
482519static void
483520initInGameMenu (void )
484521{
485- static TEXT_MENU_ITEM menu_items [] = {
486- {"RESUME" , "" , toggleInGameMenu },
487- {"HOW TO PLAY" , "" , showHowToTooltip },
488- {"MAIN MENU" , "" , goToMainMenu },
489- {"QUIT" , "Exit game" , exitGame },
490- };
522+ static char seed_label [32 ];
523+ buildSeedLabel (seed_label , sizeof (seed_label ));
524+
525+ TEXT_MENU_ITEM menu_items [5 ];
526+ int count = 0 ;
491527
492- menu_create_text_menu (& inGameMenu , & menu_items [0 ], 4 , gRenderer );
528+ menu_items [count ++ ] = (TEXT_MENU_ITEM ){"RESUME" , "Resume the current game" , toggleInGameMenu };
529+ menu_items [count ++ ] = (TEXT_MENU_ITEM ){"HOW TO PLAY" , "Show the in-game guide" , showHowToTooltip };
530+ if (!weeklyGame ) {
531+ menu_items [count ++ ] = (TEXT_MENU_ITEM ){seed_label , "Copy seed to clipboard" , copySeedToClipboard };
532+ }
533+ menu_items [count ++ ] = (TEXT_MENU_ITEM ){"MAIN MENU" , "Return to the main menu" , goToMainMenu };
534+ menu_items [count ++ ] = (TEXT_MENU_ITEM ){"QUIT" , "Exit game" , exitGame };
535+
536+ menu_create_text_menu (& inGameMenu , & menu_items [0 ], count , gRenderer );
493537}
494538
495539static void
496540createInGameGameOverMenu (void )
497541{
498- static TEXT_MENU_ITEM menu_items [] = {
499- {"NEW GAME" , "Start a new game with the same settings" , goToCharacterMenu },
500- {"MAIN MENU" , "" , goToMainMenu },
501- {"QUIT" , "Exit game" , exitGame },
502- };
542+ static char seed_label [32 ];
543+ buildSeedLabel (seed_label , sizeof (seed_label ));
503544
504545 if (inGameMenu ) {
505546 menu_destroy (inGameMenu );
506547 inGameMenu = NULL ;
507548 }
508- menu_create_text_menu (& inGameMenu , & menu_items [0 ], 3 , gRenderer );
549+
550+ TEXT_MENU_ITEM menu_items [4 ];
551+ int count = 0 ;
552+
553+ menu_items [count ++ ] =
554+ (TEXT_MENU_ITEM ){"NEW GAME" , "Start a new game with the same settings" , goToCharacterMenu };
555+ if (!weeklyGame ) {
556+ menu_items [count ++ ] = (TEXT_MENU_ITEM ){seed_label , "Copy seed to clipboard" , copySeedToClipboard };
557+ }
558+ menu_items [count ++ ] = (TEXT_MENU_ITEM ){"MAIN MENU" , "Return to the main menu" , goToMainMenu };
559+ menu_items [count ++ ] = (TEXT_MENU_ITEM ){"QUIT" , "Exit game" , exitGame };
560+
561+ menu_create_text_menu (& inGameMenu , & menu_items [0 ], count , gRenderer );
509562}
510563
511564static void
@@ -547,6 +600,7 @@ initMainMenu(void)
547600{
548601 static TEXT_MENU_ITEM menu_items [] = {
549602 {"PLAY" , "Start game" , goToGameSelectMenu },
603+ {"SET SEED" , "Set the game seed" , openSeedEntry },
550604 {"SCORES" , "View your top 10 scores" , viewScoreScreen },
551605 {"CREDITS" , "View game credits" , viewCredits },
552606 {"QUIT" , "Exit game" , exitGame },
@@ -557,7 +611,7 @@ initMainMenu(void)
557611
558612 gMap = map_lua_generator_single_room__run (cLevel , gRenderer );
559613
560- menu_create_text_menu (& mainMenu , & menu_items [0 ], 4 , gRenderer );
614+ menu_create_text_menu (& mainMenu , & menu_items [0 ], SDL_arraysize ( menu_items ) , gRenderer );
561615 mixer_play_music (MENU_MUSIC );
562616 creditsScreen = screen_create_credits (gRenderer );
563617 scoreScreen = screen_create_hiscore (gRenderer );
@@ -752,6 +806,10 @@ handle_main_input(void)
752806 charSelectMenu = NULL ;
753807 gGameState = GAME_SELECT ;
754808 break ;
809+ case SEED_ENTRY :
810+ text_input_close (gWindow );
811+ gGameState = MENU ;
812+ break ;
755813 case MENU :
756814 gGameState = QUIT ;
757815 break ;
@@ -769,7 +827,7 @@ handle_main_input(void)
769827 }
770828
771829 handle_settings_input ();
772- if (input_key_is_pressed (& input , KEY_TAB )) {
830+ if (( gGameState == PLAYING || gGameState == GAME_OVER ) && input_key_is_pressed (& input , KEY_TAB )) {
773831 gShowMap = !gShowMap ;
774832 }
775833}
@@ -1059,6 +1117,7 @@ run_game_render(void)
10591117static inline void
10601118register_scores (void )
10611119{
1120+ debug ("Registering steam scores" );
10621121 uint8_t details [4 ] = {(uint8_t )gPlayer -> stats .lvl , (uint8_t )cLevel , (uint8_t )(gPlayer -> class + 1 ), 0 };
10631122 steam_register_score ((int )gPlayer -> gold , (int32_t * )& details , 1 );
10641123 steam_register_kills ((int )gPlayer -> stat_data .kills , (int32_t * )& details , 1 );
@@ -1080,6 +1139,10 @@ register_scores(void)
10801139 steam_set_achievement (MAGICAL );
10811140 steam_register_mage_score ((int )gPlayer -> gold , (int32_t * )& details , 1 );
10821141 }
1142+
1143+ if (gCustomSeed != 0 && !weeklyGame ) {
1144+ steam_set_achievement (SEEDLING );
1145+ }
10831146}
10841147#endif
10851148
@@ -1207,6 +1270,28 @@ run_menu(void)
12071270 SDL_RenderPresent (gRenderer );
12081271}
12091272
1273+ static void
1274+ run_seed_entry (void )
1275+ {
1276+ SDL_SetRenderViewport (gRenderer , & mainViewport );
1277+ text_input_update (& input );
1278+ text_input_render (gCamera );
1279+ SDL_RenderPresent (gRenderer );
1280+
1281+ // Di this last since it resets the text_input
1282+ if (text_input_is_confirmed ()) {
1283+ const char * val = text_input_get_value ();
1284+ if (SDL_strlen (val ) > 0 ) {
1285+ gCustomSeed = (unsigned int )SDL_atoi (val );
1286+ debug ("Custom seed set: %u" , gCustomSeed );
1287+ } else {
1288+ gCustomSeed = 0 ;
1289+ }
1290+ text_input_close (gWindow );
1291+ gGameState = MENU ;
1292+ }
1293+ }
1294+
12101295static void
12111296run (void )
12121297{
@@ -1252,6 +1337,9 @@ run(void)
12521337 case CHARACTER_MENU :
12531338 run_menu ();
12541339 break ;
1340+ case SEED_ENTRY :
1341+ run_seed_entry ();
1342+ break ;
12551343 case QUIT :
12561344 quit = true;
12571345 break ;
0 commit comments