mirror of
https://github.com/kwsch/NHSE.git
synced 2026-08-27 21:34:15 -05:00
Update for 3.0.0 (no map editing)
Map field items/placement is revised, need a fair bit of time to figure out how best to handle it along with backwards version support.
This commit is contained in:
@@ -138,7 +138,7 @@ public void SetDesignsTailor(IReadOnlyList<DesignPatternPRO> value)
|
||||
{
|
||||
var count = Math.Min(Offsets.PatternCount, value.Count);
|
||||
for (int i = 0; i < count; i++)
|
||||
value[i].Data.CopyTo(Data.Slice(Offsets.PatternTailor + (i * DesignPatternPRO.SIZE)));
|
||||
value[i].Data.CopyTo(Data[(Offsets.PatternTailor + (i * DesignPatternPRO.SIZE))..]);
|
||||
}
|
||||
|
||||
private const int EventFlagsSaveCount = 0x400;
|
||||
@@ -166,14 +166,14 @@ public ushort GetAcre(int index)
|
||||
{
|
||||
if ((uint)index > AcreMax)
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
return ReadUInt16LittleEndian(Data.Slice(Offsets.OutsideField + (index * 2)));
|
||||
return ReadUInt16LittleEndian(Data[(Offsets.OutsideField + (index * 2))..]);
|
||||
}
|
||||
|
||||
public void SetAcre(int index, ushort value)
|
||||
{
|
||||
if ((uint)index > AcreMax)
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
WriteUInt16LittleEndian(Data.Slice(Offsets.OutsideField + (index * 2)), value);
|
||||
WriteUInt16LittleEndian(Data[(Offsets.OutsideField + (index * 2))..], value);
|
||||
}
|
||||
|
||||
public byte[] GetAcreBytes() => Data.Slice(Offsets.OutsideField, AcreSizeAll).ToArray();
|
||||
@@ -182,7 +182,7 @@ public void SetAcreBytes(ReadOnlySpan<byte> data)
|
||||
{
|
||||
if (data.Length != AcreSizeAll)
|
||||
throw new ArgumentOutOfRangeException(nameof(data.Length));
|
||||
data.CopyTo(Data.Slice(Offsets.OutsideField));
|
||||
data.CopyTo(Data[Offsets.OutsideField..]);
|
||||
}
|
||||
|
||||
public TerrainTile[] GetTerrainTiles() => TerrainTile.GetArray(Data.Slice(Offsets.LandMakingMap, MapGrid.MapTileCount16x16 * TerrainTile.SIZE));
|
||||
@@ -224,20 +224,20 @@ public ushort OutsideFieldTemplateUniqueId
|
||||
|
||||
public ushort MainFieldParamUniqueID
|
||||
{
|
||||
get => ReadUInt16LittleEndian(Data.Slice(Offsets.OutsideField + AcreSizeAll + 2));
|
||||
set => WriteUInt16LittleEndian(Data.Slice(Offsets.OutsideField + AcreSizeAll + 2), value);
|
||||
get => ReadUInt16LittleEndian(Data[(Offsets.OutsideField + AcreSizeAll + 2)..]);
|
||||
set => WriteUInt16LittleEndian(Data[(Offsets.OutsideField + AcreSizeAll + 2)..], value);
|
||||
}
|
||||
|
||||
public uint EventPlazaLeftUpX
|
||||
{
|
||||
get => ReadUInt32LittleEndian(Data.Slice(Offsets.OutsideField + AcreSizeAll + 4));
|
||||
set => WriteUInt32LittleEndian(Data.Slice(Offsets.OutsideField + AcreSizeAll + 4), value);
|
||||
get => ReadUInt32LittleEndian(Data[(Offsets.OutsideField + AcreSizeAll + 4)..]);
|
||||
set => WriteUInt32LittleEndian(Data[(Offsets.OutsideField + AcreSizeAll + 4)..], value);
|
||||
}
|
||||
|
||||
public uint EventPlazaLeftUpZ
|
||||
{
|
||||
get => ReadUInt32LittleEndian(Data.Slice(Offsets.OutsideField + AcreSizeAll + 8));
|
||||
set => WriteUInt32LittleEndian(Data.Slice(Offsets.OutsideField + AcreSizeAll + 8), value);
|
||||
get => ReadUInt32LittleEndian(Data[(Offsets.OutsideField + AcreSizeAll + 8)..]);
|
||||
set => WriteUInt32LittleEndian(Data[(Offsets.OutsideField + AcreSizeAll + 8)..], value);
|
||||
}
|
||||
|
||||
public GSaveVisitorNpc Visitor
|
||||
|
||||
@@ -54,6 +54,8 @@ public abstract class MainSaveOffsets
|
||||
public abstract int PlayerHouseSize { get; }
|
||||
public abstract int PlayerRoomSize { get; }
|
||||
|
||||
public virtual int AcreColumnCount => 7;
|
||||
|
||||
public abstract IVillager ReadVillager(Memory<byte> data);
|
||||
public abstract IVillagerHouse ReadVillagerHouse(Memory<byte> data);
|
||||
public abstract IPlayerHouse ReadPlayerHouse(Memory<byte> data);
|
||||
|
||||
@@ -5,54 +5,78 @@ namespace NHSE.Core;
|
||||
/// <summary>
|
||||
/// <inheritdoc cref="MainSaveOffsets"/>
|
||||
/// </summary>
|
||||
/// <remarks>Same as <see cref="MainSaveOffsets110"/></remarks>
|
||||
public class MainSaveOffsets30 : MainSaveOffsets
|
||||
{
|
||||
public override int PatternCount => PatternCount2;
|
||||
|
||||
#region GSaveLand
|
||||
public const int GSaveLandStart = 0x110;
|
||||
|
||||
// GSaveNpc @ 0x000
|
||||
public override int Animal => GSaveLandStart + 0x10;
|
||||
|
||||
// GSaveWeather
|
||||
public const int GSaveWeather = GSaveLandStart + 0x1e35f0;
|
||||
public override int WeatherArea => GSaveWeather + 0x14; // Hemisphere
|
||||
public override int WeatherRandSeed => GSaveWeather + 0x18;
|
||||
|
||||
// GSaveLandMyDesign
|
||||
public override int LandMyDesign => GSaveLandStart + 0x1e3848;
|
||||
public override int PatternsPRO => LandMyDesign + (PatternCount2 * DesignPattern.SIZE);
|
||||
public override int PatternFlag => PatternsPRO + (PatternCount2 * DesignPatternPRO.SIZE);
|
||||
public override int PatternTailor => PatternFlag + DesignPattern.SIZE;
|
||||
|
||||
public override int PatternsEditFlagStart => GSaveLandStart + 0x8BE150; // x100, HasPlayerEdited?
|
||||
public override int PatternsProEditFlagStart => PatternsEditFlagStart + 0x64; // x100, HasPlayerEdited?
|
||||
|
||||
public const int GSaveWeather = GSaveLandStart + 0x1e35f0;
|
||||
public override int WeatherArea => GSaveWeather + 0x14; // Hemisphere
|
||||
public override int WeatherRandSeed => GSaveWeather + 0x18;
|
||||
|
||||
// GSaveEventFlagLand
|
||||
public override int EventFlagLand => GSaveLandStart + 0x22ebf0;
|
||||
|
||||
// GSaveMainField
|
||||
public const int GSaveMainFieldStart = GSaveLandStart + 0x22f3f0;
|
||||
|
||||
// Map size increased to accommodate the Hotel, by adding 2 columns of acres!
|
||||
public override int AcreColumnCount => 9; // from 7 to 9
|
||||
// does this actually impact anything? We'll eventually find out if so; I hope it is just 2 columns of unused.
|
||||
|
||||
// Layer0: 54000 => 6C000
|
||||
// Layer1: 54000 => 6C000
|
||||
// ItemSwitch0 1500 => 1B00
|
||||
// ItemSwitch1 1500 => 1B00
|
||||
// MainField 398 => 3AC
|
||||
public override int FieldItem => GSaveMainFieldStart + 0x00000;
|
||||
public override int LandMakingMap => GSaveMainFieldStart + 0xAAA00;
|
||||
public override int MainFieldStructure => GSaveMainFieldStart + 0xCF600;
|
||||
public override int OutsideField => GSaveMainFieldStart + 0xCF998;
|
||||
public override int MyDesignMap => GSaveMainFieldStart + 0xCFA34;
|
||||
public override int LandMakingMap => GSaveMainFieldStart + 0xdb600; // CHANGED*** all following are shifted.
|
||||
public override int MainFieldStructure => GSaveMainFieldStart + 0x100200;
|
||||
public override int OutsideField => GSaveMainFieldStart + 0x1005ac;
|
||||
public override int MyDesignMap => GSaveMainFieldStart + 0x100648;
|
||||
|
||||
public override int PlayerHouseList => GSaveLandStart + 0x30a6bc;
|
||||
public override int NpcHouseList => GSaveLandStart + 0x44f7fc;
|
||||
// GSavePlayerHouseList
|
||||
public override int PlayerHouseList => GSaveLandStart + 0x33cad0;
|
||||
|
||||
public const int GSaveShop = GSaveLandStart + 0x45b50c;
|
||||
// GSaveNpcHouseList
|
||||
public override int NpcHouseList => GSaveLandStart + 0x481c10;
|
||||
|
||||
// GSaveShop
|
||||
public const int GSaveShop = GSaveLandStart + 0x48d920;
|
||||
public override int ShopKabu => GSaveShop + 0x2d40; // part of shop; tailor & zakka increased size
|
||||
public override int Museum => GSaveLandStart + 0x45ec44;
|
||||
public override int Visitor => GSaveLandStart + 0x462048;
|
||||
public override int SaveFg => GSaveLandStart + 0x462278;
|
||||
public override int BulletinBoard => GSaveLandStart + 0x462bc0;
|
||||
public override int AirportThemeColor => GSaveLandStart + 0x5437c8;
|
||||
|
||||
// GSaveMuseum
|
||||
public override int Museum => GSaveLandStart + 0x491110;
|
||||
// GSaveVisitorNpc
|
||||
public override int Visitor => GSaveLandStart + 0x494514;
|
||||
// GSaveSaveFg
|
||||
public override int SaveFg => GSaveLandStart + 0x494760;
|
||||
// GSaveBulletinBoard
|
||||
public override int BulletinBoard => GSaveLandStart + 0x4950a8;
|
||||
public override int AirportThemeColor => GSaveLandStart + 0x575cb0;
|
||||
#endregion
|
||||
|
||||
#region GSaveLandOther
|
||||
public const int GSaveLandOtherStart = 0x547520;
|
||||
public const int GSaveLandOtherStart = 0x5b3d50;
|
||||
|
||||
public override int LostItemBox => GSaveLandOtherStart + 0x3726c0;
|
||||
public override int LastSavedTime => GSaveLandOtherStart + 0x377020;
|
||||
public const int GSaveMyDesignHolderList = GSaveLandOtherStart + 0x3c9640;
|
||||
public override int PatternsEditFlagStart => GSaveMyDesignHolderList; // x100, HasPlayerEdited? NormalHolders
|
||||
public override int PatternsProEditFlagStart => PatternsEditFlagStart + 0x64; // x100, HasPlayerEdited? // ProHolders
|
||||
|
||||
public override int LostItemBox => GSaveLandOtherStart + 0x3c4fc0;
|
||||
public override int LastSavedTime => GSaveLandOtherStart + 0x3c9920;
|
||||
#endregion
|
||||
|
||||
public override int VillagerSize => Villager2.SIZE;
|
||||
|
||||
@@ -32,10 +32,10 @@ public abstract class PersonalOffsets
|
||||
public abstract int Bank { get; }
|
||||
public abstract int Recipes { get; }
|
||||
|
||||
public int MaxAchievementID { get; } = 512;
|
||||
public int Pockets1Count { get; } = 20;
|
||||
public int Pockets2Count { get; } = 20;
|
||||
public int ItemChestCount { get; } = 5000;
|
||||
public int MaxAchievementID => 512;
|
||||
public int Pockets1Count => 20;
|
||||
public int Pockets2Count => 20;
|
||||
public virtual int ItemChestCount => 5000;
|
||||
public abstract int MaxRecipeID { get; }
|
||||
public abstract int MaxRemakeBitFlag { get; }
|
||||
|
||||
|
||||
@@ -7,19 +7,22 @@ namespace NHSE.Core;
|
||||
/// </summary>
|
||||
public sealed class PersonalOffsets30 : PersonalOffsets
|
||||
{
|
||||
// GSavePlayer
|
||||
private const int Player = 0x110;
|
||||
|
||||
public override int PersonalId => Player + 0xAFA8;
|
||||
public override int EventFlagsPlayer => Player + 0xAFE0;
|
||||
// shifted down as LookPack increased from af90->c120
|
||||
public override int PersonalId => Player + 0xc138;
|
||||
public override int EventFlagsPlayer => Player + 0xc170;
|
||||
|
||||
private const int GSaveLifeSupport = Player + 0xBFE0;
|
||||
// GSaveLifeSupport
|
||||
private const int GSaveLifeSupport = Player + 0xd170;
|
||||
public override int CountAchievement => GSaveLifeSupport + 0xE98; // CountAchievement
|
||||
|
||||
public override int NowPoint => GSaveLifeSupport + 0x5498; // Nook Miles
|
||||
public override int TotalPoint => NowPoint + 8; // Total Nook Miles Earned
|
||||
public override int Birthday => Player + 0x1228c;
|
||||
|
||||
public override int ProfileMain => Player + 0x122a0;
|
||||
public override int Birthday => Player + 0x1341c;
|
||||
|
||||
public override int ProfileMain => Player + 0x13430;
|
||||
public override int ProfilePhoto => ProfileMain + 0x14;
|
||||
public override int ProfileBirthday => ProfileMain + 0x23058;
|
||||
public override int ProfileFruit => ProfileMain + 0x2305C;
|
||||
@@ -28,19 +31,23 @@ public sealed class PersonalOffsets30 : PersonalOffsets
|
||||
|
||||
// end player
|
||||
|
||||
private const int PlayerOther = 0x36a50;
|
||||
private const int PlayerOther = 0x37be0;
|
||||
|
||||
public override int Pockets1 => PlayerOther + 0x10;
|
||||
public override int Pockets2 => Pockets1 + (8 * Pockets1Count) + 0x18;
|
||||
public override int Wallet => Pockets2 + (8 * Pockets2Count) + 0x18;
|
||||
public override int ItemChest => PlayerOther + 0x18C;
|
||||
public override int ItemCollectBit => PlayerOther + 0xA058;
|
||||
public override int ItemRemakeCollectBit => PlayerOther + 0xA7AC;
|
||||
public override int Manpu => PlayerOther + 0xAF7C;
|
||||
public override int Bank => PlayerOther + 0x24afc;
|
||||
|
||||
// chest increased in size! 9C44 => 11944
|
||||
public override int ItemChestCount => 0x11944 / Item.SIZE; // 9000
|
||||
|
||||
public override int ItemCollectBit => PlayerOther + 0x11d58;
|
||||
public override int ItemRemakeCollectBit => PlayerOther + 0x124ac;
|
||||
public override int Manpu => PlayerOther + 0x12c7c;
|
||||
public override int Bank => PlayerOther + 0x2d69c;
|
||||
public override int Recipes => Bank + 0x10;
|
||||
|
||||
public override int MaxRecipeID => 0x430;
|
||||
public override int MaxRecipeID => 0x430; // unchanged
|
||||
public override int MaxRemakeBitFlag => 0x7D0 * 32;
|
||||
|
||||
public override IReactionStore ReadReactions(ReadOnlySpan<byte> data) => data.Slice(Manpu, GSavePlayerManpu15.SIZE).ToStructure<GSavePlayerManpu15>();
|
||||
|
||||
Reference in New Issue
Block a user