mirror of
https://github.com/kwsch/NHSE.git
synced 2026-08-08 02:34:36 -05:00
94 lines
3.7 KiB
C#
94 lines
3.7 KiB
C#
using System;
|
|
using System.Runtime.InteropServices;
|
|
using static System.Buffers.Binary.BinaryPrimitives;
|
|
|
|
namespace NHSE.Core;
|
|
|
|
public class PlayerHouse1(Memory<byte> raw) : IPlayerHouse
|
|
{
|
|
public const int SIZE = 0x26400;
|
|
public virtual string Extension => "nhph";
|
|
|
|
public Span<byte> Data => raw.Span;
|
|
|
|
public byte[] Write() => Data.ToArray();
|
|
|
|
public uint HouseLevel { get => ReadUInt32LittleEndian(Data); set => WriteUInt32LittleEndian(Data, value); }
|
|
public WallType WallUniqueID { get => (WallType)ReadUInt16LittleEndian(Data[0x04..]); set => WriteUInt16LittleEndian(Data[0x04..], (ushort)value); }
|
|
public RoofType RoofUniqueID { get => (RoofType)ReadUInt16LittleEndian(Data[0x06..]); set => WriteUInt16LittleEndian(Data[0x06..], (ushort)value); }
|
|
public DoorKind DoorUniqueID { get => (DoorKind)ReadUInt16LittleEndian(Data[0x08..]); set => WriteUInt16LittleEndian(Data[0x08..], (ushort)value); }
|
|
public WallType OrderWallUniqueID { get => (WallType)ReadUInt16LittleEndian(Data[0x0A..]); set => WriteUInt16LittleEndian(Data[0x0A..], (ushort)value); }
|
|
public RoofType OrderRoofUniqueID { get => (RoofType)ReadUInt16LittleEndian(Data[0x0C..]); set => WriteUInt16LittleEndian(Data[0x0C..], (ushort)value); }
|
|
public DoorKind OrderDoorUniqueID { get => (DoorKind)ReadUInt16LittleEndian(Data[0x0E..]); set => WriteUInt16LittleEndian(Data[0x0E..], (ushort)value); }
|
|
|
|
public EncryptedInt32 Loan
|
|
{
|
|
get => EncryptedInt32.Read(Data[0x10..]);
|
|
set => value.Write(Data[0x10..]);
|
|
}
|
|
|
|
public EncryptedInt32 Unknown
|
|
{
|
|
get => EncryptedInt32.Read(Data[0x18..]);
|
|
set => value.Write(Data[0x18..]);
|
|
}
|
|
|
|
public Span<short> EventFlags => MemoryMarshal.Cast<byte, short>(Data.Slice(0x20, 0x100));
|
|
|
|
public const int MaxRoom = 6;
|
|
public const int RoomStart = 0x120;
|
|
|
|
public virtual IPlayerRoom GetRoom(int roomIndex)
|
|
{
|
|
if ((uint)roomIndex >= MaxRoom)
|
|
throw new ArgumentOutOfRangeException(nameof(roomIndex));
|
|
|
|
var data = Data.Slice(RoomStart + (roomIndex * PlayerRoom1.SIZE), PlayerRoom1.SIZE);
|
|
return new PlayerRoom1(data.ToArray());
|
|
}
|
|
|
|
public virtual void SetRoom(int roomIndex, IPlayerRoom room)
|
|
{
|
|
if ((uint)roomIndex >= MaxRoom)
|
|
throw new ArgumentOutOfRangeException(nameof(roomIndex));
|
|
|
|
var dest = Data.Slice(RoomStart + (roomIndex * PlayerRoom1.SIZE), PlayerRoom1.SIZE);
|
|
room.Write().CopyTo(dest);
|
|
}
|
|
|
|
public sbyte NPC1 { get => (sbyte)Data[0x263D0]; set => Data[0x263D0] = (byte)value; }
|
|
public sbyte NPC2 { get => (sbyte)Data[0x263D1]; set => Data[0x263D1] = (byte)value; }
|
|
|
|
// 2 bytes padding
|
|
|
|
public Item DoorDecoItemName
|
|
{
|
|
get => Data.Slice(0x263D4, 8).ToArray().ToClass<Item>();
|
|
set => value.ToBytesClass().CopyTo(Data[0x263D4..]);
|
|
}
|
|
|
|
public bool PlayerHouseFlag { get => Data[0x263DC] != 0; set => Data[0x263DC] = (byte)(value ? 1 : 0); }
|
|
|
|
public Item PostItemName
|
|
{
|
|
get => Data.Slice(0x263E0, 8).ToArray().ToClass<Item>();
|
|
set => value.ToBytesClass().CopyTo(Data[0x263E0..]);
|
|
}
|
|
|
|
public Item OrderPostItemName
|
|
{
|
|
get => Data.Slice(0x263E8, 8).ToArray().ToClass<Item>();
|
|
set => value.ToBytesClass().CopyTo(Data[0x263E8..]);
|
|
}
|
|
|
|
// cockroach @ 0x263f0 -- meh
|
|
public PlayerHouse2 Upgrade()
|
|
{
|
|
var data = new byte[PlayerHouse2.SIZE];
|
|
Data[..0x120].CopyTo(data.AsSpan(0)); // HouseLevel -> EventFlag
|
|
for (int i = 0; i < MaxRoom; i++)
|
|
((PlayerRoom1)GetRoom(i)).Upgrade().Write().CopyTo(data.AsSpan(0x120 + (i * PlayerRoom2.SIZE))); // RoomList
|
|
Data.Slice(0x263D0, 0x30).CopyTo(data.AsSpan(0x289F8)); // PlayerList -> Cockroach
|
|
return new PlayerHouse2(data);
|
|
}
|
|
} |