mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-10-02 01:38:07 -05:00
Extract y2k datetime logic, also wardrobe tweak
swsh gonna have wardrobe, so rename class and relocate some logic in for better docs
This commit is contained in:
@@ -9,27 +9,53 @@ public sealed class FashionBlock7 : SaveBlock
|
||||
|
||||
private const int FashionLength = 0x1A08;
|
||||
|
||||
public sealed class FashionItem
|
||||
// Every fashion item is 2 bits, New Flag (high) & Owned Flag (low)
|
||||
public sealed class FashionItem7
|
||||
{
|
||||
public bool IsOwned { get; set; }
|
||||
public bool IsNew { get; set; }
|
||||
|
||||
public FashionItem7(byte b)
|
||||
{
|
||||
IsOwned = (b & 1) != 0;
|
||||
IsNew = (b & 2) != 0;
|
||||
}
|
||||
|
||||
public byte Value => (byte)((IsOwned ? 1 : 0) | (IsNew ? 2 : 0));
|
||||
}
|
||||
|
||||
public FashionItem[] Wardrobe
|
||||
public FashionItem7[] Wardrobe
|
||||
{
|
||||
get
|
||||
{
|
||||
var data = SAV.GetData(Offset, 0x5A8);
|
||||
return data.Select(b => new FashionItem { IsOwned = (b & 1) != 0, IsNew = (b & 2) != 0 }).ToArray();
|
||||
return data.Select(b => new FashionItem7(b)).ToArray();
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value.Length != 0x5A8)
|
||||
throw new ArgumentOutOfRangeException($"Unexpected size: 0x{value.Length:X}");
|
||||
SAV.SetData(value.Select(t => (byte)((t.IsOwned ? 1 : 0) | (t.IsNew ? 2 : 0))).ToArray(), Offset);
|
||||
SAV.SetData(value.Select(z => z.Value).ToArray(), Offset);
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear() => Array.Clear(Data, Offset, FashionLength);
|
||||
|
||||
/// <summary>
|
||||
/// Resets the fashion unlocks to default values.
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
var offsetList = SAV is SAV7USUM
|
||||
? (SAV.Gender == 0
|
||||
? new[] { 0x03A, 0x109, 0x1DA, 0x305, 0x3D9, 0x4B1, 0x584 } // M
|
||||
: new[] { 0x05E, 0x208, 0x264, 0x395, 0x3B4, 0x4F9, 0x5A8 }) // F
|
||||
: (SAV.Gender == 0
|
||||
? new[] { 0x000, 0x0FB, 0x124, 0x28F, 0x3B4, 0x452, 0x517 } // M
|
||||
: new[] { 0x000, 0x100, 0x223, 0x288, 0x3B4, 0x452, 0x517 }); // F
|
||||
|
||||
foreach (var ofs in offsetList)
|
||||
SAV.Data[Offset + ofs] = 3; // owned | new
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,5 +27,33 @@ public static bool IsDateValid(uint year, uint month, uint day)
|
||||
{
|
||||
return year < int.MaxValue && month < int.MaxValue && day < int.MaxValue && IsDateValid((int)year, (int)month, (int)day);
|
||||
}
|
||||
|
||||
private static readonly DateTime Epoch2000 = new DateTime(2000, 1, 1);
|
||||
private const int spd = 86400; // seconds per day
|
||||
|
||||
public static int GetSecondsFrom2000(DateTime date, DateTime time)
|
||||
{
|
||||
int seconds = (int)(date - Epoch2000).TotalSeconds;
|
||||
seconds -= seconds % spd;
|
||||
seconds += (int)(time - Epoch2000).TotalSeconds;
|
||||
return seconds;
|
||||
}
|
||||
|
||||
public static void GetDateTime2000(uint seconds, out DateTime date, out DateTime time)
|
||||
{
|
||||
date = Epoch2000.AddSeconds(seconds);
|
||||
time = Epoch2000.AddSeconds(seconds % spd);
|
||||
}
|
||||
|
||||
public static string ConvertDateValueToString(int value, int secondsBias = -1)
|
||||
{
|
||||
string tip = string.Empty;
|
||||
if (value >= spd)
|
||||
tip += (value / spd) + "d ";
|
||||
tip += new DateTime(0).AddSeconds(value).ToString("HH:mm:ss");
|
||||
if (secondsBias >= 0)
|
||||
tip += Environment.NewLine + $"Date: {Epoch2000.AddSeconds(value + secondsBias)}";
|
||||
return tip;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,10 +53,12 @@ public SAV_Trainer(SaveFile sav)
|
||||
L_Style.Visible = TB_Style.Visible = SAV is SAV6XY;
|
||||
if (!(SAV is SAV6XY))
|
||||
TC_Editor.TabPages.Remove(Tab_Appearance);
|
||||
|
||||
if (SAV is SAV6AODemo)
|
||||
{
|
||||
TC_Editor.TabPages.Remove(Tab_Multiplayer);
|
||||
if (SAV is SAV6AODemo)
|
||||
TC_Editor.TabPages.Remove(Tab_Maison);
|
||||
}
|
||||
|
||||
GetComboBoxes();
|
||||
GetTextBoxes();
|
||||
@@ -68,7 +70,7 @@ public SAV_Trainer(SaveFile sav)
|
||||
CHK_MegaRayquazaUnlocked.Checked = status.IsMegaRayquazaUnlocked;
|
||||
}
|
||||
|
||||
private readonly bool editing = true;
|
||||
private readonly bool editing;
|
||||
private readonly ToolTip Tip1 = new ToolTip(), Tip2 = new ToolTip();
|
||||
private readonly MaskedTextBox[] MaisonRecords;
|
||||
private readonly CheckBox[] cba;
|
||||
@@ -217,11 +219,13 @@ private void GetTextBoxes()
|
||||
L_LastSaved.Visible = CAL_LastSavedDate.Visible = CAL_LastSavedTime.Visible = false;
|
||||
}
|
||||
|
||||
var epoch = new DateTime(2000, 1, 1);
|
||||
CAL_AdventureStartDate.Value = epoch.AddSeconds(SAV.SecondsToStart);
|
||||
CAL_AdventureStartTime.Value = epoch.AddSeconds(SAV.SecondsToStart % 86400);
|
||||
CAL_HoFDate.Value = epoch.AddSeconds(SAV.SecondsToFame);
|
||||
CAL_HoFTime.Value = epoch.AddSeconds(SAV.SecondsToFame % 86400);
|
||||
Util.GetDateTime2000(SAV.SecondsToStart, out var date, out var time);
|
||||
CAL_AdventureStartDate.Value = date;
|
||||
CAL_AdventureStartTime.Value = time;
|
||||
|
||||
Util.GetDateTime2000(SAV.SecondsToStart, out date, out time);
|
||||
CAL_HoFDate.Value = date;
|
||||
CAL_HoFTime.Value = time;
|
||||
}
|
||||
|
||||
private void Save()
|
||||
@@ -295,15 +299,8 @@ private void Save()
|
||||
// Vivillon
|
||||
SAV.Vivillon = CB_Vivillon.SelectedIndex;
|
||||
|
||||
uint seconds = (uint)(CAL_AdventureStartDate.Value - new DateTime(2000, 1, 1)).TotalSeconds;
|
||||
seconds -= seconds%86400;
|
||||
seconds += (uint)(CAL_AdventureStartTime.Value - new DateTime(2000, 1, 1)).TotalSeconds;
|
||||
SAV.SecondsToStart = seconds;
|
||||
|
||||
uint fame = (uint)(CAL_HoFDate.Value - new DateTime(2000, 1, 1)).TotalSeconds;
|
||||
fame -= fame % 86400;
|
||||
fame += (uint)(CAL_HoFTime.Value - new DateTime(2000, 1, 1)).TotalSeconds;
|
||||
SAV.SecondsToFame = fame;
|
||||
SAV.SecondsToStart = (uint)Util.GetSecondsFrom2000(CAL_AdventureStartDate.Value, CAL_AdventureStartTime.Value);
|
||||
SAV.SecondsToFame = (uint)Util.GetSecondsFrom2000(CAL_HoFDate.Value, CAL_HoFTime.Value);
|
||||
|
||||
if (SAV.Played.LastSavedDate.HasValue)
|
||||
SAV.Played.LastSavedDate = new DateTime(CAL_LastSavedDate.Value.Year, CAL_LastSavedDate.Value.Month, CAL_LastSavedDate.Value.Day, CAL_LastSavedTime.Value.Hour, CAL_LastSavedTime.Value.Minute, 0);
|
||||
@@ -360,8 +357,10 @@ private void Change255(object sender, EventArgs e)
|
||||
private void ChangeFFFF(object sender, EventArgs e)
|
||||
{
|
||||
MaskedTextBox box = (MaskedTextBox)sender;
|
||||
if (box.Text.Length == 0) box.Text = "0";
|
||||
if (Util.ToInt32(box.Text) > 65535) box.Text = "65535";
|
||||
if (box.Text.Length == 0)
|
||||
box.Text = "0";
|
||||
else if (Util.ToInt32(box.Text) > 65535)
|
||||
box.Text = "65535";
|
||||
}
|
||||
|
||||
private void GiveAllAccessories(object sender, EventArgs e)
|
||||
@@ -401,26 +400,11 @@ private string UpdateTip(int index)
|
||||
switch (index)
|
||||
{
|
||||
case 2: // Storyline Completed Time
|
||||
var epoch = new DateTime(2000, 1, 1);
|
||||
int seconds = (int)(CAL_AdventureStartDate.Value - epoch).TotalSeconds;
|
||||
seconds -= seconds % 86400;
|
||||
seconds += (int)(CAL_AdventureStartTime.Value - epoch).TotalSeconds;
|
||||
return ConvertDateValueToString(SAV.GetRecord(index), seconds);
|
||||
var seconds = Util.GetSecondsFrom2000(CAL_AdventureStartDate.Value, CAL_AdventureStartTime.Value);
|
||||
return Util.ConvertDateValueToString(SAV.GetRecord(index), seconds);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static string ConvertDateValueToString(int value, int secondsBias = -1)
|
||||
{
|
||||
const int spd = 86400; // seconds per day
|
||||
string tip = string.Empty;
|
||||
if (value >= spd)
|
||||
tip += (value / spd) + "d ";
|
||||
tip += new DateTime(0).AddSeconds(value).ToString("HH:mm:ss");
|
||||
if (secondsBias >= 0)
|
||||
tip += Environment.NewLine + $"Date: {new DateTime(2000, 1, 1).AddSeconds(value + secondsBias)}";
|
||||
return tip;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -111,13 +111,13 @@ private void GetTextBoxes()
|
||||
CB_Region.SelectedValue = SAV.SubRegion;
|
||||
CB_3DSReg.SelectedValue = SAV.ConsoleRegion;
|
||||
CB_Language.SelectedValue = SAV.Language;
|
||||
var time = SAV.GameTime.AlolaTime;
|
||||
if (time == 0)
|
||||
time = 24 * 60 * 60; // Patch up any bad times from previous program versions.
|
||||
if (time == 9_999_999)
|
||||
var timeA = SAV.GameTime.AlolaTime;
|
||||
if (timeA == 0)
|
||||
timeA = 24 * 60 * 60; // Patch up any bad times from previous program versions.
|
||||
if (timeA == 9_999_999)
|
||||
CB_AlolaTime.Enabled = false; // alola time doesn't exist yet
|
||||
else
|
||||
CB_AlolaTime.SelectedValue = (int)time;
|
||||
CB_AlolaTime.SelectedValue = (int)timeA;
|
||||
if (CB_AlolaTime.SelectedValue == null)
|
||||
CB_AlolaTime.Enabled = false;
|
||||
|
||||
@@ -147,11 +147,13 @@ private void GetTextBoxes()
|
||||
L_LastSaved.Visible = CAL_LastSavedDate.Visible = CAL_LastSavedTime.Visible = false;
|
||||
}
|
||||
|
||||
var epoch = new DateTime(2000, 1, 1);
|
||||
CAL_AdventureStartDate.Value = epoch.AddSeconds(SAV.SecondsToStart);
|
||||
CAL_AdventureStartTime.Value = epoch.AddSeconds(SAV.SecondsToStart % 86400);
|
||||
CAL_HoFDate.Value = epoch.AddSeconds(SAV.SecondsToFame);
|
||||
CAL_HoFTime.Value = epoch.AddSeconds(SAV.SecondsToFame % 86400);
|
||||
Util.GetDateTime2000(SAV.SecondsToStart, out var date, out var time);
|
||||
CAL_AdventureStartDate.Value = date;
|
||||
CAL_AdventureStartTime.Value = time;
|
||||
|
||||
Util.GetDateTime2000(SAV.SecondsToStart, out date, out time);
|
||||
CAL_HoFDate.Value = date;
|
||||
CAL_HoFTime.Value = time;
|
||||
|
||||
NUD_BP.Value = Math.Min(NUD_BP.Maximum, SAV.MiscBlock.BP);
|
||||
NUD_FC.Value = Math.Min(NUD_FC.Maximum, SAV.Festa.FestaCoins);
|
||||
@@ -349,16 +351,8 @@ private void SaveTrainerInfo()
|
||||
SAV.PlayedMinutes = ushort.Parse(MT_Minutes.Text)%60;
|
||||
SAV.PlayedSeconds = ushort.Parse(MT_Seconds.Text)%60;
|
||||
|
||||
var epoch = new DateTime(2000, 1, 1);
|
||||
uint seconds = (uint)(CAL_AdventureStartDate.Value - epoch).TotalSeconds;
|
||||
seconds -= seconds%86400;
|
||||
seconds += (uint)(CAL_AdventureStartTime.Value - epoch).TotalSeconds;
|
||||
SAV.SecondsToStart = seconds;
|
||||
|
||||
uint fame = (uint)(CAL_HoFDate.Value - epoch).TotalSeconds;
|
||||
fame -= fame % 86400;
|
||||
fame += (uint)(CAL_HoFTime.Value - epoch).TotalSeconds;
|
||||
SAV.SecondsToFame = fame;
|
||||
SAV.SecondsToStart = (uint)Util.GetSecondsFrom2000(CAL_AdventureStartDate.Value, CAL_AdventureStartTime.Value);
|
||||
SAV.SecondsToFame = (uint)Util.GetSecondsFrom2000(CAL_HoFDate.Value, CAL_HoFTime.Value);
|
||||
|
||||
if (SAV.Played.LastSavedDate.HasValue)
|
||||
SAV.Played.LastSavedDate = new DateTime(CAL_LastSavedDate.Value.Year, CAL_LastSavedDate.Value.Month, CAL_LastSavedDate.Value.Day, CAL_LastSavedTime.Value.Hour, CAL_LastSavedTime.Value.Minute, 0);
|
||||
@@ -505,13 +499,6 @@ private void Change255(object sender, EventArgs e)
|
||||
if (Util.ToInt32(box.Text) > 255) box.Text = "255";
|
||||
}
|
||||
|
||||
private void ChangeFFFF(object sender, EventArgs e)
|
||||
{
|
||||
MaskedTextBox box = (MaskedTextBox)sender;
|
||||
if (box.Text.Length == 0) box.Text = "0";
|
||||
if (Util.ToInt32(box.Text) > 65535) box.Text = "65535";
|
||||
}
|
||||
|
||||
private void ChangeMapValue(object sender, EventArgs e)
|
||||
{
|
||||
if (!Loading)
|
||||
@@ -535,35 +522,25 @@ private void B_Fashion_Click(object sender, EventArgs e)
|
||||
SAV.FashionBlock.Clear();
|
||||
|
||||
// Write Payload
|
||||
// Every fashion item is 2 bits, New Flag (high) & Owned Flag (low)
|
||||
|
||||
switch (CB_Fashion.SelectedIndex)
|
||||
{
|
||||
case 0: // Base Fashion
|
||||
{
|
||||
var list = SAV is SAV7USUM
|
||||
? (SAV.Gender == 0
|
||||
? new[] {0x03A, 0x109, 0x1DA, 0x305, 0x3D9, 0x4B1, 0x584} // M
|
||||
: new[] {0x05E, 0x208, 0x264, 0x395, 0x3B4, 0x4F9, 0x5A8}) // F
|
||||
: (SAV.Gender == 0
|
||||
? new[] {0x000, 0x0FB, 0x124, 0x28F, 0x3B4, 0x452, 0x517} // M
|
||||
: new[] {0x000, 0x100, 0x223, 0x288, 0x3B4, 0x452, 0x517}); // F
|
||||
|
||||
foreach (var ofs in list)
|
||||
SAV.Data[SAV.Fashion + ofs] = 3;
|
||||
SAV.FashionBlock.Reset();
|
||||
break;
|
||||
}
|
||||
case 1: // Full Legal
|
||||
byte[] data1 = SAV is SAV7USUM
|
||||
? SAV.Gender == 0 ? Properties.Resources.fashion_m_uu : Properties.Resources.fashion_f_uu
|
||||
: SAV.Gender == 0 ? Properties.Resources.fashion_m_sm : Properties.Resources.fashion_f_sm;
|
||||
data1.CopyTo(SAV.Data, SAV.Fashion);
|
||||
SAV.SetData(data1, SAV.Fashion);
|
||||
break;
|
||||
case 2: // Everything
|
||||
byte[] data2 = SAV is SAV7USUM
|
||||
? SAV.Gender == 0 ? Properties.Resources.fashion_m_uu_illegal : Properties.Resources.fashion_f_uu_illegal
|
||||
: SAV.Gender == 0 ? Properties.Resources.fashion_m_sm_illegal : Properties.Resources.fashion_f_sm_illegal;
|
||||
data2.CopyTo(SAV.Data, SAV.Fashion);
|
||||
SAV.SetData(data2, SAV.Fashion);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
@@ -576,27 +553,13 @@ private string UpdateTip(int index)
|
||||
switch (index)
|
||||
{
|
||||
case 2: // Storyline Completed Time
|
||||
int seconds = (int)(CAL_AdventureStartDate.Value - new DateTime(2000, 1, 1)).TotalSeconds;
|
||||
seconds -= seconds % 86400;
|
||||
seconds += (int)(CAL_AdventureStartTime.Value - new DateTime(2000, 1, 1)).TotalSeconds;
|
||||
return ConvertDateValueToString(SAV.GetRecord(index), seconds);
|
||||
var seconds = Util.GetSecondsFrom2000(CAL_AdventureStartDate.Value, CAL_AdventureStartTime.Value);
|
||||
return Util.ConvertDateValueToString(SAV.GetRecord(index), seconds);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static string ConvertDateValueToString(int value, int secondsBias = -1)
|
||||
{
|
||||
const int spd = 86400; // seconds per day
|
||||
string tip = string.Empty;
|
||||
if (value >= spd)
|
||||
tip += (value / spd) + "d ";
|
||||
tip += new DateTime(0).AddSeconds(value).ToString("HH:mm:ss");
|
||||
if (secondsBias >= 0)
|
||||
tip += Environment.NewLine + $"Date: {new DateTime(2000, 1, 1).AddSeconds(value + secondsBias)}";
|
||||
return tip;
|
||||
}
|
||||
|
||||
private void UpdateBattleStyle(object sender, EventArgs e)
|
||||
{
|
||||
if (CB_BallThrowTypeListMode.SelectedIndex == 0)
|
||||
|
||||
@@ -151,10 +151,13 @@ public SAV_SimpleTrainer(SaveFile sav)
|
||||
cba[i].Checked = (badgeval & 1 << i) != 0;
|
||||
}
|
||||
|
||||
CAL_HoFDate.Value = new DateTime(2000, 1, 1).AddSeconds(SAV.SecondsToFame);
|
||||
CAL_HoFTime.Value = new DateTime(2000, 1, 1).AddSeconds(SAV.SecondsToFame % 86400);
|
||||
CAL_AdventureStartDate.Value = new DateTime(2000, 1, 1).AddSeconds(SAV.SecondsToStart);
|
||||
CAL_AdventureStartTime.Value = new DateTime(2000, 1, 1).AddSeconds(SAV.SecondsToStart % 86400);
|
||||
Util.GetDateTime2000(SAV.SecondsToStart, out var date, out var time);
|
||||
CAL_AdventureStartDate.Value = date;
|
||||
CAL_AdventureStartTime.Value = time;
|
||||
|
||||
Util.GetDateTime2000(SAV.SecondsToStart, out date, out time);
|
||||
CAL_HoFDate.Value = date;
|
||||
CAL_HoFTime.Value = time;
|
||||
|
||||
Loading = false;
|
||||
}
|
||||
@@ -252,8 +255,8 @@ private void B_Save_Click(object sender, EventArgs e)
|
||||
s.BattleSubwayBlock.BP = (ushort)Math.Min(Util.ToUInt32(MT_Coins.Text), SAV.MaxCoins);
|
||||
}
|
||||
|
||||
SAV.SecondsToStart = GetSeconds(CAL_AdventureStartDate, CAL_AdventureStartTime);
|
||||
SAV.SecondsToFame = GetSeconds(CAL_HoFDate, CAL_HoFTime);
|
||||
SAV.SecondsToStart = (uint)Util.GetSecondsFrom2000(CAL_AdventureStartDate.Value, CAL_AdventureStartTime.Value);
|
||||
SAV.SecondsToFame = (uint)Util.GetSecondsFrom2000(CAL_HoFDate.Value, CAL_HoFTime.Value);
|
||||
|
||||
Origin.CopyChangesFrom(SAV);
|
||||
Close();
|
||||
@@ -264,15 +267,6 @@ private void B_Cancel_Click(object sender, EventArgs e)
|
||||
Close();
|
||||
}
|
||||
|
||||
private static uint GetSeconds(DateTimePicker date, DateTimePicker time)
|
||||
{
|
||||
var epoch = new DateTime(2000, 1, 1);
|
||||
uint val = (uint)(date.Value - epoch).TotalSeconds;
|
||||
val -= val % 86400;
|
||||
val += (uint)(time.Value - epoch).TotalSeconds;
|
||||
return val;
|
||||
}
|
||||
|
||||
private void ChangeMapValue(object sender, EventArgs e)
|
||||
{
|
||||
if (!Loading)
|
||||
|
||||
Reference in New Issue
Block a user