using System;
using System.Collections.Generic;
using System.IO;
using ACE.DatLoader.Entity;
using ACE.Entity.Enum;
namespace ACE.DatLoader.FileTypes
{
///
/// This reads an "indoor" cell from the client_cell.dat. This is mostly dungeons, but can also be a building interior.
/// An EnvCell is designated by starting 0x0100 (whereas all landcells are in the 0x0001 - 0x0040 range.
///
/// The fileId is the full int32/dword landblock value as reported by the @loc command (e.g. 0x12345678)
///
///
/// Very special thanks again to David Simpson for his early work on reading the cell.dat. Even bigger thanks for his documentation of it!
///
[DatFileType(DatFileType.EnvCell)]
public class EnvCell : FileType
{
public EnvCellFlags Flags { get; private set; }
// 0x08000000 surfaces (which contains degrade/quality info to reference the specific 0x06000000 graphics)
public List Surfaces { get; } = new List();
// the 0x0D000000 model of the pre-fab dungeon block
public uint EnvironmentId { get; private set; }
public ushort CellStructure { get; private set; }
public Frame Position { get; } = new Frame();
public List CellPortals { get; } = new List();
public List VisibleCells { get; } = new List();
public List StaticObjects { get; } = new List();
public uint RestrictionObj { get; private set; }
public bool SeenOutside => Flags.HasFlag(EnvCellFlags.SeenOutside);
public override void Unpack(BinaryReader reader)
{
Id = reader.ReadUInt32();
Flags = (EnvCellFlags)reader.ReadUInt32();
reader.BaseStream.Position += 4; // Skip ahead 4 bytes, because this is the CellId. Again. Twice.
byte numSurfaces = reader.ReadByte();
byte numPortals = reader.ReadByte(); // Note that "portal" in this context does not refer to the swirly pink/purple thing, its basically connecting cells
ushort numStabs = reader.ReadUInt16(); // I believe this is what cells can be seen from this one. So the engine knows what else it needs to load/draw.
// Read what surfaces are used in this cell
for (uint i = 0; i < numSurfaces; i++)
Surfaces.Add(0x08000000u | reader.ReadUInt16()); // these are stored in the dat as short values, so we'll make them a full dword
EnvironmentId = (0x0D000000u | reader.ReadUInt16());
CellStructure = reader.ReadUInt16();
Position.Unpack(reader);
CellPortals.Unpack(reader, numPortals);
for (uint i = 0; i < numStabs; i++)
VisibleCells.Add(reader.ReadUInt16());
if ((Flags & EnvCellFlags.HasStaticObjs) != 0)
StaticObjects.Unpack(reader);
if ((Flags & EnvCellFlags.HasRestrictionObj) != 0)
RestrictionObj = reader.ReadUInt32();
}
}
}