@@ -143,6 +143,8 @@ protected GameModeMap GameModeMap
143143 protected ToolTip mapListTooltip ;
144144 protected XNAClientDropDown ddGameModeMapFilter ;
145145 protected XNALabel lblGameModeSelect ;
146+ protected XNAClientDropDown ddDifficulty ;
147+ protected XNALabel lblDifficulty ;
146148 protected XNAContextMenu mapContextMenu ;
147149 private XNAContextMenuItem toggleFavoriteItem ;
148150
@@ -170,6 +172,7 @@ protected GameModeMap GameModeMap
170172 protected int UniqueGameID { get ; set ; }
171173 protected int SideCount { get ; private set ; }
172174 protected int RandomSelectorCount { get ; private set ; } = 1 ;
175+ protected int PreviousSelectedDifficulty { get ; set ; }
173176
174177 protected List < int [ ] > RandomSelectors = new List < int [ ] > ( ) ;
175178
@@ -296,6 +299,21 @@ public override void Initialize()
296299
297300 lblGameModeSelect = FindChild < XNALabel > ( nameof ( lblGameModeSelect ) ) ;
298301
302+ ddDifficulty = FindChild < XNAClientDropDown > ( nameof ( ddDifficulty ) , true ) ;
303+ lblDifficulty = FindChild < XNALabel > ( nameof ( lblDifficulty ) , true ) ;
304+
305+ if ( ddDifficulty != null )
306+ {
307+ // Hardcode difficulty items just in case someone tries something stupid.
308+ ddDifficulty . Items . Clear ( ) ;
309+
310+ foreach ( string difficultyName in ProgramConstants . DIFFICULTY_NAMES )
311+ ddDifficulty . AddItem ( difficultyName ) ;
312+
313+ ddDifficulty . SelectedIndex = - 1 ;
314+ ddDifficulty . SelectedIndexChanged += DdDifficulty_SelectedIndexChanged ;
315+ }
316+
299317 InitBtnMapSort ( ) ;
300318
301319 tbMapSearch = FindChild < XNASuggestionTextBox > ( nameof ( tbMapSearch ) ) ;
@@ -479,9 +497,23 @@ protected void DdGameModeMapFilter_SelectedIndexChanged(object sender, EventArgs
479497 ListMaps ( ) ;
480498
481499 if ( lbGameModeMapList . SelectedIndex == - 1 )
500+ {
482501 lbGameModeMapList . SelectedIndex = 0 ; // Select default GameModeMap
502+ UpdateDifficultyDropdown ( ) ;
503+ }
483504 else
505+ {
484506 ChangeMap ( GameModeMap ) ;
507+ }
508+ }
509+
510+ protected void DdDifficulty_SelectedIndexChanged ( object sender , EventArgs e )
511+ {
512+ if ( ddDifficulty . SelectedIndex >= 0 )
513+ PreviousSelectedDifficulty = ddDifficulty . SelectedIndex ;
514+
515+ OnGameOptionChanged ( ) ;
516+ SetMapLabels ( ) ;
485517 }
486518
487519 protected void BtnPlayerExtraOptions_LeftClick ( object sender , EventArgs e )
@@ -604,7 +636,7 @@ protected void ListMaps()
604636 if ( gameModeMap . Map . IsCoop )
605637 {
606638 if ( StatisticsManager . Instance . HasBeatCoOpMap ( gameModeMap . Map . UntranslatedName , gameModeMap . GameMode . UntranslatedUIName ) )
607- rankItem . Texture = RankTextures [ Math . Abs ( 2 - gameModeMap . GameMode . CoopDifficultyLevel ) + 1 ] ;
639+ rankItem . Texture = RankTextures [ Math . Abs ( 2 - GetCoopDifficultyLevel ( ) ) + 1 ] ;
608640 else
609641 rankItem . Texture = RankTextures [ 0 ] ;
610642 }
@@ -657,6 +689,45 @@ protected void ListMaps()
657689 LbGameModeMapList_SelectedIndexChanged ( ) ;
658690 }
659691
692+ protected int GetCoopDifficultyLevel ( )
693+ {
694+ var gameMode = GameModeMap ? . GameMode ;
695+
696+ if ( gameMode != null )
697+ {
698+ if ( gameMode . UseDifficultyDropDown && ddDifficulty != null && ddDifficulty . SelectedIndex >= 0 )
699+ {
700+ return ddDifficulty . Items . Count - ddDifficulty . SelectedIndex - 1 ;
701+ }
702+ else
703+ {
704+ return gameMode . CoopDifficultyLevel ;
705+ }
706+ }
707+
708+ return 0 ;
709+ }
710+
711+ protected virtual void UpdateDifficultyDropdown ( )
712+ {
713+ bool enabled = GameModeMap != null && GameModeMap . GameMode != null && GameModeMap . GameMode . UseDifficultyDropDown ;
714+
715+ if ( ddDifficulty != null )
716+ {
717+ ddDifficulty . AllowDropDown = enabled ;
718+
719+ if ( enabled && ddDifficulty . SelectedIndex < 0 )
720+ ddDifficulty . SelectedIndex = PreviousSelectedDifficulty ;
721+ else if ( ! enabled )
722+ ddDifficulty . SelectedIndex = - 1 ;
723+ }
724+
725+ if ( lblDifficulty != null )
726+ {
727+ lblDifficulty . TextColor = enabled ? UISettings . ActiveSettings . TextColor : UISettings . ActiveSettings . DisabledItemColor ;
728+ }
729+ }
730+
660731 protected abstract int GetDefaultMapRankIndex ( GameModeMap gameModeMap ) ;
661732
662733 private void LbGameModeMapList_RightClick ( object sender , EventArgs e )
@@ -1476,7 +1547,7 @@ private PlayerHouseInfo[] WriteSpawnIni()
14761547
14771548 GameMode . ApplySpawnIniCode ( spawnIni ) ; // Forced options from the game mode
14781549 Map . ApplySpawnIniCode ( spawnIni , Players . Count + AIPlayers . Count ,
1479- AIPlayers . Count , GameMode . CoopDifficultyLevel ) ; // Forced options from the map
1550+ AIPlayers . Count , GetCoopDifficultyLevel ( ) ) ; // Forced options from the map
14801551
14811552 // Player options
14821553
@@ -1696,6 +1767,23 @@ private void WriteMap(PlayerHouseInfo[] houseInfos)
16961767 mapIni . SetStringValue ( "Basic" , "OriginalFilename" , mapIniFileName ) ;
16971768 }
16981769
1770+ if ( GameMode . UseDifficultyDropDown && ddDifficulty != null && ddDifficulty . SelectedIndex >= 0 )
1771+ {
1772+ var filePath = string . Empty ;
1773+
1774+ try
1775+ {
1776+ filePath = ClientConfiguration . Instance . CoopDifficultyINIPaths [ ddDifficulty . SelectedIndex ] ;
1777+ }
1778+ catch ( IndexOutOfRangeException )
1779+ {
1780+ Logger . Log ( $ "CoopDifficultyINIPaths does not contain file path for difficulty index { ddDifficulty . SelectedIndex } ") ;
1781+ }
1782+
1783+ IniFile difficultyIni = new IniFile ( filePath ) ;
1784+ MapCodeHelper . ApplyMapCode ( mapIni , difficultyIni ) ;
1785+ }
1786+
16991787 foreach ( GameLobbyCheckBox checkBox in CheckBoxes )
17001788 checkBox . ApplyMapCode ( mapIni , GameMode ) ;
17011789
@@ -2197,6 +2285,11 @@ protected virtual void SetMapLabels()
21972285 lblMapAuthor . Text = "By" . L10N ( "Client:Main:AuthorBy" ) + " " + Renderer . GetSafeString ( Map . Author , lblMapAuthor . FontIndex ) ;
21982286 lblGameMode . Text = "Game mode:" . L10N ( "Client:Main:GameModeLabel" ) + " " + GameMode . UIName ;
21992287 lblMapSize . Text = "Size:" . L10N ( "Client:Main:MapSize" ) + " " + Map . GetSizeString ( ) ;
2288+
2289+ if ( GameMode . UseDifficultyDropDown && ddDifficulty != null && ddDifficulty . SelectedIndex >= 0 )
2290+ {
2291+ lblGameMode . Text += " (" + "Difficulty: " . L10N ( "Client:Main:DifficultyLabel" ) + ddDifficulty . SelectedItem . Text + ")" ;
2292+ }
22002293 }
22012294
22022295 /// <summary>
@@ -2215,6 +2308,7 @@ protected virtual void ChangeMap(GameModeMap gameModeMap)
22152308 {
22162309 MapPreviewBox . GameModeMap = null ;
22172310 OnGameOptionChanged ( ) ;
2311+ UpdateDifficultyDropdown ( ) ;
22182312 return ;
22192313 }
22202314
@@ -2227,6 +2321,8 @@ protected virtual void ChangeMap(GameModeMap gameModeMap)
22272321 foreach ( var checkBox in CheckBoxes )
22282322 checkBox . AllowChecking = true ;
22292323
2324+ UpdateDifficultyDropdown ( ) ;
2325+
22302326 // We could either pass the CheckBoxes and DropDowns of this class
22312327 // to the Map and GameMode instances and let them apply their forced
22322328 // options, or we could do it in this class with helper functions.
0 commit comments