Add getter/setter for Sav Gen3/4 Trendy Word, Trainer Hill, Berry Blender, Accessory, Backdrop, Wallpaper (#4152)

This commit is contained in:
Samuel Magnan
2024-01-06 19:44:58 -05:00
committed by GitHub
parent 608f7ebe12
commit dbb4df6ddc
9 changed files with 445 additions and 32 deletions

View File

@@ -128,6 +128,9 @@ public override uint Coin
private const int OFS_PouchBalls = 0x0650;
private const int OFS_PouchTMHM = 0x0690;
private const int OFS_PouchBerry = 0x0790;
private const int OFS_BerryBlenderRecord = 0x9BC;
private const int OFS_TrendyWord = 0x2E20;
private const int OFS_TrainerHillRecord = 0x3718;
protected override InventoryPouch3[] GetItems()
{
@@ -185,6 +188,50 @@ public int SwarmIndex
protected override int ExternalEventData => 0x31B3;
/// <summary>
/// Max RPM for 2, 3 and 4 players. Each value unit represents 0.01 RPM. Value 0 if no record.
/// </summary>
/// <remarks>2 players: index 0, 3 players: index 1, 4 players: index 2</remarks>
public const int BerryBlenderRPMRecordCount = 3;
private Span<byte> GetBlenderRPMSpan(int index)
{
if ((uint)index >= BerryBlenderRPMRecordCount)
throw new ArgumentOutOfRangeException(nameof(index));
return Large.AsSpan(OFS_BerryBlenderRecord + (index * 2));
}
public ushort GetBerryBlenderRPMRecord(int index) => ReadUInt16LittleEndian(GetBlenderRPMSpan(index));
public void SetBerryBlenderRPMRecord(int index, ushort value)
{
WriteUInt16LittleEndian(GetBlenderRPMSpan(index), value);
State.Edited = true;
}
public bool GetTrendyWordUnlocked(TrendyWord3E word)
{
return GetFlag(OFS_TrendyWord + ((byte)word >> 3), (byte)word & 7);
}
public void SetTrendyWordUnlocked(TrendyWord3E word, bool value)
{
SetFlag(OFS_TrendyWord + ((byte)word >> 3), (byte)word & 7, value);
State.Edited = true;
}
/** Each value unit represents 1/60th of a second. Value 0 if no record. */
public uint GetTrainerHillRecord(TrainerHillMode3E mode)
{
return ReadUInt32LittleEndian(Large.AsSpan(OFS_TrainerHillRecord + (byte)mode * 4));
}
public void SetTrainerHillRecord(TrainerHillMode3E mode, uint value)
{
WriteUInt32LittleEndian(Large.AsSpan(OFS_TrainerHillRecord + (byte)mode * 4), value);
State.Edited = true;
}
#region eBerry
private const int OFFSET_EBERRY = 0x31F8;
private const int SIZE_EBERRY = 0x34;

View File

@@ -29,7 +29,8 @@ public SAV4Pt(byte[] data) : base(data, GeneralSize, StorageSize, GeneralSize)
public const int GeneralSize = 0xCF2C;
private const int StorageSize = 0x121E4; // Start 0xCF2C, +4 starts box data
private const int VillaFurnitureStart = 0x111F;
public const byte BACKDROP_POSITION_IF_NOT_UNLOCKED = 0x12;
protected override BlockInfo4[] ExtraBlocks =>
[
@@ -51,6 +52,12 @@ private void Initialize()
protected override int EventFlag => 0xFEC;
public override BattleFrontierFacility4 MaxFacility => BattleFrontierFacility4.Arcade;
private const int OFS_AccessoryMultiCount = 0x4E38; // 4 bits each
private const int OFS_AccessorySingleCount = 0x4E58; // 1 bit each
private const int OFS_Backdrop = 0x4E60;
private const int OFS_ToughWord = 0xCEB4;
private const int OFS_VillaFurniture = 0x111F;
private void GetSAVOffsets()
{
AdventureInfo = 0;
@@ -78,6 +85,8 @@ private void GetSAVOffsets()
}
#region Storage
private const int OFS_Wallpaper = 0x121C6;
private static int AdjustWallpaper(int value, int shift)
{
// Pt's Special Wallpapers 1-8 are shifted by +0x8
@@ -102,6 +111,25 @@ public override void SetBoxWallpaper(int box, int value)
value = AdjustWallpaper(value, 0x08);
Storage[GetBoxWallpaperOffset(box)] = (byte)value;
}
public bool GetWallpaperUnlocked(Wallpaper4Pt wallpaperId)
{
if (wallpaperId < Wallpaper4Pt.Distortion)
return true;
var unlockableWallpaperIdx = wallpaperId - Wallpaper4Pt.Distortion;
return FlagUtil.GetFlag(Storage, OFS_Wallpaper + (unlockableWallpaperIdx >> 3), unlockableWallpaperIdx & 7);
}
public void SetWallpaperUnlocked(Wallpaper4Pt wallpaperId, bool value)
{
if (wallpaperId < Wallpaper4Pt.Distortion)
return; // Always unlocked
var unlockableWallpaperIdx = wallpaperId - Wallpaper4Pt.Distortion;
FlagUtil.SetFlag(Storage, OFS_Wallpaper + (unlockableWallpaperIdx >> 3), unlockableWallpaperIdx & 7, value);
State.Edited = true;
}
#endregion
public override IReadOnlyList<InventoryPouch> Inventory
@@ -169,41 +197,112 @@ private Roamer4 GetRoamer(int index)
return new Roamer4(mem);
}
public bool GetVillaFurniturePurchased(VillaFurniture index)
public byte GetAccessoryOwnedCount(Accessory4 accessory)
{
if (index > VillaFurniture.MAX)
throw new ArgumentOutOfRangeException(nameof(index));
return FlagUtil.GetFlag(General, VillaFurnitureStart + ((byte)index >> 3), (byte)index & 7);
if (accessory < Accessory4.ColoredParasol)
{
byte enumIdx = (byte)accessory;
byte val = General[OFS_AccessoryMultiCount + (enumIdx / 2)];
if (enumIdx % 2 == 0)
return (byte)(val & 0x0F);
return (byte)(val >> 4);
}
// Otherwise, it's a single-count accessory
var flagIdx = accessory - Accessory4.ColoredParasol;
if (GetFlag(OFS_AccessorySingleCount + (flagIdx >> 3), flagIdx & 7))
return 1;
return 0;
}
public void SetVillaFurniturePurchased(VillaFurniture index, bool value = true)
public void SetAccessoryOwnedCount(Accessory4 accessory, byte count)
{
if (index > VillaFurniture.MAX)
if (accessory < Accessory4.ColoredParasol)
{
if (count > 9)
count = 9;
var enumIdx = (byte)accessory;
var addr = OFS_AccessoryMultiCount + (enumIdx / 2);
if (enumIdx % 2 == 0)
{
General[addr] &= 0xF0; // Reset old count to 0
General[addr] |= count; // Set new count
}
else
{
General[addr] &= 0x0F; // Reset old count to 0
General[addr] |= (byte)(count << 4); // Set new count
}
}
else
{
var flagIdx = accessory - Accessory4.ColoredParasol;
SetFlag(OFS_AccessorySingleCount + (flagIdx >> 3), flagIdx & 7, count != 0);
}
State.Edited = true;
}
public byte GetBackdropPosition(Backdrop4 backdrop)
{
if (backdrop > Backdrop4.Theater)
throw new ArgumentOutOfRangeException(nameof(backdrop), backdrop, null);
return General[OFS_Backdrop + (byte)backdrop];
}
public bool GetBackdropUnlocked(Backdrop4 backdrop)
{
return GetBackdropPosition(backdrop) != BACKDROP_POSITION_IF_NOT_UNLOCKED;
}
public void RemoveBackdrop(Backdrop4 backdrop) => SetBackdropPosition(backdrop, BACKDROP_POSITION_IF_NOT_UNLOCKED);
/// <summary>
/// Sets the position of a backdrop.
/// </summary>
/// <remarks>
/// Every unlocked backdrop must have a different position.
/// Use <see cref="RemoveBackdrop"/> to remove a backdrop.
/// </remarks>
public void SetBackdropPosition(Backdrop4 backdrop, byte position)
{
if (backdrop > Backdrop4.Theater)
throw new ArgumentOutOfRangeException(nameof(backdrop), backdrop, null);
if (position > BACKDROP_POSITION_IF_NOT_UNLOCKED)
position = BACKDROP_POSITION_IF_NOT_UNLOCKED;
General[OFS_Backdrop + (byte)backdrop] = position;
State.Edited = true;
}
public bool GetToughWordUnlocked(ToughWord4 word)
{
if (word > ToughWord4.REMSleep)
throw new ArgumentOutOfRangeException(nameof(word), word, null);
return GetFlag(OFS_ToughWord + ((byte)word >> 3), (byte)word & 7);
}
public void SetToughWordUnlocked(ToughWord4 word, bool value)
{
if (word > ToughWord4.REMSleep)
throw new ArgumentOutOfRangeException(nameof(word), word, null);
SetFlag(OFS_ToughWord + ((byte)word >> 3), (byte)word & 7, value);
State.Edited = true;
}
public bool GetVillaFurniturePurchased(VillaFurniture4 index)
{
if (index > VillaFurniture4.Chandelier)
throw new ArgumentOutOfRangeException(nameof(index));
FlagUtil.SetFlag(General, VillaFurnitureStart + ((byte)index >> 3), (byte)index & 7, value);
return GetFlag(OFS_VillaFurniture + ((byte)index >> 3), (byte)index & 7);
}
public void SetVillaFurniturePurchased(VillaFurniture4 index, bool value = true)
{
if (index > VillaFurniture4.Chandelier)
throw new ArgumentOutOfRangeException(nameof(index));
SetFlag(OFS_VillaFurniture + ((byte)index >> 3), (byte)index & 7, value);
State.Edited = true;
}
}
public enum VillaFurniture
{
BigSofa,
SmallSofa,
Bed,
NightTable,
TV,
AudioSystem,
Bookshelf,
Rack,
Houseplant,
PCDesk,
MusicBox,
PokemonBust1,
PokemonBust2,
Piano,
GuestSet,
WallClock,
Masterpiece,
TeaSet,
Chandelier,
MAX = Chandelier,
}

View File

@@ -0,0 +1,9 @@
namespace PKHeX.Core;
public enum TrainerHillMode3E : byte
{
Normal = 0,
Variety = 1,
Unique = 2,
Expert = 3,
}

View File

@@ -0,0 +1,38 @@
namespace PKHeX.Core;
public enum TrendyWord3E : byte
{
KTHXBYE = 0,
YESSIR = 1,
AVANTGARDE = 2,
COUPLE = 3,
MUCHOBLIGED = 4,
YEEHAW = 5,
MEGA = 6,
ONEHITKO = 7,
DESTINY = 8,
CANCEL = 9,
NEW = 10,
FLATTEN = 11,
KIDDING = 12,
LOSER = 13,
LOSING = 14,
HAPPENING = 15,
HIPAND = 16,
SHAKE = 17,
SHADY = 18,
UPBEAT = 19,
MODERN = 20,
SMELLYA = 21,
BANG = 22,
KNOCKOUT = 23,
HASSLE = 24,
WINNER = 25,
FEVER = 26,
WANNABE = 27,
BABY = 28,
HEART = 29,
OLD = 30,
YOUNG = 31,
UGLY = 32,
}

View File

@@ -0,0 +1,107 @@
namespace PKHeX.Core;
public enum Accessory4 : byte
{
WhiteFluff = 0,
YellowFluff = 1,
PinkFluff = 2,
BrownFluff = 3,
BlackFluff = 4,
OrangeFluff = 5,
RoundPebble = 6,
GlitterBoulder = 7,
SnaggyPebble = 8,
JaggedBoulder = 9,
BlackPebble = 10,
MiniPebble = 11,
PinkScale = 12,
BlueScale = 13,
GreenScale = 14,
PurpleScale = 15,
BigScale = 16,
NarrowScale = 17,
BlueFeather = 18,
RedFeather = 19,
YellowFeather = 20,
WhiteFeather = 21,
BlackMoustache = 22,
WhiteMoustache = 23,
BlackBeard = 24,
WhiteBeard = 25,
SmallLeaf = 26,
BigLeaf = 27,
NarrowLeaf = 28,
ShedClaw = 29,
ShedHorn = 30,
ThinMushroom = 31,
ThickMushroom = 32,
Stump = 33,
PrettyDewdrop = 34,
SnowCrystal = 35,
Sparks = 36,
ShimmeringFire = 37,
MysticFire = 38,
Determination = 39,
PeculiarSpoon = 40,
PuffySmoke = 41,
PoisonExtract = 42,
WealthyCoin = 43,
EerieThing = 44,
Spring = 45,
Seashell = 46,
HummingNote = 47,
ShinyPowder = 48,
GlitterPowder = 49,
RedFlower = 50,
PinkFlower = 51,
WhiteFlower = 52,
BlueFlower = 53,
OrangeFlower = 54,
YellowFlower = 55,
GooglySpecs = 56,
BlackSpecs = 57,
GorgeousSpecs = 58,
SweetCandy = 59,
Confetti = 60,
// For accessories below this point, only 1 copy can be owned at once
ColoredParasol = 61,
OldUmbrella = 62,
Spotlight = 63,
Cape = 64,
StandingMike = 65,
Surfboard = 66,
Carpet = 67,
RetroPipe = 68,
FluffyBed = 69,
MirrorBall = 70,
PhotoBoard = 71,
PinkBarrette = 72,
RedBarrette = 73,
BlueBarrette = 74,
YellowBarrette = 75,
GreenBarrette = 76,
PinkBalloon = 77,
RedBalloons = 78,
BlueBalloons = 79,
YellowBalloon = 80,
GreenBalloons = 81,
LaceHeadress = 82,
TopHat = 83,
SilkVeil = 84,
HeroicHeadband = 85,
ProfessorHat = 86,
FlowerStage = 87,
GoldPedestal = 88,
GlassStage = 89,
AwardPodium = 90,
CubeStage = 91,
TURTWIGMask = 92,
CHIMCHARMask = 93,
PIPLUPMask = 94,
BigTree = 95,
Flag = 96,
Crown = 97,
Tiara = 98,
Comet = 99,
}

View File

@@ -0,0 +1,23 @@
namespace PKHeX.Core;
public enum Backdrop4 : byte
{
DressUp = 0,
Ranch = 1,
CityatNight = 2,
SnowyTown = 3,
Fiery = 4,
OuterSpace = 5,
Desert = 6,
CumulusCloud = 7,
FlowerPatch = 8,
FutureRoom = 9,
OpenSea = 10,
TotalDarkness = 11,
TatamiRoom = 12,
GingerbreadRoom = 13,
Seafloor = 14,
Underground = 15,
Sky = 16,
Theater = 17,
}

View File

@@ -0,0 +1,37 @@
namespace PKHeX.Core;
public enum ToughWord4 : byte
{
EarthTones = 0,
Implant = 1,
GoldenRatio = 2,
Omnibus = 3,
Starboard = 4,
MoneyRate = 5,
Resolution = 6,
Cadenza = 7,
Education = 8,
Cubism = 9,
CrossStitch = 10,
Artery = 11,
BoneDensity = 12,
Gommage = 13,
Streaming = 14,
Conductivity = 15,
Copyright = 16,
TwoStep = 17,
Contour = 18,
Neutrino = 19,
Howling = 20,
Spreadsheet = 21,
GMT = 22,
Irritability = 23,
Fractals = 24,
Flambe = 25,
StockPrices = 26,
PHBalance = 27,
Vector = 28,
Polyphenol = 29,
Ubiquitous = 30,
REMSleep = 31,
}

View File

@@ -0,0 +1,24 @@
namespace PKHeX.Core;
public enum VillaFurniture4 : byte
{
BigSofa = 0,
SmallSofa = 1,
Bed = 2,
NightTable = 3,
TV = 4,
AudioSystem = 5,
Bookshelf = 6,
Rack = 7,
Houseplant = 8,
PCDesk = 9,
MusicBox = 10,
PokemonBust1 = 11,
PokemonBust2 = 12,
Piano = 13,
GuestSet = 14,
WallClock = 15,
Masterpiece = 16,
TeaSet = 17,
Chandelier = 18,
}

View File

@@ -0,0 +1,29 @@
namespace PKHeX.Core;
public enum Wallpaper4Pt : byte
{
Forest = 0,
City = 1,
Desert = 2,
Savanna = 3,
Crag = 4,
Volcano = 5,
Snow = 6,
Cave = 7,
Beach = 8,
Seafloor = 9,
River = 10,
Sky = 11,
Checks = 12,
PokeCenter = 13,
Machine = 14,
Simple = 15,
Distortion = 16,
Contest = 17,
Nostalgic = 18,
Croagunk = 19,
trio = 20,
PikaPika = 21,
Legend = 22,
Team_Galactic = 23,
}