Skip to content

Commit

Permalink
Update 21.11.19 - Brilliant Diamond & Shining Pearl (#3289)
Browse files Browse the repository at this point in the history
Big thanks to @SciresM @sora10pls @Lusamine @architdate @ReignOfComputer for testing and contributing code / test cases. Can't add co-authors from the PR menu :(

Builds will fail because azure pipelines not yet updated with net6.
  • Loading branch information
kwsch committed Nov 20, 2021
1 parent 5cff79f commit 723514e
Show file tree
Hide file tree
Showing 242 changed files with 15,669 additions and 763 deletions.
14 changes: 14 additions & 0 deletions PKHeX.Core/Editing/Applicators/MoveSetApplicator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,20 @@ public static IReadOnlyList<int> GetSuggestedRelearnMoves(this LegalityAnalysis
}
}

if (enc is EncounterSlot8b { IsUnderground: true } ug)
{
var moves = legal.Info.Moves;
for (int i = 0; i < moves.Length; i++)
{
if (!moves[i].ShouldBeInRelearnMoves())
continue;

var move = legal.pkm.GetMove(i);
if (ug.CanBeUndergroundMove(move))
return new[] { move, 0, 0, 0 };
}
}

var encounter = EncounterSuggestion.GetSuggestedMetInfo(legal.pkm);
if (encounter is IRelearn {Relearn: {Count: > 0} r})
return r;
Expand Down
2 changes: 1 addition & 1 deletion PKHeX.Core/Editing/CommonEdits.cs
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ public static void SetEggMetData(this PKM pk, GameVersion origin, GameVersion de
{
bool traded = origin == dest;
var today = pk.MetDate = DateTime.Today;
pk.Egg_Location = EncounterSuggestion.GetSuggestedEncounterEggLocationEgg(pk.Generation, traded);
pk.Egg_Location = EncounterSuggestion.GetSuggestedEncounterEggLocationEgg(pk.Generation, origin, traded);
pk.EggMetDate = today;
}

Expand Down
125 changes: 125 additions & 0 deletions PKHeX.Core/Editing/Saves/Editors/EventOld/EventLabelCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,131 @@ private static int TryParseHexDecConst(string c)
};
}

public sealed class EventLabelCollectionSystem
{
public readonly IReadOnlyList<NamedEventWork> Work;
public readonly IReadOnlyList<NamedEventValue> Flag;
public readonly IReadOnlyList<NamedEventValue> System;

public EventLabelCollectionSystem(string game, int maxFlag = int.MaxValue, int maxSystem = int.MaxValue, int maxValue = int.MaxValue)
{
var f = GameLanguage.GetStrings(game, GameInfo.CurrentLanguage, "flag");
var s = GameLanguage.GetStrings(game, GameInfo.CurrentLanguage, "system");
var c = GameLanguage.GetStrings(game, GameInfo.CurrentLanguage, "work");
Flag = GetFlags(f, maxFlag);
System = GetFlags(s, maxSystem);
Work = GetValues(c, maxValue);
}

private static List<NamedEventValue> GetFlags(IReadOnlyCollection<string> strings, int maxValue)
{
var result = new List<NamedEventValue>(strings.Count);
var processed = new HashSet<int>();
foreach (var s in strings)
{
var split = s.Split('\t');
if (split.Length != 3)
continue;

var index = TryParseHexDec(split[0]);
if (index >= maxValue)
throw new ArgumentOutOfRangeException(nameof(index));

if (processed.Contains(index))
throw new ArgumentException("Already have an entry for this!", nameof(index));

var type = GetEventType(split[1]);
var desc = split[2];

var item = new NamedEventValue(desc, index, type);
result.Add(item);
processed.Add(index);
}

return result;
}

private static readonly NamedEventConst Custom = new("Custom", NamedEventConst.CustomMagicValue);
private static readonly NamedEventConst[] Empty = { Custom };

private static IReadOnlyList<NamedEventWork> GetValues(IReadOnlyCollection<string> strings, int maxValue)
{
var result = new List<NamedEventWork>(strings.Count);
var processed = new HashSet<int>();
foreach (var s in strings)
{
var split = s.Split('\t');
if (split.Length is not (3 or 4))
continue;

var index = TryParseHexDecConst(split[0]);
if (index >= maxValue)
throw new ArgumentOutOfRangeException(nameof(index));

if (processed.Contains(index))
throw new ArgumentException("Already have an entry for this!", nameof(index));

var type = GetEventType(split[1]);
var desc = split[2];
var predefined = split.Length is 3 ? Empty : GetPredefinedArray(split[3]);
var item = new NamedEventWork(desc, index, type, predefined);
result.Add(item);
processed.Add(index);
}

return result;
}

private static IReadOnlyList<NamedEventConst> GetPredefinedArray(string combined)
{
var result = new List<NamedEventConst> { Custom };
var split = combined.Split(',');
foreach (var entry in split)
{
var subsplit = entry.Split(':');
var name = subsplit[1];
var value = Convert.ToUInt16(subsplit[0]);
result.Add(new NamedEventConst(name, value));
}
return result;
}

private static int TryParseHexDec(string flag)
{
if (!flag.StartsWith("0x"))
return Convert.ToInt16(flag);
flag = flag[2..];
return Convert.ToInt16(flag, 16);
}

private static int TryParseHexDecConst(string c)
{
if (!c.StartsWith("0x40"))
return Convert.ToInt16(c);
c = c[4..];
return Convert.ToInt16(c, 16);
}

private static NamedEventType GetEventType(string s) => s.Length == 0 ? 0 : GetEventType(s[0]);

private static NamedEventType GetEventType(char c) => c switch
{
'h' => NamedEventType.HiddenItem,
'm' => NamedEventType.Misc,
'f' => NamedEventType.FlyToggle,
't' => NamedEventType.TrainerToggle,
's' => NamedEventType.StoryProgress,

'a' => NamedEventType.Achievement,
'+' => NamedEventType.Statistic,
'*' => NamedEventType.UsefulFeature,
'e' => NamedEventType.EncounterEvent,
'g' => NamedEventType.GiftAvailable,
'r' => NamedEventType.Rebattle,
_ => NamedEventType.None,
};
}

public enum NamedEventType
{
None,
Expand Down
109 changes: 109 additions & 0 deletions PKHeX.Core/Editing/Saves/Editors/EventWork/EventWorkDiff.cs
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,113 @@ public WorkSummary(int rawIndex, EventWork7b ew, string text)
}
}
}

public sealed class EventWorkDiff8b : EventBlockDiff
{
public readonly List<int> WorkChanged = new();
private SaveFile? S1;
public readonly List<int> SetSystem = new();
public readonly List<int> ClearedSystem = new();

public EventWorkDiff8b(string f1, string f2)
{
if (!SanityCheckFiles(f1, f2))
return;
var s1 = SaveUtil.GetVariantSAV(f1);
var s2 = SaveUtil.GetVariantSAV(f2);
if (s1 == null || s2 == null || s1.GetType() != s2.GetType())
{
Message = MsgSaveDifferentTypes;
return;
}
Diff(s1, s2);
}

public EventWorkDiff8b(SaveFile s1, SaveFile s2) => Diff(s1, s2);

protected override void Diff(SaveFile s1, SaveFile s2)
{
if (!SanityCheckSaveInfo(s1, s2))
return;

EventWorkUtil.DiffSavesFlag(((SAV8BS)s1).Work, ((SAV8BS)s2).Work, SetFlags, ClearedFlags);
EventWorkUtil.DiffSavesSystem(((SAV8BS)s1).Work, ((SAV8BS)s2).Work, SetSystem, ClearedSystem);
EventWorkUtil.DiffSavesWork(((SAV8BS)s1).Work, ((SAV8BS)s2).Work, WorkChanged, WorkDiff);
S1 = s1;
}

public IReadOnlyList<string> Summarize()
{
if (S1 == null)
return Array.Empty<string>();

var fOn = SetFlags.Select(z => new FlagSummary(z).ToString());
var fOff = ClearedFlags.Select(z => new FlagSummary(z).ToString());

var sOn = SetSystem.Select(z => new FlagSummary(z).ToString());
var sOff = ClearedSystem.Select(z => new FlagSummary(z).ToString());

var wt = WorkChanged.Select((z, i) => new WorkSummary(z, WorkDiff[i]).ToString());

var list = new List<string> { "Flags: ON", "=========" };
list.AddRange(fOn);
if (SetFlags.Count == 0)
list.Add("None.");

list.Add("");
list.Add("Flags: OFF");
list.Add("==========");
list.AddRange(fOff);
if (ClearedFlags.Count == 0)
list.Add("None.");

list.Add("System: ON");
list.Add("=========");
list.AddRange(sOn);
if (SetFlags.Count == 0)
list.Add("None.");

list.Add("");
list.Add("System: OFF");
list.Add("==========");
list.AddRange(sOff);
if (ClearedSystem.Count == 0)
list.Add("None.");

list.Add("");
list.Add("Work:");
list.Add("=====");
if (WorkChanged.Count == 0)
list.Add("None.");
list.AddRange(wt);

return list;
}

private readonly struct FlagSummary
{
private int Raw { get; }

public override string ToString() => $"{Raw:0000}\t{false}";

public FlagSummary(int rawIndex)
{
Raw = rawIndex;
}
}

private readonly struct WorkSummary
{
private int Raw { get; }
private string Text { get; }

public override string ToString() => $"{Raw:000}\t{Text}";

public WorkSummary(int rawIndex, string text)
{
Raw = rawIndex;
Text = text;
}
}
}
}
31 changes: 26 additions & 5 deletions PKHeX.Core/Editing/Saves/Editors/EventWork/EventWorkUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,13 @@ public static List<EventVarGroup> GetVars(IEnumerable<string> lines, Func<int, E
/// <summary>
/// Compares a <see cref="before"/> and <see cref="after"/> <see cref="IEventWork{T}"/> object of the same type to find <see cref="EventFlag"/> changes.
/// </summary>
/// <typeparam name="T">Type of value used by <see cref="EventWork{T}"/></typeparam>
/// <param name="before">Data before the event was triggered</param>
/// <param name="after">Data after the event was triggered</param>
/// <param name="on">List of flags that were turned on</param>
/// <param name="off">List of flags that were turned off</param>
public static void DiffSavesFlag<T>(IEventWork<T> before, IEventWork<T> after, List<int> on, List<int> off)
public static void DiffSavesFlag(IEventFlag before, IEventFlag after, List<int> on, List<int> off)
{
int max = before.MaxFlag;
int max = before.CountFlag;
for (int i = 0; i < max; i++)
{
var b = before.GetFlag(i);
Expand All @@ -90,6 +89,28 @@ public static void DiffSavesFlag<T>(IEventWork<T> before, IEventWork<T> after, L
}
}

/// <summary>
/// Compares a <see cref="before"/> and <see cref="after"/> <see cref="IEventWork{T}"/> object of the same type to find <see cref="EventFlag"/> changes.
/// </summary>
/// <param name="before">Data before the event was triggered</param>
/// <param name="after">Data after the event was triggered</param>
/// <param name="on">List of flags that were turned on</param>
/// <param name="off">List of flags that were turned off</param>
public static void DiffSavesSystem(ISystemFlag before, ISystemFlag after, List<int> on, List<int> off)
{
int max = before.CountSystem;
for (int i = 0; i < max; i++)
{
var b = before.GetSystemFlag(i);
var a = after.GetSystemFlag(i);
if (b == a)
continue;

var arr = a ? on : off;
arr.Add(i);
}
}

/// <summary>
/// Compares a <see cref="before"/> and <see cref="after"/> <see cref="IEventWork{T}"/> object of the same type to find <see cref="EventWork{T}"/> changes.
/// </summary>
Expand All @@ -100,7 +121,7 @@ public static void DiffSavesFlag<T>(IEventWork<T> before, IEventWork<T> after, L
/// <param name="changes">Summary of the <see cref="EventWork{T}"/> value change</param>
public static void DiffSavesWork<T>(IEventWork<T> before, IEventWork<T> after, List<int> changed, List<string> changes)
{
int max = before.MaxWork;
int max = before.CountWork;
for (int i = 0; i < max; i++)
{
var b = before.GetWork(i);
Expand All @@ -113,4 +134,4 @@ public static void DiffSavesWork<T>(IEventWork<T> before, IEventWork<T> after, L
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ public sealed class SplitEventEditor<T> where T : struct
{
public readonly IList<EventVarGroup> Work;
public readonly IList<EventVarGroup> Flag;
public readonly IEventWork<T> Block;
public readonly IEventVar<T> Block;

public SplitEventEditor(IEventWork<T> block, IEnumerable<string> work, IEnumerable<string> flag)
public SplitEventEditor(IEventVar<T> block, IEnumerable<string> work, IEnumerable<string> flag)
{
Block = block;
// load lines
Expand Down
16 changes: 16 additions & 0 deletions PKHeX.Core/Editing/Saves/Slots/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public static List<SlotInfoMisc> GetExtraSlots(this SaveFile sav, bool all = fal
SAV7 sav7 => GetExtraSlots7(sav7, all),
SAV7b lgpe => GetExtraSlots7b(lgpe),
SAV8SWSH ss => GetExtraSlots8(ss),
SAV8BS bs => GetExtraSlots8b(bs),
_ => None,
};

Expand Down Expand Up @@ -201,5 +202,20 @@ private static List<SlotInfoMisc> GetExtraSlots8(ISaveBlock8Main sav)

return list;
}

private static List<SlotInfoMisc> GetExtraSlots8b(SAV8BS sav)
{
return new()
{
new SlotInfoMisc(sav.Data, 0, 0x96080, true) { Type = StorageSlotType.Daycare },
new SlotInfoMisc(sav.Data, 1, 0x96080 + PokeCrypto.SIZE_8PARTY, true) { Type = StorageSlotType.Daycare },

new SlotInfoMisc(sav.Data, 0, 0x9A8E8 + (0 * PokeCrypto.SIZE_8PARTY), true) { Type = StorageSlotType.Misc },
new SlotInfoMisc(sav.Data, 1, 0x9A8E8 + (1 * PokeCrypto.SIZE_8PARTY), true) { Type = StorageSlotType.Misc },
new SlotInfoMisc(sav.Data, 2, 0x9A8E8 + (2 * PokeCrypto.SIZE_8PARTY), true) { Type = StorageSlotType.Misc },
new SlotInfoMisc(sav.Data, 3, 0x9A8E8 + (3 * PokeCrypto.SIZE_8PARTY), true) { Type = StorageSlotType.Misc },
new SlotInfoMisc(sav.Data, 4, 0x9A8E8 + (4 * PokeCrypto.SIZE_8PARTY), true) { Type = StorageSlotType.Misc },
};
}
}
}
Loading

0 comments on commit 723514e

Please sign in to comment.