using System; using static PKHeX.Core.Species; namespace PKHeX.Core { /// /// Alternate form data has an associated value. /// /// /// How long (days) the form can last before reverting to Form-0 (5 days max) /// : How long (days) the form can last before reverting to Form-0 (3 days max) /// : Topping (Strawberry, Star, etc); [0,7] /// How much damage the Pokémon has taken as Yamask-1 [0,9999]. /// How much damage the Pokémon has taken as Yamask-1 [0,9999]. /// public interface IFormArgument { /// /// Argument for the associated /// uint FormArgument { get; set; } /// /// Amount of days the timed will remain active for. /// byte FormArgumentRemain { get; set; } /// /// Amount of days the timed has been active for. /// byte FormArgumentElapsed { get; set; } /// /// Maximum amount of days the has maintained a without reverting to its base form. /// byte FormArgumentMaximum { get; set; } } /// /// Logic for mutating an object. /// public static class FormArgumentUtil { /// /// Sets the suggested Form Argument to the . /// public static void SetSuggestedFormArgument(this PKM pkm, int originalSpecies = 0) { if (pkm is not IFormArgument) return; if (!IsFormArgumentTypeDatePair(pkm.Species, pkm.Form)) { var suggest = originalSpecies switch { (int) Yamask when pkm.Species == (int) Runerigus => 49u, _ => 0u, }; pkm.ChangeFormArgument(suggest); return; } var max = GetFormArgumentMax(pkm.Species, pkm.Form, pkm.Format); pkm.ChangeFormArgument(max); } /// /// Modifies the values for the provided to the requested . /// public static void ChangeFormArgument(this PKM pkm, uint value) { if (pkm is not IFormArgument f) return; f.ChangeFormArgument(pkm.Species, pkm.Form, pkm.Format, value); } /// /// Modifies the values for the provided inputs to the requested . /// /// Form Argument object /// Entity Species /// Entity Species /// Entity current format generation /// Value to apply public static void ChangeFormArgument(this IFormArgument f, int species, int form, int generation, uint value) { if (!IsFormArgumentTypeDatePair(species, form)) { f.FormArgument = value; return; } var max = GetFormArgumentMax(species, form, generation); f.FormArgumentRemain = (byte)value; if (value == max) { f.FormArgumentElapsed = f.FormArgumentMaximum = 0; return; } byte elapsed = max < value ? 0 : (byte)(max - value); f.FormArgumentElapsed = elapsed; if (species == (int)Furfrou) f.FormArgumentMaximum = Math.Max(f.FormArgumentMaximum, elapsed); } public static uint GetFormArgumentMax(int species, int form, int generation) { if (generation <= 5) return 0; return species switch { (int)Furfrou when form != 0 => 5, (int)Hoopa when form == 1 => 3, (int)Yamask when form == 1 => 9999, (int)Runerigus when form == 0 => 9999, (int)Alcremie => (uint)AlcremieDecoration.Ribbon, _ => 0, }; } public static bool IsFormArgumentTypeDatePair(int species, int form) { return species switch { (int)Furfrou when form != 0 => true, (int)Hoopa when form == 1 => true, _ => false, }; } } }