using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
namespace OpenVIII
{
namespace Kernel
{
///
/// Devour Data
///
///
[StructLayout(LayoutKind.Explicit, Size = 12, Pack = 0)]
public class Devour
{
#region Fields
public const int Count = 16;
public const int ID = 28;
public const int Size = 12;
#endregion Fields
#region Constructors
public FF8String Description => Memory.Strings.ReadByOffset(Strings.FileID.Kernel, ID, _descriptionOffset);
public override string ToString() => Description;
public Devour(BinaryReader br, int i)
{
//Description = Memory.Strings.Read(Strings.FileID.KERNEL, ID, i);
//br.BaseStream.Seek(2, SeekOrigin.Current);
if (!br.Read(out _descriptionOffset)) return;
Debug.WriteLine(Description); //TODO fix description
//0x0000 2 bytes Offset to devour description
if (!br.Read(out _damageOrHeal)) return;
//0x0002 1 byte Damage or heal HP and Status
//0x1E - Cure
//0x1F - Damage
_quantity = (Quantity)br.ReadByte();
//0x0003 1 byte HP Heal / DMG Quantity Flag
//0x00 - 0 %
//0x01 - 6.25 %
//0x02 - 12.50 %
//0x04 - 25 %
//0x08 - 50 %
//0x10 - 100 %
Statuses1 = (BattleOnlyStatuses)br.ReadUInt32();
//0x0004 4 bytes status_1; //statuses 8-39
Statuses0 = (PersistentStatuses)br.ReadUInt16();
//0x0008 2 bytes status_0; //statuses 0-7
StatFlags = (StatFlags)br.ReadByte();
//0x000A 1 byte Raised Stat Flag
//0x00 - None
//0x01 - STR
//0x02 - VIT
//0x04 - MAG
//0x08 - SPR
//0x10 - SPD
HP = br.ReadByte();
//0x000B 1 byte Raised Stat HP Quantity
}
#endregion Constructors
#region Properties
[field: FieldOffset(0x3)]
private readonly Quantity _quantity;
[field: FieldOffset(0x2)]
private readonly byte _damageOrHeal;
public float Amount
{
get
{
var a = 0f;
if (_quantity.HasFlag(Quantity._0625f)) a += .0625f;
if (_quantity.HasFlag(Quantity._1250f)) a += .1250f;
if (_quantity.HasFlag(Quantity._1f)) a += 1f;
if (_quantity.HasFlag(Quantity._25f)) a += .25f;
if (_quantity.HasFlag(Quantity._50f)) a += .50f;
return a;
}
}
[field: FieldOffset(0x0)]
private readonly ushort _descriptionOffset;
///
/// True for heal, False for damage
///
public bool DamageOrHeal
{
get
{
switch (_damageOrHeal)
{
case 0x1E:
return true;
case 0x1F:
return false;
default:
throw new InvalidDataException($"{nameof(Devour)}::{nameof(DamageOrHeal)} Invalid value: 0x{_damageOrHeal:X2} to be 0x1E or 0x1F");
}
}
}
[field: FieldOffset(0xB)]
public byte HP { get; }
[field: FieldOffset(0xA)]
public StatFlags StatFlags { get; }
[field: FieldOffset(0x8)]
public PersistentStatuses Statuses0 { get; }
[field: FieldOffset(0x4)]
public BattleOnlyStatuses Statuses1 { get; }
#endregion Properties
#region Methods
public static IReadOnlyList Read(BinaryReader br)
=> Enumerable.Range(0, Count).Select(x => CreateInstance(br, x)).ToList();
//public override string ToString() => Description;
private static Devour CreateInstance(BinaryReader br, int i) => new Devour(br, i);
#endregion Methods
}
}
}