@@ -117,6 +117,20 @@ public record PlayerInfo
117117 private const string MysteryRaidTitle = "Mystery Shiny Raid" ;
118118 private const string UserRequestedRaidSuffix = "'s Requested Raid" ;
119119
120+ // Region boundary constants for raid index calculations
121+ private const int PaldeaRaidCount = 69 ;
122+ private const int KitakamiRaidCount = 25 ;
123+ private const int KitakamiStartIndex = PaldeaRaidCount ;
124+ private const int BlueberryStartIndex = PaldeaRaidCount + KitakamiRaidCount ;
125+
126+ // Cached den locations to avoid repeated JSON loading
127+ private static readonly Lazy < Dictionary < string , float [ ] > > CachedPaldeaDenLocations = new ( ( ) =>
128+ LoadDenLocations ( "SysBot.Pokemon.SV.BotRaid.DenLocations.den_locations_base.json" ) ) ;
129+ private static readonly Lazy < Dictionary < string , float [ ] > > CachedKitakamiDenLocations = new ( ( ) =>
130+ LoadDenLocations ( "SysBot.Pokemon.SV.BotRaid.DenLocations.den_locations_kitakami.json" ) ) ;
131+ private static readonly Lazy < Dictionary < string , float [ ] > > CachedBlueberryDenLocations = new ( ( ) =>
132+ LoadDenLocations ( "SysBot.Pokemon.SV.BotRaid.DenLocations.den_locations_blueberry.json" ) ) ;
133+
120134 /// <summary>
121135 /// Main execution loop for the raid bot
122136 /// </summary>
@@ -2381,7 +2395,6 @@ private async Task<int> PrepareForRaid(CancellationToken token)
23812395 return 2 ;
23822396 }
23832397
2384- _ = _settings . ActiveRaids [ _currentRaidIndex ] ;
23852398 var currentSeed = _settings . ActiveRaids [ _currentRaidIndex ] . Seed . ToUpper ( ) ;
23862399
23872400 if ( ! _denHexSeed . Equals ( currentSeed , StringComparison . CurrentCultureIgnoreCase ) )
@@ -3060,7 +3073,7 @@ private static async Task<bool> IsValidImageUrlAsync(string url)
30603073 }
30613074 }
30623075
3063- private readonly Dictionary < string , string > _typeAdvantages = new ( )
3076+ private static readonly Dictionary < string , string > TypeAdvantages = new ( )
30643077 {
30653078 { "normal" , "Fighting" } ,
30663079 { "fire" , "Water, Ground, Rock" } ,
@@ -3089,7 +3102,7 @@ private string GetTypeAdvantage(string teraType)
30893102 {
30903103 string englishTypeName = GetEnglishTypeNameFromLocalized ( teraType ) ;
30913104
3092- if ( _typeAdvantages . TryGetValue ( englishTypeName . ToLower ( ) , out string advantage ) )
3105+ if ( TypeAdvantages . TryGetValue ( englishTypeName . ToLower ( ) , out string ? advantage ) )
30933106 {
30943107 return advantage ;
30953108 }
@@ -3101,7 +3114,7 @@ private string GetTypeAdvantage(string teraType)
31013114 /// </summary>
31023115 private string GetEnglishTypeNameFromLocalized ( string teraType )
31033116 {
3104- if ( _typeAdvantages . ContainsKey ( teraType . ToLower ( ) ) )
3117+ if ( TypeAdvantages . ContainsKey ( teraType . ToLower ( ) ) )
31053118 return teraType . ToLower ( ) ;
31063119 var englishStrings = GameInfo . GetStrings ( 2 ) ;
31073120 var localizedStrings = GameInfo . GetStrings ( ( int ) _settings . EmbedToggles . EmbedLanguage ) ;
@@ -4253,6 +4266,20 @@ private static Dictionary<string, float[]> LoadDenLocations(string resourceName)
42534266 return denLocations ;
42544267 }
42554268
4269+ /// <summary>
4270+ /// Gets cached den locations for the specified map type
4271+ /// </summary>
4272+ private static Dictionary < string , float [ ] > GetCachedDenLocations ( TeraRaidMapParent mapType )
4273+ {
4274+ return mapType switch
4275+ {
4276+ TeraRaidMapParent . Paldea => CachedPaldeaDenLocations . Value ,
4277+ TeraRaidMapParent . Kitakami => CachedKitakamiDenLocations . Value ,
4278+ TeraRaidMapParent . Blueberry => CachedBlueberryDenLocations . Value ,
4279+ _ => throw new ArgumentException ( "Invalid map type" , nameof ( mapType ) )
4280+ } ;
4281+ }
4282+
42564283 /// <summary>
42574284 /// Finds the nearest den location to the player
42584285 /// </summary>
@@ -4377,10 +4404,10 @@ private async Task LogPlayerLocation(CancellationToken token)
43774404 {
43784405 var playerLocation = await GetPlayersLocation ( token ) ;
43794406
4380- // Load den locations for all regions
4381- var blueberryLocations = LoadDenLocations ( "SysBot.Pokemon.SV.BotRaid.DenLocations.den_locations_blueberry.json" ) ;
4382- var kitakamiLocations = LoadDenLocations ( "SysBot.Pokemon.SV.BotRaid.DenLocations.den_locations_kitakami.json" ) ;
4383- var baseLocations = LoadDenLocations ( "SysBot.Pokemon.SV.BotRaid.DenLocations.den_locations_base.json" ) ;
4407+ // Use cached den locations for all regions
4408+ var blueberryLocations = GetCachedDenLocations ( TeraRaidMapParent . Blueberry ) ;
4409+ var kitakamiLocations = GetCachedDenLocations ( TeraRaidMapParent . Kitakami ) ;
4410+ var baseLocations = GetCachedDenLocations ( TeraRaidMapParent . Paldea ) ;
43844411
43854412 // Find the nearest location for each set and keep track of the overall nearest
43864413 var nearestDen = new Dictionary < string , string >
@@ -4394,15 +4421,15 @@ private async Task LogPlayerLocation(CancellationToken token)
43944421 . Where ( kv => ! string . IsNullOrEmpty ( kv . Value ) )
43954422 . Select ( kv =>
43964423 {
4397- Dictionary < string , float [ ] > ? denLocations = kv . Key switch
4424+ var denLocations = GetCachedDenLocations ( kv . Key switch
43984425 {
4399- "Blueberry" => blueberryLocations ,
4400- "Kitakami" => kitakamiLocations ,
4401- "Paldea" => baseLocations ,
4402- _ => null
4403- } ;
4426+ "Blueberry" => TeraRaidMapParent . Blueberry ,
4427+ "Kitakami" => TeraRaidMapParent . Kitakami ,
4428+ "Paldea" => TeraRaidMapParent . Paldea ,
4429+ _ => TeraRaidMapParent . Paldea
4430+ } ) ;
44044431
4405- if ( denLocations == null || ! denLocations . TryGetValue ( kv . Value , out var denLocationArray ) )
4432+ if ( ! denLocations . TryGetValue ( kv . Value , out var denLocationArray ) )
44064433 return null ;
44074434
44084435 var denLocationTuple = ( denLocationArray [ 0 ] , denLocationArray [ 1 ] , denLocationArray [ 2 ] ) ;
@@ -4479,22 +4506,17 @@ private async Task LogPlayerLocation(CancellationToken token)
44794506 // Read the raw raid data for the region
44804507 byte [ ] raidData = await ReadRaidsForRegion ( mapType , token ) ;
44814508
4482- Dictionary < string , float [ ] > denLocations = mapType switch
4483- {
4484- TeraRaidMapParent . Paldea => LoadDenLocations ( "SysBot.Pokemon.SV.BotRaid.DenLocations.den_locations_base.json" ) ,
4485- TeraRaidMapParent . Kitakami => LoadDenLocations ( "SysBot.Pokemon.SV.BotRaid.DenLocations.den_locations_kitakami.json" ) ,
4486- TeraRaidMapParent . Blueberry => LoadDenLocations ( "SysBot.Pokemon.SV.BotRaid.DenLocations.den_locations_blueberry.json" ) ,
4487- _ => throw new InvalidOperationException ( "Invalid region" )
4488- } ;
4509+ // Use cached den locations
4510+ var denLocations = GetCachedDenLocations ( mapType ) ;
44894511
44904512 var activeRaids = new List < ( string DenIdentifier , float [ ] Coordinates , int Index , uint Seed , uint Flags , bool IsEvent ) > ( ) ;
44914513
44924514 // Calculate the starting index offset based on the map type
44934515 int startingIndex = mapType switch
44944516 {
44954517 TeraRaidMapParent . Paldea => 0 ,
4496- TeraRaidMapParent . Kitakami => 69 ,
4497- TeraRaidMapParent . Blueberry => 94 ,
4518+ TeraRaidMapParent . Kitakami => KitakamiStartIndex ,
4519+ TeraRaidMapParent . Blueberry => BlueberryStartIndex ,
44984520 _ => 0
44994521 } ;
45004522
@@ -4533,48 +4555,19 @@ private async Task WriteProgressLive(GameProgress progress)
45334555 if ( Connection is null )
45344556 return ;
45354557
4536- if ( progress >= GameProgress . Unlocked3Stars )
4537- {
4538- var toexpect = ( bool ? ) await ReadBlock ( RaidDataBlocks . KUnlockedRaidDifficulty3 , CancellationToken . None ) ;
4539- await WriteBlock ( true , RaidDataBlocks . KUnlockedRaidDifficulty3 , CancellationToken . None , toexpect ) ;
4540- }
4541- else
4542- {
4543- var toexpect = ( bool ? ) await ReadBlock ( RaidDataBlocks . KUnlockedRaidDifficulty3 , CancellationToken . None ) ;
4544- await WriteBlock ( false , RaidDataBlocks . KUnlockedRaidDifficulty3 , CancellationToken . None , toexpect ) ;
4545- }
4546-
4547- if ( progress >= GameProgress . Unlocked4Stars )
4548- {
4549- var toexpect = ( bool ? ) await ReadBlock ( RaidDataBlocks . KUnlockedRaidDifficulty4 , CancellationToken . None ) ;
4550- await WriteBlock ( true , RaidDataBlocks . KUnlockedRaidDifficulty4 , CancellationToken . None , toexpect ) ;
4551- }
4552- else
4558+ var difficultyBlocks = new [ ]
45534559 {
4554- var toexpect = ( bool ? ) await ReadBlock ( RaidDataBlocks . KUnlockedRaidDifficulty4 , CancellationToken . None ) ;
4555- await WriteBlock ( false , RaidDataBlocks . KUnlockedRaidDifficulty4 , CancellationToken . None , toexpect ) ;
4556- }
4557-
4558- if ( progress >= GameProgress . Unlocked5Stars )
4559- {
4560- var toexpect = ( bool ? ) await ReadBlock ( RaidDataBlocks . KUnlockedRaidDifficulty5 , CancellationToken . None ) ;
4561- await WriteBlock ( true , RaidDataBlocks . KUnlockedRaidDifficulty5 , CancellationToken . None , toexpect ) ;
4562- }
4563- else
4564- {
4565- var toexpect = ( bool ? ) await ReadBlock ( RaidDataBlocks . KUnlockedRaidDifficulty5 , CancellationToken . None ) ;
4566- await WriteBlock ( false , RaidDataBlocks . KUnlockedRaidDifficulty5 , CancellationToken . None , toexpect ) ;
4567- }
4560+ ( GameProgress . Unlocked3Stars , RaidDataBlocks . KUnlockedRaidDifficulty3 ) ,
4561+ ( GameProgress . Unlocked4Stars , RaidDataBlocks . KUnlockedRaidDifficulty4 ) ,
4562+ ( GameProgress . Unlocked5Stars , RaidDataBlocks . KUnlockedRaidDifficulty5 ) ,
4563+ ( GameProgress . Unlocked6Stars , RaidDataBlocks . KUnlockedRaidDifficulty6 ) ,
4564+ } ;
45684565
4569- if ( progress >= GameProgress . Unlocked6Stars )
4566+ foreach ( var ( requiredProgress , block ) in difficultyBlocks )
45704567 {
4571- var toexpect = ( bool ? ) await ReadBlock ( RaidDataBlocks . KUnlockedRaidDifficulty6 , CancellationToken . None ) ;
4572- await WriteBlock ( true , RaidDataBlocks . KUnlockedRaidDifficulty6 , CancellationToken . None , toexpect ) ;
4573- }
4574- else
4575- {
4576- var toexpect = ( bool ? ) await ReadBlock ( RaidDataBlocks . KUnlockedRaidDifficulty6 , CancellationToken . None ) ;
4577- await WriteBlock ( false , RaidDataBlocks . KUnlockedRaidDifficulty6 , CancellationToken . None , toexpect ) ;
4568+ bool shouldUnlock = progress >= requiredProgress ;
4569+ var toexpect = ( bool ? ) await ReadBlock ( block , CancellationToken . None ) ;
4570+ await WriteBlock ( shouldUnlock , block , CancellationToken . None , toexpect ) ;
45784571 }
45794572 }
45804573
@@ -4919,15 +4912,11 @@ private static (PK9, uint) IsSeedReturned(ITeraRaid encounter, Raid raid)
49194912 /// </summary>
49204913 private async Task FindSeedIndexInRaids ( uint denHexSeedUInt , CancellationToken token )
49214914 {
4922- const int kitakamiDensCount = 25 ;
4923- int upperBound = kitakamiDensCount == 25 ? 94 : 95 ;
4924- int startIndex = kitakamiDensCount == 25 ? 94 : 95 ;
4925-
49264915 // Search in Paldea region
49274916 var dataP = await SwitchConnection . ReadBytesAbsoluteAsync ( _raidBlockPointerP , 2304 , token ) . ConfigureAwait ( false ) ;
4928- for ( int i = 0 ; i < 69 ; i ++ )
4917+ for ( int i = 0 ; i < PaldeaRaidCount ; i ++ )
49294918 {
4930- var seed = BitConverter . ToUInt32 ( dataP . AsSpan ( 0x20 + i * 0x20 , 4 ) ) ;
4919+ var seed = BitConverter . ToUInt32 ( dataP . AsSpan ( Raid . SIZE + i * Raid . SIZE , 4 ) ) ;
49314920 if ( seed == denHexSeedUInt )
49324921 {
49334922 _seedIndexToReplace = i ;
@@ -4937,21 +4926,21 @@ private async Task FindSeedIndexInRaids(uint denHexSeedUInt, CancellationToken t
49374926
49384927 // Search in Kitakami region
49394928 var dataK = await SwitchConnection . ReadBytesAbsoluteAsync ( _raidBlockPointerK + 0x10 , 0xC80 , token ) . ConfigureAwait ( false ) ;
4940- for ( int i = 0 ; i < upperBound ; i ++ )
4929+ for ( int i = 0 ; i < BlueberryStartIndex ; i ++ )
49414930 {
4942- var seed = BitConverter . ToUInt32 ( dataK . AsSpan ( i * 0x20 , 4 ) ) ;
4931+ var seed = BitConverter . ToUInt32 ( dataK . AsSpan ( i * Raid . SIZE , 4 ) ) ;
49434932 if ( seed == denHexSeedUInt )
49444933 {
4945- _seedIndexToReplace = i + 69 ;
4934+ _seedIndexToReplace = i + KitakamiStartIndex ;
49464935 return ;
49474936 }
49484937 }
49494938
49504939 // Search in Blueberry region
49514940 var dataB = await SwitchConnection . ReadBytesAbsoluteAsync ( _raidBlockPointerB + 0x10 , 0xA00 , token ) . ConfigureAwait ( false ) ;
4952- for ( int i = startIndex ; i < 118 ; i ++ )
4941+ for ( int i = BlueberryStartIndex ; i < 118 ; i ++ )
49534942 {
4954- var seed = BitConverter . ToUInt32 ( dataB . AsSpan ( ( i - startIndex ) * 0x20 , 4 ) ) ;
4943+ var seed = BitConverter . ToUInt32 ( dataB . AsSpan ( ( i - BlueberryStartIndex ) * Raid . SIZE , 4 ) ) ;
49554944 if ( seed == denHexSeedUInt )
49564945 {
49574946 _seedIndexToReplace = i - 1 ;
0 commit comments