using System.Collections.Generic;
using System.IO;
using System.Numerics;
using ACE.DatLoader.Entity;
using ACE.Entity.Enum;
namespace ACE.DatLoader.FileTypes
{
///
/// These are client_portal.dat files starting with 0x02.
/// They are basically 3D model descriptions.
///
///
/// A big huge thank you to "Pea" for his trailblazing work on decoding this structure. Without his work on this, we might still be decoding models on cave walls.
///
[DatFileType(DatFileType.Setup)]
public class SetupModel : FileType
{
public SetupFlags Flags { get; private set; }
public bool AllowFreeHeading { get; private set; }
public bool HasPhysicsBSP { get; private set; }
public List Parts { get; } = new List();
public List ParentIndex { get; } = new List();
public List DefaultScale { get; } = new List();
public Dictionary HoldingLocations { get; } = new Dictionary();
public Dictionary ConnectionPoints { get; } = new Dictionary();
public Dictionary PlacementFrames { get; } = new Dictionary();
public List CylSpheres { get; } = new List();
public List Spheres { get; } = new List();
public float Height { get; private set; }
public float Radius { get; private set; }
public float StepUpHeight { get; private set; }
public float StepDownHeight { get; private set; }
public Sphere SortingSphere { get; private set; } = new Sphere();
public Sphere SelectionSphere { get; private set; } = new Sphere();
public Dictionary Lights { get; } = new Dictionary();
public uint DefaultAnimation { get; private set; }
public uint DefaultScript { get; private set; }
public uint DefaultMotionTable { get; private set; }
public uint DefaultSoundTable { get; private set; }
public uint DefaultScriptTable { get; private set; }
public bool HasMissileFlightPlacement { get; private set; } = false;
public override void Unpack(BinaryReader reader)
{
Id = reader.ReadUInt32();
Flags = (SetupFlags)reader.ReadUInt32();
AllowFreeHeading = (Flags & SetupFlags.AllowFreeHeading) != 0;
HasPhysicsBSP = (Flags & SetupFlags.HasPhysicsBSP) != 0;
// Get all the GraphicsObjects in this SetupModel. These are all the 01-types.
uint numParts = reader.ReadUInt32();
for (int i = 0; i < numParts; i++)
Parts.Add(reader.ReadUInt32());
if ((Flags & SetupFlags.HasParent) != 0)
{
for (int i = 0; i < numParts; i++)
ParentIndex.Add(reader.ReadUInt32());
}
if ((Flags & SetupFlags.HasDefaultScale) != 0)
{
for (int i = 0; i < numParts; i++)
DefaultScale.Add(reader.ReadVector3());
}
HoldingLocations.Unpack(reader);
ConnectionPoints.Unpack(reader);
int placementsCount = reader.ReadInt32();
for (int i = 0; i < placementsCount; i++)
{
int key = reader.ReadInt32();
// there is a frame for each Part
var placementType = new PlacementType();
placementType.Unpack(reader, (uint)Parts.Count);
PlacementFrames.Add(key, placementType);
if (key == (int)Placement.MissileFlight)
HasMissileFlightPlacement = true;
}
CylSpheres.Unpack(reader);
Spheres.Unpack(reader);
Height = reader.ReadSingle();
Radius = reader.ReadSingle();
StepUpHeight = reader.ReadSingle();
StepDownHeight = reader.ReadSingle();
SortingSphere.Unpack(reader);
SelectionSphere.Unpack(reader);
Lights.Unpack(reader);
DefaultAnimation = reader.ReadUInt32();
DefaultScript = reader.ReadUInt32();
DefaultMotionTable = reader.ReadUInt32();
DefaultSoundTable = reader.ReadUInt32();
DefaultScriptTable = reader.ReadUInt32();
}
public static SetupModel CreateSimpleSetup()
{
var setup = new SetupModel();
setup.SortingSphere = Sphere.CreateDummySphere();
setup.SelectionSphere = Sphere.CreateDummySphere();
setup.AllowFreeHeading = true;
return setup;
}
}
}