mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-27 06:20:25 +00:00
Add strategy memo editing
Saves folder getting pretty populated, move to substructures
This commit is contained in:
parent
97919a5354
commit
7b6ecd11ba
9 changed files with 194 additions and 8 deletions
|
@ -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">
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
33
PKHeX/Saves/Substructures/ShadowInfo.cs
Normal file
33
PKHeX/Saves/Substructures/ShadowInfo.cs
Normal 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); } }
|
||||
}
|
||||
}
|
107
PKHeX/Saves/Substructures/StrategyMemo.cs
Normal file
107
PKHeX/Saves/Substructures/StrategyMemo.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue