diff --git a/PKHeX.Core/Saves/SAV4DP.cs b/PKHeX.Core/Saves/SAV4DP.cs index 21c535542..bc8c028f6 100644 --- a/PKHeX.Core/Saves/SAV4DP.cs +++ b/PKHeX.Core/Saves/SAV4DP.cs @@ -55,7 +55,7 @@ private void GetSAVOffsets() OFS_UG_Stats = 0x3A2C; - _currentPoketchApp = 0x114E; + PoketchStart = 0x114C; Seal = 0x6178; OFS_PoffinCase = 0x5050; diff --git a/PKHeX.Core/Saves/SAV4Pt.cs b/PKHeX.Core/Saves/SAV4Pt.cs index 36ade5d0d..be3d8cdaf 100644 --- a/PKHeX.Core/Saves/SAV4Pt.cs +++ b/PKHeX.Core/Saves/SAV4Pt.cs @@ -53,7 +53,7 @@ private void GetSAVOffsets() OFS_UG_Stats = 0x3CB4; - _currentPoketchApp = 0x1162; + PoketchStart = 0x1160; OFS_PoffinCase = 0x52E8; Seal = 0x6494; diff --git a/PKHeX.Core/Saves/SAV4Sinnoh.cs b/PKHeX.Core/Saves/SAV4Sinnoh.cs index 4f0d51dbc..1176bdffe 100644 --- a/PKHeX.Core/Saves/SAV4Sinnoh.cs +++ b/PKHeX.Core/Saves/SAV4Sinnoh.cs @@ -56,10 +56,61 @@ public override void SetBoxName(int box, string value) } #endregion - public int CurrentPoketchApp { get => (sbyte)General[_currentPoketchApp]; set => General[_currentPoketchApp] = (byte)Math.Min(24, value); /* Alarm Clock */ } - protected int _currentPoketchApp; + #region Poketch + public int PoketchStart { get; protected set; } + private byte PoketchPacked { get => General[PoketchStart]; set => General[PoketchStart] = value; } - // Honey Trees + public bool PoketchEnabled { get => (PoketchPacked & 1) != 0; set => PoketchPacked = (byte)(value ? (PoketchPacked | 1) : (PoketchPacked & ~1)); } + public bool PoketchFlag1 { get => (PoketchPacked & 2) != 0; set => PoketchPacked = (byte)(value ? (PoketchPacked | 2) : (PoketchPacked & ~2)); } + public bool PoketchFlag2 { get => (PoketchPacked & 4) != 0; set => PoketchPacked = (byte)(value ? (PoketchPacked | 4) : (PoketchPacked & ~4)); } + + public PoketchColor PoketchColor + { + get => (PoketchColor) ((PoketchPacked >> 3) & 7); + set => PoketchPacked = (byte) ((PoketchPacked & 0xC7) | ((int) value << 3)); + } + + public bool PoketchFlag6 { get => (PoketchPacked & 0x40) != 0; set => PoketchPacked = (byte)(value ? (PoketchPacked | 0x40) : (PoketchPacked & ~0x40)); } + public bool PoketchFlag7 { get => (PoketchPacked & 0x80) != 0; set => PoketchPacked = (byte)(value ? (PoketchPacked | 0x80) : (PoketchPacked & ~0x80)); } + private byte Poketch1 { get => General[PoketchStart + 1]; set => General[PoketchStart + 1] = value; } + public sbyte CurrentPoketchApp { get => (sbyte)General[PoketchStart + 2]; set => General[PoketchStart + 2] = (byte)Math.Min((sbyte)PoketchApp.Alarm_Clock, value); } + + public bool GetPoketchAppUnlocked(PoketchApp index) + { + if (index > PoketchApp.Alarm_Clock) + throw new ArgumentException(nameof(index)); + return General[PoketchStart + 3 + (int) index] != 0; + } + + public void SetPoketchAppUnlocked(PoketchApp index, bool value = true) + { + if (index > PoketchApp.Alarm_Clock) + throw new ArgumentException(nameof(index)); + var b = value ? 1 : 0; + General[PoketchStart + 3 + (int)index] = (byte)b; + } + + // 8 bytes unk + + public uint PoketchStepCounter + { + get => BitConverter.ToUInt32(General, PoketchStart + 0x24); + set => SetData(General, BitConverter.GetBytes(value), PoketchStart + 0x24); + } + + // 2 bytes for alarm clock time setting + + public byte[] PoketchDotArtistData + { + get => General.Slice(PoketchStart + 0x2A, 120); + set => SetData(General, value, PoketchStart + 0x2A); + } + + // map marking stuff is at the end, unimportant + + #endregion + + #region Honey Trees protected int OFS_HONEY; protected const int HONEY_SIZE = 8; @@ -95,6 +146,7 @@ public int[] MunchlaxTrees return new[] { A, B, C, D }; } } + #endregion public int OFS_PoffinCase { get; protected set; } @@ -108,4 +160,45 @@ public int[] MunchlaxTrees public int UG_TrapsTriggered { get => BitConverter.ToInt32(General, OFS_UG_Stats + 0x1C); set => SetData(General, BitConverter.GetBytes(value), OFS_UG_Stats + 0x1C); } public int UG_Flags { get => BitConverter.ToInt32(General, OFS_UG_Stats + 0x34); set => SetData(General, BitConverter.GetBytes(value), OFS_UG_Stats + 0x34); } } + + public enum PoketchColor + { + Green = 0, + Yellow = 1, + Orange = 2, + Red = 3, + Purple = 4, + Blue = 5, + Turquoise = 6, + White = 7, + } + + public enum PoketchApp + { + Digital_Watch, + Calculator, + Memo_Pad, + Pedometer, + Party, + Friendship_Checker, + Dowsing_Machine, + Berry_Searcher, + Daycare, + History, + Counter, + Analog_Watch, + Marking_Map, + Link_Searcher, + Coin_Toss, + Move_Tester, + Calendar, + Dot_Artist, + Roulette, + Trainer_Counter, + Kitchen_Timer, + Color_Changer, + Matchup_Checker, + Stopwatch, + Alarm_Clock, + } } \ No newline at end of file diff --git a/PKHeX.WinForms/Subforms/Save Editors/Gen4/SAV_Misc4.cs b/PKHeX.WinForms/Subforms/Save Editors/Gen4/SAV_Misc4.cs index 25ce3dc96..33d0683a6 100644 --- a/PKHeX.WinForms/Subforms/Save Editors/Gen4/SAV_Misc4.cs +++ b/PKHeX.WinForms/Subforms/Save Editors/Gen4/SAV_Misc4.cs @@ -29,7 +29,6 @@ public SAV_Misc4(SAV4 sav) ofsFlag = 0xFDC; ofsBP = 0x65F8; ofsUGFlagCount = 0x3A60; - ofsPoketch = 0x114E; L_CurrentMap.Visible = CB_UpgradeMap.Visible = false; GB_Prints.Visible = GB_Prints.Enabled = GB_Hall.Visible = GB_Hall.Enabled = GB_Castle.Visible = GB_Castle.Enabled = false; BFF = new[] { new[] { 0, 1, 0x5FCA, 0x04, 0x6601 }, }; @@ -38,7 +37,6 @@ public SAV_Misc4(SAV4 sav) ofsFlag = 0xFEC; ofsBP = 0x7234; ofsUGFlagCount = 0x3CE8; - ofsPoketch = 0x1162; L_CurrentMap.Visible = CB_UpgradeMap.Visible = false; ofsPrints = 0xE4A; BFF = new[] { @@ -109,7 +107,6 @@ private void B_Cancel_Click(object sender, EventArgs e) private readonly int ofsBP; private readonly int ofsMap = -1; private readonly int ofsUGFlagCount = -1; - private readonly int ofsPoketch = -1; private int[] FlyDestC; private void ReadMain() @@ -139,7 +136,9 @@ private void ReadMain() uint valBP = BitConverter.ToUInt16(SAV.General, ofsBP); NUD_BP.Value = valBP > 9999 ? 9999 : valBP; - if (ofsPoketch > 0) ReadPoketch(); + if (SAV is SAV4Sinnoh) + ReadPoketch(); + if (ofsUGFlagCount > 0) { uint fc = BitConverter.ToUInt32(SAV.General, ofsUGFlagCount) & 0xFFFFF; @@ -147,7 +146,7 @@ private void ReadMain() } if (ofsMap > 0) { - string[] items = new[] { "Map Johto", "Map Johto+", "Map Johto & Kanto" }; + string[] items = { "Map Johto", "Map Johto+", "Map Johto & Kanto" }; int index = SAV.General[ofsMap] >> 3 & 3; if (index > 2) index = 2; CB_UpgradeMap.Items.AddRange(items); @@ -177,7 +176,9 @@ private void SaveMain() BitConverter.GetBytes(valFly).CopyTo(SAV.General, ofsFly); BitConverter.GetBytes((ushort)NUD_BP.Value).CopyTo(SAV.General, ofsBP); - if (ofsPoketch > 0) SavePoketch(); + if (SAV is SAV4Sinnoh) + SavePoketch(); + if (ofsUGFlagCount > 0) BitConverter.GetBytes((BitConverter.ToUInt32(SAV.General, ofsUGFlagCount) & ~0xFFFFFu) | (uint)NUD_UGFlags.Value).CopyTo(SAV.General, ofsUGFlagCount); if (ofsMap > 0) @@ -197,29 +198,24 @@ private void B_AllFlyDest_Click(object sender, EventArgs e) #region Poketch private byte[] DotArtistByte; private byte[] ColorTable; - private bool[] oldPoketchVal; private readonly ToolTip tip1 = new ToolTip(); private void ReadPoketch() { - string[] PoketchTitle = new[] { - "Unavailable", "01 - Digital Watch", "02 - Calculator", "03 - Memo Pad", "04 - Pedometer", "05 - Pokémon List", - "06 - Friendship Checker", "07 - Dowsing Machine", "08 - Berry Searcher", "09 - Day Care Checker", "10 - Pokémon History", - "11 - Counter", "12 - Analog Watch", "13 - Marking Map", "14 - Link Searcher", "15 - Coin Toss", - "16 - Move Tester", "17 - Calendar", "18 - Dot Artist", "19 - Roulette", "20 - Trainer Counter", - "21 - Kitchen Timer", "22 - Color Changer", "23 - Matchup Checker", "24 - Stopwatch", "25 - Alarm Clock" - }; + string[] PoketchTitle = Enum.GetNames(typeof(PoketchApp)); + var s = (SAV4Sinnoh) SAV; + CB_CurrentApp.Items.AddRange(PoketchTitle); - CB_CurrentApp.SelectedIndex = ((SAV4Sinnoh)SAV).CurrentPoketchApp + 1; - oldPoketchVal = new bool[PoketchTitle.Length]; + CB_CurrentApp.SelectedIndex = s.CurrentPoketchApp; CLB_Poketch.Items.Clear(); - for (int i = 1; i < PoketchTitle.Length; i++) + for (int i = 0; i < PoketchTitle.Length; i++) { - oldPoketchVal[i] = SAV.General[ofsPoketch + i] != 0; - CLB_Poketch.Items.Add(PoketchTitle[i], oldPoketchVal[i]); + var title = $"{i:00} - {PoketchTitle[i]}"; + var val = s.GetPoketchAppUnlocked((PoketchApp)i); + CLB_Poketch.Items.Add(title, val); } - DotArtistByte = SAV.General.Skip(ofsPoketch + 0x27).Take(120).ToArray(); + DotArtistByte = s.PoketchDotArtistData; ColorTable = new byte[] { 248, 168, 88, 8 }; SetPictureBoxFromFlags(DotArtistByte); string tip = "Guide about D&D ImageFile Format"; @@ -233,27 +229,14 @@ private void ReadPoketch() private void SavePoketch() { - byte count = 0; - for (int i = 1; i <= CLB_Poketch.Items.Count; i++) + var s = (SAV4Sinnoh)SAV; + s.CurrentPoketchApp = (sbyte)CB_CurrentApp.SelectedIndex; + for (int i = 0; i < CLB_Poketch.Items.Count; i++) { - if (CLB_Poketch.GetItemChecked(i - 1)) - { - count++; - if (!oldPoketchVal[i]) - SAV.General[ofsPoketch + i] = 1; - } - else if (oldPoketchVal[i]) - { - SAV.General[ofsPoketch + i] = 0; - } + var b = CLB_Poketch.GetItemChecked(i); + s.SetPoketchAppUnlocked((PoketchApp)i, b); } - SAV.General[ofsPoketch - 2] = count; - byte current = SAV.General[ofsPoketch - 1]; - if (current >= CLB_Poketch.Items.Count || !CLB_Poketch.GetItemChecked(current)) - SAV.General[ofsPoketch - 1] = 0; - DotArtistByte.CopyTo(SAV.General, ofsPoketch + 0x27); - SAV.General[ofsPoketch - 3] |= 0x04; // "Touch!" - ((SAV4Sinnoh)SAV).CurrentPoketchApp = CB_CurrentApp.SelectedIndex - 1; + s.PoketchDotArtistData = DotArtistByte; } private void SetPictureBoxFromFlags(byte[] inp) @@ -403,6 +386,7 @@ private void B_GiveAll_Click(object sender, EventArgs e) // foreach (CheckBox c in Apps) c.Checked = true; for (int i = 0; i < CLB_Poketch.Items.Count; i++) CLB_Poketch.SetItemChecked(i, true); + System.Media.SystemSounds.Asterisk.Play(); } private void TAB_Poketch_DragEnter(object sender, DragEventArgs e)