using System;
using System.Collections.Generic;
namespace PKHeX.Core;
///
/// Miscellaneous setup utility for legality checking data sources.
///
internal static class EncounterUtil
{
internal static ReadOnlySpan Get(string resource) => Util.GetBinaryResource($"encounter_{resource}.pkl");
internal static BinLinkerAccessor Get(string resource, string ident) => BinLinkerAccessor.Get(Get(resource), ident);
///
/// Gets the relevant objects that appear in the relevant game.
///
/// Table of valid encounters that appear for the game pairing
/// Game to filter for
/// Array of encounter objects that can be encountered in the input game
internal static T[] GetEncounters(T[] source, GameVersion game) where T : IVersion
{
return Array.FindAll(source, s => s.Version.Contains(game));
}
///
/// Gets the relevant objects that appear in the relevant game.
///
/// Table of valid encounters that appear for the game pairing
/// Game to filter out
/// Array of encounter objects that can be encountered in the input game
internal static T[] GetEncounters(T[][] source, GameVersion exclude) where T : EncounterStatic
{
var count = 0;
foreach (T[] arr in source)
count += arr.Length;
var temp = new T[count];
count = 0;
foreach (var arr in source)
{
foreach (var enc in arr)
{
if (enc.Version != exclude)
temp[count++] = enc;
}
}
Array.Resize(ref temp, count);
return temp;
}
internal static T? GetMinByLevel(EvoCriteria[] chain, IEnumerable possible) where T : class, IEncounterTemplate
{
// MinBy grading: prefer species-form match, select lowest min level encounter.
// Minimum allocation :)
T? result = null;
int min = int.MaxValue;
foreach (var enc in possible)
{
int m = int.MaxValue;
foreach (var evo in chain)
{
bool specDiff = enc.Species != evo.Species || enc.Form != evo.Form;
var val = (Convert.ToInt32(specDiff) << 16) | enc.LevelMin;
if (val < m)
m = val;
}
if (m >= min)
continue;
min = m;
result = enc;
}
return result;
}
///
/// Loads the language string lists into the objects.
///
/// Encounter template type
/// Trade templates
/// Localization strings, grouped by language.
///
/// The first half of strings in the language resource array are
/// The second half of strings in the language resource strings are
///
internal static void MarkEncounterTradeStrings(T[] table, ReadOnlySpan strings) where T : EncounterTrade
{
uint languageCount = (uint)strings[1].Length / 2;
for (uint i = 0; i < languageCount; i++)
{
var t = table[i];
t.Nicknames = GetNamesForLanguage(strings, i);
t.TrainerNames = GetNamesForLanguage(strings, languageCount + i);
}
}
///
/// Loads the language string lists into the objects.
///
/// Encounter template type
/// Trade templates
/// Localization strings, grouped by language.
internal static void MarkEncounterTradeNicknames(T[] table, ReadOnlySpan strings) where T : EncounterTrade
{
for (uint i = 0; i < table.Length; i++)
{
var t = table[i];
t.Nicknames = GetNamesForLanguage(strings, i);
}
}
///
/// Grabs the localized names for individual templates for all languages from the specified of the list.
///
/// Arrays of strings grouped by language
/// Index to grab from the language arrays
/// Row of localized strings for the template.
private static string[] GetNamesForLanguage(ReadOnlySpan names, uint index)
{
var result = new string[names.Length];
for (int i = 0; i < result.Length; i++)
{
var arr = names[i];
result[i] = index < arr.Length ? arr[index] : string.Empty;
}
return result;
}
}