Add strategy memo editing

Saves folder getting pretty populated, move to substructures
This commit is contained in:
Kaphotics 2016-09-30 19:05:35 -07:00
parent 97919a5354
commit 7b6ecd11ba
9 changed files with 194 additions and 8 deletions

View file

@ -168,9 +168,9 @@
<Compile Include="Misc\QR.Designer.cs">
<DependentUpon>QR.cs</DependentUpon>
</Compile>
<Compile Include="Saves\BlockInfo.cs" />
<Compile Include="Saves\BoxWallpaper.cs" />
<Compile Include="Saves\Inventory.cs" />
<Compile Include="Saves\Substructures\BlockInfo.cs" />
<Compile Include="Saves\Substructures\BoxWallpaper.cs" />
<Compile Include="Saves\Substructures\Inventory.cs" />
<Compile Include="Saves\SAV2.cs" />
<Compile Include="Saves\SAV1.cs" />
<Compile Include="Saves\SAV3XD.cs" />
@ -183,6 +183,8 @@
<Compile Include="Saves\SAV6.cs" />
<Compile Include="Saves\SaveFile.cs" />
<Compile Include="MysteryGifts\WC6.cs" />
<Compile Include="Saves\Substructures\ShadowInfo.cs" />
<Compile Include="Saves\Substructures\StrategyMemo.cs" />
<Compile Include="Settings.cs" />
<Compile Include="Subforms\PKM Editors\BatchEditor.cs">
<SubType>Form</SubType>
@ -232,7 +234,7 @@
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Saves\SaveObjects.cs" />
<Compile Include="Saves\Substructures\SaveObjects.cs" />
<Compile Include="Saves\SaveUtil.cs" />
<Compile Include="Subforms\Save Editors\Gen5\CGearBackground.cs" />
<Compile Include="Subforms\Save Editors\Gen5\SAV_CGearSkin.cs">

View file

@ -24,6 +24,8 @@ namespace PKHeX
private readonly int SaveCount = -1;
private readonly int SaveIndex = -1;
private readonly StrategyMemo StrategyMemo;
private readonly int Memo;
private readonly ushort[] LegalItems, LegalKeyItems, LegalBalls, LegalTMHMs, LegalBerries, LegalCologne;
private readonly int OFS_PouchCologne;
public SAV3Colosseum(byte[] data = null)
@ -72,6 +74,8 @@ namespace PKHeX
Box = 0x00B90;
Daycare = 0x08170;
Memo = 0x082B0;
StrategyMemo = new StrategyMemo(Data, Memo, xd:false);
LegalItems = Legal.Pouch_Items_COLO;
LegalKeyItems = Legal.Pouch_Key_COLO;
@ -90,6 +94,7 @@ namespace PKHeX
private readonly byte[] OriginalData;
public override byte[] Write(bool DSV)
{
StrategyMemo.FinalData.CopyTo(Data, Memo);
setChecksums();
// Get updated save slot data
@ -267,7 +272,24 @@ namespace PKHeX
return data;
}
protected override void setDex(PKM pkm) { }
protected override void setDex(PKM pkm)
{
// Dex Related
var entry = StrategyMemo.GetEntry(pkm.Species);
if (entry.IsEmpty) // Populate
{
entry.Species = pkm.Species;
entry.PID = pkm.PID;
entry.TID = pkm.TID;
entry.SID = pkm.SID;
}
if (entry.Matches(pkm.Species, pkm.PID, pkm.TID, pkm.SID))
{
entry.Seen = true;
entry.Owned = true;
}
StrategyMemo.SetEntry(entry);
}
private TimeSpan PlayedSpan
{

View file

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace PKHeX
@ -15,6 +16,8 @@ namespace PKHeX
private readonly int SaveCount = -1;
private readonly int SaveIndex = -1;
private readonly int Memo;
private readonly StrategyMemo StrategyMemo;
private readonly ushort[] LegalItems, LegalKeyItems, LegalBalls, LegalTMHMs, LegalBerries, LegalCologne, LegalDisc;
private readonly int OFS_PouchCologne, OFS_PouchDisc;
private readonly int[] subOffsets = new int[16];
@ -67,11 +70,11 @@ namespace PKHeX
Party = Trainer1 + 0x30;
Box = subOffsets[2] + 0xA8;
Daycare = subOffsets[4] + 0xA8;
// Memo = subOffsets[5] + 0xA8;
Memo = subOffsets[5] + 0xA8;
// Shadow = subOffsets[7] + 0xA8;
// Purifier = subOffsets[14] + 0xA8;
System.IO.File.WriteAllBytes("xd", Data);
StrategyMemo = new StrategyMemo(Data, Memo, xd: true);
OFS_PouchHeldItem = Trainer1 + 0x4C8;
OFS_PouchKeyItem = Trainer1 + 0x540;
@ -99,6 +102,8 @@ namespace PKHeX
private readonly byte[] OriginalData;
public override byte[] Write(bool DSV)
{
// Set Memo Back
StrategyMemo.FinalData.CopyTo(Data, Memo);
setChecksums();
// Get updated save slot data
@ -239,7 +244,24 @@ namespace PKHeX
return data;
}
protected override void setDex(PKM pkm) { }
protected override void setDex(PKM pkm)
{
// Dex Related
var entry = StrategyMemo.GetEntry(pkm.Species);
if (entry.IsEmpty) // Populate
{
entry.Species = pkm.Species;
entry.PID = pkm.PID;
entry.TID = pkm.TID;
entry.SID = pkm.SID;
}
if (entry.Matches(pkm.Species, pkm.PID, pkm.TID, pkm.SID))
{
entry.Seen = true;
entry.Owned = true;
}
StrategyMemo.SetEntry(entry);
}
public override InventoryPouch[] Inventory
{

View file

@ -0,0 +1,33 @@
namespace PKHeX
{
public class ShadowInfoXD
{
private readonly byte[] Data;
private const int SIZE_ENTRY = 72;
public ShadowInfoXD(byte[] data)
{
Data = (byte[])(data?.Clone() ?? new byte[SIZE_ENTRY]);
}
public bool IsSnagged => Data[0] >> 6 != 0;
public bool IsPurified { get { return Data[0] >> 7 == 1; } set { Data[0] &= 0x7F; if (value) Data[0] |= 0x80; } }
public ushort Species { get { return BigEndian.ToUInt16(Data, 0x1A); } set { BigEndian.GetBytes(value).CopyTo(Data, 0x1A); } }
public uint PID { get { return BigEndian.ToUInt32(Data, 0x1C); }set { BigEndian.GetBytes(value).CopyTo(Data, 0x1C); } }
public int Purification { get { return BigEndian.ToInt32(Data, 0x24); } set { BigEndian.GetBytes(value).CopyTo(Data, 0x24); } }
public uint EXP { get { return BigEndian.ToUInt32(Data, 0x04) >> 12; } set { BigEndian.GetBytes((BigEndian.ToUInt32(Data, 0x04) & 0xFFF) | (value << 12)).CopyTo(Data, 0x04); } }
}
public class ShadowInfoColo
{
private readonly byte[] Data;
private const int SIZE_ENTRY = 12;
public ShadowInfoColo(byte[] data = null)
{
Data = (byte[])(data?.Clone() ?? new byte[SIZE_ENTRY]);
}
public uint PID { get { return BigEndian.ToUInt32(Data, 0x00); } set { BigEndian.GetBytes(value).CopyTo(Data, 0x00); } }
public int Met_Location { get { return BigEndian.ToUInt16(Data, 0x06); } set { BigEndian.GetBytes((ushort)value).CopyTo(Data, 0x06); } }
public uint _0x08 { get { return BigEndian.ToUInt32(Data, 0x08); } set { BigEndian.GetBytes(value).CopyTo(Data, 0x08); } }
}
}

View file

@ -0,0 +1,107 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace PKHeX
{
public class StrategyMemo
{
private readonly bool XD;
private const int SIZE_ENTRY = 12;
private readonly List<StrategyMemoEntry> Entries = new List<StrategyMemoEntry>();
private StrategyMemoEntry this[int Species] => Entries.FirstOrDefault(e => e.Species == Species);
public StrategyMemo(byte[] input, int offset, bool xd)
{
XD = xd;
int count = BigEndian.ToInt16(input, offset);
if (count > 500)
count = 500;
for (int i = 0; i < count; i++)
{
byte[] data = new byte[SIZE_ENTRY];
Array.Copy(input, 4 + offset + SIZE_ENTRY * i, data, 0, SIZE_ENTRY);
Entries.Add(new StrategyMemoEntry(XD, data));
}
}
public byte[] FinalData => BigEndian.GetBytes(Entries.Count) // count followed by populated entries
.Concat(Entries.Where(entry => entry.Species != 0).SelectMany(entry => entry.Data)).ToArray();
public StrategyMemoEntry GetEntry(int Species)
{
return this[Species] ?? new StrategyMemoEntry(XD);
}
public void SetEntry(StrategyMemoEntry entry)
{
int index = Array.FindIndex(Entries.ToArray(), ent => ent.Species == entry.Species);
if (index > 0)
Entries[index] = entry;
else
Entries.Add(entry);
}
public class StrategyMemoEntry
{
public readonly byte[] Data;
private readonly bool XD;
public StrategyMemoEntry(bool xd, byte[] data = null)
{
Data = data ?? new byte[SIZE_ENTRY];
XD = xd;
}
public int Species
{
get
{
int val = BigEndian.ToUInt16(Data, 0) & 0x1FF;
return PKX.getG4Species(val);
}
set
{
value = PKX.getG3Species(value);
int cval = BigEndian.ToUInt16(Data, 0);
cval &= 0xE00; value &= 0x1FF; cval |= value;
BigEndian.GetBytes((ushort)cval).CopyTo(Data, 0);
}
}
private bool Flag0 { get { return Data[0] >> 6 == 1; } set { Data[0] &= 0xBF; if (value) Data[0] |= 0x40; } } // Unused
private bool Flag1 { get { return Data[0] >> 7 == 1; } set { Data[0] &= 0x7F; if (value) Data[0] |= 0x80; } } // Complete Entry
public int SID { get { return BigEndian.ToUInt16(Data, 4); } set { BigEndian.GetBytes((ushort)value).CopyTo(Data, 4); } }
public int TID { get { return BigEndian.ToUInt16(Data, 6); } set { BigEndian.GetBytes((ushort)value).CopyTo(Data, 6); } }
public uint PID { get { return BigEndian.ToUInt32(Data, 8); } set { BigEndian.GetBytes(value).CopyTo(Data, 8); } }
public bool Seen
{
get
{
if (XD) return !Flag1;
return Species != 0;
}
set
{
if (XD)
Flag1 = !value;
else if (!value)
new byte[SIZE_ENTRY].CopyTo(Data, 0);
}
}
public bool Owned
{
get
{
if (XD) return false;
return Flag0 | Flag1 == false;
}
set
{
if (XD) return;
if (!value)
Flag1 = true;
}
}
public bool IsEmpty => Species == 0;
public bool Matches(int species, uint pid, int tid, int sid) => Species == species && PID == pid && TID == tid && SID == sid;
}
}
}