Split S/MAX from base 1-3 levels

ORAS can unlock MAX & Full Recovery flags, add special handling for that
This commit is contained in:
Kurt 2018-06-10 11:28:20 -07:00
parent 29c610870e
commit 75f4318335
4 changed files with 89 additions and 33 deletions

View File

@ -48,22 +48,20 @@ public OPower6(byte[] data, int offset)
Data = data;
}
public int GetOPowerCount(OPower6Type type)
{
var m = Array.Find(Mapping, t => t.Identifier == type);
return m.Count;
}
public int GetOPowerLevel(OPower6Type type)
{
var m = Array.Find(Mapping, t => t.Identifier == type);
return m.GetOPowerLevel(Data, Offset);
}
public void SetOPowerLevel(OPower6Type type, int lvl)
{
var m = Array.Find(Mapping, t => t.Identifier == type);
m.SetOPowerLevel(Data, Offset, lvl);
}
private OPowerFlagSet this[OPower6Type type] => Array.Find(Mapping, t => t.Identifier == type);
public int GetOPowerCount(OPower6Type type) => this[type].BaseCount;
public int GetOPowerLevel(OPower6Type type) => this[type].GetOPowerLevel(Data, Offset);
public bool GetHasOPowerS(OPower6Type type) => this[type].HasOPowerS;
public bool GetHasOPowerMAX(OPower6Type type) => this[type].HasOPowerMAX;
public bool GetOPowerS(OPower6Type type) => this[type].GetOPowerS(Data, Offset);
public bool GetOPowerMAX(OPower6Type type) => this[type].GetOPowerMAX(Data, Offset);
public void SetOPowerLevel(OPower6Type type, int lvl) => this[type].SetOPowerLevel(Data, Offset, lvl);
public void SetOPowerS(OPower6Type type, bool value) => this[type].SetOPowerS(Data, Offset, value);
public void SetOPowerMAX(OPower6Type type, bool value) => this[type].SetOPowerMAX(Data, Offset, value);
public bool MasterFlag
{
get => Data[Offset] == 1;
@ -71,20 +69,26 @@ public bool MasterFlag
}
public void UnlockAll() => ToggleFlags(allEvents: true);
public void UnlockRegular() => ToggleFlags();
public void UnlockRegular(bool ORAS) => ToggleFlags(ORAS: ORAS);
public void ClearAll() => ToggleFlags(clearOnly: true);
private void ToggleFlags(bool allEvents = false, bool clearOnly = false)
private void ToggleFlags(bool allEvents = false, bool clearOnly = false, bool ORAS = false)
{
foreach (var m in Mapping)
{
// Clear before applying new value
m.SetOPowerLevel(Data, Offset, 0);
m.SetOPowerS(Data, Offset, false);
m.SetOPowerMAX(Data, Offset, false);
if (clearOnly)
continue;
int lvl = allEvents ? m.Count : (m.Count != 1 ? 3 : 0); // Full_Recovery is event only @ 1 level
int lvl = ORAS || allEvents ? m.BaseCount : (m.BaseCount != 1 ? 3 : 0); // Full_Recovery is ORAS/event only @ 1 level
m.SetOPowerLevel(Data, Offset, lvl);
if (allEvents)
m.SetOPowerS(Data, Offset, true);
if (ORAS || allEvents)
m.SetOPowerMAX(Data, Offset, true);
}
}

View File

@ -1,3 +1,4 @@
using System;
using System.Diagnostics;
namespace PKHeX.Core
@ -7,6 +8,9 @@ internal class OPowerFlagSet
public readonly OPower6Type Identifier;
public readonly int Count;
public int Offset;
public int BaseCount => Math.Min(3, Count);
public bool HasOPowerS => Count > 3;
public bool HasOPowerMAX => Count == 5;
public OPowerFlagSet(int count, OPower6Type ident)
{
@ -16,23 +20,38 @@ public OPowerFlagSet(int count, OPower6Type ident)
public int GetOPowerLevel(byte[] data, int offset)
{
for (int i = 0; i < Count; i++)
for (int i = 0; i < BaseCount; i++)
{
if (data[Offset + offset + i] != 0)
if (GetFlag(data, offset, i))
continue;
Debug.WriteLine($"Fetched {Identifier}: {i}");
return i;
}
Debug.WriteLine($"Fetched {Identifier}: {Count}");
return Count;
Debug.WriteLine($"Fetched {Identifier}: {BaseCount}");
return BaseCount;
}
public void SetOPowerLevel(byte[] data, int offset, int value)
{
Debug.WriteLine($"Setting {Identifier}: {value}");
for (int i = 0; i < Count; i++)
data[Offset + offset + i] = (byte)(i + 1 > value ? OPowerFlagState.Locked : OPowerFlagState.Unlocked);
for (int i = 0; i < BaseCount; i++)
SetFlag(data, offset, i, i + 1 <= value);
Debug.Assert(value == GetOPowerLevel(data, offset));
}
public bool GetOPowerS(byte[] data, int offset) => HasOPowerS && GetFlag(data, offset, 3);
public bool GetOPowerMAX(byte[] data, int offset) => HasOPowerMAX && GetFlag(data, offset, 4);
public void SetOPowerS(byte[] data, int offset, bool value) => SetFlag(data, offset, 3, value);
public void SetOPowerMAX(byte[] data, int offset, bool value) => SetFlag(data, offset, 4, value);
private bool GetFlag(byte[] data, int offset, int index)
{
return data[Offset + offset + index] == (byte)OPowerFlagState.Unlocked;
}
private void SetFlag(byte[] data, int offset, int index, bool value)
{
if (index < Count)
data[Offset + offset + index] = (byte)(value ? OPowerFlagState.Unlocked : OPowerFlagState.Locked);
}
}
}

View File

@ -38,12 +38,14 @@ private void InitializeComponent()
this.B_GiveAll = new System.Windows.Forms.Button();
this.B_GiveAllMAX = new System.Windows.Forms.Button();
this.CHK_Master = new System.Windows.Forms.CheckBox();
this.CHK_S = new System.Windows.Forms.CheckBox();
this.CHK_MAX = new System.Windows.Forms.CheckBox();
this.SuspendLayout();
//
// B_Cancel
//
this.B_Cancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.B_Cancel.Location = new System.Drawing.Point(118, 71);
this.B_Cancel.Location = new System.Drawing.Point(214, 71);
this.B_Cancel.Name = "B_Cancel";
this.B_Cancel.Size = new System.Drawing.Size(64, 23);
this.B_Cancel.TabIndex = 34;
@ -54,7 +56,7 @@ private void InitializeComponent()
// B_Save
//
this.B_Save.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.B_Save.Location = new System.Drawing.Point(188, 71);
this.B_Save.Location = new System.Drawing.Point(284, 71);
this.B_Save.Name = "B_Save";
this.B_Save.Size = new System.Drawing.Size(64, 23);
this.B_Save.TabIndex = 35;
@ -79,7 +81,7 @@ private void InitializeComponent()
this.CB_Type.FormattingEnabled = true;
this.CB_Type.Location = new System.Drawing.Point(65, 14);
this.CB_Type.Name = "CB_Type";
this.CB_Type.Size = new System.Drawing.Size(111, 21);
this.CB_Type.Size = new System.Drawing.Size(103, 21);
this.CB_Type.TabIndex = 37;
//
// CB_Value
@ -87,7 +89,7 @@ private void InitializeComponent()
this.CB_Value.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.CB_Value.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.CB_Value.FormattingEnabled = true;
this.CB_Value.Location = new System.Drawing.Point(188, 14);
this.CB_Value.Location = new System.Drawing.Point(174, 14);
this.CB_Value.Name = "CB_Value";
this.CB_Value.Size = new System.Drawing.Size(64, 21);
this.CB_Value.TabIndex = 38;
@ -123,18 +125,40 @@ private void InitializeComponent()
//
this.CHK_Master.AutoSize = true;
this.CHK_Master.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
this.CHK_Master.Location = new System.Drawing.Point(188, 45);
this.CHK_Master.Location = new System.Drawing.Point(101, 75);
this.CHK_Master.Name = "CHK_Master";
this.CHK_Master.Size = new System.Drawing.Size(67, 17);
this.CHK_Master.TabIndex = 42;
this.CHK_Master.Text = "??? Flag";
this.CHK_Master.UseVisualStyleBackColor = true;
//
// CHK_S
//
this.CHK_S.AutoSize = true;
this.CHK_S.Location = new System.Drawing.Point(244, 16);
this.CHK_S.Name = "CHK_S";
this.CHK_S.Size = new System.Drawing.Size(33, 17);
this.CHK_S.TabIndex = 43;
this.CHK_S.Text = "S";
this.CHK_S.UseVisualStyleBackColor = true;
//
// CHK_MAX
//
this.CHK_MAX.AutoSize = true;
this.CHK_MAX.Location = new System.Drawing.Point(283, 16);
this.CHK_MAX.Name = "CHK_MAX";
this.CHK_MAX.Size = new System.Drawing.Size(49, 17);
this.CHK_MAX.TabIndex = 44;
this.CHK_MAX.Text = "MAX";
this.CHK_MAX.UseVisualStyleBackColor = true;
//
// SAV_OPower
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(259, 106);
this.ClientSize = new System.Drawing.Size(355, 106);
this.Controls.Add(this.CHK_MAX);
this.Controls.Add(this.CHK_S);
this.Controls.Add(this.CHK_Master);
this.Controls.Add(this.B_GiveAllMAX);
this.Controls.Add(this.B_GiveAll);
@ -166,5 +190,7 @@ private void InitializeComponent()
private System.Windows.Forms.Button B_GiveAll;
private System.Windows.Forms.Button B_GiveAllMAX;
private System.Windows.Forms.CheckBox CHK_Master;
private System.Windows.Forms.CheckBox CHK_S;
private System.Windows.Forms.CheckBox CHK_MAX;
}
}

View File

@ -26,7 +26,7 @@ public SAV_OPower(SAV6 sav)
CB_Type.SelectedIndexChanged += (s, e) => { SaveCurrent(); LoadCurrent(); };
B_ClearAll.Click += (s, e) => { Data.ClearAll(); LoadCurrent(); };
B_GiveAll.Click += (s, e) => { Data.UnlockRegular(); LoadCurrent(); };
B_GiveAll.Click += (s, e) => { Data.UnlockRegular(Origin.ORAS); LoadCurrent(); };
B_GiveAllMAX.Click += (s, e) => { Data.UnlockAll(); LoadCurrent(); };
}
@ -56,12 +56,19 @@ private void LoadCurrent()
int count = Data.GetOPowerCount(Current);
for (int i = 0; i <= count; i++)
CB_Value.Items.Add(Values[i]);
int lvl = Data.GetOPowerLevel(Current);
CB_Value.SelectedIndex = lvl;
CB_Value.SelectedIndex = Data.GetOPowerLevel(Current);
CHK_S.Enabled = Data.GetHasOPowerS(Current);
CHK_S.Checked = Data.GetOPowerS(Current);
CHK_MAX.Enabled = Data.GetHasOPowerMAX(Current);
CHK_MAX.Checked = Data.GetOPowerMAX(Current);
}
private void SaveCurrent()
{
Data.SetOPowerLevel(Current, CB_Value.SelectedIndex);
Data.SetOPowerS(Current, CHK_S.Checked);
Data.SetOPowerMAX(Current, CHK_MAX.Checked);
}
}
}