NHSE/NHSE.Core/Structures/Misc/GSavePlayerManpu.cs
Kurt eb554a623b Fix reaction wheel UI display
revised structure, need to abstract things a little for it
Closes #427
see also #428
2020-11-22 19:57:29 -08:00

126 lines
3.9 KiB
C#

using System;
using System.Runtime.InteropServices;
#pragma warning disable CS8618, CA1815, CA1819, IDE1006
namespace NHSE.Core
{
/// <summary>
/// Original Reactions object from release
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct GSavePlayerManpu : IReactionStore
{
public const int SIZE = 0x88;
private const int MaxCount = 64;
private const int WheelCount = 8;
/// <summary>
/// List of known Reaction IDs
/// </summary>
[field: MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxCount)]
public Reaction[] ManpuBit { get; set; }
/// <summary>
/// Emotions that are currently bound to the Reaction Wheel.
/// </summary>
[field: MarshalAs(UnmanagedType.ByValArray, SizeConst = WheelCount)]
public Reaction[] UIList { get; set; }
/// <summary>
/// Flags indicating if an Reaction (at the same index?) is newly learned or not.
/// </summary>
[field: MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = MaxCount)]
public bool[] NewFlag { get; set; }
public void AddMissingReactions()
{
var all = (Reaction[])Enum.GetValues(typeof(Reaction));
foreach (var react in all)
AddReaction(react);
}
// returns true if failed
public bool AddReaction(Reaction react)
{
if (react.ToString().StartsWith("UNUSED"))
return true;
var index = Array.IndexOf(ManpuBit, react);
if (index >= 0)
return false;
var empty = EmptyIndex;
if (empty < 0)
return true;
ManpuBit[empty] = react;
return false;
}
private int EmptyIndex => Array.FindIndex(ManpuBit, z => z == 0);
}
/// <summary>
/// Reactions object revised in v1.5.0
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct GSavePlayerManpu15 : IReactionStore
{
public const int SIZE = 0x208;
private const int MaxCount = 256; // up from 64
private const int WheelCount = 8;
/// <summary>
/// List of known Reaction IDs
/// </summary>
[field: MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxCount)]
public Reaction[] ManpuBit { get; set; }
/// <summary>
/// Emotions that are currently bound to the Reaction Wheel.
/// </summary>
[field: MarshalAs(UnmanagedType.ByValArray, SizeConst = WheelCount)]
public Reaction[] UIList { get; set; }
/// <summary>
/// Flags indicating if an Reaction (at the same index?) is newly learned or not.
/// </summary>
[field: MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = MaxCount)]
public bool[] NewFlag { get; set; }
public void AddMissingReactions()
{
var all = (Reaction[])Enum.GetValues(typeof(Reaction));
foreach (var react in all)
AddReaction(react);
}
// returns true if failed
public bool AddReaction(Reaction react)
{
if (react.ToString().StartsWith("UNUSED"))
return true;
var index = Array.IndexOf(ManpuBit, react);
if (index >= 0)
return false;
var empty = EmptyIndex;
if (empty < 0)
return true;
ManpuBit[empty] = react;
return false;
}
private int EmptyIndex => Array.FindIndex(ManpuBit, z => z == 0);
}
public interface IReactionStore
{
Reaction[] ManpuBit { get; set; }
Reaction[] UIList { get; set; }
bool[] NewFlag { get; set; }
bool AddReaction(Reaction react);
void AddMissingReactions();
}
}