mirror of
https://github.com/celisej567/LibBSP.git
synced 2026-01-04 06:10:07 +03:00
Refactors to reuse some commonly used code. This changes a lot.
Refactor everything to use a base ILump interface, and a Lump class implementing it to use in place of regular List. Refactor lump structures to use an ILumpObject interface. Eventually Lump<T> will enforce T is ILumpObject, there are some other things to do first. Use Path class to simplify some code in BSP.
This commit is contained in:
@@ -74,6 +74,9 @@
|
||||
<Compile Include="Source\Structs\BSP\StaticModel.cs" />
|
||||
<Compile Include="Source\Structs\BSP\StaticProp.cs" />
|
||||
<Compile Include="Source\Structs\BSP\TextureData.cs" />
|
||||
<Compile Include="Source\Structs\Common\ILumpObject.cs" />
|
||||
<Compile Include="Source\Structs\Common\Lumps\ILump.cs" />
|
||||
<Compile Include="Source\Structs\Common\Lumps\Lump.cs" />
|
||||
<Compile Include="Source\Structs\Common\TextureInfo.cs" />
|
||||
<Compile Include="Source\Structs\BSP\Texture.cs" />
|
||||
<Compile Include="Source\Structs\Common\Entity.cs" />
|
||||
|
||||
@@ -329,22 +329,22 @@ namespace LibBSP {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Factory method to parse a <c>byte</c> array into a <c>List</c> of <see cref="Plane"/> objects.
|
||||
/// Factory method to parse a <c>byte</c> array into a <see cref="Lump{Plane}"/>.
|
||||
/// </summary>
|
||||
/// <param name="data">The data to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <returns>A <c>List</c> of <see cref="Plane"/> objects.</returns>
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
/// <returns>A <see cref="Lump{Plane}"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data" /> was null.</exception>
|
||||
/// <remarks>This function goes here since it can't go into Unity's Plane class, and so can't depend
|
||||
/// on having a constructor taking a byte array.</remarks>
|
||||
public static List<Plane> LumpFactory(byte[] data, MapType type, int version = 0) {
|
||||
public static Lump<Plane> LumpFactory(byte[] data, BSP bsp, LumpInfo lumpInfo) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
int structLength = GetStructLength(type, version);
|
||||
int structLength = GetStructLength(bsp.version, lumpInfo.version);
|
||||
int numObjects = data.Length / structLength;
|
||||
List<Plane> lump = new List<Plane>(numObjects);
|
||||
Lump<Plane> lump = new Lump<Plane>(numObjects, bsp, lumpInfo);
|
||||
for (int i = 0; i < numObjects; ++i) {
|
||||
Vector3d normal = new Vector3d(BitConverter.ToSingle(data, structLength * i), BitConverter.ToSingle(data, (structLength * i) + 4), BitConverter.ToSingle(data, (structLength * i) + 8));
|
||||
float distance = BitConverter.ToSingle(data, (structLength * i) + 12);
|
||||
|
||||
@@ -190,27 +190,26 @@ namespace LibBSP {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Factory method to parse a <c>byte</c> array into a <c>List</c> of <see cref="Vertex"/> objects.
|
||||
/// Factory method to parse a <c>byte</c> array into a <see cref="Lump{Vertex}"/>.
|
||||
/// </summary>
|
||||
/// <param name="data">The data to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <returns>A <c>List</c> of <see cref="Vertex"/> objects.</returns>
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
/// <returns>A <see cref="Lump{Vertex}"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> was <c>null</c>.</exception>
|
||||
/// <exception cref="ArgumentException">This structure is not implemented for the given maptype.</exception>
|
||||
/// <remarks>This function goes here since it can't be in Unity's <c>UIVertex</c> class, and so I can't
|
||||
/// depend on having a constructor taking a byte array.</remarks>
|
||||
public static List<Vertex> LumpFactory(byte[] data, MapType type, int version = 0) {
|
||||
public static Lump<Vertex> LumpFactory(byte[] data, BSP bsp, LumpInfo lumpInfo) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
int structLength = GetStructLength(type, version);
|
||||
int structLength = GetStructLength(bsp.version, lumpInfo.version);
|
||||
int numObjects = data.Length / structLength;
|
||||
List<Vertex> lump = new List<Vertex>(numObjects);
|
||||
Lump<Vertex> lump = new Lump<Vertex>(numObjects, bsp, lumpInfo);
|
||||
byte[] bytes = new byte[structLength];
|
||||
for (int i = 0; i < numObjects; ++i) {
|
||||
Array.Copy(data, i * structLength, bytes, 0, structLength);
|
||||
lump.Add(CreateVertex(bytes, type, version));
|
||||
lump.Add(CreateVertex(bytes, bsp.version, lumpInfo.version));
|
||||
}
|
||||
return lump;
|
||||
}
|
||||
|
||||
@@ -59,9 +59,9 @@ namespace LibBSP {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class containing basic information for a lump in a BSP file.
|
||||
/// Struct containing basic information for a lump in a BSP file.
|
||||
/// </summary>
|
||||
public class LumpInfo {
|
||||
public struct LumpInfo {
|
||||
public int ident;
|
||||
public int flags;
|
||||
public int version;
|
||||
@@ -81,41 +81,41 @@ namespace LibBSP {
|
||||
// Map structures
|
||||
// Quake 1/GoldSrc
|
||||
private Entities _entities;
|
||||
private List<Plane> _planes;
|
||||
private Lump<Plane> _planes;
|
||||
private Textures _textures;
|
||||
private List<Vertex> _vertices;
|
||||
private List<Node> _nodes;
|
||||
private List<TextureInfo> _texInfo;
|
||||
private List<Face> _faces;
|
||||
private List<Leaf> _leaves;
|
||||
private Lump<Vertex> _vertices;
|
||||
private Lump<Node> _nodes;
|
||||
private Lump<TextureInfo> _texInfo;
|
||||
private Lump<Face> _faces;
|
||||
private Lump<Leaf> _leaves;
|
||||
private NumList _markSurfaces;
|
||||
private List<Edge> _edges;
|
||||
private Lump<Edge> _edges;
|
||||
private NumList _surfEdges;
|
||||
private List<Model> _models;
|
||||
private Lump<Model> _models;
|
||||
// public byte[] pvs;
|
||||
// Quake 2
|
||||
private List<Brush> _brushes;
|
||||
private List<BrushSide> _brushSides;
|
||||
private Lump<Brush> _brushes;
|
||||
private Lump<BrushSide> _brushSides;
|
||||
private NumList _markBrushes;
|
||||
// MoHAA
|
||||
private List<LODTerrain> _lodTerrains;
|
||||
private List<StaticModel> _staticModels;
|
||||
private Lump<LODTerrain> _lodTerrains;
|
||||
private Lump<StaticModel> _staticModels;
|
||||
// CoD
|
||||
private List<Patch> _patches;
|
||||
private List<Vertex> _patchVerts;
|
||||
private Lump<Patch> _patches;
|
||||
private Lump<Vertex> _patchVerts;
|
||||
private NumList _patchIndices;
|
||||
// Nightfire
|
||||
private Textures _materials;
|
||||
private NumList _indices;
|
||||
// Source
|
||||
private List<Face> _originalFaces;
|
||||
private Lump<Face> _originalFaces;
|
||||
private NumList _texTable;
|
||||
private List<TextureData> _texDatas;
|
||||
private List<DisplacementInfo> _dispInfos;
|
||||
private Lump<TextureData> _texDatas;
|
||||
private Lump<DisplacementInfo> _dispInfos;
|
||||
private DisplacementVertices _dispVerts;
|
||||
private NumList _displacementTriangles;
|
||||
// public SourceOverlays overlays;
|
||||
private List<Cubemap> _cubemaps;
|
||||
private Lump<Cubemap> _cubemaps;
|
||||
private GameLump _gameLump;
|
||||
private StaticProps _staticProps;
|
||||
|
||||
@@ -152,7 +152,7 @@ namespace LibBSP {
|
||||
if (_entities == null) {
|
||||
int index = Entity.GetIndexForLump(version);
|
||||
if (index >= 0) {
|
||||
_entities = Entity.LumpFactory(reader.ReadLump(this[index]), version, this[index].version);
|
||||
_entities = Entity.LumpFactory(reader.ReadLump(this[index]), this, this[index]);
|
||||
}
|
||||
}
|
||||
return _entities;
|
||||
@@ -160,14 +160,14 @@ namespace LibBSP {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <c>List</c> of <see cref="Plane"/> objects in the BSP file, if available.
|
||||
/// A <see cref="Lump{Plane}"/> of <see cref="Plane"/> objects in the BSP file, if available.
|
||||
/// </summary>
|
||||
public List<Plane> planes {
|
||||
public Lump<Plane> planes {
|
||||
get {
|
||||
if (_planes == null) {
|
||||
int index = PlaneExtensions.GetIndexForLump(version);
|
||||
if (index >= 0) {
|
||||
_planes = PlaneExtensions.LumpFactory(reader.ReadLump(this[index]), version, this[index].version);
|
||||
_planes = PlaneExtensions.LumpFactory(reader.ReadLump(this[index]), this, this[index]);
|
||||
}
|
||||
}
|
||||
return _planes;
|
||||
@@ -182,7 +182,7 @@ namespace LibBSP {
|
||||
if (_textures == null) {
|
||||
int index = Texture.GetIndexForLump(version);
|
||||
if (index >= 0) {
|
||||
_textures = Texture.LumpFactory(reader.ReadLump(this[index]), version, this[index].version);
|
||||
_textures = Texture.LumpFactory(reader.ReadLump(this[index]), this, this[index]);
|
||||
}
|
||||
}
|
||||
return _textures;
|
||||
@@ -190,14 +190,14 @@ namespace LibBSP {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <c>List</c> of <see cref="Vertex"/> objects in the BSP file representing the vertices of the BSP, if available.
|
||||
/// A <see cref="Lump{Vertex}"/> of <see cref="Vertex"/> objects in the BSP file representing the vertices of the BSP, if available.
|
||||
/// </summary>
|
||||
public List<Vertex> vertices {
|
||||
public Lump<Vertex> vertices {
|
||||
get {
|
||||
if (_vertices == null) {
|
||||
int index = VertexExtensions.GetIndexForLump(version);
|
||||
if (index >= 0) {
|
||||
_vertices = VertexExtensions.LumpFactory(reader.ReadLump(this[index]), version, this[index].version);
|
||||
_vertices = VertexExtensions.LumpFactory(reader.ReadLump(this[index]), this, this[index]);
|
||||
}
|
||||
}
|
||||
return _vertices;
|
||||
@@ -205,14 +205,14 @@ namespace LibBSP {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <c>List</c> of <see cref="Node"/> objects in the BSP file, if available.
|
||||
/// A <see cref="Lump{Node}"/> of <see cref="Node"/> objects in the BSP file, if available.
|
||||
/// </summary>
|
||||
public List<Node> nodes {
|
||||
public Lump<Node> nodes {
|
||||
get {
|
||||
if (_nodes == null) {
|
||||
int index = Node.GetIndexForLump(version);
|
||||
if (index >= 0) {
|
||||
_nodes = Node.LumpFactory(reader.ReadLump(this[index]), version, this[index].version);
|
||||
_nodes = Node.LumpFactory(reader.ReadLump(this[index]), this, this[index]);
|
||||
}
|
||||
}
|
||||
return _nodes;
|
||||
@@ -220,14 +220,14 @@ namespace LibBSP {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <c>List</c> of <see cref="TextureInfo"/> objects in the BSP file, if available.
|
||||
/// A <see cref="Lump{TextureInfo}"/> of <see cref="TextureInfo"/> objects in the BSP file, if available.
|
||||
/// </summary>
|
||||
public List<TextureInfo> texInfo {
|
||||
public Lump<TextureInfo> texInfo {
|
||||
get {
|
||||
if (_texInfo == null) {
|
||||
int index = TextureInfo.GetIndexForLump(version);
|
||||
if (index >= 0) {
|
||||
_texInfo = TextureInfo.LumpFactory(reader.ReadLump(this[index]), version, this[index].version);
|
||||
_texInfo = TextureInfo.LumpFactory(reader.ReadLump(this[index]), this, this[index]);
|
||||
}
|
||||
}
|
||||
return _texInfo;
|
||||
@@ -235,14 +235,14 @@ namespace LibBSP {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <c>List</c> of <see cref="Face"/> objects in the BSP file, if available.
|
||||
/// A <see cref="Lump{Face}"/> of <see cref="Face"/> objects in the BSP file, if available.
|
||||
/// </summary>
|
||||
public List<Face> faces {
|
||||
public Lump<Face> faces {
|
||||
get {
|
||||
if (_faces == null) {
|
||||
int index = Face.GetIndexForLump(version);
|
||||
if (index >= 0) {
|
||||
_faces = Face.LumpFactory(reader.ReadLump(this[index]), version, this[index].version);
|
||||
_faces = Face.LumpFactory(reader.ReadLump(this[index]), this, this[index]);
|
||||
}
|
||||
}
|
||||
return _faces;
|
||||
@@ -250,14 +250,14 @@ namespace LibBSP {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <c>List</c> of <see cref="Leaf"/> objects in the BSP file, if available.
|
||||
/// A <see cref="Lump{Leaf}"/> of <see cref="Leaf"/> objects in the BSP file, if available.
|
||||
/// </summary>
|
||||
public List<Leaf> leaves {
|
||||
public Lump<Leaf> leaves {
|
||||
get {
|
||||
if (_leaves == null) {
|
||||
int index = Leaf.GetIndexForLump(version);
|
||||
if (index >= 0) {
|
||||
_leaves = Leaf.LumpFactory(reader.ReadLump(this[index]), version, this[index].version);
|
||||
_leaves = Leaf.LumpFactory(reader.ReadLump(this[index]), this, this[index]);
|
||||
}
|
||||
}
|
||||
return _leaves;
|
||||
@@ -265,14 +265,14 @@ namespace LibBSP {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <c>List</c> of <see cref="Edge"/> objects in the BSP file, if available.
|
||||
/// A <see cref="Lump{Edge}"/> of <see cref="Edge"/> objects in the BSP file, if available.
|
||||
/// </summary>
|
||||
public List<Edge> edges {
|
||||
public Lump<Edge> edges {
|
||||
get {
|
||||
if (_edges == null) {
|
||||
int index = Edge.GetIndexForLump(version);
|
||||
if (index >= 0) {
|
||||
_edges = Edge.LumpFactory(reader.ReadLump(this[index]), version, this[index].version);
|
||||
_edges = Edge.LumpFactory(reader.ReadLump(this[index]), this, this[index]);
|
||||
}
|
||||
}
|
||||
return _edges;
|
||||
@@ -280,14 +280,14 @@ namespace LibBSP {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <c>List</c> of <see cref="Model"/> objects in the BSP file, if available.
|
||||
/// A <see cref="Lump{Model}"/> of <see cref="Model"/> objects in the BSP file, if available.
|
||||
/// </summary>
|
||||
public List<Model> models {
|
||||
public Lump<Model> models {
|
||||
get {
|
||||
if (_models == null) {
|
||||
int index = Model.GetIndexForLump(version);
|
||||
if (index >= 0) {
|
||||
_models = Model.LumpFactory(reader.ReadLump(this[index]), version, this[index].version);
|
||||
_models = Model.LumpFactory(reader.ReadLump(this[index]), this, this[index]);
|
||||
}
|
||||
}
|
||||
return _models;
|
||||
@@ -295,14 +295,14 @@ namespace LibBSP {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <c>List</c> of <see cref="Brush"/> objects in the BSP file, if available.
|
||||
/// A <see cref="Lump{Brush}"/> of <see cref="Brush"/> objects in the BSP file, if available.
|
||||
/// </summary>
|
||||
public List<Brush> brushes {
|
||||
public Lump<Brush> brushes {
|
||||
get {
|
||||
if (_brushes == null) {
|
||||
int index = Brush.GetIndexForLump(version);
|
||||
if (index >= 0) {
|
||||
_brushes = Brush.LumpFactory(reader.ReadLump(this[index]), version, this[index].version);
|
||||
_brushes = Brush.LumpFactory(reader.ReadLump(this[index]), this, this[index]);
|
||||
}
|
||||
}
|
||||
return _brushes;
|
||||
@@ -310,14 +310,14 @@ namespace LibBSP {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <c>List</c> of <see cref="BrushSide"/> objects in the BSP file, if available.
|
||||
/// A <see cref="Lump{BrushSide}"/> of <see cref="BrushSide"/> objects in the BSP file, if available.
|
||||
/// </summary>
|
||||
public List<BrushSide> brushSides {
|
||||
public Lump<BrushSide> brushSides {
|
||||
get {
|
||||
if (_brushSides == null) {
|
||||
int index = BrushSide.GetIndexForLump(version);
|
||||
if (index >= 0) {
|
||||
_brushSides = BrushSide.LumpFactory(reader.ReadLump(this[index]), version, this[index].version);
|
||||
_brushSides = BrushSide.LumpFactory(reader.ReadLump(this[index]), this, this[index]);
|
||||
}
|
||||
}
|
||||
return _brushSides;
|
||||
@@ -325,14 +325,14 @@ namespace LibBSP {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <c>List</c> of <see cref="Texture"/> objects in the BSP file representing Materials (shaders), if available.
|
||||
/// A <see cref="Textures"/> object representing Materials (shaders), if available.
|
||||
/// </summary>
|
||||
public Textures materials {
|
||||
get {
|
||||
if (_materials == null) {
|
||||
int index = Texture.GetIndexForMaterialLump(version);
|
||||
if (index >= 0) {
|
||||
_materials = Texture.LumpFactory(reader.ReadLump(this[index]), version, this[index].version);
|
||||
_materials = Texture.LumpFactory(reader.ReadLump(this[index]), this, this[index]);
|
||||
}
|
||||
}
|
||||
return _materials;
|
||||
@@ -340,14 +340,14 @@ namespace LibBSP {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <c>List</c> of <see cref="Face"/> objects in the BSP file representing the Original Faces, if available.
|
||||
/// A <see cref="Lump{Face}"/> of <see cref="Face"/> objects in the BSP file representing the Original Faces, if available.
|
||||
/// </summary>
|
||||
public List<Face> originalFaces {
|
||||
public Lump<Face> originalFaces {
|
||||
get {
|
||||
if (_originalFaces == null) {
|
||||
int index = Face.GetIndexForOriginalFacesLump(version);
|
||||
if (index >= 0) {
|
||||
_originalFaces = Face.LumpFactory(reader.ReadLump(this[index]), version, this[index].version);
|
||||
_originalFaces = Face.LumpFactory(reader.ReadLump(this[index]), this, this[index]);
|
||||
}
|
||||
}
|
||||
return _originalFaces;
|
||||
@@ -355,14 +355,14 @@ namespace LibBSP {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <c>List</c> of <see cref="TextureData"/> objects in the BSP file, if available.
|
||||
/// A <see cref="Lump{TextureData}"/> of <see cref="TextureData"/> objects in the BSP file, if available.
|
||||
/// </summary>
|
||||
public List<TextureData> texDatas {
|
||||
public Lump<TextureData> texDatas {
|
||||
get {
|
||||
if (_texDatas == null) {
|
||||
int index = TextureData.GetIndexForLump(version);
|
||||
if (index >= 0) {
|
||||
_texDatas = TextureData.LumpFactory(reader.ReadLump(this[index]), version, this[index].version);
|
||||
_texDatas = TextureData.LumpFactory(reader.ReadLump(this[index]), this, this[index]);
|
||||
}
|
||||
}
|
||||
return _texDatas;
|
||||
@@ -370,14 +370,14 @@ namespace LibBSP {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <c>List</c> of <see cref="DisplacementInfo"/> objects in the BSP file, if available.
|
||||
/// A <see cref="Lump{DisplacementInfo}"/> of <see cref="DisplacementInfo"/> objects in the BSP file, if available.
|
||||
/// </summary>
|
||||
public List<DisplacementInfo> dispInfos {
|
||||
public Lump<DisplacementInfo> dispInfos {
|
||||
get {
|
||||
if (_dispInfos == null) {
|
||||
int index = DisplacementInfo.GetIndexForLump(version);
|
||||
if (index >= 0) {
|
||||
_dispInfos = DisplacementInfo.LumpFactory(reader.ReadLump(this[index]), version, this[index].version);
|
||||
_dispInfos = DisplacementInfo.LumpFactory(reader.ReadLump(this[index]), this, this[index]);
|
||||
}
|
||||
}
|
||||
return _dispInfos;
|
||||
@@ -392,7 +392,7 @@ namespace LibBSP {
|
||||
if (_dispVerts == null) {
|
||||
int index = DisplacementVertex.GetIndexForLump(version);
|
||||
if (index >= 0) {
|
||||
_dispVerts = DisplacementVertex.LumpFactory(reader.ReadLump(this[index]), version, this[index].version);
|
||||
_dispVerts = DisplacementVertex.LumpFactory(reader.ReadLump(this[index]), this, this[index]);
|
||||
}
|
||||
}
|
||||
return _dispVerts;
|
||||
@@ -400,14 +400,14 @@ namespace LibBSP {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <c>List</c> of <see cref="Cubemap"/> objects in the BSP file, if available.
|
||||
/// A <see cref="Lump{Cubemap}"/> of <see cref="Cubemap"/> objects in the BSP file, if available.
|
||||
/// </summary>
|
||||
public List<Cubemap> cubemaps {
|
||||
public Lump<Cubemap> cubemaps {
|
||||
get {
|
||||
if (_cubemaps == null) {
|
||||
int index = Cubemap.GetIndexForLump(version);
|
||||
if (index >= 0) {
|
||||
_cubemaps = Cubemap.LumpFactory(reader.ReadLump(this[index]), version, this[index].version);
|
||||
_cubemaps = Cubemap.LumpFactory(reader.ReadLump(this[index]), this, this[index]);
|
||||
}
|
||||
}
|
||||
return _cubemaps;
|
||||
@@ -423,7 +423,7 @@ namespace LibBSP {
|
||||
NumList.DataType type;
|
||||
int index = NumList.GetIndexForMarkSurfacesLump(version, out type);
|
||||
if (index >= 0) {
|
||||
_markSurfaces = NumList.LumpFactory(reader.ReadLump(this[index]), type);
|
||||
_markSurfaces = NumList.LumpFactory(reader.ReadLump(this[index]), type, this, this[index]);
|
||||
}
|
||||
}
|
||||
return _markSurfaces;
|
||||
@@ -439,7 +439,7 @@ namespace LibBSP {
|
||||
NumList.DataType type;
|
||||
int index = NumList.GetIndexForSurfEdgesLump(version, out type);
|
||||
if (index >= 0) {
|
||||
_surfEdges = NumList.LumpFactory(reader.ReadLump(this[index]), type);
|
||||
_surfEdges = NumList.LumpFactory(reader.ReadLump(this[index]), type, this, this[index]);
|
||||
}
|
||||
}
|
||||
return _surfEdges;
|
||||
@@ -455,7 +455,7 @@ namespace LibBSP {
|
||||
NumList.DataType type;
|
||||
int index = NumList.GetIndexForMarkBrushesLump(version, out type);
|
||||
if (index >= 0) {
|
||||
_markBrushes = NumList.LumpFactory(reader.ReadLump(this[index]), type);
|
||||
_markBrushes = NumList.LumpFactory(reader.ReadLump(this[index]), type, this, this[index]);
|
||||
}
|
||||
}
|
||||
return _markBrushes;
|
||||
@@ -463,14 +463,14 @@ namespace LibBSP {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <c>List</c> of <see cref="StaticModel"/> objects in the BSP file, if available.
|
||||
/// A <see cref="Lump{StaticModel}"/> of <see cref="StaticModel"/> objects in the BSP file, if available.
|
||||
/// </summary>
|
||||
public List<StaticModel> staticModels {
|
||||
public Lump<StaticModel> staticModels {
|
||||
get {
|
||||
if (_staticModels == null) {
|
||||
int index = StaticModel.GetIndexForLump(version);
|
||||
if (index >= 0) {
|
||||
_staticModels = StaticModel.LumpFactory(reader.ReadLump(this[index]), version, this[index].version);
|
||||
_staticModels = StaticModel.LumpFactory(reader.ReadLump(this[index]), this, this[index]);
|
||||
}
|
||||
}
|
||||
return _staticModels;
|
||||
@@ -478,14 +478,14 @@ namespace LibBSP {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <c>List</c> of <see cref="LODTerrain"/> objects in the BSP file, if available.
|
||||
/// A <see cref="Lump{LODTerrain}"/> of <see cref="LODTerrain"/> objects in the BSP file, if available.
|
||||
/// </summary>
|
||||
public List<LODTerrain> lodTerrains {
|
||||
public Lump<LODTerrain> lodTerrains {
|
||||
get {
|
||||
if (_lodTerrains == null) {
|
||||
int index = LODTerrain.GetIndexForLump(version);
|
||||
if (index >= 0) {
|
||||
_lodTerrains = LODTerrain.LumpFactory(reader.ReadLump(this[index]), version, this[index].version);
|
||||
_lodTerrains = LODTerrain.LumpFactory(reader.ReadLump(this[index]), this, this[index]);
|
||||
}
|
||||
}
|
||||
return _lodTerrains;
|
||||
@@ -493,14 +493,14 @@ namespace LibBSP {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <c>List</c> of <see cref="Patch"/> objects in the BSP file, if available.
|
||||
/// A <see cref="Lump{Patch}"/> of <see cref="Patch"/> objects in the BSP file, if available.
|
||||
/// </summary>
|
||||
public List<Patch> patches {
|
||||
public Lump<Patch> patches {
|
||||
get {
|
||||
if (_patches == null) {
|
||||
int index = Patch.GetIndexForLump(version);
|
||||
if (index >= 0) {
|
||||
_patches = Patch.LumpFactory(reader.ReadLump(this[index]), version, this[index].version);
|
||||
_patches = Patch.LumpFactory(reader.ReadLump(this[index]), this, this[index]);
|
||||
}
|
||||
}
|
||||
return _patches;
|
||||
@@ -508,14 +508,17 @@ namespace LibBSP {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <c>List</c> of <see cref="Vertex"/> objects in the BSP file representing the patch vertices of the BSP, if available.
|
||||
/// A <see cref="Lump{Vertex}"/> of <see cref="Vertex"/> objects in the BSP file representing the patch vertices of the BSP, if available.
|
||||
/// </summary>
|
||||
public List<Vertex> patchVerts {
|
||||
public Lump<Vertex> patchVerts {
|
||||
get {
|
||||
if (_patchVerts == null) {
|
||||
int index = VertexExtensions.GetIndexForPatchVertsLump(version);
|
||||
if (index >= 0) {
|
||||
_patchVerts = VertexExtensions.LumpFactory(reader.ReadLump(this[index]), version, 1);
|
||||
// Hax: CoD maps will read Vertex lump with version 1 as simply Vector3s rather than vertices.
|
||||
LumpInfo lumpInfo = this[index];
|
||||
lumpInfo.version = 1;
|
||||
_patchVerts = VertexExtensions.LumpFactory(reader.ReadLump(this[index]), this, lumpInfo);
|
||||
}
|
||||
}
|
||||
return _patchVerts;
|
||||
@@ -531,7 +534,7 @@ namespace LibBSP {
|
||||
NumList.DataType type;
|
||||
int index = NumList.GetIndexForPatchIndicesLump(version, out type);
|
||||
if (index >= 0) {
|
||||
_patchIndices = NumList.LumpFactory(reader.ReadLump(this[index]), type);
|
||||
_patchIndices = NumList.LumpFactory(reader.ReadLump(this[index]), type, this, this[index]);
|
||||
}
|
||||
}
|
||||
return _patchIndices;
|
||||
@@ -547,7 +550,7 @@ namespace LibBSP {
|
||||
NumList.DataType type;
|
||||
int index = NumList.GetIndexForIndicesLump(version, out type);
|
||||
if (index >= 0) {
|
||||
_indices = NumList.LumpFactory(reader.ReadLump(this[index]), type);
|
||||
_indices = NumList.LumpFactory(reader.ReadLump(this[index]), type, this, this[index]);
|
||||
}
|
||||
}
|
||||
return _indices;
|
||||
@@ -563,7 +566,7 @@ namespace LibBSP {
|
||||
NumList.DataType type;
|
||||
int index = NumList.GetIndexForTexTableLump(version, out type);
|
||||
if (index >= 0) {
|
||||
_texTable = NumList.LumpFactory(reader.ReadLump(this[index]), type);
|
||||
_texTable = NumList.LumpFactory(reader.ReadLump(this[index]), type, this, this[index]);
|
||||
}
|
||||
}
|
||||
return _texTable;
|
||||
@@ -579,7 +582,7 @@ namespace LibBSP {
|
||||
NumList.DataType type;
|
||||
int index = NumList.GetIndexForDisplacementTrianglesLump(version, out type);
|
||||
if (index >= 0) {
|
||||
_displacementTriangles = NumList.LumpFactory(reader.ReadLump(this[index]), type);
|
||||
_displacementTriangles = NumList.LumpFactory(reader.ReadLump(this[index]), type, this, this[index]);
|
||||
}
|
||||
}
|
||||
return _displacementTriangles;
|
||||
@@ -594,7 +597,7 @@ namespace LibBSP {
|
||||
if (_gameLump == null) {
|
||||
int index = GameLump.GetIndexForLump(version);
|
||||
if (index >= 0) {
|
||||
_gameLump = GameLump.LumpFactory(reader.ReadLump(this[index]), version, this[index].version);
|
||||
_gameLump = GameLump.LumpFactory(reader.ReadLump(this[index]), this, this[index]);
|
||||
}
|
||||
}
|
||||
return _gameLump;
|
||||
@@ -622,7 +625,7 @@ namespace LibBSP {
|
||||
} else {
|
||||
thisLump = reader.ReadLump(info);
|
||||
}
|
||||
_staticProps = StaticProp.LumpFactory(thisLump, version, info.version);
|
||||
_staticProps = StaticProp.LumpFactory(thisLump, this, info);
|
||||
}
|
||||
}
|
||||
return _staticProps;
|
||||
@@ -639,16 +642,7 @@ namespace LibBSP {
|
||||
/// </summary>
|
||||
public string MapName {
|
||||
get {
|
||||
int i;
|
||||
for (i = 0; i < filePath.Length; ++i) {
|
||||
if (filePath[filePath.Length - 1 - i] == '\\') {
|
||||
break;
|
||||
}
|
||||
if (filePath[filePath.Length - 1 - i] == '/') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return filePath.Substring(filePath.Length - i, (filePath.Length) - (filePath.Length - i));
|
||||
return Path.GetFileName(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -657,14 +651,7 @@ namespace LibBSP {
|
||||
/// </summary>
|
||||
public string MapNameNoExtension {
|
||||
get {
|
||||
string name = MapName;
|
||||
int i;
|
||||
for (i = 0; i < name.Length; ++i) {
|
||||
if (name[name.Length - 1 - i] == '.') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return name.Substring(0, (name.Length - 1 - i) - (0));
|
||||
return Path.GetFileNameWithoutExtension(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -673,16 +660,7 @@ namespace LibBSP {
|
||||
/// </summary>
|
||||
public string Folder {
|
||||
get {
|
||||
int i;
|
||||
for (i = 0; i < filePath.Length; ++i) {
|
||||
if (filePath[filePath.Length - 1 - i] == '\\') {
|
||||
break;
|
||||
}
|
||||
if (filePath[filePath.Length - 1 - i] == '/') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return filePath.Substring(0, (filePath.Length - i) - (0));
|
||||
return Path.GetDirectoryName(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace LibBSP {
|
||||
|
||||
/// <summary>
|
||||
/// Holds the data used by the brush structures of all formats of BSP.
|
||||
/// </summary>
|
||||
public struct Brush {
|
||||
public struct Brush : ILumpObject {
|
||||
|
||||
public byte[] data;
|
||||
public MapType type;
|
||||
public int version;
|
||||
/// <summary>
|
||||
/// The <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public ILump Parent { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Array of <c>byte</c>s used as the data source for this <see cref="ILumpObject"/>.
|
||||
/// </summary>
|
||||
public byte[] Data { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="LibBSP.MapType"/> to use to interpret <see cref="Data"/>.
|
||||
/// </summary>
|
||||
public MapType MapType {
|
||||
get {
|
||||
if (Parent == null || Parent.Bsp == null) {
|
||||
return MapType.Undefined;
|
||||
}
|
||||
return Parent.Bsp.version;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The version number of the <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public int LumpVersion {
|
||||
get {
|
||||
if (Parent == null) {
|
||||
return 0;
|
||||
}
|
||||
return Parent.LumpInfo.version;
|
||||
}
|
||||
}
|
||||
|
||||
[Index("brushSides")] public int firstSide {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Quake2:
|
||||
case MapType.Daikatana:
|
||||
case MapType.SiN:
|
||||
@@ -36,11 +67,11 @@ namespace LibBSP {
|
||||
case MapType.Raven:
|
||||
case MapType.Quake3:
|
||||
case MapType.FAKK: {
|
||||
return BitConverter.ToInt32(data, 0);
|
||||
return BitConverter.ToInt32(Data, 0);
|
||||
}
|
||||
case MapType.Nightfire:
|
||||
case MapType.STEF2: {
|
||||
return BitConverter.ToInt32(data, 4);
|
||||
return BitConverter.ToInt32(Data, 4);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -49,7 +80,7 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Quake2:
|
||||
case MapType.Daikatana:
|
||||
case MapType.SiN:
|
||||
@@ -71,12 +102,12 @@ namespace LibBSP {
|
||||
case MapType.Raven:
|
||||
case MapType.Quake3:
|
||||
case MapType.FAKK: {
|
||||
bytes.CopyTo(data, 0);
|
||||
bytes.CopyTo(Data, 0);
|
||||
break;
|
||||
}
|
||||
case MapType.Nightfire:
|
||||
case MapType.STEF2: {
|
||||
bytes.CopyTo(data, 4);
|
||||
bytes.CopyTo(Data, 4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -85,14 +116,14 @@ namespace LibBSP {
|
||||
|
||||
[Count("brushSides")] public int numSides {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2:
|
||||
case MapType.CoD4: {
|
||||
return BitConverter.ToInt16(data, 0);
|
||||
return BitConverter.ToInt16(Data, 0);
|
||||
}
|
||||
case MapType.STEF2: {
|
||||
return BitConverter.ToInt32(data, 0);
|
||||
return BitConverter.ToInt32(Data, 0);
|
||||
}
|
||||
case MapType.Quake2:
|
||||
case MapType.Daikatana:
|
||||
@@ -115,10 +146,10 @@ namespace LibBSP {
|
||||
case MapType.Raven:
|
||||
case MapType.Quake3:
|
||||
case MapType.FAKK: {
|
||||
return BitConverter.ToInt32(data, 4);
|
||||
return BitConverter.ToInt32(Data, 4);
|
||||
}
|
||||
case MapType.Nightfire: {
|
||||
return BitConverter.ToInt32(data, 8);
|
||||
return BitConverter.ToInt32(Data, 8);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -127,16 +158,16 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2:
|
||||
case MapType.CoD4: {
|
||||
data[0] = bytes[0];
|
||||
data[1] = bytes[1];
|
||||
Data[0] = bytes[0];
|
||||
Data[1] = bytes[1];
|
||||
break;
|
||||
}
|
||||
case MapType.STEF2: {
|
||||
bytes.CopyTo(data, 0);
|
||||
bytes.CopyTo(Data, 0);
|
||||
break;
|
||||
}
|
||||
case MapType.Quake2:
|
||||
@@ -160,11 +191,11 @@ namespace LibBSP {
|
||||
case MapType.Raven:
|
||||
case MapType.Quake3:
|
||||
case MapType.FAKK: {
|
||||
bytes.CopyTo(data, 4);
|
||||
bytes.CopyTo(Data, 4);
|
||||
break;
|
||||
}
|
||||
case MapType.Nightfire: {
|
||||
bytes.CopyTo(data, 8);
|
||||
bytes.CopyTo(Data, 8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -173,11 +204,11 @@ namespace LibBSP {
|
||||
|
||||
public int texture {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2:
|
||||
case MapType.CoD4: {
|
||||
return BitConverter.ToInt16(data, 2);
|
||||
return BitConverter.ToInt16(Data, 2);
|
||||
}
|
||||
case MapType.MOHAA:
|
||||
case MapType.STEF2Demo:
|
||||
@@ -185,7 +216,7 @@ namespace LibBSP {
|
||||
case MapType.Quake3:
|
||||
case MapType.FAKK:
|
||||
case MapType.STEF2: {
|
||||
return BitConverter.ToInt32(data, 8);
|
||||
return BitConverter.ToInt32(Data, 8);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -194,11 +225,11 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2:
|
||||
case MapType.CoD4: {
|
||||
bytes.CopyTo(data, 2);
|
||||
bytes.CopyTo(Data, 2);
|
||||
break;
|
||||
}
|
||||
case MapType.MOHAA:
|
||||
@@ -207,7 +238,7 @@ namespace LibBSP {
|
||||
case MapType.Quake3:
|
||||
case MapType.FAKK:
|
||||
case MapType.STEF2: {
|
||||
bytes.CopyTo(data, 8);
|
||||
bytes.CopyTo(Data, 8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -216,9 +247,9 @@ namespace LibBSP {
|
||||
|
||||
public int contents {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Nightfire: {
|
||||
return BitConverter.ToInt32(data, 0);
|
||||
return BitConverter.ToInt32(Data, 0);
|
||||
}
|
||||
case MapType.Quake2:
|
||||
case MapType.Daikatana:
|
||||
@@ -236,7 +267,7 @@ namespace LibBSP {
|
||||
case MapType.Vindictus:
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.DMoMaM: {
|
||||
return BitConverter.ToInt32(data, 8);
|
||||
return BitConverter.ToInt32(Data, 8);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -245,9 +276,9 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Nightfire: {
|
||||
bytes.CopyTo(data, 0);
|
||||
bytes.CopyTo(Data, 0);
|
||||
break;
|
||||
}
|
||||
case MapType.Quake2:
|
||||
@@ -266,7 +297,7 @@ namespace LibBSP {
|
||||
case MapType.Vindictus:
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.DMoMaM: {
|
||||
bytes.CopyTo(data, 8);
|
||||
bytes.CopyTo(Data, 8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -277,33 +308,42 @@ namespace LibBSP {
|
||||
/// Creates a new <see cref="Brush"/> object from a <c>byte</c> array.
|
||||
/// </summary>
|
||||
/// <param name="data"><c>byte</c> array to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <param name="parent">The <see cref="ILump"/> this <see cref="Brush"/> came from.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> was <c>null</c>.</exception>
|
||||
public Brush(byte[] data, MapType type, int version = 0) : this() {
|
||||
public Brush(byte[] data, ILump parent = null) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
this.data = data;
|
||||
this.type = type;
|
||||
this.version = version;
|
||||
|
||||
Data = data;
|
||||
Parent = parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Factory method to parse a <c>byte</c> array into a <c>List</c> of <see cref="Brush"/> objects.
|
||||
/// Factory method to parse a <c>byte</c> array into a <see cref="Lump{Brush}"/>.
|
||||
/// </summary>
|
||||
/// <param name="data">The data to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <returns>A <c>List</c> of <see cref="Brush"/> objects.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data" /> was <c>null</c>.</exception>
|
||||
/// <exception cref="ArgumentException">This structure is not implemented for the given maptype.</exception>
|
||||
public static List<Brush> LumpFactory(byte[] data, MapType type, int version = 0) {
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
/// <returns>A <see cref="Lump{Brush}"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> parameter was <c>null</c>.</exception>
|
||||
public static Lump<Brush> LumpFactory(byte[] data, BSP bsp, LumpInfo lumpInfo) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
int structLength = 0;
|
||||
switch (type) {
|
||||
|
||||
return new Lump<Brush>(data, GetStructLength(bsp.version, lumpInfo.version), bsp, lumpInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length of this struct's data for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.
|
||||
/// </summary>
|
||||
/// <param name="mapType">The <see cref="LibBSP.MapType"/> of the BSP.</param>
|
||||
/// <param name="lumpVersion">The version number for the lump.</param>
|
||||
/// <returns>The length, in <c>byte</c>s, of this struct.</returns>
|
||||
/// <exception cref="ArgumentException">This struct is not valid or is not implemented for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.</exception>
|
||||
public static int GetStructLength(MapType mapType, int lumpVersion = 0) {
|
||||
switch (mapType) {
|
||||
case MapType.Quake2:
|
||||
case MapType.Daikatana:
|
||||
case MapType.SiN:
|
||||
@@ -327,27 +367,17 @@ namespace LibBSP {
|
||||
case MapType.Raven:
|
||||
case MapType.Quake3:
|
||||
case MapType.FAKK: {
|
||||
structLength = 12;
|
||||
break;
|
||||
return 12;
|
||||
}
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2:
|
||||
case MapType.CoD4: {
|
||||
structLength = 4;
|
||||
break;
|
||||
return 4;
|
||||
}
|
||||
default: {
|
||||
throw new ArgumentException("Map type " + type + " isn't supported by the Brush lump factory.");
|
||||
throw new ArgumentException("Lump object " + MethodBase.GetCurrentMethod().DeclaringType.Name + " does not exist in map type " + mapType + " or has not been implemented.");
|
||||
}
|
||||
}
|
||||
int numObjects = data.Length / structLength;
|
||||
List<Brush> lump = new List<Brush>(numObjects);
|
||||
for (int i = 0; i < numObjects; ++i) {
|
||||
byte[] bytes = new byte[structLength];
|
||||
Array.Copy(data, (i * structLength), bytes, 0, structLength);
|
||||
lump.Add(new Brush(bytes, type, version));
|
||||
}
|
||||
return lump;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,20 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace LibBSP {
|
||||
|
||||
/// <summary>
|
||||
/// Holds the data used by the brush side structures of all formats of BSP.
|
||||
/// </summary>
|
||||
public struct BrushSide {
|
||||
public struct BrushSide : ILumpObject {
|
||||
|
||||
public byte[] data;
|
||||
public MapType type;
|
||||
public int version;
|
||||
/// <summary>
|
||||
/// The <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public ILump Parent { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Array of <c>byte</c>s used as the data source for this <see cref="ILumpObject"/>.
|
||||
/// </summary>
|
||||
public byte[] Data { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="LibBSP.MapType"/> to use to interpret <see cref="Data"/>.
|
||||
/// </summary>
|
||||
public MapType MapType {
|
||||
get {
|
||||
if (Parent == null || Parent.Bsp == null) {
|
||||
return MapType.Undefined;
|
||||
}
|
||||
return Parent.Bsp.version;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The version number of the <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public int LumpVersion {
|
||||
get {
|
||||
if (Parent == null) {
|
||||
return 0;
|
||||
}
|
||||
return Parent.LumpInfo.version;
|
||||
}
|
||||
}
|
||||
|
||||
public int plane {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.SiN:
|
||||
case MapType.Quake2:
|
||||
case MapType.Daikatana:
|
||||
@@ -30,7 +61,7 @@ namespace LibBSP {
|
||||
case MapType.L4D2:
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.DMoMaM: {
|
||||
return BitConverter.ToUInt16(data, 0);
|
||||
return BitConverter.ToUInt16(Data, 0);
|
||||
}
|
||||
case MapType.Raven:
|
||||
case MapType.CoD:
|
||||
@@ -41,11 +72,11 @@ namespace LibBSP {
|
||||
case MapType.STEF2Demo:
|
||||
case MapType.MOHAA:
|
||||
case MapType.Vindictus: {
|
||||
return BitConverter.ToInt32(data, 0);
|
||||
return BitConverter.ToInt32(Data, 0);
|
||||
}
|
||||
case MapType.STEF2:
|
||||
case MapType.Nightfire: {
|
||||
return BitConverter.ToInt32(data, 4);
|
||||
return BitConverter.ToInt32(Data, 4);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -54,7 +85,7 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.SiN:
|
||||
case MapType.Quake2:
|
||||
case MapType.Daikatana:
|
||||
@@ -70,8 +101,8 @@ namespace LibBSP {
|
||||
case MapType.L4D2:
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.DMoMaM: {
|
||||
data[0] = bytes[0];
|
||||
data[1] = bytes[1];
|
||||
Data[0] = bytes[0];
|
||||
Data[1] = bytes[1];
|
||||
break;
|
||||
}
|
||||
case MapType.Raven:
|
||||
@@ -83,12 +114,12 @@ namespace LibBSP {
|
||||
case MapType.STEF2Demo:
|
||||
case MapType.MOHAA:
|
||||
case MapType.Vindictus: {
|
||||
bytes.CopyTo(data, 0);
|
||||
bytes.CopyTo(Data, 0);
|
||||
break;
|
||||
}
|
||||
case MapType.STEF2:
|
||||
case MapType.Nightfire: {
|
||||
bytes.CopyTo(data, 4);
|
||||
bytes.CopyTo(Data, 4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -97,11 +128,11 @@ namespace LibBSP {
|
||||
|
||||
public float dist {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2:
|
||||
case MapType.CoD4: {
|
||||
return BitConverter.ToSingle(data, 0);
|
||||
return BitConverter.ToSingle(Data, 0);
|
||||
}
|
||||
default: {
|
||||
return float.NaN;
|
||||
@@ -110,11 +141,11 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2:
|
||||
case MapType.CoD4: {
|
||||
bytes.CopyTo(data, 0);
|
||||
bytes.CopyTo(Data, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -123,9 +154,9 @@ namespace LibBSP {
|
||||
|
||||
public int texture {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.STEF2: {
|
||||
return BitConverter.ToInt32(data, 0);
|
||||
return BitConverter.ToInt32(Data, 0);
|
||||
}
|
||||
case MapType.SiN:
|
||||
case MapType.Quake2:
|
||||
@@ -142,7 +173,7 @@ namespace LibBSP {
|
||||
case MapType.L4D2:
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.DMoMaM: {
|
||||
return BitConverter.ToInt16(data, 2);
|
||||
return BitConverter.ToInt16(Data, 2);
|
||||
}
|
||||
case MapType.Vindictus:
|
||||
case MapType.CoD:
|
||||
@@ -153,7 +184,7 @@ namespace LibBSP {
|
||||
case MapType.STEF2Demo:
|
||||
case MapType.MOHAA:
|
||||
case MapType.Raven: {
|
||||
return BitConverter.ToInt32(data, 4);
|
||||
return BitConverter.ToInt32(Data, 4);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -162,9 +193,9 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.STEF2: {
|
||||
bytes.CopyTo(data, 0);
|
||||
bytes.CopyTo(Data, 0);
|
||||
break;
|
||||
}
|
||||
case MapType.SiN:
|
||||
@@ -182,8 +213,8 @@ namespace LibBSP {
|
||||
case MapType.L4D2:
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.DMoMaM: {
|
||||
data[2] = bytes[0];
|
||||
data[3] = bytes[1];
|
||||
Data[2] = bytes[0];
|
||||
Data[3] = bytes[1];
|
||||
break;
|
||||
}
|
||||
case MapType.Vindictus:
|
||||
@@ -195,7 +226,7 @@ namespace LibBSP {
|
||||
case MapType.STEF2Demo:
|
||||
case MapType.MOHAA:
|
||||
case MapType.Raven: {
|
||||
bytes.CopyTo(data, 4);
|
||||
bytes.CopyTo(Data, 4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -204,12 +235,12 @@ namespace LibBSP {
|
||||
|
||||
public int face {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Nightfire: {
|
||||
return BitConverter.ToInt32(data, 0);
|
||||
return BitConverter.ToInt32(Data, 0);
|
||||
}
|
||||
case MapType.Raven: {
|
||||
return BitConverter.ToInt32(data, 8);
|
||||
return BitConverter.ToInt32(Data, 8);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -218,13 +249,13 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Nightfire: {
|
||||
bytes.CopyTo(data, 0);
|
||||
bytes.CopyTo(Data, 0);
|
||||
break;
|
||||
}
|
||||
case MapType.Raven: {
|
||||
bytes.CopyTo(data, 8);
|
||||
bytes.CopyTo(Data, 8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -233,7 +264,7 @@ namespace LibBSP {
|
||||
|
||||
public int displacement {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Source17:
|
||||
case MapType.Source18:
|
||||
case MapType.Source19:
|
||||
@@ -245,10 +276,10 @@ namespace LibBSP {
|
||||
case MapType.L4D2:
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.DMoMaM: {
|
||||
return BitConverter.ToInt16(data, 4);
|
||||
return BitConverter.ToInt16(Data, 4);
|
||||
}
|
||||
case MapType.Vindictus: {
|
||||
return BitConverter.ToInt32(data, 8);
|
||||
return BitConverter.ToInt32(Data, 8);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -257,7 +288,7 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Source17:
|
||||
case MapType.Source18:
|
||||
case MapType.Source19:
|
||||
@@ -269,12 +300,12 @@ namespace LibBSP {
|
||||
case MapType.L4D2:
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.DMoMaM: {
|
||||
data[4] = bytes[0];
|
||||
data[5] = bytes[1];
|
||||
Data[4] = bytes[0];
|
||||
Data[5] = bytes[1];
|
||||
break;
|
||||
}
|
||||
case MapType.Vindictus: {
|
||||
bytes.CopyTo(data, 8);
|
||||
bytes.CopyTo(Data, 8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -283,7 +314,7 @@ namespace LibBSP {
|
||||
|
||||
public bool bevel {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Source17:
|
||||
case MapType.Source18:
|
||||
case MapType.Source19:
|
||||
@@ -295,10 +326,10 @@ namespace LibBSP {
|
||||
case MapType.L4D2:
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.DMoMaM: {
|
||||
return data[6] > 0;
|
||||
return Data[6] > 0;
|
||||
}
|
||||
case MapType.Vindictus: {
|
||||
return data[12] > 0;
|
||||
return Data[12] > 0;
|
||||
}
|
||||
default: {
|
||||
return false;
|
||||
@@ -306,7 +337,7 @@ namespace LibBSP {
|
||||
}
|
||||
}
|
||||
set {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Source17:
|
||||
case MapType.Source18:
|
||||
case MapType.Source19:
|
||||
@@ -318,11 +349,11 @@ namespace LibBSP {
|
||||
case MapType.L4D2:
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.DMoMaM: {
|
||||
data[6] = (byte)(value ? 1 : 0);
|
||||
Data[6] = (byte)(value ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
case MapType.Vindictus: {
|
||||
data[12] = (byte)(value ? 1 : 0);
|
||||
Data[12] = (byte)(value ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -331,7 +362,7 @@ namespace LibBSP {
|
||||
|
||||
public bool thin {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Source17:
|
||||
case MapType.Source18:
|
||||
case MapType.Source19:
|
||||
@@ -343,7 +374,7 @@ namespace LibBSP {
|
||||
case MapType.L4D2:
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.DMoMaM: {
|
||||
return data[7] > 0;
|
||||
return Data[7] > 0;
|
||||
}
|
||||
default: {
|
||||
return false;
|
||||
@@ -351,7 +382,7 @@ namespace LibBSP {
|
||||
}
|
||||
}
|
||||
set {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Source17:
|
||||
case MapType.Source18:
|
||||
case MapType.Source19:
|
||||
@@ -363,7 +394,7 @@ namespace LibBSP {
|
||||
case MapType.L4D2:
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.DMoMaM: {
|
||||
data[7] = (byte)(value ? 1 : 0);
|
||||
Data[7] = (byte)(value ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -374,38 +405,46 @@ namespace LibBSP {
|
||||
/// Creates a new <see cref="BrushSide"/> object from a <c>byte</c> array.
|
||||
/// </summary>
|
||||
/// <param name="data"><c>byte</c> array to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data" /> was <c>null</c>.</exception>
|
||||
public BrushSide(byte[] data, MapType type, int version = 0) : this() {
|
||||
/// <param name="parent">The <see cref="ILump"/> this <see cref="BrushSide"/> came from.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> was <c>null</c>.</exception>
|
||||
public BrushSide(byte[] data, ILump parent) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
this.data = data;
|
||||
this.type = type;
|
||||
this.version = version;
|
||||
|
||||
Data = data;
|
||||
Parent = parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Factory method to parse a <c>byte</c> array into a <see cref="Lump{BrushSide}"/>.
|
||||
/// </summary>
|
||||
/// <param name="data">The data to parse.</param>
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
/// <returns>A <see cref="Lump{BrushSide}"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> parameter was <c>null</c>.</exception>
|
||||
public static Lump<BrushSide> LumpFactory(byte[] data, BSP bsp, LumpInfo lumpInfo) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
return new Lump<BrushSide>(data, GetStructLength(bsp.version, lumpInfo.version), bsp, lumpInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Factory method to parse a <c>byte</c> array into a <c>List</c> of <see cref="BrushSide"/> objects.
|
||||
/// Gets the length of this struct's data for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.
|
||||
/// </summary>
|
||||
/// <param name="data">The data to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <returns>A <c>List</c> of <see cref="BrushSide"/> objects.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data" /> was <c>null</c>.</exception>
|
||||
/// <exception cref="ArgumentException">This structure is not implemented for the given maptype.</exception>
|
||||
public static List<BrushSide> LumpFactory(byte[] data, MapType type, int version = 0) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
int structLength = 0;
|
||||
/// <param name="mapType">The <see cref="LibBSP.MapType"/> of the BSP.</param>
|
||||
/// <param name="lumpVersion">The version number for the lump.</param>
|
||||
/// <returns>The length, in <c>byte</c>s, of this struct.</returns>
|
||||
/// <exception cref="ArgumentException">This struct is not valid or is not implemented for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.</exception>
|
||||
public static int GetStructLength(MapType type, int version = 0) {
|
||||
switch (type) {
|
||||
case MapType.Quake2:
|
||||
case MapType.Daikatana:
|
||||
case MapType.SoF: {
|
||||
structLength = 4;
|
||||
break;
|
||||
return 4;
|
||||
}
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2:
|
||||
@@ -427,30 +466,19 @@ namespace LibBSP {
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.DMoMaM:
|
||||
case MapType.FAKK: {
|
||||
structLength = 8;
|
||||
break;
|
||||
return 8;
|
||||
}
|
||||
case MapType.MOHAA:
|
||||
case MapType.Raven: {
|
||||
structLength = 12;
|
||||
break;
|
||||
return 12;
|
||||
}
|
||||
case MapType.Vindictus: {
|
||||
structLength = 16;
|
||||
break;
|
||||
return 16;
|
||||
}
|
||||
default: {
|
||||
throw new ArgumentException("Map type " + type + " isn't supported by the BrushSide lump factory.");
|
||||
throw new ArgumentException("Lump object " + MethodBase.GetCurrentMethod().DeclaringType.Name + " does not exist in map type " + type + " or has not been implemented.");
|
||||
}
|
||||
}
|
||||
int numObjects = data.Length / structLength;
|
||||
List<BrushSide> lump = new List<BrushSide>(numObjects);
|
||||
for (int i = 0; i < numObjects; i++) {
|
||||
byte[] bytes = new byte[structLength];
|
||||
Array.Copy(data, (i * structLength), bytes, 0, structLength);
|
||||
lump.Add(new BrushSide(bytes, type, version));
|
||||
}
|
||||
return lump;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace LibBSP {
|
||||
#if UNITY
|
||||
@@ -15,15 +16,45 @@ namespace LibBSP {
|
||||
/// <summary>
|
||||
/// Holds all data for a Cubemap from Source engine.
|
||||
/// </summary>
|
||||
public struct Cubemap {
|
||||
public struct Cubemap : ILumpObject {
|
||||
|
||||
public byte[] data;
|
||||
public MapType type;
|
||||
public int version;
|
||||
/// <summary>
|
||||
/// The <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public ILump Parent { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Array of <c>byte</c>s used as the data source for this <see cref="ILumpObject"/>.
|
||||
/// </summary>
|
||||
public byte[] Data { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="LibBSP.MapType"/> to use to interpret <see cref="Data"/>.
|
||||
/// </summary>
|
||||
public MapType MapType {
|
||||
get {
|
||||
if (Parent == null || Parent.Bsp == null) {
|
||||
return MapType.Undefined;
|
||||
}
|
||||
return Parent.Bsp.version;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The version number of the <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public int LumpVersion {
|
||||
get {
|
||||
if (Parent == null) {
|
||||
return 0;
|
||||
}
|
||||
return Parent.LumpInfo.version;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3d origin {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Source17:
|
||||
case MapType.Source18:
|
||||
case MapType.Source19:
|
||||
@@ -36,7 +67,7 @@ namespace LibBSP {
|
||||
case MapType.L4D2:
|
||||
case MapType.Vindictus:
|
||||
case MapType.DMoMaM: {
|
||||
return new Vector3d(BitConverter.ToInt32(data, 0), BitConverter.ToInt32(data, 4), BitConverter.ToInt32(data, 8));
|
||||
return new Vector3d(BitConverter.ToInt32(Data, 0), BitConverter.ToInt32(Data, 4), BitConverter.ToInt32(Data, 8));
|
||||
}
|
||||
default: {
|
||||
return new Vector3d(float.NaN, float.NaN, float.NaN);
|
||||
@@ -44,7 +75,7 @@ namespace LibBSP {
|
||||
}
|
||||
}
|
||||
set {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Source17:
|
||||
case MapType.Source18:
|
||||
case MapType.Source19:
|
||||
@@ -57,7 +88,7 @@ namespace LibBSP {
|
||||
case MapType.L4D2:
|
||||
case MapType.Vindictus:
|
||||
case MapType.DMoMaM: {
|
||||
value.GetBytes().CopyTo(data, 0);
|
||||
value.GetBytes().CopyTo(Data, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -66,7 +97,7 @@ namespace LibBSP {
|
||||
|
||||
public int size {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Source17:
|
||||
case MapType.Source18:
|
||||
case MapType.Source19:
|
||||
@@ -79,7 +110,7 @@ namespace LibBSP {
|
||||
case MapType.L4D2:
|
||||
case MapType.Vindictus:
|
||||
case MapType.DMoMaM: {
|
||||
return BitConverter.ToInt32(data, 12);
|
||||
return BitConverter.ToInt32(Data, 12);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -88,7 +119,7 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Source17:
|
||||
case MapType.Source18:
|
||||
case MapType.Source19:
|
||||
@@ -101,7 +132,7 @@ namespace LibBSP {
|
||||
case MapType.L4D2:
|
||||
case MapType.Vindictus:
|
||||
case MapType.DMoMaM: {
|
||||
bytes.CopyTo(data, 12);
|
||||
bytes.CopyTo(Data, 12);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -112,33 +143,42 @@ namespace LibBSP {
|
||||
/// Creates a new <see cref="Cubemap"/> object from a <c>byte</c> array.
|
||||
/// </summary>
|
||||
/// <param name="data"><c>byte</c> array to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data" /> was <c>null</c>.</exception>
|
||||
public Cubemap(byte[] data, MapType type, int version = 0) : this() {
|
||||
/// <param name="parent">The <see cref="ILump"/> this <see cref="Cubemap"/> came from.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> was <c>null</c>.</exception>
|
||||
public Cubemap(byte[] data, ILump parent = null) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
this.data = data;
|
||||
this.type = type;
|
||||
this.version = version;
|
||||
|
||||
Data = data;
|
||||
Parent = parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Factory method to parse a <c>byte</c> array into a <c>List</c> of <see cref="Cubemap"/> objects.
|
||||
/// Factory method to parse a <c>byte</c> array into a <see cref="Lump{Cubemap}"/>.
|
||||
/// </summary>
|
||||
/// <param name="data">The data to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <returns>A <c>List</c> of <see cref="Cubemap"/> objects.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data" /> was <c>null</c>.</exception>
|
||||
/// <exception cref="ArgumentException">This structure is not implemented for the given maptype.</exception>
|
||||
public static List<Cubemap> LumpFactory(byte[] data, MapType type, int version = 0) {
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
/// <returns>A <see cref="Lump{Cubemap}"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> parameter was <c>null</c>.</exception>
|
||||
public static Lump<Cubemap> LumpFactory(byte[] data, BSP bsp, LumpInfo lumpInfo) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
int structLength = 0;
|
||||
switch (type) {
|
||||
|
||||
return new Lump<Cubemap>(data, GetStructLength(bsp.version, lumpInfo.version), bsp, lumpInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length of this struct's data for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.
|
||||
/// </summary>
|
||||
/// <param name="mapType">The <see cref="LibBSP.MapType"/> of the BSP.</param>
|
||||
/// <param name="lumpVersion">The version number for the lump.</param>
|
||||
/// <returns>The length, in <c>byte</c>s, of this struct.</returns>
|
||||
/// <exception cref="ArgumentException">This struct is not valid or is not implemented for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.</exception>
|
||||
public static int GetStructLength(MapType mapType, int lumpVersion = 0) {
|
||||
switch (mapType) {
|
||||
case MapType.Source17:
|
||||
case MapType.Source18:
|
||||
case MapType.Source19:
|
||||
@@ -151,21 +191,12 @@ namespace LibBSP {
|
||||
case MapType.L4D2:
|
||||
case MapType.Vindictus:
|
||||
case MapType.DMoMaM: {
|
||||
structLength = 16;
|
||||
break;
|
||||
return 16;
|
||||
}
|
||||
default: {
|
||||
throw new ArgumentException("Map type " + type + " isn't supported by the SourceCubemap lump factory.");
|
||||
throw new ArgumentException("Lump object " + MethodBase.GetCurrentMethod().DeclaringType.Name + " does not exist in map type " + mapType + " or has not been implemented.");
|
||||
}
|
||||
}
|
||||
int numObjects = data.Length / structLength;
|
||||
List<Cubemap> lump = new List<Cubemap>(numObjects);
|
||||
for (int i = 0; i < numObjects; ++i) {
|
||||
byte[] bytes = new byte[structLength];
|
||||
Array.Copy(data, (i * structLength), bytes, 0, structLength);
|
||||
lump.Add(new Cubemap(bytes, type, version));
|
||||
}
|
||||
return lump;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace LibBSP {
|
||||
#if UNITY
|
||||
@@ -15,99 +16,129 @@ namespace LibBSP {
|
||||
/// <summary>
|
||||
/// Holds all data for a Displacement from Source engine.
|
||||
/// </summary>
|
||||
public struct DisplacementInfo {
|
||||
public struct DisplacementInfo : ILumpObject {
|
||||
|
||||
public byte[] data;
|
||||
public MapType type;
|
||||
public int version;
|
||||
/// <summary>
|
||||
/// The <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public ILump Parent { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Array of <c>byte</c>s used as the data source for this <see cref="ILumpObject"/>.
|
||||
/// </summary>
|
||||
public byte[] Data { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="LibBSP.MapType"/> to use to interpret <see cref="Data"/>.
|
||||
/// </summary>
|
||||
public MapType MapType {
|
||||
get {
|
||||
if (Parent == null || Parent.Bsp == null) {
|
||||
return MapType.Undefined;
|
||||
}
|
||||
return Parent.Bsp.version;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The version number of the <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public int LumpVersion {
|
||||
get {
|
||||
if (Parent == null) {
|
||||
return 0;
|
||||
}
|
||||
return Parent.LumpInfo.version;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3d startPosition {
|
||||
get {
|
||||
return new Vector3d(BitConverter.ToSingle(data, 0), BitConverter.ToSingle(data, 4), BitConverter.ToSingle(data, 8));
|
||||
return new Vector3d(BitConverter.ToSingle(Data, 0), BitConverter.ToSingle(Data, 4), BitConverter.ToSingle(Data, 8));
|
||||
}
|
||||
set {
|
||||
value.GetBytes().CopyTo(data, 0);
|
||||
value.GetBytes().CopyTo(Data, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public int dispVertStart {
|
||||
get {
|
||||
return BitConverter.ToInt32(data, 12);
|
||||
return BitConverter.ToInt32(Data, 12);
|
||||
}
|
||||
set {
|
||||
BitConverter.GetBytes(value).CopyTo(data, 12);
|
||||
BitConverter.GetBytes(value).CopyTo(Data, 12);
|
||||
}
|
||||
}
|
||||
|
||||
public int dispTriStart {
|
||||
get {
|
||||
return BitConverter.ToInt32(data, 16);
|
||||
return BitConverter.ToInt32(Data, 16);
|
||||
}
|
||||
set {
|
||||
BitConverter.GetBytes(value).CopyTo(data, 16);
|
||||
BitConverter.GetBytes(value).CopyTo(Data, 16);
|
||||
}
|
||||
}
|
||||
|
||||
public int power {
|
||||
get {
|
||||
return BitConverter.ToInt32(data, 20);
|
||||
return BitConverter.ToInt32(Data, 20);
|
||||
}
|
||||
set {
|
||||
BitConverter.GetBytes(value).CopyTo(data, 20);
|
||||
BitConverter.GetBytes(value).CopyTo(Data, 20);
|
||||
}
|
||||
}
|
||||
|
||||
public int minTess {
|
||||
get {
|
||||
return BitConverter.ToInt32(data, 24);
|
||||
return BitConverter.ToInt32(Data, 24);
|
||||
}
|
||||
set {
|
||||
BitConverter.GetBytes(value).CopyTo(data, 24);
|
||||
BitConverter.GetBytes(value).CopyTo(Data, 24);
|
||||
}
|
||||
}
|
||||
|
||||
public float smoothingAngle {
|
||||
get {
|
||||
return BitConverter.ToSingle(data, 28);
|
||||
return BitConverter.ToSingle(Data, 28);
|
||||
}
|
||||
set {
|
||||
BitConverter.GetBytes(value).CopyTo(data, 28);
|
||||
BitConverter.GetBytes(value).CopyTo(Data, 28);
|
||||
}
|
||||
}
|
||||
|
||||
public int contents {
|
||||
get {
|
||||
return BitConverter.ToInt32(data, 32);
|
||||
return BitConverter.ToInt32(Data, 32);
|
||||
}
|
||||
set {
|
||||
BitConverter.GetBytes(value).CopyTo(data, 32);
|
||||
BitConverter.GetBytes(value).CopyTo(Data, 32);
|
||||
}
|
||||
}
|
||||
|
||||
public ushort mapFace {
|
||||
get {
|
||||
return BitConverter.ToUInt16(data, 36);
|
||||
return BitConverter.ToUInt16(Data, 36);
|
||||
}
|
||||
set {
|
||||
BitConverter.GetBytes(value).CopyTo(data, 36);
|
||||
BitConverter.GetBytes(value).CopyTo(Data, 36);
|
||||
}
|
||||
}
|
||||
|
||||
public int lightmapAlphaStart {
|
||||
get {
|
||||
return BitConverter.ToInt32(data, 38);
|
||||
return BitConverter.ToInt32(Data, 38);
|
||||
}
|
||||
set {
|
||||
BitConverter.GetBytes(value).CopyTo(data, 38);
|
||||
BitConverter.GetBytes(value).CopyTo(Data, 38);
|
||||
}
|
||||
}
|
||||
|
||||
public int lightmapSamplePositionStart {
|
||||
get {
|
||||
return BitConverter.ToInt32(data, 42);
|
||||
return BitConverter.ToInt32(Data, 42);
|
||||
}
|
||||
set {
|
||||
BitConverter.GetBytes(value).CopyTo(data, 42);
|
||||
BitConverter.GetBytes(value).CopyTo(Data, 42);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +146,7 @@ namespace LibBSP {
|
||||
get {
|
||||
uint[] allowedVerts = new uint[10];
|
||||
int offset = -1;
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Source17:
|
||||
case MapType.Source18:
|
||||
case MapType.Source19:
|
||||
@@ -143,7 +174,7 @@ namespace LibBSP {
|
||||
}
|
||||
if (offset >= 0) {
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
allowedVerts[i] = BitConverter.ToUInt32(data, offset + (i * 4));
|
||||
allowedVerts[i] = BitConverter.ToUInt32(Data, offset + (i * 4));
|
||||
}
|
||||
}
|
||||
return allowedVerts;
|
||||
@@ -153,7 +184,7 @@ namespace LibBSP {
|
||||
throw new ArgumentException("AllowedVerts array must have 10 elements.");
|
||||
}
|
||||
int offset = -1;
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Source17:
|
||||
case MapType.Source18:
|
||||
case MapType.Source19:
|
||||
@@ -181,7 +212,7 @@ namespace LibBSP {
|
||||
}
|
||||
if (offset >= 0) {
|
||||
for (int i = 0; i < value.Length; ++i) {
|
||||
BitConverter.GetBytes(value[i]).CopyTo(data, offset + (i * 4));
|
||||
BitConverter.GetBytes(value[i]).CopyTo(Data, offset + (i * 4));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -191,33 +222,42 @@ namespace LibBSP {
|
||||
/// Creates a new <see cref="DisplacementInfo"/> object from a <c>byte</c> array.
|
||||
/// </summary>
|
||||
/// <param name="data"><c>byte</c> array to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data" /> was <c>null</c>.</exception>
|
||||
public DisplacementInfo(byte[] data, MapType type, int version = 0) : this() {
|
||||
/// <param name="parent">The <see cref="ILump"/> this <see cref="DisplacementInfo"/> came from.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> was <c>null</c>.</exception>
|
||||
public DisplacementInfo(byte[] data, ILump parent = null) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
this.data = data;
|
||||
this.type = type;
|
||||
this.version = version;
|
||||
|
||||
Data = data;
|
||||
Parent = parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Factory method to parse a <c>byte</c> array into a <c>List</c> of <see cref="DisplacementInfo"/> objects.
|
||||
/// Factory method to parse a <c>byte</c> array into a <see cref="Lump{DisplacementInfo}"/>.
|
||||
/// </summary>
|
||||
/// <param name="data">The data to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <returns>A <c>List</c> of <see cref="DisplacementInfo"/> objects.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data" /> was <c>null</c>.</exception>
|
||||
/// <exception cref="ArgumentException">This structure is not implemented for the given maptype.</exception>
|
||||
public static List<DisplacementInfo> LumpFactory(byte[] data, MapType type, int version = 0) {
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
/// <returns>A <see cref="Lump{DisplacementInfo}"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> parameter was <c>null</c>.</exception>
|
||||
public static Lump<DisplacementInfo> LumpFactory(byte[] data, BSP bsp, LumpInfo lumpInfo) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
int structLength = 0;
|
||||
switch (type) {
|
||||
|
||||
return new Lump<DisplacementInfo>(data, GetStructLength(bsp.version, lumpInfo.version), bsp, lumpInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length of this struct's data for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.
|
||||
/// </summary>
|
||||
/// <param name="mapType">The <see cref="LibBSP.MapType"/> of the BSP.</param>
|
||||
/// <param name="lumpVersion">The version number for the lump.</param>
|
||||
/// <returns>The length, in <c>byte</c>s, of this struct.</returns>
|
||||
/// <exception cref="ArgumentException">This struct is not valid or is not implemented for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.</exception>
|
||||
public static int GetStructLength(MapType mapType, int lumpVersion = 0) {
|
||||
switch (mapType) {
|
||||
case MapType.Source17:
|
||||
case MapType.Source18:
|
||||
case MapType.Source19:
|
||||
@@ -227,33 +267,21 @@ namespace LibBSP {
|
||||
case MapType.L4D2:
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.DMoMaM: {
|
||||
structLength = 176;
|
||||
break;
|
||||
return 176;
|
||||
}
|
||||
case MapType.Source22: {
|
||||
structLength = 180;
|
||||
break;
|
||||
return 180;
|
||||
}
|
||||
case MapType.Source23: {
|
||||
structLength = 184;
|
||||
break;
|
||||
return 184;
|
||||
}
|
||||
case MapType.Vindictus: {
|
||||
structLength = 232;
|
||||
break;
|
||||
return 232;
|
||||
}
|
||||
default: {
|
||||
throw new ArgumentException("Map type " + type + " isn't supported by the SourceDispInfo lump factory.");
|
||||
throw new ArgumentException("Lump object " + MethodBase.GetCurrentMethod().DeclaringType.Name + " does not exist in map type " + mapType + " or has not been implemented.");
|
||||
}
|
||||
}
|
||||
int numObjects = data.Length / structLength;
|
||||
List<DisplacementInfo> lump = new List<DisplacementInfo>(numObjects);
|
||||
for (int i = 0; i < numObjects; ++i) {
|
||||
byte[] bytes = new byte[structLength];
|
||||
Array.Copy(data, (i * structLength), bytes, 0, structLength);
|
||||
lump.Add(new DisplacementInfo(bytes, type, version));
|
||||
}
|
||||
return lump;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#endif
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace LibBSP {
|
||||
#if UNITY
|
||||
@@ -14,21 +15,51 @@ namespace LibBSP {
|
||||
/// <summary>
|
||||
/// Holds all the data for a displacement in a Source map.
|
||||
/// </summary>
|
||||
public struct DisplacementVertex {
|
||||
public struct DisplacementVertex : ILumpObject {
|
||||
|
||||
public byte[] data;
|
||||
public MapType type;
|
||||
public int version;
|
||||
/// <summary>
|
||||
/// The <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public ILump Parent { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Array of <c>byte</c>s used as the data source for this <see cref="ILumpObject"/>.
|
||||
/// </summary>
|
||||
public byte[] Data { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="LibBSP.MapType"/> to use to interpret <see cref="Data"/>.
|
||||
/// </summary>
|
||||
public MapType MapType {
|
||||
get {
|
||||
if (Parent == null || Parent.Bsp == null) {
|
||||
return MapType.Undefined;
|
||||
}
|
||||
return Parent.Bsp.version;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The version number of the <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public int LumpVersion {
|
||||
get {
|
||||
if (Parent == null) {
|
||||
return 0;
|
||||
}
|
||||
return Parent.LumpInfo.version;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The normalized vector direction this vertex points from "flat".
|
||||
/// </summary>
|
||||
public Vector3d normal {
|
||||
get {
|
||||
return new Vector3d(BitConverter.ToSingle(data, 0), BitConverter.ToSingle(data, 4), BitConverter.ToSingle(data, 8));
|
||||
return new Vector3d(BitConverter.ToSingle(Data, 0), BitConverter.ToSingle(Data, 4), BitConverter.ToSingle(Data, 8));
|
||||
}
|
||||
set {
|
||||
value.GetBytes().CopyTo(data, 0);
|
||||
value.GetBytes().CopyTo(Data, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,10 +68,10 @@ namespace LibBSP {
|
||||
/// </summary>
|
||||
public float dist {
|
||||
get {
|
||||
return BitConverter.ToSingle(data, 12);
|
||||
return BitConverter.ToSingle(Data, 12);
|
||||
}
|
||||
set {
|
||||
BitConverter.GetBytes(value).CopyTo(data, 12);
|
||||
BitConverter.GetBytes(value).CopyTo(Data, 12);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,10 +80,10 @@ namespace LibBSP {
|
||||
/// </summary>
|
||||
public float alpha {
|
||||
get {
|
||||
return BitConverter.ToSingle(data, 16);
|
||||
return BitConverter.ToSingle(Data, 16);
|
||||
}
|
||||
set {
|
||||
BitConverter.GetBytes(value).CopyTo(data, 16);
|
||||
BitConverter.GetBytes(value).CopyTo(Data, 16);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,31 +91,60 @@ namespace LibBSP {
|
||||
/// Creates a new <see cref="DisplacementVertex"/> object from a <c>byte</c> array.
|
||||
/// </summary>
|
||||
/// <param name="data"><c>byte</c> array to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <param name="parent">The <see cref="ILump"/> this <see cref="DisplacementVertex"/> came from.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> was <c>null</c>.</exception>
|
||||
public DisplacementVertex(byte[] data, MapType type, int version = 0) : this() {
|
||||
public DisplacementVertex(byte[] data, ILump parent = null) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
this.data = data;
|
||||
this.type = type;
|
||||
this.version = version;
|
||||
|
||||
Data = data;
|
||||
Parent = parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Factory method to parse a <c>byte</c> array into a <see cref="DisplacementVertices"/> object.
|
||||
/// </summary>
|
||||
/// <param name="data">The data to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
/// <returns>A <see cref="DisplacementVertices"/> object.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> was <c>null</c>.</exception>
|
||||
public static DisplacementVertices LumpFactory(byte[] data, MapType type, int version = 0) {
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> parameter was <c>null</c>.</exception>
|
||||
public static DisplacementVertices LumpFactory(byte[] data, BSP bsp, LumpInfo lumpInfo) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
return new DisplacementVertices(data, type, version);
|
||||
|
||||
return new DisplacementVertices(data, GetStructLength(bsp.version, lumpInfo.version), bsp, lumpInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length of this struct's data for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.
|
||||
/// </summary>
|
||||
/// <param name="mapType">The <see cref="LibBSP.MapType"/> of the BSP.</param>
|
||||
/// <param name="lumpVersion">The version number for the lump.</param>
|
||||
/// <returns>The length, in <c>byte</c>s, of this struct.</returns>
|
||||
/// <exception cref="ArgumentException">This struct is not valid or is not implemented for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.</exception>
|
||||
public static int GetStructLength(MapType mapType, int lumpVersion = 0) {
|
||||
switch (mapType) {
|
||||
case MapType.Vindictus:
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.Source17:
|
||||
case MapType.Source18:
|
||||
case MapType.Source19:
|
||||
case MapType.Source20:
|
||||
case MapType.Source21:
|
||||
case MapType.Source22:
|
||||
case MapType.Source23:
|
||||
case MapType.Source27:
|
||||
case MapType.L4D2:
|
||||
case MapType.DMoMaM: {
|
||||
return 20;
|
||||
}
|
||||
default: {
|
||||
throw new ArgumentException("Lump object " + MethodBase.GetCurrentMethod().DeclaringType.Name + " does not exist in map type " + mapType + " or has not been implemented.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,20 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace LibBSP {
|
||||
|
||||
/// <summary>
|
||||
/// Holds all the data for an edge in a BSP map.
|
||||
/// </summary>
|
||||
public struct Edge {
|
||||
public struct Edge : ILumpObject {
|
||||
|
||||
public byte[] data;
|
||||
public MapType type;
|
||||
public int version;
|
||||
/// <summary>
|
||||
/// The <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public ILump Parent { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Array of <c>byte</c>s used as the data source for this <see cref="ILumpObject"/>.
|
||||
/// </summary>
|
||||
public byte[] Data { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="LibBSP.MapType"/> to use to interpret <see cref="Data"/>.
|
||||
/// </summary>
|
||||
public MapType MapType {
|
||||
get {
|
||||
if (Parent == null || Parent.Bsp == null) {
|
||||
return MapType.Undefined;
|
||||
}
|
||||
return Parent.Bsp.version;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The version number of the <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public int LumpVersion {
|
||||
get {
|
||||
if (Parent == null) {
|
||||
return 0;
|
||||
}
|
||||
return Parent.LumpInfo.version;
|
||||
}
|
||||
}
|
||||
|
||||
public int firstVertex {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Quake:
|
||||
case MapType.SiN:
|
||||
case MapType.Daikatana:
|
||||
@@ -31,10 +62,10 @@ namespace LibBSP {
|
||||
case MapType.DMoMaM:
|
||||
case MapType.Quake2:
|
||||
case MapType.SoF: {
|
||||
return BitConverter.ToUInt16(data, 0);
|
||||
return BitConverter.ToUInt16(Data, 0);
|
||||
}
|
||||
case MapType.Vindictus: {
|
||||
return BitConverter.ToInt32(data, 0);
|
||||
return BitConverter.ToInt32(Data, 0);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -43,7 +74,7 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Quake:
|
||||
case MapType.SiN:
|
||||
case MapType.Daikatana:
|
||||
@@ -60,12 +91,12 @@ namespace LibBSP {
|
||||
case MapType.DMoMaM:
|
||||
case MapType.Quake2:
|
||||
case MapType.SoF: {
|
||||
data[0] = bytes[0];
|
||||
data[1] = bytes[1];
|
||||
Data[0] = bytes[0];
|
||||
Data[1] = bytes[1];
|
||||
break;
|
||||
}
|
||||
case MapType.Vindictus: {
|
||||
bytes.CopyTo(data, 0);
|
||||
bytes.CopyTo(Data, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -74,7 +105,7 @@ namespace LibBSP {
|
||||
|
||||
public int secondVertex {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Quake:
|
||||
case MapType.SiN:
|
||||
case MapType.Daikatana:
|
||||
@@ -91,10 +122,10 @@ namespace LibBSP {
|
||||
case MapType.DMoMaM:
|
||||
case MapType.Quake2:
|
||||
case MapType.SoF: {
|
||||
return BitConverter.ToUInt16(data, 2);
|
||||
return BitConverter.ToUInt16(Data, 2);
|
||||
}
|
||||
case MapType.Vindictus: {
|
||||
return BitConverter.ToInt32(data, 4);
|
||||
return BitConverter.ToInt32(Data, 4);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -103,7 +134,7 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Quake:
|
||||
case MapType.SiN:
|
||||
case MapType.Daikatana:
|
||||
@@ -120,12 +151,12 @@ namespace LibBSP {
|
||||
case MapType.DMoMaM:
|
||||
case MapType.Quake2:
|
||||
case MapType.SoF: {
|
||||
data[2] = bytes[0];
|
||||
data[3] = bytes[1];
|
||||
Data[2] = bytes[0];
|
||||
Data[3] = bytes[1];
|
||||
break;
|
||||
}
|
||||
case MapType.Vindictus: {
|
||||
BitConverter.GetBytes(value).CopyTo(data, 4);
|
||||
BitConverter.GetBytes(value).CopyTo(Data, 4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -136,33 +167,42 @@ namespace LibBSP {
|
||||
/// Creates a new <see cref="Edge"/> object from a <c>byte</c> array.
|
||||
/// </summary>
|
||||
/// <param name="data"><c>byte</c> array to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <param name="parent">The <see cref="ILump"/> this <see cref="Edge"/> came from.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> was <c>null</c>.</exception>
|
||||
public Edge(byte[] data, MapType type, int version = 0) : this() {
|
||||
public Edge(byte[] data, ILump parent = null) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
this.data = data;
|
||||
this.type = type;
|
||||
this.version = version;
|
||||
|
||||
Data = data;
|
||||
Parent = parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Factory method to parse a <c>byte</c> array into a <c>List</c> of <see cref="Edge"/> objects.
|
||||
/// Factory method to parse a <c>byte</c> array into a <see cref="Lump{Edge}"/>.
|
||||
/// </summary>
|
||||
/// <param name="data">The data to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <returns>A <c>List</c> of <see cref="Edge"/> objects.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> was null.</exception>
|
||||
/// <exception cref="ArgumentException">This structure is not implemented for the given maptype.</exception>
|
||||
public static List<Edge> LumpFactory(byte[] data, MapType type, int version = 0) {
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
/// <returns>A <see cref="Lump{Edge}"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> parameter was <c>null</c>.</exception>
|
||||
public static Lump<Edge> LumpFactory(byte[] data, BSP bsp, LumpInfo lumpInfo) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
int structLength = 0;
|
||||
switch (type) {
|
||||
|
||||
return new Lump<Edge>(data, GetStructLength(bsp.version, lumpInfo.version), bsp, lumpInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length of this struct's data for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.
|
||||
/// </summary>
|
||||
/// <param name="mapType">The <see cref="LibBSP.MapType"/> of the BSP.</param>
|
||||
/// <param name="lumpVersion">The version number for the lump.</param>
|
||||
/// <returns>The length, in <c>byte</c>s, of this struct.</returns>
|
||||
/// <exception cref="ArgumentException">This struct is not valid or is not implemented for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.</exception>
|
||||
public static int GetStructLength(MapType mapType, int lumpVersion = 0) {
|
||||
switch (mapType) {
|
||||
case MapType.Quake:
|
||||
case MapType.SiN:
|
||||
case MapType.Daikatana:
|
||||
@@ -179,25 +219,15 @@ namespace LibBSP {
|
||||
case MapType.DMoMaM:
|
||||
case MapType.Quake2:
|
||||
case MapType.SoF: {
|
||||
structLength = 4;
|
||||
break;
|
||||
return 4;
|
||||
}
|
||||
case MapType.Vindictus: {
|
||||
structLength = 8;
|
||||
break;
|
||||
return 8;
|
||||
}
|
||||
default: {
|
||||
throw new ArgumentException("Map type " + type + " isn't supported by the Edge lump factory.");
|
||||
throw new ArgumentException("Lump object " + MethodBase.GetCurrentMethod().DeclaringType.Name + " does not exist in map type " + mapType + " or has not been implemented.");
|
||||
}
|
||||
}
|
||||
int numObjects = data.Length / structLength;
|
||||
List<Edge> lump = new List<Edge>(numObjects);
|
||||
for (int i = 0; i < numObjects; ++i) {
|
||||
byte[] bytes = new byte[structLength];
|
||||
Array.Copy(data, (i * structLength), bytes, 0, structLength);
|
||||
lump.Add(new Edge(bytes, type, version));
|
||||
}
|
||||
return lump;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,22 +1,53 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace LibBSP {
|
||||
|
||||
/// <summary>
|
||||
/// Holds the data for a terrain object in MoHAA.
|
||||
/// </summary>
|
||||
public struct LODTerrain {
|
||||
public struct LODTerrain : ILumpObject {
|
||||
|
||||
public byte[] data;
|
||||
public MapType type;
|
||||
public int version;
|
||||
/// <summary>
|
||||
/// The <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public ILump Parent { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Array of <c>byte</c>s used as the data source for this <see cref="ILumpObject"/>.
|
||||
/// </summary>
|
||||
public byte[] Data { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="LibBSP.MapType"/> to use to interpret <see cref="Data"/>.
|
||||
/// </summary>
|
||||
public MapType MapType {
|
||||
get {
|
||||
if (Parent == null || Parent.Bsp == null) {
|
||||
return MapType.Undefined;
|
||||
}
|
||||
return Parent.Bsp.version;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The version number of the <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public int LumpVersion {
|
||||
get {
|
||||
if (Parent == null) {
|
||||
return 0;
|
||||
}
|
||||
return Parent.LumpInfo.version;
|
||||
}
|
||||
}
|
||||
|
||||
public byte flags {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
return data[0];
|
||||
return Data[0];
|
||||
}
|
||||
default: {
|
||||
return 0;
|
||||
@@ -24,9 +55,9 @@ namespace LibBSP {
|
||||
}
|
||||
}
|
||||
set {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
data[0] = value;
|
||||
Data[0] = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -35,9 +66,9 @@ namespace LibBSP {
|
||||
|
||||
public byte scale {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
return data[1];
|
||||
return Data[1];
|
||||
}
|
||||
default: {
|
||||
return 0;
|
||||
@@ -45,9 +76,9 @@ namespace LibBSP {
|
||||
}
|
||||
}
|
||||
set {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
data[1] = value;
|
||||
Data[1] = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -56,9 +87,9 @@ namespace LibBSP {
|
||||
|
||||
public byte[] lightmapCoords {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
return new byte[] { data[2], data[3] };
|
||||
return new byte[] { Data[2], Data[3] };
|
||||
}
|
||||
default: {
|
||||
return null;
|
||||
@@ -69,10 +100,10 @@ namespace LibBSP {
|
||||
if (value.Length != 2) {
|
||||
throw new ArgumentException("LightmapCoords array must have 2 elements.");
|
||||
}
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
data[2] = value[0];
|
||||
data[3] = value[1];
|
||||
Data[2] = value[0];
|
||||
Data[3] = value[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -81,17 +112,17 @@ namespace LibBSP {
|
||||
|
||||
public float[] textureCoords {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
return new float[] {
|
||||
BitConverter.ToSingle(data, 4),
|
||||
BitConverter.ToSingle(data, 8),
|
||||
BitConverter.ToSingle(data, 12),
|
||||
BitConverter.ToSingle(data, 16),
|
||||
BitConverter.ToSingle(data, 20),
|
||||
BitConverter.ToSingle(data, 24),
|
||||
BitConverter.ToSingle(data, 28),
|
||||
BitConverter.ToSingle(data, 32),
|
||||
BitConverter.ToSingle(Data, 4),
|
||||
BitConverter.ToSingle(Data, 8),
|
||||
BitConverter.ToSingle(Data, 12),
|
||||
BitConverter.ToSingle(Data, 16),
|
||||
BitConverter.ToSingle(Data, 20),
|
||||
BitConverter.ToSingle(Data, 24),
|
||||
BitConverter.ToSingle(Data, 28),
|
||||
BitConverter.ToSingle(Data, 32),
|
||||
};
|
||||
}
|
||||
default: {
|
||||
@@ -103,11 +134,11 @@ namespace LibBSP {
|
||||
if (value.Length != 8) {
|
||||
throw new ArgumentException("TextureCoords array must have 8 elements.");
|
||||
}
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
int offset = 4;
|
||||
for (int i = 0; i < value.Length; ++i) {
|
||||
BitConverter.GetBytes(value[i]).CopyTo(data, offset + (i * 4));
|
||||
BitConverter.GetBytes(value[i]).CopyTo(Data, offset + (i * 4));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -117,9 +148,9 @@ namespace LibBSP {
|
||||
|
||||
public sbyte x {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
return (sbyte)data[36];
|
||||
return (sbyte)Data[36];
|
||||
}
|
||||
default: {
|
||||
return 0;
|
||||
@@ -127,9 +158,9 @@ namespace LibBSP {
|
||||
}
|
||||
}
|
||||
set {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
data[36] = (byte)value;
|
||||
Data[36] = (byte)value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -138,9 +169,9 @@ namespace LibBSP {
|
||||
|
||||
public sbyte y {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
return (sbyte)data[37];
|
||||
return (sbyte)Data[37];
|
||||
}
|
||||
default: {
|
||||
return 0;
|
||||
@@ -148,9 +179,9 @@ namespace LibBSP {
|
||||
}
|
||||
}
|
||||
set {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
data[37] = (byte)value;
|
||||
Data[37] = (byte)value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -159,9 +190,9 @@ namespace LibBSP {
|
||||
|
||||
public short baseZ {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
return BitConverter.ToInt16(data, 38);
|
||||
return BitConverter.ToInt16(Data, 38);
|
||||
}
|
||||
default: {
|
||||
return 0;
|
||||
@@ -170,9 +201,9 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
bytes.CopyTo(data, 38);
|
||||
bytes.CopyTo(Data, 38);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -181,9 +212,9 @@ namespace LibBSP {
|
||||
|
||||
public ushort texture {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
return BitConverter.ToUInt16(data, 40);
|
||||
return BitConverter.ToUInt16(Data, 40);
|
||||
}
|
||||
default: {
|
||||
return 0;
|
||||
@@ -192,9 +223,9 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
bytes.CopyTo(data, 40);
|
||||
bytes.CopyTo(Data, 40);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -203,9 +234,9 @@ namespace LibBSP {
|
||||
|
||||
public short lightmap {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
return BitConverter.ToInt16(data, 42);
|
||||
return BitConverter.ToInt16(Data, 42);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -214,9 +245,9 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
bytes.CopyTo(data, 42);
|
||||
bytes.CopyTo(Data, 42);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -226,11 +257,11 @@ namespace LibBSP {
|
||||
public ushort[,] vertexFlags {
|
||||
get {
|
||||
ushort[,] ret = new ushort[2,63];
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
for (int i = 0; i < ret.GetLength(0); ++i) {
|
||||
for (int j = 0; j < ret.GetLength(1); ++j) {
|
||||
ret[i, j] = BitConverter.ToUInt16(data, 52 + (i * 126) + (j * 2));
|
||||
ret[i, j] = BitConverter.ToUInt16(Data, 52 + (i * 126) + (j * 2));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -244,7 +275,7 @@ namespace LibBSP {
|
||||
}
|
||||
for (int i = 0; i < value.GetLength(0); ++i) {
|
||||
for (int j = 0; j < value.GetLength(1); ++j) {
|
||||
BitConverter.GetBytes(value[i, j]).CopyTo(data, 52 + (i * 126) + (j * 2));
|
||||
BitConverter.GetBytes(value[i, j]).CopyTo(Data, 52 + (i * 126) + (j * 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -253,11 +284,11 @@ namespace LibBSP {
|
||||
public byte[,] heightmap {
|
||||
get {
|
||||
byte[,] ret = new byte[9, 9];
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
for (int i = 0; i < ret.GetLength(0); ++i) {
|
||||
for (int j = 0; j < ret.GetLength(1); ++j) {
|
||||
ret[i, j] = data[304 + (i * 9) + j];
|
||||
ret[i, j] = Data[304 + (i * 9) + j];
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -271,7 +302,7 @@ namespace LibBSP {
|
||||
}
|
||||
for (int i = 0; i < value.GetLength(0); ++i) {
|
||||
for (int j = 0; j < value.GetLength(1); ++j) {
|
||||
data[304 + (i * 9) + j] = value[i, j];
|
||||
Data[304 + (i * 9) + j] = value[i, j];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -281,49 +312,49 @@ namespace LibBSP {
|
||||
/// Creates a new <see cref="LODTerrain"/> object from a <c>byte</c> array.
|
||||
/// </summary>
|
||||
/// <param name="data"><c>byte</c> array to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <param name="parent">The <see cref="ILump"/> this <see cref="LODTerrain"/> came from.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> was <c>null</c>.</exception>
|
||||
public LODTerrain(byte[] data, MapType type, int version = 0) : this() {
|
||||
public LODTerrain(byte[] data, ILump parent = null) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
this.data = data;
|
||||
this.type = type;
|
||||
this.version = version;
|
||||
|
||||
Data = data;
|
||||
Parent = parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Factory method to parse a <c>byte</c> array into a <c>List</c> of <see cref="LODTerrain"/> objects.
|
||||
/// Factory method to parse a <c>byte</c> array into a <see cref="Lump{LODTerrain}"/>.
|
||||
/// </summary>
|
||||
/// <param name="data">The data to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <returns>A <c>List</c> of <see cref="LODTerrain"/> objects.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data" /> was <c>null</c>.</exception>
|
||||
/// <exception cref="ArgumentException">This structure is not implemented for the given maptype.</exception>
|
||||
public static List<LODTerrain> LumpFactory(byte[] data, MapType type, int version = 0) {
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
/// <returns>A <see cref="Lump{LODTerrain}"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> parameter was <c>null</c>.</exception>
|
||||
public static Lump<LODTerrain> LumpFactory(byte[] data, BSP bsp, LumpInfo lumpInfo) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
int structLength = 0;
|
||||
switch (type) {
|
||||
|
||||
return new Lump<LODTerrain>(data, GetStructLength(bsp.version, lumpInfo.version), bsp, lumpInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length of this struct's data for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.
|
||||
/// </summary>
|
||||
/// <param name="mapType">The <see cref="LibBSP.MapType"/> of the BSP.</param>
|
||||
/// <param name="lumpVersion">The version number for the lump.</param>
|
||||
/// <returns>The length, in <c>byte</c>s, of this struct.</returns>
|
||||
/// <exception cref="ArgumentException">This struct is not valid or is not implemented for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.</exception>
|
||||
public static int GetStructLength(MapType mapType, int lumpVersion = 0) {
|
||||
switch (mapType) {
|
||||
case MapType.MOHAA: {
|
||||
structLength = 388;
|
||||
break;
|
||||
return 388;
|
||||
}
|
||||
default: {
|
||||
throw new ArgumentException("Map type " + type + " isn't supported by the LODTerrain lump factory.");
|
||||
throw new ArgumentException("Lump object " + MethodBase.GetCurrentMethod().DeclaringType.Name + " does not exist in map type " + mapType + " or has not been implemented.");
|
||||
}
|
||||
}
|
||||
int numObjects = data.Length / structLength;
|
||||
List<LODTerrain> lump = new List<LODTerrain>(numObjects);
|
||||
for (int i = 0; i < numObjects; ++i) {
|
||||
byte[] bytes = new byte[structLength];
|
||||
Array.Copy(data, (i * structLength), bytes, 0, structLength);
|
||||
lump.Add(new LODTerrain(bytes, type, version));
|
||||
}
|
||||
return lump;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,20 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace LibBSP {
|
||||
|
||||
/// <summary>
|
||||
/// Holds data for a leaf structure in a BSP map.
|
||||
/// </summary>
|
||||
public struct Leaf {
|
||||
public struct Leaf : ILumpObject {
|
||||
|
||||
public byte[] data;
|
||||
public MapType type;
|
||||
public int version;
|
||||
/// <summary>
|
||||
/// The <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public ILump Parent { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Array of <c>byte</c>s used as the data source for this <see cref="ILumpObject"/>.
|
||||
/// </summary>
|
||||
public byte[] Data { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="LibBSP.MapType"/> to use to interpret <see cref="Data"/>.
|
||||
/// </summary>
|
||||
public MapType MapType {
|
||||
get {
|
||||
if (Parent == null || Parent.Bsp == null) {
|
||||
return MapType.Undefined;
|
||||
}
|
||||
return Parent.Bsp.version;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The version number of the <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public int LumpVersion {
|
||||
get {
|
||||
if (Parent == null) {
|
||||
return 0;
|
||||
}
|
||||
return Parent.LumpInfo.version;
|
||||
}
|
||||
}
|
||||
|
||||
public int contents {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.SoF:
|
||||
case MapType.Quake2:
|
||||
case MapType.SiN:
|
||||
@@ -32,7 +63,7 @@ namespace LibBSP {
|
||||
case MapType.Daikatana:
|
||||
case MapType.Vindictus:
|
||||
case MapType.Nightfire: {
|
||||
return BitConverter.ToInt32(data, 0);
|
||||
return BitConverter.ToInt32(Data, 0);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -41,7 +72,7 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.SoF:
|
||||
case MapType.Quake2:
|
||||
case MapType.SiN:
|
||||
@@ -59,7 +90,7 @@ namespace LibBSP {
|
||||
case MapType.Daikatana:
|
||||
case MapType.Vindictus:
|
||||
case MapType.Nightfire: {
|
||||
bytes.CopyTo(data, 0);
|
||||
bytes.CopyTo(Data, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -68,13 +99,13 @@ namespace LibBSP {
|
||||
|
||||
[Index("markBrushes")] public int firstMarkBrush {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD4: {
|
||||
return BitConverter.ToInt32(data, 12);
|
||||
return BitConverter.ToInt32(Data, 12);
|
||||
}
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2: {
|
||||
return BitConverter.ToInt32(data, 16);
|
||||
return BitConverter.ToInt32(Data, 16);
|
||||
}
|
||||
case MapType.Quake2:
|
||||
case MapType.SiN:
|
||||
@@ -90,10 +121,10 @@ namespace LibBSP {
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.DMoMaM:
|
||||
case MapType.Daikatana: {
|
||||
return BitConverter.ToUInt16(data, 24);
|
||||
return BitConverter.ToUInt16(Data, 24);
|
||||
}
|
||||
case MapType.SoF: {
|
||||
return BitConverter.ToUInt16(data, 26);
|
||||
return BitConverter.ToUInt16(Data, 26);
|
||||
}
|
||||
case MapType.Quake3:
|
||||
case MapType.FAKK:
|
||||
@@ -102,10 +133,10 @@ namespace LibBSP {
|
||||
case MapType.MOHAA:
|
||||
case MapType.Raven:
|
||||
case MapType.Nightfire: {
|
||||
return BitConverter.ToInt32(data, 40);
|
||||
return BitConverter.ToInt32(Data, 40);
|
||||
}
|
||||
case MapType.Vindictus: {
|
||||
return BitConverter.ToInt32(data, 44);
|
||||
return BitConverter.ToInt32(Data, 44);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -114,14 +145,14 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD4: {
|
||||
bytes.CopyTo(data, 12);
|
||||
bytes.CopyTo(Data, 12);
|
||||
break;
|
||||
}
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2: {
|
||||
bytes.CopyTo(data, 16);
|
||||
bytes.CopyTo(Data, 16);
|
||||
break;
|
||||
}
|
||||
case MapType.Quake2:
|
||||
@@ -138,13 +169,13 @@ namespace LibBSP {
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.DMoMaM:
|
||||
case MapType.Daikatana: {
|
||||
data[24] = bytes[0];
|
||||
data[25] = bytes[1];
|
||||
Data[24] = bytes[0];
|
||||
Data[25] = bytes[1];
|
||||
break;
|
||||
}
|
||||
case MapType.SoF: {
|
||||
data[26] = bytes[0];
|
||||
data[27] = bytes[1];
|
||||
Data[26] = bytes[0];
|
||||
Data[27] = bytes[1];
|
||||
break;
|
||||
}
|
||||
case MapType.Quake3:
|
||||
@@ -154,11 +185,11 @@ namespace LibBSP {
|
||||
case MapType.MOHAA:
|
||||
case MapType.Raven:
|
||||
case MapType.Nightfire: {
|
||||
bytes.CopyTo(data, 40);
|
||||
bytes.CopyTo(Data, 40);
|
||||
break;
|
||||
}
|
||||
case MapType.Vindictus: {
|
||||
bytes.CopyTo(data, 44);
|
||||
bytes.CopyTo(Data, 44);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -167,13 +198,13 @@ namespace LibBSP {
|
||||
|
||||
[Count("markBrushes")] public int numMarkBrushes {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD4: {
|
||||
return BitConverter.ToInt32(data, 16);
|
||||
return BitConverter.ToInt32(Data, 16);
|
||||
}
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2: {
|
||||
return BitConverter.ToInt32(data, 20);
|
||||
return BitConverter.ToInt32(Data, 20);
|
||||
}
|
||||
case MapType.Quake2:
|
||||
case MapType.SiN:
|
||||
@@ -189,10 +220,10 @@ namespace LibBSP {
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.DMoMaM:
|
||||
case MapType.Daikatana: {
|
||||
return BitConverter.ToUInt16(data, 26);
|
||||
return BitConverter.ToUInt16(Data, 26);
|
||||
}
|
||||
case MapType.SoF: {
|
||||
return BitConverter.ToUInt16(data, 28);
|
||||
return BitConverter.ToUInt16(Data, 28);
|
||||
}
|
||||
case MapType.Nightfire:
|
||||
case MapType.Quake3:
|
||||
@@ -201,10 +232,10 @@ namespace LibBSP {
|
||||
case MapType.STEF2:
|
||||
case MapType.MOHAA:
|
||||
case MapType.Raven: {
|
||||
return BitConverter.ToInt32(data, 44);
|
||||
return BitConverter.ToInt32(Data, 44);
|
||||
}
|
||||
case MapType.Vindictus: {
|
||||
return BitConverter.ToInt32(data, 48);
|
||||
return BitConverter.ToInt32(Data, 48);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -213,14 +244,14 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD4: {
|
||||
bytes.CopyTo(data, 16);
|
||||
bytes.CopyTo(Data, 16);
|
||||
break;
|
||||
}
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2: {
|
||||
bytes.CopyTo(data, 20);
|
||||
bytes.CopyTo(Data, 20);
|
||||
break;
|
||||
}
|
||||
case MapType.Quake2:
|
||||
@@ -237,13 +268,13 @@ namespace LibBSP {
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.DMoMaM:
|
||||
case MapType.Daikatana: {
|
||||
data[26] = bytes[0];
|
||||
data[27] = bytes[1];
|
||||
Data[26] = bytes[0];
|
||||
Data[27] = bytes[1];
|
||||
break;
|
||||
}
|
||||
case MapType.SoF: {
|
||||
data[28] = bytes[0];
|
||||
data[29] = bytes[1];
|
||||
Data[28] = bytes[0];
|
||||
Data[29] = bytes[1];
|
||||
break;
|
||||
}
|
||||
case MapType.Nightfire:
|
||||
@@ -253,11 +284,11 @@ namespace LibBSP {
|
||||
case MapType.STEF2:
|
||||
case MapType.MOHAA:
|
||||
case MapType.Raven: {
|
||||
bytes.CopyTo(data, 44);
|
||||
bytes.CopyTo(Data, 44);
|
||||
break;
|
||||
}
|
||||
case MapType.Vindictus: {
|
||||
bytes.CopyTo(data, 48);
|
||||
bytes.CopyTo(Data, 48);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -266,10 +297,10 @@ namespace LibBSP {
|
||||
|
||||
[Index("markSurfaces")] public int firstMarkFace {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2: {
|
||||
return BitConverter.ToInt32(data, 8);
|
||||
return BitConverter.ToInt32(Data, 8);
|
||||
}
|
||||
case MapType.Quake:
|
||||
case MapType.Quake2:
|
||||
@@ -286,10 +317,10 @@ namespace LibBSP {
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.DMoMaM:
|
||||
case MapType.Daikatana: {
|
||||
return BitConverter.ToUInt16(data, 20);
|
||||
return BitConverter.ToUInt16(Data, 20);
|
||||
}
|
||||
case MapType.SoF: {
|
||||
return BitConverter.ToUInt16(data, 22);
|
||||
return BitConverter.ToUInt16(Data, 22);
|
||||
}
|
||||
case MapType.Quake3:
|
||||
case MapType.FAKK:
|
||||
@@ -298,10 +329,10 @@ namespace LibBSP {
|
||||
case MapType.MOHAA:
|
||||
case MapType.Raven:
|
||||
case MapType.Nightfire: {
|
||||
return BitConverter.ToInt32(data, 32);
|
||||
return BitConverter.ToInt32(Data, 32);
|
||||
}
|
||||
case MapType.Vindictus: {
|
||||
return BitConverter.ToInt32(data, 36);
|
||||
return BitConverter.ToInt32(Data, 36);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -310,10 +341,10 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2: {
|
||||
bytes.CopyTo(data, 8);
|
||||
bytes.CopyTo(Data, 8);
|
||||
break;
|
||||
}
|
||||
case MapType.Quake:
|
||||
@@ -331,13 +362,13 @@ namespace LibBSP {
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.DMoMaM:
|
||||
case MapType.Daikatana: {
|
||||
data[20] = bytes[0];
|
||||
data[21] = bytes[1];
|
||||
Data[20] = bytes[0];
|
||||
Data[21] = bytes[1];
|
||||
break;
|
||||
}
|
||||
case MapType.SoF: {
|
||||
data[22] = bytes[0];
|
||||
data[23] = bytes[1];
|
||||
Data[22] = bytes[0];
|
||||
Data[23] = bytes[1];
|
||||
break;
|
||||
}
|
||||
case MapType.Quake3:
|
||||
@@ -347,11 +378,11 @@ namespace LibBSP {
|
||||
case MapType.MOHAA:
|
||||
case MapType.Raven:
|
||||
case MapType.Nightfire: {
|
||||
bytes.CopyTo(data, 32);
|
||||
bytes.CopyTo(Data, 32);
|
||||
break;
|
||||
}
|
||||
case MapType.Vindictus: {
|
||||
bytes.CopyTo(data, 36);
|
||||
bytes.CopyTo(Data, 36);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -360,10 +391,10 @@ namespace LibBSP {
|
||||
|
||||
[Count("markSurfaces")] public int numMarkFaces {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2: {
|
||||
return BitConverter.ToInt32(data, 12);
|
||||
return BitConverter.ToInt32(Data, 12);
|
||||
}
|
||||
case MapType.Quake:
|
||||
case MapType.Quake2:
|
||||
@@ -380,10 +411,10 @@ namespace LibBSP {
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.DMoMaM:
|
||||
case MapType.Daikatana: {
|
||||
return BitConverter.ToUInt16(data, 22);
|
||||
return BitConverter.ToUInt16(Data, 22);
|
||||
}
|
||||
case MapType.SoF: {
|
||||
return BitConverter.ToUInt16(data, 24);
|
||||
return BitConverter.ToUInt16(Data, 24);
|
||||
}
|
||||
case MapType.Quake3:
|
||||
case MapType.FAKK:
|
||||
@@ -392,10 +423,10 @@ namespace LibBSP {
|
||||
case MapType.MOHAA:
|
||||
case MapType.Raven:
|
||||
case MapType.Nightfire: {
|
||||
return BitConverter.ToInt32(data, 36);
|
||||
return BitConverter.ToInt32(Data, 36);
|
||||
}
|
||||
case MapType.Vindictus: {
|
||||
return BitConverter.ToInt32(data, 40);
|
||||
return BitConverter.ToInt32(Data, 40);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -404,10 +435,10 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2: {
|
||||
bytes.CopyTo(data, 12);
|
||||
bytes.CopyTo(Data, 12);
|
||||
break;
|
||||
}
|
||||
case MapType.Quake:
|
||||
@@ -425,13 +456,13 @@ namespace LibBSP {
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.DMoMaM:
|
||||
case MapType.Daikatana: {
|
||||
data[22] = bytes[0];
|
||||
data[23] = bytes[1];
|
||||
Data[22] = bytes[0];
|
||||
Data[23] = bytes[1];
|
||||
break;
|
||||
}
|
||||
case MapType.SoF: {
|
||||
data[24] = bytes[0];
|
||||
data[25] = bytes[1];
|
||||
Data[24] = bytes[0];
|
||||
Data[25] = bytes[1];
|
||||
break;
|
||||
}
|
||||
case MapType.Quake3:
|
||||
@@ -441,11 +472,11 @@ namespace LibBSP {
|
||||
case MapType.MOHAA:
|
||||
case MapType.Raven:
|
||||
case MapType.Nightfire: {
|
||||
bytes.CopyTo(data, 36);
|
||||
bytes.CopyTo(Data, 36);
|
||||
break;
|
||||
}
|
||||
case MapType.Vindictus: {
|
||||
bytes.CopyTo(data, 40);
|
||||
bytes.CopyTo(Data, 40);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -454,9 +485,9 @@ namespace LibBSP {
|
||||
|
||||
public int pvs {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Nightfire: {
|
||||
return BitConverter.ToInt32(data, 4);
|
||||
return BitConverter.ToInt32(Data, 4);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -465,9 +496,9 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Nightfire: {
|
||||
bytes.CopyTo(data, 4);
|
||||
bytes.CopyTo(Data, 4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -478,42 +509,49 @@ namespace LibBSP {
|
||||
/// Creates a new <see cref="Leaf"/> object from a <c>byte</c> array.
|
||||
/// </summary>
|
||||
/// <param name="data"><c>byte</c> array to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data" /> was <c>null</c>.</exception>
|
||||
public Leaf(byte[] data, MapType type, int version = 0) : this() {
|
||||
/// <param name="parent">The <see cref="ILump"/> this <see cref="Leaf"/> came from.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> was <c>null</c>.</exception>
|
||||
public Leaf(byte[] data, ILump parent = null) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
this.data = data;
|
||||
this.type = type;
|
||||
this.version = version;
|
||||
|
||||
Data = data;
|
||||
Parent = parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Factory method to parse a <c>byte</c> array into a <c>List</c> of <see cref="Leaf"/> objects.
|
||||
/// Factory method to parse a <c>byte</c> array into a <see cref="Lump{Leaf}"/>.
|
||||
/// </summary>
|
||||
/// <param name="data">The data to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <returns>A <c>List</c> of <see cref="Leaf"/> objects.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data" /> was <c>null</c>.</exception>
|
||||
/// <exception cref="ArgumentException">This structure is not implemented for the given maptype.</exception>
|
||||
public static List<Leaf> LumpFactory(byte[] data, MapType type, int version = 0) {
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
/// <returns>A <see cref="Lump{Leaf}"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> parameter was <c>null</c>.</exception>
|
||||
public static Lump<Leaf> LumpFactory(byte[] data, BSP bsp, LumpInfo lumpInfo) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
int structLength = 0;
|
||||
switch (type) {
|
||||
|
||||
return new Lump<Leaf>(data, GetStructLength(bsp.version, lumpInfo.version), bsp, lumpInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length of this struct's data for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.
|
||||
/// </summary>
|
||||
/// <param name="mapType">The <see cref="LibBSP.MapType"/> of the BSP.</param>
|
||||
/// <param name="lumpVersion">The version number for the lump.</param>
|
||||
/// <returns>The length, in <c>byte</c>s, of this struct.</returns>
|
||||
/// <exception cref="ArgumentException">This struct is not valid or is not implemented for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.</exception>
|
||||
public static int GetStructLength(MapType mapType, int lumpVersion = 0) {
|
||||
switch (mapType) {
|
||||
case MapType.CoD4: {
|
||||
structLength = 24;
|
||||
break;
|
||||
return 24;
|
||||
}
|
||||
case MapType.Quake:
|
||||
case MapType.Quake2:
|
||||
case MapType.SiN: {
|
||||
structLength = 28;
|
||||
break;
|
||||
return 28;
|
||||
}
|
||||
case MapType.Source17:
|
||||
case MapType.Source20:
|
||||
@@ -526,13 +564,11 @@ namespace LibBSP {
|
||||
case MapType.SoF:
|
||||
case MapType.Daikatana:
|
||||
case MapType.DMoMaM: {
|
||||
structLength = 32;
|
||||
break;
|
||||
return 32;
|
||||
}
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2: {
|
||||
structLength = 36;
|
||||
break;
|
||||
return 36;
|
||||
}
|
||||
case MapType.Nightfire:
|
||||
case MapType.Quake3:
|
||||
@@ -540,31 +576,20 @@ namespace LibBSP {
|
||||
case MapType.STEF2Demo:
|
||||
case MapType.STEF2:
|
||||
case MapType.Raven: {
|
||||
structLength = 48;
|
||||
break;
|
||||
return 48;
|
||||
}
|
||||
case MapType.Source18:
|
||||
case MapType.Source19:
|
||||
case MapType.Vindictus: {
|
||||
structLength = 56;
|
||||
break;
|
||||
return 56;
|
||||
}
|
||||
case MapType.MOHAA: {
|
||||
structLength = 64;
|
||||
break;
|
||||
return 64;
|
||||
}
|
||||
default: {
|
||||
throw new ArgumentException("Map type " + type + " isn't supported by the Leaf lump factory.");
|
||||
throw new ArgumentException("Lump object " + MethodBase.GetCurrentMethod().DeclaringType.Name + " does not exist in map type " + mapType + " or has not been implemented.");
|
||||
}
|
||||
}
|
||||
int numObjects = data.Length / structLength;
|
||||
List<Leaf> lump = new List<Leaf>(numObjects);
|
||||
for (int i = 0; i < numObjects; ++i) {
|
||||
byte[] bytes = new byte[structLength];
|
||||
Array.Copy(data, (i * structLength), bytes, 0, structLength);
|
||||
lump.Add(new Leaf(bytes, type, version));
|
||||
}
|
||||
return lump;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -6,27 +6,40 @@ namespace LibBSP {
|
||||
/// <summary>
|
||||
/// Class representing a group of <see cref="DisplacementVertex"/> objects. Contains helpful methods to handle Displacement Vertices in the <c>List</c>.
|
||||
/// </summary>
|
||||
public class DisplacementVertices : List<DisplacementVertex> {
|
||||
public class DisplacementVertices : Lump<DisplacementVertex> {
|
||||
|
||||
/// <summary>
|
||||
/// Parses the passed <c>byte</c> array into a <c>List</c> of <see cref="DisplacementVertex"/> objects.
|
||||
/// Creates an empty <see cref="DisplacementVertices"/> object.
|
||||
/// </summary>
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
public DisplacementVertices(BSP bsp = null, LumpInfo lumpInfo = default(LumpInfo)) : base(bsp, lumpInfo) { }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="DisplacementVertices"/> that contains elements copied from the passed <see cref="IEnumerable{DisplacementVertex}"/>.
|
||||
/// </summary>
|
||||
/// <param name="items">The elements to copy into this <c>Lump</c>.</param>
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
public DisplacementVertices(IEnumerable<DisplacementVertex> items, BSP bsp = null, LumpInfo lumpInfo = default(LumpInfo)) : base(items, bsp, lumpInfo) { }
|
||||
|
||||
/// <summary>
|
||||
/// Creates an empty <see cref="DisplacementVertices"/> object with the specified initial capactiy.
|
||||
/// </summary>
|
||||
/// <param name="capacity">The number of elements that can initially be stored.</param>
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
public DisplacementVertices(int capacity, BSP bsp = null, LumpInfo lumpInfo = default(LumpInfo)) : base(capacity, bsp, lumpInfo) { }
|
||||
|
||||
/// <summary>
|
||||
/// Parses the passed <c>byte</c> array into a <see cref="DisplacementVertices"/> object.
|
||||
/// </summary>
|
||||
/// <param name="data">Array of <c>byte</c>s to parse.</param>
|
||||
/// <param name="type">Format identifier.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <param name="structLength">Number of <c>byte</c>s to copy into the children.</param>
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data" /> was <c>null</c>.</exception>
|
||||
public DisplacementVertices(byte[] data, MapType type, int version = 0) : base(data.Length / 20) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
int structLength = 20;
|
||||
int numObjects = data.Length / structLength;
|
||||
for (int i = 0; i < numObjects; ++i) {
|
||||
byte[] bytes = new byte[structLength];
|
||||
Array.Copy(data, (i * structLength), bytes, 0, structLength);
|
||||
Add(new DisplacementVertex(bytes, type, version));
|
||||
}
|
||||
}
|
||||
public DisplacementVertices(byte[] data, int structLength, BSP bsp = null, LumpInfo lumpInfo = default(LumpInfo)) : base(data, structLength, bsp, lumpInfo) { }
|
||||
|
||||
/// <summary>
|
||||
/// Gets enough vertices from the list for a displacement of power <paramref name="power"/>, starting at <paramref name="first"/>.
|
||||
|
||||
@@ -17,24 +17,33 @@ namespace LibBSP {
|
||||
/// Class containing the identification and information for the various Game Lumps in Source
|
||||
/// engine BSPs.
|
||||
/// </summary>
|
||||
public class GameLump : Dictionary<GameLumpType, LumpInfo> {
|
||||
public class GameLump : Dictionary<GameLumpType, LumpInfo>, ILump {
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="GameLump"/> object by parsing a <c>byte</c> array into a <c>Dictionary</c> of <see cref="LumpInfo"/> objects.
|
||||
/// These objects contain offsets, lengths and versions of the GameLump lumps.
|
||||
/// The <see cref="BSP"/> this <see cref="ILump"/> came from.
|
||||
/// </summary>
|
||||
/// <param name="data">The data to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
public BSP Bsp { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="LumpInfo"/> associated with this <see cref="ILump"/>.
|
||||
/// </summary>
|
||||
public LumpInfo LumpInfo { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Parses the passed <c>byte</c> array into a <see cref="GameLump"/> object.
|
||||
/// </summary>
|
||||
/// <param name="data">Array of <c>byte</c>s to parse.</param>
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> was <c>null</c>.</exception>
|
||||
/// <exception cref="ArgumentException">This structure is not implemented for the given maptype.</exception>
|
||||
public GameLump(byte[] data, MapType type, int version = 0) {
|
||||
public GameLump(byte[] data, BSP bsp, LumpInfo lumpInfo = default(LumpInfo)) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
int structLength = 0;
|
||||
switch (type) {
|
||||
switch (bsp.version) {
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.Source17:
|
||||
case MapType.Source18:
|
||||
@@ -55,13 +64,13 @@ namespace LibBSP {
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw new ArgumentException("Map type " + type + " doesn't use a Game lump or the lump is unknown.");
|
||||
throw new ArgumentException("Game lump does not exist in map type " + bsp.version + " or has not been implemented.");
|
||||
}
|
||||
}
|
||||
|
||||
int numGameLumps = BitConverter.ToInt32(data, 0);
|
||||
if (numGameLumps > 0) {
|
||||
int lumpDictionaryOffset = (type == MapType.DMoMaM) ? 8 : 4;
|
||||
int lumpDictionaryOffset = (bsp.version == MapType.DMoMaM) ? 8 : 4;
|
||||
int lowestLumpOffset = int.MaxValue;
|
||||
|
||||
for (int i = 0; i < numGameLumps; ++i) {
|
||||
@@ -70,7 +79,7 @@ namespace LibBSP {
|
||||
int lumpVersion;
|
||||
int lumpOffset;
|
||||
int lumpLength;
|
||||
if (type == MapType.Vindictus) {
|
||||
if (bsp.version == MapType.Vindictus) {
|
||||
lumpFlags = BitConverter.ToInt32(data, (i * structLength) + lumpDictionaryOffset + 4);
|
||||
lumpVersion = BitConverter.ToInt32(data, (i * structLength) + lumpDictionaryOffset + 8);
|
||||
lumpOffset = BitConverter.ToInt32(data, (i * structLength) + lumpDictionaryOffset + 12);
|
||||
@@ -98,15 +107,19 @@ namespace LibBSP {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Passes a <c>byte</c> array into the constructor for <see cref="GameLump"/>.
|
||||
/// Factory method to parse a <c>byte</c> array into a <see cref="GameLump"/> object.
|
||||
/// </summary>
|
||||
/// <param name="data">The data to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <returns>A new <see cref="GameLump"/> object.</returns>
|
||||
/// <remarks>This is only here for consistency with the other lump structures.</remarks>
|
||||
public static GameLump LumpFactory(byte[] data, MapType type, int version = 0) {
|
||||
return new GameLump(data, type, version);
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
/// <returns>A <see cref="GameLump"/> object.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> parameter was <c>null</c>.</exception>
|
||||
public static GameLump LumpFactory(byte[] data, BSP bsp, LumpInfo lumpInfo) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
return new GameLump(data, bsp, lumpInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace LibBSP {
|
||||
@@ -6,22 +7,53 @@ namespace LibBSP {
|
||||
/// <summary>
|
||||
/// List of <see cref="StaticProp"/> objects containing data relevant to Static Props, like the dictionary of actual model paths.
|
||||
/// </summary>
|
||||
public class StaticProps : List<StaticProp> {
|
||||
public class StaticProps : Lump<StaticProp> {
|
||||
|
||||
public string[] dictionary { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Parses the passed <c>byte</c> array into a <c>List</c> of <see cref="StaticProp"/> objects.
|
||||
/// Creates an empty <see cref="StaticProps"/> object.
|
||||
/// </summary>
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
public StaticProps(BSP bsp = null, LumpInfo lumpInfo = default(LumpInfo)) : base(bsp, lumpInfo) {
|
||||
dictionary = new string[] { };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="StaticProps"/> that contains elements copied from the passed <see cref="IEnumerable{StaticProp}"/> and the passed <paramref name="dictionary"/>.
|
||||
/// </summary>
|
||||
/// <param name="items">The elements to copy into this <c>Lump</c>.</param>
|
||||
/// <param name="dictionary">A dictionary of static prop models. This is referenced from <see cref="StaticProp"/> objects.</param>
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
public StaticProps(IEnumerable<StaticProp> items, IList<string> dictionary, BSP bsp = null, LumpInfo lumpInfo = default(LumpInfo)) : base(items, bsp, lumpInfo) {
|
||||
this.dictionary = dictionary.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an empty <see cref="StaticProps"/> object with the specified initial capactiy.
|
||||
/// </summary>
|
||||
/// <param name="capacity">The number of elements that can initially be stored.</param>
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
public StaticProps(int capacity, BSP bsp = null, LumpInfo lumpInfo = default(LumpInfo)) : base(capacity, bsp, lumpInfo) {
|
||||
dictionary = new string[] { };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses the passed <c>byte</c> array into a <see cref="StaticProps"/> object.
|
||||
/// </summary>
|
||||
/// <param name="data">Array of <c>byte</c>s to parse.</param>
|
||||
/// <param name="type">Format identifier.</param>
|
||||
/// <param name="version">Version of static prop lump this is.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data" /> was <c>null</c>.</exception>
|
||||
public StaticProps(byte[] data, MapType type, int version = 0) {
|
||||
if (data == null) {
|
||||
/// <param name="structLength">Number of <c>byte</c>s to copy into the children. Will be recalculated based on BSP format.</param>
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> or <paramref name="bsp"/> was <c>null</c>.</exception>
|
||||
public StaticProps(byte[] data, int structLength, BSP bsp, LumpInfo lumpInfo = default(LumpInfo)) : base(bsp, lumpInfo) {
|
||||
if (data == null || bsp == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
int structLength = 0;
|
||||
|
||||
dictionary = new string[0];
|
||||
if (data.Length > 0) {
|
||||
int offset = 0;
|
||||
@@ -33,12 +65,12 @@ namespace LibBSP {
|
||||
}
|
||||
int numLeafDefinitions = BitConverter.ToInt32(data, offset);
|
||||
offset += 4 + (numLeafDefinitions * 2);
|
||||
if (type == MapType.Vindictus && version == 6) {
|
||||
if (Bsp.version == MapType.Vindictus && lumpInfo.version == 6) {
|
||||
int numPropScales = BitConverter.ToInt32(data, offset);
|
||||
offset += 4 + (numPropScales * 16);
|
||||
}
|
||||
int numProps = BitConverter.ToInt32(data, offset);
|
||||
if (version == 12) { // So far only Titanfall
|
||||
if (lumpInfo.version == 12) { // So far only Titanfall
|
||||
offset += 12;
|
||||
} else {
|
||||
offset += 4;
|
||||
@@ -48,7 +80,7 @@ namespace LibBSP {
|
||||
for (int i = 0; i < numProps; ++i) {
|
||||
byte[] bytes = new byte[structLength];
|
||||
Array.Copy(data, offset, bytes, 0, structLength);
|
||||
Add(new StaticProp(bytes, type, version));
|
||||
Add(new StaticProp(bytes, this));
|
||||
offset += structLength;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace LibBSP {
|
||||
|
||||
@@ -7,22 +8,45 @@ namespace LibBSP {
|
||||
/// <c>List</c><<see cref="Texture"/>> with some useful methods for manipulating <see cref="Texture"/> objects,
|
||||
/// especially when handling them as a group.
|
||||
/// </summary>
|
||||
public class Textures : List<Texture> {
|
||||
public class Textures : Lump<Texture> {
|
||||
|
||||
/// <summary>
|
||||
/// Parses a <c>byte</c> array into this <c>List</c> of <see cref="Texture"/> objects.
|
||||
/// Creates an empty <see cref="Textures"/> object.
|
||||
/// </summary>
|
||||
/// <param name="data">The data to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data" /> was <c>null</c>.</exception>
|
||||
/// <exception cref="ArgumentException">This structure is not implemented for the given maptype.</exception>
|
||||
public Textures(byte[] data, MapType type, int version = 0) {
|
||||
if (data == null) {
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
public Textures(BSP bsp = null, LumpInfo lumpInfo = default(LumpInfo)) : base(bsp, lumpInfo) { }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="Textures"/> that contains elements copied from the passed <see cref="IEnumerable{Texture}"/>.
|
||||
/// </summary>
|
||||
/// <param name="items">The elements to copy into this <c>Lump</c>.</param>
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
public Textures(IEnumerable<Texture> items, BSP bsp = null, LumpInfo lumpInfo = default(LumpInfo)) : base(items, bsp, lumpInfo) { }
|
||||
|
||||
/// <summary>
|
||||
/// Creates an empty <see cref="Textures"/> object with the specified initial capactiy.
|
||||
/// </summary>
|
||||
/// <param name="capacity">The number of elements that can initially be stored.</param>
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
public Textures(int capacity, BSP bsp = null, LumpInfo lumpInfo = default(LumpInfo)) : base(capacity, bsp, lumpInfo) { }
|
||||
|
||||
/// <summary>
|
||||
/// Parses the passed <c>byte</c> array into a <see cref="Textures"/> object.
|
||||
/// </summary>
|
||||
/// <param name="data">Array of <c>byte</c>s to parse.</param>
|
||||
/// <param name="structLength">Number of <c>byte</c>s to copy into the children. Will be recalculated based on BSP format.</param>
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> or <paramref name="bsp"/> was <c>null</c>.</exception>
|
||||
public Textures(byte[] data, int structLength, BSP bsp, LumpInfo lumpInfo = default(LumpInfo)) : base(bsp, lumpInfo) {
|
||||
if (data == null || bsp == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
int structLength = 0;
|
||||
switch (type) {
|
||||
|
||||
switch (bsp.version) {
|
||||
case MapType.Nightfire: {
|
||||
structLength = 64;
|
||||
break;
|
||||
@@ -70,7 +94,7 @@ namespace LibBSP {
|
||||
// They are null-terminated strings, of non-constant length (not padded)
|
||||
byte[] myBytes = new byte[i - offset];
|
||||
Array.Copy(data, offset, myBytes, 0, i - offset);
|
||||
Add(new Texture(myBytes, type, version));
|
||||
Add(new Texture(myBytes, this));
|
||||
offset = i + 1;
|
||||
}
|
||||
}
|
||||
@@ -82,12 +106,12 @@ namespace LibBSP {
|
||||
for (int i = 0; i < numElements; ++i) {
|
||||
byte[] myBytes = new byte[structLength];
|
||||
Array.Copy(data, BitConverter.ToInt32(data, (i + 1) * 4), myBytes, 0, structLength);
|
||||
Add(new Texture(myBytes, type, version));
|
||||
Add(new Texture(myBytes, this));
|
||||
}
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
throw new ArgumentException("Map type " + type + " doesn't use a Texture lump or the lump is unknown.");
|
||||
throw new ArgumentException("Lump object Texture does not exist in map type " + bsp.version + " or has not been implemented.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +119,7 @@ namespace LibBSP {
|
||||
for (int i = 0; i < numObjects; ++i) {
|
||||
byte[] bytes = new byte[structLength];
|
||||
Array.Copy(data, (i * structLength), bytes, 0, structLength);
|
||||
Add(new Texture(bytes, type, version));
|
||||
Add(new Texture(bytes, this));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,28 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace LibBSP {
|
||||
|
||||
/// <summary>
|
||||
/// A class containing all data needed for the models lump in any given BSP.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// In general, we need to use models to find one or more leaves containing the
|
||||
/// information for the solids described by this model. Some formats do it by
|
||||
/// referencing a head node to iterate through and find the leaves. Others
|
||||
/// directly point to a set of leaves, and still others simply directly reference
|
||||
/// brushes. The ideal format simply points to brush information from here (Quake
|
||||
/// 3-based engines do), but most of them don't.
|
||||
/// </remarks>
|
||||
public struct Model {
|
||||
public struct Model : ILumpObject {
|
||||
|
||||
public byte[] data;
|
||||
public MapType type;
|
||||
public int version;
|
||||
/// <summary>
|
||||
/// The <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public ILump Parent { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Array of <c>byte</c>s used as the data source for this <see cref="ILumpObject"/>.
|
||||
/// </summary>
|
||||
public byte[] Data { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="LibBSP.MapType"/> to use to interpret <see cref="Data"/>.
|
||||
/// </summary>
|
||||
public MapType MapType {
|
||||
get {
|
||||
if (Parent == null || Parent.Bsp == null) {
|
||||
return MapType.Undefined;
|
||||
}
|
||||
return Parent.Bsp.version;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The version number of the <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public int LumpVersion {
|
||||
get {
|
||||
if (Parent == null) {
|
||||
return 0;
|
||||
}
|
||||
return Parent.LumpInfo.version;
|
||||
}
|
||||
}
|
||||
|
||||
[Index("nodes")] public int headNode {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Quake:
|
||||
case MapType.Quake2:
|
||||
case MapType.Daikatana:
|
||||
@@ -39,10 +62,10 @@ namespace LibBSP {
|
||||
case MapType.L4D2:
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.Vindictus: {
|
||||
return BitConverter.ToInt32(data, 36);
|
||||
return BitConverter.ToInt32(Data, 36);
|
||||
}
|
||||
case MapType.DMoMaM: {
|
||||
return BitConverter.ToInt32(data, 40);
|
||||
return BitConverter.ToInt32(Data, 40);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -51,7 +74,7 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Quake:
|
||||
case MapType.Quake2:
|
||||
case MapType.Daikatana:
|
||||
@@ -68,11 +91,11 @@ namespace LibBSP {
|
||||
case MapType.L4D2:
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.Vindictus: {
|
||||
bytes.CopyTo(data, 36);
|
||||
bytes.CopyTo(Data, 36);
|
||||
break;
|
||||
}
|
||||
case MapType.DMoMaM: {
|
||||
bytes.CopyTo(data, 40);
|
||||
bytes.CopyTo(Data, 40);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -81,9 +104,9 @@ namespace LibBSP {
|
||||
|
||||
[Index("leaves")] public int firstLeaf {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Nightfire: {
|
||||
return BitConverter.ToInt32(data, 40);
|
||||
return BitConverter.ToInt32(Data, 40);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -92,9 +115,9 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Nightfire: {
|
||||
bytes.CopyTo(data, 40);
|
||||
bytes.CopyTo(Data, 40);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -103,9 +126,9 @@ namespace LibBSP {
|
||||
|
||||
[Count("leaves")] public int numLeaves {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Nightfire: {
|
||||
return BitConverter.ToInt32(data, 44);
|
||||
return BitConverter.ToInt32(Data, 44);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -114,9 +137,9 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Nightfire: {
|
||||
bytes.CopyTo(data, 44);
|
||||
bytes.CopyTo(Data, 44);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -125,19 +148,19 @@ namespace LibBSP {
|
||||
|
||||
[Index("brushes")] public int firstBrush {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.STEF2:
|
||||
case MapType.STEF2Demo:
|
||||
case MapType.Quake3:
|
||||
case MapType.MOHAA:
|
||||
case MapType.Raven:
|
||||
case MapType.FAKK: {
|
||||
return BitConverter.ToInt32(data, 32);
|
||||
return BitConverter.ToInt32(Data, 32);
|
||||
}
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2:
|
||||
case MapType.CoD4: {
|
||||
return BitConverter.ToInt32(data, 40);
|
||||
return BitConverter.ToInt32(Data, 40);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -146,20 +169,20 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.STEF2:
|
||||
case MapType.STEF2Demo:
|
||||
case MapType.Quake3:
|
||||
case MapType.MOHAA:
|
||||
case MapType.Raven:
|
||||
case MapType.FAKK: {
|
||||
bytes.CopyTo(data, 32);
|
||||
bytes.CopyTo(Data, 32);
|
||||
break;
|
||||
}
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2:
|
||||
case MapType.CoD4: {
|
||||
bytes.CopyTo(data, 40);
|
||||
bytes.CopyTo(Data, 40);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -168,19 +191,19 @@ namespace LibBSP {
|
||||
|
||||
[Count("brushes")] public int numBrushes {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.STEF2:
|
||||
case MapType.STEF2Demo:
|
||||
case MapType.Quake3:
|
||||
case MapType.MOHAA:
|
||||
case MapType.Raven:
|
||||
case MapType.FAKK: {
|
||||
return BitConverter.ToInt32(data, 36);
|
||||
return BitConverter.ToInt32(Data, 36);
|
||||
}
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2:
|
||||
case MapType.CoD4: {
|
||||
return BitConverter.ToInt32(data, 44);
|
||||
return BitConverter.ToInt32(Data, 44);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -189,20 +212,20 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.STEF2:
|
||||
case MapType.STEF2Demo:
|
||||
case MapType.Quake3:
|
||||
case MapType.MOHAA:
|
||||
case MapType.Raven:
|
||||
case MapType.FAKK: {
|
||||
bytes.CopyTo(data, 36);
|
||||
bytes.CopyTo(Data, 36);
|
||||
break;
|
||||
}
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2:
|
||||
case MapType.CoD4: {
|
||||
bytes.CopyTo(data, 44);
|
||||
bytes.CopyTo(Data, 44);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -211,9 +234,9 @@ namespace LibBSP {
|
||||
|
||||
[Index("faces")] public int firstFace {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD4: {
|
||||
return BitConverter.ToInt16(data, 24);
|
||||
return BitConverter.ToInt16(Data, 24);
|
||||
}
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2:
|
||||
@@ -223,7 +246,7 @@ namespace LibBSP {
|
||||
case MapType.MOHAA:
|
||||
case MapType.Raven:
|
||||
case MapType.FAKK: {
|
||||
return BitConverter.ToInt32(data, 24);
|
||||
return BitConverter.ToInt32(Data, 24);
|
||||
}
|
||||
case MapType.Quake2:
|
||||
case MapType.Daikatana:
|
||||
@@ -240,16 +263,16 @@ namespace LibBSP {
|
||||
case MapType.L4D2:
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.Vindictus: {
|
||||
return BitConverter.ToInt32(data, 40);
|
||||
return BitConverter.ToInt32(Data, 40);
|
||||
}
|
||||
case MapType.DMoMaM: {
|
||||
return BitConverter.ToInt32(data, 44);
|
||||
return BitConverter.ToInt32(Data, 44);
|
||||
}
|
||||
case MapType.Nightfire: {
|
||||
return BitConverter.ToInt32(data, 48);
|
||||
return BitConverter.ToInt32(Data, 48);
|
||||
}
|
||||
case MapType.Quake: {
|
||||
return BitConverter.ToInt32(data, 56);
|
||||
return BitConverter.ToInt32(Data, 56);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -258,10 +281,10 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD4: {
|
||||
data[24] = bytes[0];
|
||||
data[25] = bytes[1];
|
||||
Data[24] = bytes[0];
|
||||
Data[25] = bytes[1];
|
||||
break;
|
||||
}
|
||||
case MapType.CoD:
|
||||
@@ -272,7 +295,7 @@ namespace LibBSP {
|
||||
case MapType.MOHAA:
|
||||
case MapType.Raven:
|
||||
case MapType.FAKK: {
|
||||
bytes.CopyTo(data, 24);
|
||||
bytes.CopyTo(Data, 24);
|
||||
break;
|
||||
}
|
||||
case MapType.Quake2:
|
||||
@@ -290,19 +313,19 @@ namespace LibBSP {
|
||||
case MapType.L4D2:
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.Vindictus: {
|
||||
bytes.CopyTo(data, 40);
|
||||
bytes.CopyTo(Data, 40);
|
||||
break;
|
||||
}
|
||||
case MapType.DMoMaM: {
|
||||
bytes.CopyTo(data, 44);
|
||||
bytes.CopyTo(Data, 44);
|
||||
break;
|
||||
}
|
||||
case MapType.Nightfire: {
|
||||
bytes.CopyTo(data, 48);
|
||||
bytes.CopyTo(Data, 48);
|
||||
break;
|
||||
}
|
||||
case MapType.Quake: {
|
||||
bytes.CopyTo(data, 56);
|
||||
bytes.CopyTo(Data, 56);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -311,9 +334,9 @@ namespace LibBSP {
|
||||
|
||||
[Count("faces")] public int numFaces {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD4: {
|
||||
return BitConverter.ToInt16(data, 28);
|
||||
return BitConverter.ToInt16(Data, 28);
|
||||
}
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2:
|
||||
@@ -323,7 +346,7 @@ namespace LibBSP {
|
||||
case MapType.MOHAA:
|
||||
case MapType.Raven:
|
||||
case MapType.FAKK: {
|
||||
return BitConverter.ToInt32(data, 28);
|
||||
return BitConverter.ToInt32(Data, 28);
|
||||
}
|
||||
case MapType.Quake2:
|
||||
case MapType.Daikatana:
|
||||
@@ -340,16 +363,16 @@ namespace LibBSP {
|
||||
case MapType.L4D2:
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.Vindictus: {
|
||||
return BitConverter.ToInt32(data, 44);
|
||||
return BitConverter.ToInt32(Data, 44);
|
||||
}
|
||||
case MapType.DMoMaM: {
|
||||
return BitConverter.ToInt32(data, 48);
|
||||
return BitConverter.ToInt32(Data, 48);
|
||||
}
|
||||
case MapType.Nightfire: {
|
||||
return BitConverter.ToInt32(data, 52);
|
||||
return BitConverter.ToInt32(Data, 52);
|
||||
}
|
||||
case MapType.Quake: {
|
||||
return BitConverter.ToInt32(data, 60);
|
||||
return BitConverter.ToInt32(Data, 60);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -358,10 +381,10 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD4: {
|
||||
data[28] = bytes[0];
|
||||
data[29] = bytes[1];
|
||||
Data[28] = bytes[0];
|
||||
Data[29] = bytes[1];
|
||||
break;
|
||||
}
|
||||
case MapType.CoD:
|
||||
@@ -372,7 +395,7 @@ namespace LibBSP {
|
||||
case MapType.MOHAA:
|
||||
case MapType.Raven:
|
||||
case MapType.FAKK: {
|
||||
bytes.CopyTo(data, 28);
|
||||
bytes.CopyTo(Data, 28);
|
||||
break;
|
||||
}
|
||||
case MapType.Quake2:
|
||||
@@ -390,19 +413,19 @@ namespace LibBSP {
|
||||
case MapType.L4D2:
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.Vindictus: {
|
||||
bytes.CopyTo(data, 44);
|
||||
bytes.CopyTo(Data, 44);
|
||||
break;
|
||||
}
|
||||
case MapType.DMoMaM: {
|
||||
bytes.CopyTo(data, 48);
|
||||
bytes.CopyTo(Data, 48);
|
||||
break;
|
||||
}
|
||||
case MapType.Nightfire: {
|
||||
bytes.CopyTo(data, 52);
|
||||
bytes.CopyTo(Data, 52);
|
||||
break;
|
||||
}
|
||||
case MapType.Quake: {
|
||||
bytes.CopyTo(data, 60);
|
||||
bytes.CopyTo(Data, 60);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -412,10 +435,10 @@ namespace LibBSP {
|
||||
[Index("markSurfaces")]
|
||||
public int firstLeafPatch {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2: {
|
||||
return BitConverter.ToInt32(data, 32);
|
||||
return BitConverter.ToInt32(Data, 32);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -424,10 +447,10 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2: {
|
||||
bytes.CopyTo(data, 32);
|
||||
bytes.CopyTo(Data, 32);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -436,10 +459,10 @@ namespace LibBSP {
|
||||
|
||||
[Count("markSurfaces")] public int numLeafPatches {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2: {
|
||||
return BitConverter.ToInt32(data, 36);
|
||||
return BitConverter.ToInt32(Data, 36);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -448,10 +471,10 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2: {
|
||||
bytes.CopyTo(data, 36);
|
||||
bytes.CopyTo(Data, 36);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -462,36 +485,44 @@ namespace LibBSP {
|
||||
/// Creates a new <see cref="Model"/> object from a <c>byte</c> array.
|
||||
/// </summary>
|
||||
/// <param name="data"><c>byte</c> array to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <param name="parent">The <see cref="ILump"/> this <see cref="Model"/> came from.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> was <c>null</c>.</exception>
|
||||
public Model(byte[] data, MapType type, int version = 0) : this() {
|
||||
public Model(byte[] data, ILump parent = null) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
this.data = data;
|
||||
this.type = type;
|
||||
this.version = version;
|
||||
|
||||
Data = data;
|
||||
Parent = parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Factory method to parse a <c>byte</c> array into a <c>List</c> of <see cref="Model"/> objects.
|
||||
/// Factory method to parse a <c>byte</c> array into a <see cref="Lump{Model}"/>.
|
||||
/// </summary>
|
||||
/// <param name="data">The data to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <returns>A <c>List</c> of <see cref="Model"/> objects.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> was <c>null</c>.</exception>
|
||||
/// <exception cref="ArgumentException">This structure is not implemented for the given maptype.</exception>
|
||||
public static List<Model> LumpFactory(byte[] data, MapType type, int version = 0) {
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
/// <returns>A <see cref="Lump{Model}"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> parameter was <c>null</c>.</exception>
|
||||
public static Lump<Model> LumpFactory(byte[] data, BSP bsp, LumpInfo lumpInfo) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
int structLength = 0;
|
||||
switch (type) {
|
||||
|
||||
return new Lump<Model>(data, GetStructLength(bsp.version, lumpInfo.version), bsp, lumpInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length of this struct's data for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.
|
||||
/// </summary>
|
||||
/// <param name="mapType">The <see cref="LibBSP.MapType"/> of the BSP.</param>
|
||||
/// <param name="lumpVersion">The version number for the lump.</param>
|
||||
/// <returns>The length, in <c>byte</c>s, of this struct.</returns>
|
||||
/// <exception cref="ArgumentException">This struct is not valid or is not implemented for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.</exception>
|
||||
public static int GetStructLength(MapType mapType, int lumpVersion = 0) {
|
||||
switch (mapType) {
|
||||
case MapType.Titanfall: {
|
||||
structLength = 32;
|
||||
break;
|
||||
return 32;
|
||||
}
|
||||
case MapType.Quake3:
|
||||
case MapType.Raven:
|
||||
@@ -499,8 +530,7 @@ namespace LibBSP {
|
||||
case MapType.STEF2Demo:
|
||||
case MapType.MOHAA:
|
||||
case MapType.FAKK: {
|
||||
structLength = 40;
|
||||
break;
|
||||
return 40;
|
||||
}
|
||||
case MapType.Quake2:
|
||||
case MapType.Daikatana:
|
||||
@@ -520,33 +550,21 @@ namespace LibBSP {
|
||||
case MapType.L4D2:
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.Vindictus: {
|
||||
structLength = 48;
|
||||
break;
|
||||
return 48;
|
||||
}
|
||||
case MapType.DMoMaM: {
|
||||
structLength = 52;
|
||||
break;
|
||||
return 52;
|
||||
}
|
||||
case MapType.Nightfire: {
|
||||
structLength = 56;
|
||||
break;
|
||||
return 56;
|
||||
}
|
||||
case MapType.Quake: {
|
||||
structLength = 64;
|
||||
break;
|
||||
return 64;
|
||||
}
|
||||
default: {
|
||||
throw new ArgumentException("Map type " + type + " isn't supported by the Leaf lump factory.");
|
||||
throw new ArgumentException("Lump object " + MethodBase.GetCurrentMethod().DeclaringType.Name + " does not exist in map type " + mapType + " or has not been implemented.");
|
||||
}
|
||||
}
|
||||
int numObjects = data.Length / structLength;
|
||||
List<Model> lump = new List<Model>(numObjects);
|
||||
for (int i = 0; i < numObjects; ++i) {
|
||||
byte[] bytes = new byte[structLength];
|
||||
Array.Copy(data, (i * structLength), bytes, 0, structLength);
|
||||
lump.Add(new Model(bytes, type, version));
|
||||
}
|
||||
return lump;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,31 +1,62 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace LibBSP {
|
||||
|
||||
/// <summary>
|
||||
/// Contains all data needed for a node in a BSP tree.
|
||||
/// </summary>
|
||||
public struct Node {
|
||||
public struct Node : ILumpObject {
|
||||
|
||||
public byte[] data;
|
||||
public MapType type;
|
||||
public int version;
|
||||
/// <summary>
|
||||
/// The <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public ILump Parent { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Array of <c>byte</c>s used as the data source for this <see cref="ILumpObject"/>.
|
||||
/// </summary>
|
||||
public byte[] Data { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="LibBSP.MapType"/> to use to interpret <see cref="Data"/>.
|
||||
/// </summary>
|
||||
public MapType MapType {
|
||||
get {
|
||||
if (Parent == null || Parent.Bsp == null) {
|
||||
return MapType.Undefined;
|
||||
}
|
||||
return Parent.Bsp.version;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The version number of the <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public int LumpVersion {
|
||||
get {
|
||||
if (Parent == null) {
|
||||
return 0;
|
||||
}
|
||||
return Parent.LumpInfo.version;
|
||||
}
|
||||
}
|
||||
|
||||
public int plane {
|
||||
get {
|
||||
return BitConverter.ToInt32(data, 0);
|
||||
return BitConverter.ToInt32(Data, 0);
|
||||
}
|
||||
set {
|
||||
BitConverter.GetBytes(value).CopyTo(data, 0);
|
||||
BitConverter.GetBytes(value).CopyTo(Data, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public int child1 {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Quake: {
|
||||
return BitConverter.ToInt16(data, 4);
|
||||
return BitConverter.ToInt16(Data, 4);
|
||||
}
|
||||
case MapType.SiN:
|
||||
case MapType.SoF:
|
||||
@@ -52,7 +83,7 @@ namespace LibBSP {
|
||||
case MapType.FAKK:
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2: {
|
||||
return BitConverter.ToInt32(data, 4);
|
||||
return BitConverter.ToInt32(Data, 4);
|
||||
}
|
||||
default: {
|
||||
return 0;
|
||||
@@ -61,10 +92,10 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Quake: {
|
||||
data[4] = bytes[0];
|
||||
data[5] = bytes[1];
|
||||
Data[4] = bytes[0];
|
||||
Data[5] = bytes[1];
|
||||
break;
|
||||
}
|
||||
case MapType.SiN:
|
||||
@@ -92,7 +123,7 @@ namespace LibBSP {
|
||||
case MapType.FAKK:
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2: {
|
||||
bytes.CopyTo(data, 4);
|
||||
bytes.CopyTo(Data, 4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -101,9 +132,9 @@ namespace LibBSP {
|
||||
|
||||
public int child2 {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Quake: {
|
||||
return BitConverter.ToInt16(data, 6);
|
||||
return BitConverter.ToInt16(Data, 6);
|
||||
}
|
||||
case MapType.SiN:
|
||||
case MapType.SoF:
|
||||
@@ -130,7 +161,7 @@ namespace LibBSP {
|
||||
case MapType.FAKK:
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2: {
|
||||
return BitConverter.ToInt32(data, 8);
|
||||
return BitConverter.ToInt32(Data, 8);
|
||||
}
|
||||
default: {
|
||||
return 0;
|
||||
@@ -139,10 +170,10 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Quake: {
|
||||
data[6] = bytes[0];
|
||||
data[7] = bytes[1];
|
||||
Data[6] = bytes[0];
|
||||
Data[7] = bytes[1];
|
||||
break;
|
||||
}
|
||||
case MapType.SiN:
|
||||
@@ -170,7 +201,7 @@ namespace LibBSP {
|
||||
case MapType.FAKK:
|
||||
case MapType.CoD:
|
||||
case MapType.CoD2: {
|
||||
bytes.CopyTo(data, 8);
|
||||
bytes.CopyTo(Data, 8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -181,43 +212,50 @@ namespace LibBSP {
|
||||
/// Creates a new <see cref="Node"/> object from a <c>byte</c> array.
|
||||
/// </summary>
|
||||
/// <param name="data"><c>byte</c> array to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data" /> was <c>null</c>.</exception>
|
||||
public Node(byte[] data, MapType type, int version = 0) : this() {
|
||||
/// <param name="parent">The <see cref="ILump"/> this <see cref="Node"/> came from.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> was <c>null</c>.</exception>
|
||||
public Node(byte[] data, ILump parent = null) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
this.data = data;
|
||||
this.type = type;
|
||||
this.version = version;
|
||||
|
||||
Data = data;
|
||||
Parent = parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Factory method to parse a <c>byte</c> array into a <c>List</c> of <see cref="Node"/> objects.
|
||||
/// Factory method to parse a <c>byte</c> array into a <see cref="Lump{Node}"/>.
|
||||
/// </summary>
|
||||
/// <param name="data">The data to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <returns>A <c>List</c> of <see cref="Node"/> objects.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data" /> was <c>null</c>.</exception>
|
||||
/// <exception cref="ArgumentException">This structure is not implemented for the given maptype.</exception>
|
||||
public static List<Node> LumpFactory(byte[] data, MapType type, int version = 0) {
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
/// <returns>A <see cref="Lump{Node}"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> parameter was <c>null</c>.</exception>
|
||||
public static Lump<Node> LumpFactory(byte[] data, BSP bsp, LumpInfo lumpInfo) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
int structLength = 0;
|
||||
switch (type) {
|
||||
|
||||
return new Lump<Node>(data, GetStructLength(bsp.version, lumpInfo.version), bsp, lumpInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length of this struct's data for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.
|
||||
/// </summary>
|
||||
/// <param name="mapType">The <see cref="LibBSP.MapType"/> of the BSP.</param>
|
||||
/// <param name="lumpVersion">The version number for the lump.</param>
|
||||
/// <returns>The length, in <c>byte</c>s, of this struct.</returns>
|
||||
/// <exception cref="ArgumentException">This struct is not valid or is not implemented for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.</exception>
|
||||
public static int GetStructLength(MapType mapType, int lumpVersion = 0) {
|
||||
switch (mapType) {
|
||||
case MapType.Quake: {
|
||||
structLength = 24;
|
||||
break;
|
||||
return 24;
|
||||
}
|
||||
case MapType.Quake2:
|
||||
case MapType.SiN:
|
||||
case MapType.SoF:
|
||||
case MapType.Daikatana: {
|
||||
structLength = 28;
|
||||
break;
|
||||
return 28;
|
||||
}
|
||||
case MapType.Source17:
|
||||
case MapType.Source18:
|
||||
@@ -230,12 +268,10 @@ namespace LibBSP {
|
||||
case MapType.L4D2:
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.DMoMaM: {
|
||||
structLength = 32;
|
||||
break;
|
||||
return 32;
|
||||
}
|
||||
case MapType.Vindictus: {
|
||||
structLength = 48;
|
||||
break;
|
||||
return 48;
|
||||
}
|
||||
case MapType.Quake3:
|
||||
case MapType.FAKK:
|
||||
@@ -246,21 +282,12 @@ namespace LibBSP {
|
||||
case MapType.MOHAA:
|
||||
case MapType.Raven:
|
||||
case MapType.Nightfire: {
|
||||
structLength = 36;
|
||||
break;
|
||||
return 36;
|
||||
}
|
||||
default: {
|
||||
throw new ArgumentException("Map type " + type + " isn't supported by the Node lump factory.");
|
||||
throw new ArgumentException("Lump object " + MethodBase.GetCurrentMethod().DeclaringType.Name + " does not exist in map type " + mapType + " or has not been implemented.");
|
||||
}
|
||||
}
|
||||
int numObjects = data.Length / structLength;
|
||||
List<Node> lump = new List<Node>(numObjects);
|
||||
for (int i = 0; i < numObjects; ++i) {
|
||||
byte[] bytes = new byte[structLength];
|
||||
Array.Copy(data, (i * structLength), bytes, 0, structLength);
|
||||
lump.Add(new Node(bytes, type, version));
|
||||
}
|
||||
return lump;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace LibBSP {
|
||||
#if UNITY
|
||||
@@ -15,17 +16,47 @@ namespace LibBSP {
|
||||
/// <summary>
|
||||
/// Holds the data for a patch in a CoD BSP.
|
||||
/// </summary>
|
||||
public struct Patch {
|
||||
public struct Patch : ILumpObject {
|
||||
|
||||
public byte[] data;
|
||||
public MapType type;
|
||||
public int version;
|
||||
/// <summary>
|
||||
/// The <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public ILump Parent { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Array of <c>byte</c>s used as the data source for this <see cref="ILumpObject"/>.
|
||||
/// </summary>
|
||||
public byte[] Data { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="LibBSP.MapType"/> to use to interpret <see cref="Data"/>.
|
||||
/// </summary>
|
||||
public MapType MapType {
|
||||
get {
|
||||
if (Parent == null || Parent.Bsp == null) {
|
||||
return MapType.Undefined;
|
||||
}
|
||||
return Parent.Bsp.version;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The version number of the <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public int LumpVersion {
|
||||
get {
|
||||
if (Parent == null) {
|
||||
return 0;
|
||||
}
|
||||
return Parent.LumpInfo.version;
|
||||
}
|
||||
}
|
||||
|
||||
public short shader {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
return BitConverter.ToInt16(data, 0);
|
||||
return BitConverter.ToInt16(Data, 0);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -34,9 +65,9 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
bytes.CopyTo(data, 0);
|
||||
bytes.CopyTo(Data, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -45,9 +76,9 @@ namespace LibBSP {
|
||||
|
||||
public short patchType {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
return BitConverter.ToInt16(data, 2);
|
||||
return BitConverter.ToInt16(Data, 2);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -56,9 +87,9 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
bytes.CopyTo(data, 2);
|
||||
bytes.CopyTo(Data, 2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -67,10 +98,10 @@ namespace LibBSP {
|
||||
|
||||
public Vector2d dimensions {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
if (patchType == 0) {
|
||||
return new Vector2d(BitConverter.ToInt16(data, 4), BitConverter.ToInt16(data, 6));
|
||||
return new Vector2d(BitConverter.ToInt16(Data, 4), BitConverter.ToInt16(Data, 6));
|
||||
} else {
|
||||
return new Vector2d(float.NaN, float.NaN);
|
||||
}
|
||||
@@ -81,11 +112,11 @@ namespace LibBSP {
|
||||
}
|
||||
}
|
||||
set {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
if (patchType == 0) {
|
||||
BitConverter.GetBytes((short)value.x).CopyTo(data, 4);
|
||||
BitConverter.GetBytes((short)value.y).CopyTo(data, 6);
|
||||
BitConverter.GetBytes((short)value.x).CopyTo(Data, 4);
|
||||
BitConverter.GetBytes((short)value.y).CopyTo(Data, 6);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -95,10 +126,10 @@ namespace LibBSP {
|
||||
|
||||
public int flags {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
if (patchType == 0) {
|
||||
return BitConverter.ToInt32(data, 8);
|
||||
return BitConverter.ToInt32(Data, 8);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
@@ -110,10 +141,10 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
if (patchType == 0) {
|
||||
bytes.CopyTo(data, 8);
|
||||
bytes.CopyTo(Data, 8);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -123,12 +154,12 @@ namespace LibBSP {
|
||||
|
||||
[Index("patchVerts")] public int firstVertex {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
if (patchType == 0) {
|
||||
return BitConverter.ToInt32(data, 12);
|
||||
return BitConverter.ToInt32(Data, 12);
|
||||
} else if (patchType == 1) {
|
||||
return BitConverter.ToInt32(data, 8);
|
||||
return BitConverter.ToInt32(Data, 8);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
@@ -140,12 +171,12 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
if (patchType == 0) {
|
||||
bytes.CopyTo(data, 12);
|
||||
bytes.CopyTo(Data, 12);
|
||||
} else if (patchType == 1) {
|
||||
bytes.CopyTo(data, 8);
|
||||
bytes.CopyTo(Data, 8);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -155,12 +186,12 @@ namespace LibBSP {
|
||||
|
||||
[Count("patchVerts")] public int numVertices {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
if (patchType == 0) {
|
||||
return BitConverter.ToInt16(data, 4) * BitConverter.ToInt16(data, 6);
|
||||
return BitConverter.ToInt16(Data, 4) * BitConverter.ToInt16(Data, 6);
|
||||
} else if (patchType == 1) {
|
||||
return BitConverter.ToInt16(data, 4);
|
||||
return BitConverter.ToInt16(Data, 4);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
@@ -172,11 +203,11 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
if (patchType == 1) {
|
||||
data[4] = bytes[0];
|
||||
data[5] = bytes[1];
|
||||
Data[4] = bytes[0];
|
||||
Data[5] = bytes[1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -186,10 +217,10 @@ namespace LibBSP {
|
||||
|
||||
[Count("patchIndices")] public int numIndices {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
if (patchType == 1) {
|
||||
return BitConverter.ToInt16(data, 6);
|
||||
return BitConverter.ToInt16(Data, 6);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
@@ -201,11 +232,11 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
if (patchType == 1) {
|
||||
data[6] = bytes[0];
|
||||
data[7] = bytes[1];
|
||||
Data[6] = bytes[0];
|
||||
Data[7] = bytes[1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -215,10 +246,10 @@ namespace LibBSP {
|
||||
|
||||
[Index("patchIndices")] public int firstIndex {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
if (patchType == 1) {
|
||||
return BitConverter.ToInt32(data, 12);
|
||||
return BitConverter.ToInt32(Data, 12);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
@@ -230,10 +261,10 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
if (patchType == 1) {
|
||||
bytes.CopyTo(data, 12);
|
||||
bytes.CopyTo(Data, 12);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -245,49 +276,49 @@ namespace LibBSP {
|
||||
/// Creates a new <see cref="Patch"/> object from a <c>byte</c> array.
|
||||
/// </summary>
|
||||
/// <param name="data"><c>byte</c> array to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <param name="parent">The <see cref="ILump"/> this <see cref="Patch"/> came from.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> was <c>null</c>.</exception>
|
||||
public Patch(byte[] data, MapType type, int version = 0) : this() {
|
||||
public Patch(byte[] data, ILump parent = null) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
this.data = data;
|
||||
this.type = type;
|
||||
this.version = version;
|
||||
|
||||
Data = data;
|
||||
Parent = parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Factory method to parse a <c>byte</c> array into a <c>List</c> of <see cref="Patch"/> objects.
|
||||
/// Factory method to parse a <c>byte</c> array into a <see cref="Lump{Patch}"/>.
|
||||
/// </summary>
|
||||
/// <param name="data">The data to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <returns>A <c>List</c> of <see cref="Patch"/> objects.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data" /> was <c>null</c>.</exception>
|
||||
/// <exception cref="ArgumentException">This structure is not implemented for the given maptype.</exception>
|
||||
public static List<Patch> LumpFactory(byte[] data, MapType type, int version = 0) {
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
/// <returns>A <see cref="Lump{Patch}"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> parameter was <c>null</c>.</exception>
|
||||
public static Lump<Patch> LumpFactory(byte[] data, BSP bsp, LumpInfo lumpInfo) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
int structLength = 0;
|
||||
switch (type) {
|
||||
|
||||
return new Lump<Patch>(data, GetStructLength(bsp.version, lumpInfo.version), bsp, lumpInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length of this struct's data for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.
|
||||
/// </summary>
|
||||
/// <param name="mapType">The <see cref="LibBSP.MapType"/> of the BSP.</param>
|
||||
/// <param name="lumpVersion">The version number for the lump.</param>
|
||||
/// <returns>The length, in <c>byte</c>s, of this struct.</returns>
|
||||
/// <exception cref="ArgumentException">This struct is not valid or is not implemented for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.</exception>
|
||||
public static int GetStructLength(MapType mapType, int lumpVersion = 0) {
|
||||
switch (mapType) {
|
||||
case MapType.CoD: {
|
||||
structLength = 16;
|
||||
break;
|
||||
return 16;
|
||||
}
|
||||
default: {
|
||||
throw new ArgumentException("Map type " + type + " isn't supported by the Patch lump factory.");
|
||||
throw new ArgumentException("Lump object " + MethodBase.GetCurrentMethod().DeclaringType.Name + " does not exist in map type " + mapType + " or has not been implemented.");
|
||||
}
|
||||
}
|
||||
int numObjects = data.Length / structLength;
|
||||
List<Patch> lump = new List<Patch>(numObjects);
|
||||
for (int i = 0; i < numObjects; ++i) {
|
||||
byte[] bytes = new byte[structLength];
|
||||
Array.Copy(data, (i * structLength), bytes, 0, structLength);
|
||||
lump.Add(new Patch(bytes, type, version));
|
||||
}
|
||||
return lump;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace LibBSP {
|
||||
@@ -16,17 +17,47 @@ namespace LibBSP {
|
||||
/// <summary>
|
||||
/// Handles the data needed for a static model object from MoHAA.
|
||||
/// </summary>
|
||||
public struct StaticModel {
|
||||
public struct StaticModel : ILumpObject {
|
||||
|
||||
public byte[] data;
|
||||
public MapType type;
|
||||
public int version;
|
||||
/// <summary>
|
||||
/// The <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public ILump Parent { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Array of <c>byte</c>s used as the data source for this <see cref="ILumpObject"/>.
|
||||
/// </summary>
|
||||
public byte[] Data { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="LibBSP.MapType"/> to use to interpret <see cref="Data"/>.
|
||||
/// </summary>
|
||||
public MapType MapType {
|
||||
get {
|
||||
if (Parent == null || Parent.Bsp == null) {
|
||||
return MapType.Undefined;
|
||||
}
|
||||
return Parent.Bsp.version;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The version number of the <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public int LumpVersion {
|
||||
get {
|
||||
if (Parent == null) {
|
||||
return 0;
|
||||
}
|
||||
return Parent.LumpInfo.version;
|
||||
}
|
||||
}
|
||||
|
||||
public string name {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
return data.ToNullTerminatedString(0, 128);
|
||||
return Data.ToNullTerminatedString(0, 128);
|
||||
}
|
||||
default: {
|
||||
return null;
|
||||
@@ -34,13 +65,13 @@ namespace LibBSP {
|
||||
}
|
||||
}
|
||||
set {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
for (int i = 0; i < 128; ++i) {
|
||||
data[i] = 0;
|
||||
Data[i] = 0;
|
||||
}
|
||||
byte[] strBytes = Encoding.ASCII.GetBytes(value);
|
||||
Array.Copy(strBytes, 0, data, 0, Math.Min(strBytes.Length, 127));
|
||||
Array.Copy(strBytes, 0, Data, 0, Math.Min(strBytes.Length, 127));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -49,9 +80,9 @@ namespace LibBSP {
|
||||
|
||||
public Vector3d origin {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
return new Vector3d(BitConverter.ToSingle(data, 128), BitConverter.ToSingle(data, 132), BitConverter.ToSingle(data, 136));
|
||||
return new Vector3d(BitConverter.ToSingle(Data, 128), BitConverter.ToSingle(Data, 132), BitConverter.ToSingle(Data, 136));
|
||||
}
|
||||
default: {
|
||||
return new Vector3d(float.NaN, float.NaN, float.NaN);
|
||||
@@ -59,9 +90,9 @@ namespace LibBSP {
|
||||
}
|
||||
}
|
||||
set {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
value.GetBytes().CopyTo(data, 128);
|
||||
value.GetBytes().CopyTo(Data, 128);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -70,9 +101,9 @@ namespace LibBSP {
|
||||
|
||||
public Vector3d angles {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
return new Vector3d(BitConverter.ToSingle(data, 140), BitConverter.ToSingle(data, 144), BitConverter.ToSingle(data, 148));
|
||||
return new Vector3d(BitConverter.ToSingle(Data, 140), BitConverter.ToSingle(Data, 144), BitConverter.ToSingle(Data, 148));
|
||||
}
|
||||
default: {
|
||||
return new Vector3d(float.NaN, float.NaN, float.NaN);
|
||||
@@ -80,9 +111,9 @@ namespace LibBSP {
|
||||
}
|
||||
}
|
||||
set {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
value.GetBytes().CopyTo(data, 140);
|
||||
value.GetBytes().CopyTo(Data, 140);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -91,9 +122,9 @@ namespace LibBSP {
|
||||
|
||||
public float scale {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
return BitConverter.ToSingle(data, 152);
|
||||
return BitConverter.ToSingle(Data, 152);
|
||||
}
|
||||
default: {
|
||||
return float.NaN;
|
||||
@@ -102,9 +133,9 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
bytes.CopyTo(data, 152);
|
||||
bytes.CopyTo(Data, 152);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -113,9 +144,9 @@ namespace LibBSP {
|
||||
|
||||
[Index("vertices")] public int firstVertex {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
return BitConverter.ToInt32(data, 156);
|
||||
return BitConverter.ToInt32(Data, 156);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -124,9 +155,9 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
bytes.CopyTo(data, 156);
|
||||
bytes.CopyTo(Data, 156);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -135,9 +166,9 @@ namespace LibBSP {
|
||||
|
||||
[Count("vertices")] public short numVertices {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
return BitConverter.ToInt16(data, 160);
|
||||
return BitConverter.ToInt16(Data, 160);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -146,9 +177,9 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
bytes.CopyTo(data, 160);
|
||||
bytes.CopyTo(Data, 160);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -159,49 +190,49 @@ namespace LibBSP {
|
||||
/// Creates a new <see cref="StaticModel"/> object from a <c>byte</c> array.
|
||||
/// </summary>
|
||||
/// <param name="data"><c>byte</c> array to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of static prop lump this object is a member of.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data" /> was <c>null</c>.</exception>
|
||||
public StaticModel(byte[] data, MapType type, int version = 0) : this() {
|
||||
/// <param name="parent">The <see cref="ILump"/> this <see cref="StaticModel"/> came from.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> was <c>null</c>.</exception>
|
||||
public StaticModel(byte[] data, ILump parent = null) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
this.data = data;
|
||||
this.type = type;
|
||||
this.version = version;
|
||||
|
||||
Data = data;
|
||||
Parent = parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Factory method to parse a <c>byte</c> array into a <c>List</c> of <see cref="StaticModel"/> objects.
|
||||
/// Factory method to parse a <c>byte</c> array into a <see cref="Lump{StaticModel}"/>.
|
||||
/// </summary>
|
||||
/// <param name="data">The data to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <returns>A <c>List</c> of <see cref="StaticModel"/> objects.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data" /> was <c>null</c>.</exception>
|
||||
/// <exception cref="ArgumentException">This structure is not implemented for the given maptype.</exception>
|
||||
public static List<StaticModel> LumpFactory(byte[] data, MapType type, int version = 0) {
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
/// <returns>A <see cref="Lump{StaticModel}"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> parameter was <c>null</c>.</exception>
|
||||
public static Lump<StaticModel> LumpFactory(byte[] data, BSP bsp, LumpInfo lumpInfo) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
int structLength = 0;
|
||||
switch (type) {
|
||||
|
||||
return new Lump<StaticModel>(data, GetStructLength(bsp.version, lumpInfo.version), bsp, lumpInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length of this struct's data for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.
|
||||
/// </summary>
|
||||
/// <param name="mapType">The <see cref="LibBSP.MapType"/> of the BSP.</param>
|
||||
/// <param name="lumpVersion">The version number for the lump.</param>
|
||||
/// <returns>The length, in <c>byte</c>s, of this struct.</returns>
|
||||
/// <exception cref="ArgumentException">This struct is not valid or is not implemented for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.</exception>
|
||||
public static int GetStructLength(MapType mapType, int lumpVersion = 0) {
|
||||
switch (mapType) {
|
||||
case MapType.MOHAA: {
|
||||
structLength = 164;
|
||||
break;
|
||||
return 164;
|
||||
}
|
||||
default: {
|
||||
throw new ArgumentException("Map type " + type + " isn't supported by the StaticModel lump factory.");
|
||||
throw new ArgumentException("Lump object " + MethodBase.GetCurrentMethod().DeclaringType.Name + " does not exist in map type " + mapType + " or has not been implemented.");
|
||||
}
|
||||
}
|
||||
int numObjects = data.Length / structLength;
|
||||
List<StaticModel> lump = new List<StaticModel>(numObjects);
|
||||
for (int i = 0; i < numObjects; ++i) {
|
||||
byte[] bytes = new byte[structLength];
|
||||
Array.Copy(data, (i * structLength), bytes, 0, structLength);
|
||||
lump.Add(new StaticModel(bytes, type, version));
|
||||
}
|
||||
return lump;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -24,17 +24,47 @@ namespace LibBSP {
|
||||
/// For example, Nightfire's texture lump only contains 64-byte null-padded strings, but
|
||||
/// Quake 2's has texture scaling included.
|
||||
/// </remarks>
|
||||
public struct Texture {
|
||||
public struct Texture : ILumpObject {
|
||||
|
||||
public byte[] data;
|
||||
public MapType type;
|
||||
public int version;
|
||||
/// <summary>
|
||||
/// The <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public ILump Parent { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Array of <c>byte</c>s used as the data source for this <see cref="ILumpObject"/>.
|
||||
/// </summary>
|
||||
public byte[] Data { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="LibBSP.MapType"/> to use to interpret <see cref="Data"/>.
|
||||
/// </summary>
|
||||
public MapType MapType {
|
||||
get {
|
||||
if (Parent == null || Parent.Bsp == null) {
|
||||
return MapType.Undefined;
|
||||
}
|
||||
return Parent.Bsp.version;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The version number of the <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public int LumpVersion {
|
||||
get {
|
||||
if (Parent == null) {
|
||||
return 0;
|
||||
}
|
||||
return Parent.LumpInfo.version;
|
||||
}
|
||||
}
|
||||
|
||||
public string name {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Quake: {
|
||||
return data.ToNullTerminatedString(0, 16);
|
||||
return Data.ToNullTerminatedString(0, 16);
|
||||
}
|
||||
case MapType.STEF2:
|
||||
case MapType.STEF2Demo:
|
||||
@@ -46,12 +76,12 @@ namespace LibBSP {
|
||||
case MapType.FAKK:
|
||||
case MapType.MOHAA:
|
||||
case MapType.Nightfire: {
|
||||
return data.ToNullTerminatedString(0, 64);
|
||||
return Data.ToNullTerminatedString(0, 64);
|
||||
}
|
||||
case MapType.Quake2:
|
||||
case MapType.SoF:
|
||||
case MapType.Daikatana: {
|
||||
return data.ToNullTerminatedString(40, 32);
|
||||
return Data.ToNullTerminatedString(40, 32);
|
||||
}
|
||||
case MapType.Source17:
|
||||
case MapType.Source18:
|
||||
@@ -66,10 +96,10 @@ namespace LibBSP {
|
||||
case MapType.Vindictus:
|
||||
case MapType.DMoMaM:
|
||||
case MapType.Titanfall: {
|
||||
return data.ToRawString();
|
||||
return Data.ToRawString();
|
||||
}
|
||||
case MapType.SiN: {
|
||||
return data.ToNullTerminatedString(36, 64);
|
||||
return Data.ToNullTerminatedString(36, 64);
|
||||
}
|
||||
default: {
|
||||
return null;
|
||||
@@ -78,12 +108,12 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = Encoding.ASCII.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Quake: {
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
data[i] = 0;
|
||||
Data[i] = 0;
|
||||
}
|
||||
Array.Copy(bytes, 0, data, 0, Math.Min(bytes.Length, 15));
|
||||
Array.Copy(bytes, 0, Data, 0, Math.Min(bytes.Length, 15));
|
||||
break;
|
||||
}
|
||||
case MapType.STEF2:
|
||||
@@ -97,18 +127,18 @@ namespace LibBSP {
|
||||
case MapType.MOHAA:
|
||||
case MapType.Nightfire: {
|
||||
for (int i = 0; i < 64; ++i) {
|
||||
data[i] = 0;
|
||||
Data[i] = 0;
|
||||
}
|
||||
Array.Copy(bytes, 0, data, 0, Math.Min(bytes.Length, 63));
|
||||
Array.Copy(bytes, 0, Data, 0, Math.Min(bytes.Length, 63));
|
||||
break;
|
||||
}
|
||||
case MapType.Quake2:
|
||||
case MapType.SoF:
|
||||
case MapType.Daikatana: {
|
||||
for (int i = 0; i < 32; ++i) {
|
||||
data[i + 40] = 0;
|
||||
Data[i + 40] = 0;
|
||||
}
|
||||
Array.Copy(bytes, 0, data, 40, Math.Min(bytes.Length, 31));
|
||||
Array.Copy(bytes, 0, Data, 40, Math.Min(bytes.Length, 31));
|
||||
break;
|
||||
}
|
||||
case MapType.Source17:
|
||||
@@ -124,14 +154,14 @@ namespace LibBSP {
|
||||
case MapType.Vindictus:
|
||||
case MapType.DMoMaM:
|
||||
case MapType.Titanfall: {
|
||||
data = bytes;
|
||||
Data = bytes;
|
||||
break;
|
||||
}
|
||||
case MapType.SiN: {
|
||||
for (int i = 0; i < 64; ++i) {
|
||||
data[i + 36] = 0;
|
||||
Data[i + 36] = 0;
|
||||
}
|
||||
Array.Copy(bytes, 0, data, 36, Math.Min(bytes.Length, 63));
|
||||
Array.Copy(bytes, 0, Data, 36, Math.Min(bytes.Length, 63));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -140,9 +170,9 @@ namespace LibBSP {
|
||||
|
||||
public string mask {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
return data.ToNullTerminatedString(76, 64);
|
||||
return Data.ToNullTerminatedString(76, 64);
|
||||
}
|
||||
default: {
|
||||
return null;
|
||||
@@ -150,13 +180,13 @@ namespace LibBSP {
|
||||
}
|
||||
}
|
||||
set {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.MOHAA: {
|
||||
for (int i = 0; i < 64; ++i) {
|
||||
data[i + 76] = 0;
|
||||
Data[i + 76] = 0;
|
||||
}
|
||||
byte[] strBytes = Encoding.ASCII.GetBytes(value);
|
||||
Array.Copy(strBytes, 0, data, 76, Math.Min(strBytes.Length, 63));
|
||||
Array.Copy(strBytes, 0, Data, 76, Math.Min(strBytes.Length, 63));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -165,12 +195,12 @@ namespace LibBSP {
|
||||
|
||||
public int flags {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Quake2:
|
||||
case MapType.SoF:
|
||||
case MapType.Daikatana:
|
||||
case MapType.SiN: {
|
||||
return BitConverter.ToInt32(data, 32);
|
||||
return BitConverter.ToInt32(Data, 32);
|
||||
}
|
||||
case MapType.MOHAA:
|
||||
case MapType.STEF2:
|
||||
@@ -181,7 +211,7 @@ namespace LibBSP {
|
||||
case MapType.CoD2:
|
||||
case MapType.CoD4:
|
||||
case MapType.FAKK: {
|
||||
return BitConverter.ToInt32(data, 64);
|
||||
return BitConverter.ToInt32(Data, 64);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -190,12 +220,12 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Quake2:
|
||||
case MapType.SoF:
|
||||
case MapType.Daikatana:
|
||||
case MapType.SiN: {
|
||||
bytes.CopyTo(data, 32);
|
||||
bytes.CopyTo(Data, 32);
|
||||
break;
|
||||
}
|
||||
case MapType.MOHAA:
|
||||
@@ -207,7 +237,7 @@ namespace LibBSP {
|
||||
case MapType.CoD2:
|
||||
case MapType.CoD4:
|
||||
case MapType.FAKK: {
|
||||
bytes.CopyTo(data, 64);
|
||||
bytes.CopyTo(Data, 64);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -216,7 +246,7 @@ namespace LibBSP {
|
||||
|
||||
public int contents {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.STEF2:
|
||||
case MapType.STEF2Demo:
|
||||
case MapType.Raven:
|
||||
@@ -226,7 +256,7 @@ namespace LibBSP {
|
||||
case MapType.CoD4:
|
||||
case MapType.FAKK:
|
||||
case MapType.MOHAA: {
|
||||
return BitConverter.ToInt32(data, 68);
|
||||
return BitConverter.ToInt32(Data, 68);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -235,7 +265,7 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.STEF2:
|
||||
case MapType.STEF2Demo:
|
||||
case MapType.Raven:
|
||||
@@ -245,7 +275,7 @@ namespace LibBSP {
|
||||
case MapType.CoD4:
|
||||
case MapType.FAKK:
|
||||
case MapType.MOHAA: {
|
||||
bytes.CopyTo(data, 68);
|
||||
bytes.CopyTo(Data, 68);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -254,14 +284,14 @@ namespace LibBSP {
|
||||
|
||||
public TextureInfo texAxes {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Quake2:
|
||||
case MapType.SoF:
|
||||
case MapType.Daikatana:
|
||||
case MapType.SiN: {
|
||||
return new TextureInfo(new Vector3d(BitConverter.ToSingle(data, 0), BitConverter.ToSingle(data, 4), BitConverter.ToSingle(data, 8)),
|
||||
new Vector3d(BitConverter.ToSingle(data, 16), BitConverter.ToSingle(data, 20), BitConverter.ToSingle(data, 24)),
|
||||
new Vector2d(BitConverter.ToSingle(data, 12), BitConverter.ToSingle(data, 28)),
|
||||
return new TextureInfo(new Vector3d(BitConverter.ToSingle(Data, 0), BitConverter.ToSingle(Data, 4), BitConverter.ToSingle(Data, 8)),
|
||||
new Vector3d(BitConverter.ToSingle(Data, 16), BitConverter.ToSingle(Data, 20), BitConverter.ToSingle(Data, 24)),
|
||||
new Vector2d(BitConverter.ToSingle(Data, 12), BitConverter.ToSingle(Data, 28)),
|
||||
new Vector2d(1, 1),
|
||||
-1, -1, 0);
|
||||
}
|
||||
@@ -271,19 +301,19 @@ namespace LibBSP {
|
||||
}
|
||||
}
|
||||
set {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Quake2:
|
||||
case MapType.SoF:
|
||||
case MapType.Daikatana:
|
||||
case MapType.SiN: {
|
||||
byte[] bytes = value.uAxis.GetBytes();
|
||||
bytes.CopyTo(data, 0);
|
||||
bytes.CopyTo(Data, 0);
|
||||
bytes = value.vAxis.GetBytes();
|
||||
bytes.CopyTo(data, 16);
|
||||
bytes.CopyTo(Data, 16);
|
||||
bytes = BitConverter.GetBytes(value.translation.x);
|
||||
bytes.CopyTo(data, 12);
|
||||
bytes.CopyTo(Data, 12);
|
||||
bytes = BitConverter.GetBytes(value.translation.y);
|
||||
bytes.CopyTo(data, 28);
|
||||
bytes.CopyTo(Data, 28);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -294,27 +324,41 @@ namespace LibBSP {
|
||||
/// Creates a new <see cref="Texture"/> object from a <c>byte</c> array.
|
||||
/// </summary>
|
||||
/// <param name="data"><c>byte</c> array to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <param name="parent">The <see cref="ILump"/> this <see cref="Texture"/> came from.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> was <c>null</c>.</exception>
|
||||
public Texture(byte[] data, MapType type, int version = 0) : this() {
|
||||
public Texture(byte[] data, ILump parent) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
this.data = data;
|
||||
this.type = type;
|
||||
this.version = version;
|
||||
|
||||
Data = data;
|
||||
Parent = parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Factory method to parse a <c>byte</c> array into a <see cref="Textures"/> object.
|
||||
/// </summary>
|
||||
/// <param name="data">The data to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
/// <returns>A <see cref="Textures"/> object.</returns>
|
||||
public static Textures LumpFactory(byte[] data, MapType type, int version = 0) {
|
||||
return new Textures(data, type, version);
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> parameter was <c>null</c>.</exception>
|
||||
public static Textures LumpFactory(byte[] data, BSP bsp, LumpInfo lumpInfo) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
return new Textures(data, GetStructLength(bsp.version, lumpInfo.version), bsp, lumpInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Depending on format, this is a variable length structure. Return -1. The <see cref="Textures"/> class will handle object creation.
|
||||
/// </summary>
|
||||
/// <param name="mapType">The <see cref="LibBSP.MapType"/> of the BSP.</param>
|
||||
/// <param name="lumpVersion">The version number for the lump.</param>
|
||||
/// <returns>-1</returns>
|
||||
public static int GetStructLength(MapType type, int version) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace LibBSP {
|
||||
#if UNITY
|
||||
@@ -15,63 +16,93 @@ namespace LibBSP {
|
||||
/// <summary>
|
||||
/// Contains all the information for a single Texture Data object.
|
||||
/// </summary>
|
||||
public struct TextureData {
|
||||
public struct TextureData : ILumpObject {
|
||||
|
||||
public byte[] data;
|
||||
public MapType type;
|
||||
public int version;
|
||||
/// <summary>
|
||||
/// The <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public ILump Parent { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Array of <c>byte</c>s used as the data source for this <see cref="ILumpObject"/>.
|
||||
/// </summary>
|
||||
public byte[] Data { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="LibBSP.MapType"/> to use to interpret <see cref="Data"/>.
|
||||
/// </summary>
|
||||
public MapType MapType {
|
||||
get {
|
||||
if (Parent == null || Parent.Bsp == null) {
|
||||
return MapType.Undefined;
|
||||
}
|
||||
return Parent.Bsp.version;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The version number of the <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public int LumpVersion {
|
||||
get {
|
||||
if (Parent == null) {
|
||||
return 0;
|
||||
}
|
||||
return Parent.LumpInfo.version;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3d reflectivity {
|
||||
get {
|
||||
return new Vector3d(BitConverter.ToSingle(data, 0), BitConverter.ToSingle(data, 4), BitConverter.ToSingle(data, 8));
|
||||
return new Vector3d(BitConverter.ToSingle(Data, 0), BitConverter.ToSingle(Data, 4), BitConverter.ToSingle(Data, 8));
|
||||
}
|
||||
set {
|
||||
value.GetBytes().CopyTo(data, 0);
|
||||
value.GetBytes().CopyTo(Data, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public int stringTableIndex {
|
||||
get {
|
||||
return BitConverter.ToInt32(data, 12);
|
||||
return BitConverter.ToInt32(Data, 12);
|
||||
}
|
||||
set {
|
||||
BitConverter.GetBytes(value).CopyTo(data, 12);
|
||||
BitConverter.GetBytes(value).CopyTo(Data, 12);
|
||||
}
|
||||
}
|
||||
|
||||
public int width {
|
||||
get {
|
||||
return BitConverter.ToInt32(data, 16);
|
||||
return BitConverter.ToInt32(Data, 16);
|
||||
}
|
||||
set {
|
||||
BitConverter.GetBytes(value).CopyTo(data, 16);
|
||||
BitConverter.GetBytes(value).CopyTo(Data, 16);
|
||||
}
|
||||
}
|
||||
|
||||
public int height {
|
||||
get {
|
||||
return BitConverter.ToInt32(data, 20);
|
||||
return BitConverter.ToInt32(Data, 20);
|
||||
}
|
||||
set {
|
||||
BitConverter.GetBytes(value).CopyTo(data, 20);
|
||||
BitConverter.GetBytes(value).CopyTo(Data, 20);
|
||||
}
|
||||
}
|
||||
|
||||
public int view_width {
|
||||
get {
|
||||
return BitConverter.ToInt32(data, 24);
|
||||
return BitConverter.ToInt32(Data, 24);
|
||||
}
|
||||
set {
|
||||
BitConverter.GetBytes(value).CopyTo(data, 24);
|
||||
BitConverter.GetBytes(value).CopyTo(Data, 24);
|
||||
}
|
||||
}
|
||||
|
||||
public int view_height {
|
||||
get {
|
||||
return BitConverter.ToInt32(data, 28);
|
||||
return BitConverter.ToInt32(Data, 28);
|
||||
}
|
||||
set {
|
||||
BitConverter.GetBytes(value).CopyTo(data, 28);
|
||||
BitConverter.GetBytes(value).CopyTo(Data, 28);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,42 +110,63 @@ namespace LibBSP {
|
||||
/// Creates a new <see cref="TextureData"/> object from a <c>byte</c> array.
|
||||
/// </summary>
|
||||
/// <param name="data"><c>byte</c> array to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data" /> was <c>null</c>.</exception>
|
||||
public TextureData(byte[] data, MapType type, int version = 0) : this() {
|
||||
/// <param name="parent">The <see cref="ILump"/> this <see cref="TextureData"/> came from.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> was <c>null</c>.</exception>
|
||||
public TextureData(byte[] data, ILump parent = null) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
this.data = data;
|
||||
this.type = type;
|
||||
this.version = version;
|
||||
|
||||
Data = data;
|
||||
Parent = parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Factory method to parse a <c>byte</c> array into a <c>List</c> of <see cref="TextureData"/> objects.
|
||||
/// Factory method to parse a <c>byte</c> array into a <see cref="Lump{TextureData}"/>.
|
||||
/// </summary>
|
||||
/// <param name="data">The data to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <returns>A <c>List</c> of <see cref="TextureData"/> objects.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data" /> was <c>null</c>.</exception>
|
||||
public static List<TextureData> LumpFactory(byte[] data, MapType type, int version = 0) {
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
/// <returns>A <see cref="Lump{TextureData}"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> parameter was <c>null</c>.</exception>
|
||||
public static Lump<TextureData> LumpFactory(byte[] data, BSP bsp, LumpInfo lumpInfo) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
int structLength = 32;
|
||||
if (type == MapType.Titanfall) {
|
||||
structLength = 36;
|
||||
|
||||
return new Lump<TextureData>(data, GetStructLength(bsp.version, lumpInfo.version), bsp, lumpInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length of this struct's data for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.
|
||||
/// </summary>
|
||||
/// <param name="mapType">The <see cref="LibBSP.MapType"/> of the BSP.</param>
|
||||
/// <param name="lumpVersion">The version number for the lump.</param>
|
||||
/// <returns>The length, in <c>byte</c>s, of this struct.</returns>
|
||||
/// <exception cref="ArgumentException">This struct is not valid or is not implemented for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.</exception>
|
||||
public static int GetStructLength(MapType mapType, int lumpVersion = 0) {
|
||||
switch (mapType) {
|
||||
case MapType.Vindictus:
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.Source17:
|
||||
case MapType.Source18:
|
||||
case MapType.Source19:
|
||||
case MapType.Source20:
|
||||
case MapType.Source21:
|
||||
case MapType.Source22:
|
||||
case MapType.Source23:
|
||||
case MapType.Source27:
|
||||
case MapType.L4D2:
|
||||
case MapType.DMoMaM: {
|
||||
return 32;
|
||||
}
|
||||
case MapType.Titanfall: {
|
||||
return 36;
|
||||
}
|
||||
default: {
|
||||
throw new ArgumentException("Lump object " + MethodBase.GetCurrentMethod().DeclaringType.Name + " does not exist in map type " + mapType + " or has not been implemented.");
|
||||
}
|
||||
}
|
||||
int numObjects = data.Length / structLength;
|
||||
List<TextureData> lump = new List<TextureData>(numObjects);
|
||||
for (int i = 0; i < numObjects; ++i) {
|
||||
byte[] bytes = new byte[structLength];
|
||||
Array.Copy(data, (i * structLength), bytes, 0, structLength);
|
||||
lump.Add(new TextureData(bytes, type, version));
|
||||
}
|
||||
return lump;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -20,12 +20,53 @@ namespace LibBSP {
|
||||
/// <summary>
|
||||
/// Class containing all data for a single <see cref="Entity"/>, including attributes, Source Entity I/O connections and solids.
|
||||
/// </summary>
|
||||
[Serializable] public class Entity : Dictionary<string, string>, IComparable, IComparable<Entity>, ISerializable {
|
||||
[Serializable] public class Entity : Dictionary<string, string>, IComparable, IComparable<Entity>, ISerializable, ILumpObject {
|
||||
|
||||
private static IFormatProvider _format = CultureInfo.CreateSpecificCulture("en-US");
|
||||
|
||||
public const char ConnectionMemberSeparater = (char)0x1B;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public ILump Parent { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Array of <c>byte</c>s representing this <see cref="Entity"/>. If this is set, it will parse the bytes as a string.
|
||||
/// If accessed, will return a <c>byte</c> array of <see cref="ToString"/>.
|
||||
/// </summary>
|
||||
public byte[] Data {
|
||||
get {
|
||||
return Encoding.ASCII.GetBytes(ToString());
|
||||
}
|
||||
set {
|
||||
ParseString(Encoding.ASCII.GetString(value));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="LibBSP.MapType"/> to use to interpret <see cref="Data"/>.
|
||||
/// </summary>
|
||||
public MapType MapType {
|
||||
get {
|
||||
if (Parent == null || Parent.Bsp == null) {
|
||||
return MapType.Undefined;
|
||||
}
|
||||
return Parent.Bsp.version;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The version number of the <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public int LumpVersion {
|
||||
get {
|
||||
if (Parent == null) {
|
||||
return 0;
|
||||
}
|
||||
return Parent.LumpInfo.version;
|
||||
}
|
||||
}
|
||||
|
||||
public List<EntityConnection> connections = new List<EntityConnection>();
|
||||
public List<MAPBrush> brushes = new List<MAPBrush>();
|
||||
|
||||
@@ -164,41 +205,67 @@ namespace LibBSP {
|
||||
/// <param name="data">Array to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
public Entity(byte[] data, MapType type, int version = 0) : this(Encoding.ASCII.GetString(data).Split('\n')) { }
|
||||
public Entity(byte[] data, ILump parent = null) {
|
||||
Parent = parent;
|
||||
Data = data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of an <see cref="Entity"/> with the given classname.
|
||||
/// </summary>
|
||||
/// <param name="className">Classname of the new <see cref="Entity"/>.</param>
|
||||
public Entity(string className) : base(StringComparer.InvariantCultureIgnoreCase) {
|
||||
public Entity(string className, ILump parent = null) : this(parent) {
|
||||
Add("classname", className);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of an <see cref="Entity"/> object with no initial properties.
|
||||
/// </summary>
|
||||
public Entity() : base(StringComparer.InvariantCultureIgnoreCase) { }
|
||||
public Entity(ILump parent = null) : base(StringComparer.InvariantCultureIgnoreCase) {
|
||||
Parent = parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of an <see cref="Entity"/> object, copying the attributes, connections and brushes of the passed <see cref="Entity"/>.
|
||||
/// </summary>
|
||||
/// <param name="copy">The <see cref="Entity"/> to copy.</param>
|
||||
public Entity(Entity copy) : base(copy, StringComparer.InvariantCultureIgnoreCase) {
|
||||
public Entity(Entity copy, ILump parent = null) : base(copy, StringComparer.InvariantCultureIgnoreCase) {
|
||||
connections = new List<EntityConnection>(copy.connections);
|
||||
brushes = new List<MAPBrush>(copy.brushes);
|
||||
Parent = parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of an <see cref="Entity"/>, parsing the given <c>string</c> array into an <see cref="Entity"/> structure.
|
||||
/// Initializes a new instance of the <see cref="Entity"/> class with serialized data.
|
||||
/// </summary>
|
||||
/// <param name="lines">Array of <c>string</c>s representing attributes, patches, brushes, displacements etc. to parse.</param>
|
||||
public Entity(string[] lines) : base(StringComparer.InvariantCultureIgnoreCase) {
|
||||
int braceCount = 0;
|
||||
/// <param name="info">A <c>SerializationInfo</c> object containing the information required to serialize the <see cref="Entity"/>.</param>
|
||||
/// <param name="context">A <c>StreamingContext</c> structure containing the source and destination of the serialized stream associated with the <see cref="Entity"/>.</param>
|
||||
protected Entity(SerializationInfo info, StreamingContext context) : base(info, context) {
|
||||
connections = (List<EntityConnection>)info.GetValue("connections", typeof(List<EntityConnection>));
|
||||
brushes = (List<MAPBrush>)info.GetValue("brushes", typeof(List<MAPBrush>));
|
||||
Parent = (ILump)info.GetValue("Parent", typeof(ILump));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses the <c>string</c> <paramref name="st"/> into this <see cref="Entity"/> object.
|
||||
/// All data in this <see cref="Entity"/> will be removed and replaced with the newly parsed data.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This was necessary since the <see cref="Entity"/>(<c>string</c>) constructor was already used in a different way.
|
||||
/// </remarks>
|
||||
/// <param name="st">The string to parse.</param>
|
||||
public void ParseString(string st) {
|
||||
Clear();
|
||||
brushes = new List<MAPBrush>();
|
||||
connections = new List<EntityConnection>();
|
||||
|
||||
string[] lines = st.Split('\n');
|
||||
|
||||
int braceCount = 0;
|
||||
bool inConnections = false;
|
||||
bool inBrush = false;
|
||||
|
||||
List<string> child = new List<string>();
|
||||
List<string> brushLines = new List<string>();
|
||||
|
||||
foreach (string line in lines) {
|
||||
string current = line.Trim(' ', '\t', '\r');
|
||||
@@ -206,7 +273,7 @@ namespace LibBSP {
|
||||
// Cull everything after a "//"
|
||||
bool inQuotes = false;
|
||||
for (int i = 0; i < current.Length; ++i) {
|
||||
|
||||
|
||||
if (current[i] == '\"') {
|
||||
if (i == 0) {
|
||||
inQuotes = !inQuotes;
|
||||
@@ -229,8 +296,7 @@ namespace LibBSP {
|
||||
if (string.IsNullOrEmpty(current)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Perhaps I should not assume these will always be the first thing on the line
|
||||
|
||||
if (current[0] == '{') {
|
||||
// If we're only one brace deep, and we have no prior information, assume a brush
|
||||
if (braceCount == 1 && !inBrush && !inConnections) {
|
||||
@@ -243,14 +309,14 @@ namespace LibBSP {
|
||||
if (braceCount == 1) {
|
||||
// If we determined we were inside a brush substructure
|
||||
if (inBrush) {
|
||||
child.Add(current);
|
||||
brushes.Add(new MAPBrush(child.ToArray()));
|
||||
child = new List<string>();
|
||||
brushLines.Add(current);
|
||||
brushes.Add(new MAPBrush(brushLines));
|
||||
brushLines = new List<string>();
|
||||
}
|
||||
inBrush = false;
|
||||
inConnections = false;
|
||||
} else {
|
||||
child.Add(current);
|
||||
brushLines.Add(current);
|
||||
}
|
||||
continue;
|
||||
} else if (current.Length >= 5 && current.Substring(0, 5) == "solid") {
|
||||
@@ -262,7 +328,7 @@ namespace LibBSP {
|
||||
}
|
||||
|
||||
if (inBrush) {
|
||||
child.Add(current);
|
||||
brushLines.Add(current);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -270,29 +336,6 @@ namespace LibBSP {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Entity"/> class with serialized data.
|
||||
/// </summary>
|
||||
/// <param name="info">A <c>SerializationInfo</c> object containing the information required to serialize the <see cref="Entity"/>.</param>
|
||||
/// <param name="context">A <c>StreamingContext</c> structure containing the source and destination of the serialized stream associated with the <see cref="Entity"/>.</param>
|
||||
protected Entity(SerializationInfo info, StreamingContext context) : base(info, context) {
|
||||
connections = (List<EntityConnection>)info.GetValue("connections", typeof(List<EntityConnection>));
|
||||
brushes = (List<MAPBrush>)info.GetValue("brushes", typeof(List<MAPBrush>));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Factory method to create an <see cref="Entity"/> from a <c>string</c> "<paramref name="st"/>" where
|
||||
/// "<paramref name="st"/>" contains all lines for the entity, including attributes, brushes, etc.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This was necessary since the <see cref="Entity(System.String)"/> constructor was already used in a different way.
|
||||
/// </remarks>
|
||||
/// <param name="st">The data to parse.</param>
|
||||
/// <returns>The resulting <see cref="Entity"/> object.</returns>
|
||||
public static Entity FromString(string st) {
|
||||
return new Entity(st.Split('\n'));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renames the attribute named "<paramref name="oldName"/>" to "<paramref name="newName"/>". Replaces the old entry if it already exists.
|
||||
/// </summary>
|
||||
@@ -380,7 +423,7 @@ namespace LibBSP {
|
||||
/// <summary>
|
||||
/// Gets a <c>string</c> representation of this <see cref="Entity"/>.
|
||||
/// </summary>
|
||||
/// <returns><c>string</c> representation of this <see cref="Entity"/>.</returns>
|
||||
/// <returns>A <c>string</c> representation of this <see cref="Entity"/>.</returns>
|
||||
public override string ToString() {
|
||||
StringBuilder output = new StringBuilder();
|
||||
output.Append("{\n");
|
||||
@@ -549,8 +592,12 @@ namespace LibBSP {
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <returns>An <see cref="Entities"/> object, which is a <c>List</c> of <see cref="Entity"/>s.</returns>
|
||||
public static Entities LumpFactory(byte[] data, MapType type, int version = 0) {
|
||||
return new Entities(data, type);
|
||||
public static Entities LumpFactory(byte[] data, BSP bsp, LumpInfo lumpInfo) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
return new Entities(data, bsp, lumpInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
32
LibBSP/Source/Structs/Common/ILumpObject.cs
Normal file
32
LibBSP/Source/Structs/Common/ILumpObject.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace LibBSP {
|
||||
|
||||
/// <summary>
|
||||
/// Interface for an object intended to be stored in an <see cref="ILump"/> object.
|
||||
/// </summary>
|
||||
public interface ILumpObject {
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
ILump Parent { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Array of <c>byte</c>s used as the data source for this <see cref="ILumpObject"/>.
|
||||
/// </summary>
|
||||
byte[] Data { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="LibBSP.MapType"/> to use to interpret <see cref="Data"/>.
|
||||
/// </summary>
|
||||
MapType MapType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The version number of the <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
int LumpVersion { get; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -8,41 +8,51 @@ namespace LibBSP {
|
||||
/// <summary>
|
||||
/// Class representing a group of <see cref="Entity"/> objects. Contains helpful methods to handle Entities in the <c>List</c>.
|
||||
/// </summary>
|
||||
[Serializable] public class Entities : List<Entity> {
|
||||
[Serializable] public class Entities : Lump<Entity> {
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of an <see cref="Entities"/> object copying a passed <c>IEnumerable</c> of <see cref="Entity"/> objects.
|
||||
/// </summary>
|
||||
/// <param name="data">Collection of <see cref="Entity"/> objects to copy.</param>
|
||||
public Entities(IEnumerable<Entity> data) : base(data) { }
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
public Entities(IEnumerable<Entity> entities, BSP bsp = null, LumpInfo lumpInfo = default(LumpInfo)) : base(entities, bsp, lumpInfo) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of an <see cref="Entities"/> object with a specified initial capacity.
|
||||
/// </summary>
|
||||
/// <param name="initialCapacity">Initial capacity of the <c>List</c> of <see cref="Entity"/> objects.</param>
|
||||
public Entities(int initialCapacity) : base(initialCapacity) { }
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
public Entities(int initialCapacity, BSP bsp = null, LumpInfo lumpInfo = default(LumpInfo)) : base(initialCapacity, bsp, lumpInfo) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new empty <see cref="Entities"/> object.
|
||||
/// </summary>
|
||||
public Entities() : base() { }
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
public Entities(BSP bsp = null, LumpInfo lumpInfo = default(LumpInfo)) : base(bsp, lumpInfo) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new <see cref="Entities"/> object, parsing all the bytes in the passed <paramref name="file"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This will not populate Bsp or LumpInfo since a file is being read directly. This should not be used to read a
|
||||
/// lump file, they should be handled through <see cref="BSPReader"/>. Use this to read raw MAP formats instead.
|
||||
/// </remarks>
|
||||
/// <param name="file">The file to read.</param>
|
||||
/// <param name="type">The <see cref="MapType"/> of the source map.</param>
|
||||
public Entities(FileInfo file, MapType type) : this(File.ReadAllBytes(file.FullName), type) { }
|
||||
public Entities(FileInfo file) : this(File.ReadAllBytes(file.FullName)) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new <see cref="Entities"/> object, and parses the passed <c>byte</c> array into the <c>List</c>.
|
||||
/// Initializes a new <see cref="Entities"/> object, and parses the passed <c>byte</c> array as a <c>string</c>.
|
||||
/// </summary>
|
||||
/// <param name="data"><c>Byte</c>s read from a file.</param>
|
||||
/// <param name="type">The <see cref="MapType"/> of the source map.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
public Entities(byte[] data, MapType type, int version = 0) : base() {
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
public Entities(byte[] data, BSP bsp = null, LumpInfo lumpInfo = default(LumpInfo)) : base(bsp, lumpInfo) {
|
||||
|
||||
// Keep track of whether or not we're currently in a set of quotation marks.
|
||||
// I came across a map where the idiot map maker used { and } within a value. This broke the code before.
|
||||
// I came across a map where the map maker used { and } within a value.
|
||||
bool inQuotes = false;
|
||||
int braceCount = 0;
|
||||
|
||||
@@ -90,7 +100,9 @@ namespace LibBSP {
|
||||
if (offset == 0 || (char)data[offset - 1] == '\n' || (char)data[offset - 1] == '\t' || (char)data[offset - 1] == ' ' || (char)data[offset - 1] == '\r') {
|
||||
--braceCount;
|
||||
if (braceCount == 0) {
|
||||
Add(Entity.FromString(current.ToString()));
|
||||
Entity entity = new Entity(this);
|
||||
entity.ParseString(current.ToString());
|
||||
Add(entity);
|
||||
// Reset StringBuilder
|
||||
current.Length = 0;
|
||||
}
|
||||
@@ -146,7 +158,7 @@ namespace LibBSP {
|
||||
/// Gets the first <see cref="Entity"/> with the specified targetname.
|
||||
/// </summary>
|
||||
/// <param name="targetname">Targetname attribute to find.</param>
|
||||
/// <returns>Entity object with the specified targetname.</returns>
|
||||
/// <returns><see cref="Entity"/> object with the specified targetname.</returns>
|
||||
public Entity GetWithName(string targetname) {
|
||||
return Find(entity => { return entity.name.Equals(targetname, StringComparison.InvariantCultureIgnoreCase); });
|
||||
}
|
||||
|
||||
19
LibBSP/Source/Structs/Common/Lumps/ILump.cs
Normal file
19
LibBSP/Source/Structs/Common/Lumps/ILump.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
namespace LibBSP {
|
||||
|
||||
/// <summary>
|
||||
/// Interface for a Lump object.
|
||||
/// </summary>
|
||||
public interface ILump {
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="BSP"/> this <see cref="ILump"/> came from.
|
||||
/// </summary>
|
||||
BSP Bsp { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="LumpInfo"/> associated with this <see cref="ILump"/>.
|
||||
/// </summary>
|
||||
LumpInfo LumpInfo { get; }
|
||||
|
||||
}
|
||||
}
|
||||
76
LibBSP/Source/Structs/Common/Lumps/Lump.cs
Normal file
76
LibBSP/Source/Structs/Common/Lumps/Lump.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace LibBSP {
|
||||
public class Lump<T> : List<T>, ILump {
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="BSP"/> this <see cref="ILump"/> came from.
|
||||
/// </summary>
|
||||
public BSP Bsp { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="LumpInfo"/> associated with this <see cref="ILump"/>.
|
||||
/// </summary>
|
||||
public LumpInfo LumpInfo { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates an empty <c>Lump</c> of <typeparamref name="T"/> objects.
|
||||
/// </summary>
|
||||
/// <param name="bsp">The <see cref="BSP"/> which <paramref name="data"/> came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> object for this <c>Lump</c>.</param>
|
||||
public Lump(BSP bsp = null, LumpInfo lumpInfo = default(LumpInfo)) {
|
||||
Bsp = bsp;
|
||||
LumpInfo = lumpInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <c>Lump</c> that contains elements copied from the passed <see cref="IEnumerable{T}"/>.
|
||||
/// </summary>
|
||||
/// <param name="items">The elements to copy into this <c>Lump</c>.</param>
|
||||
/// <param name="bsp">The <see cref="BSP"/> which <paramref name="data"/> came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> object for this <c>Lump</c>.</param>
|
||||
public Lump(IEnumerable<T> items, BSP bsp = null, LumpInfo lumpInfo = default(LumpInfo)) : base(items) {
|
||||
Bsp = bsp;
|
||||
LumpInfo = lumpInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an empty <c>Lump</c> of <typeparamref name="T"/> objects with the specified initial capactiy.
|
||||
/// </summary>
|
||||
/// <param name="capacity">The number of elements that can initially be stored.</param>
|
||||
/// <param name="bsp">The <see cref="BSP"/> which <paramref name="data"/> came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> object for this <c>Lump</c>.</param>
|
||||
public Lump(int capacity, BSP bsp = null, LumpInfo lumpInfo = default(LumpInfo)) : base(capacity) {
|
||||
Bsp = bsp;
|
||||
LumpInfo = lumpInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses the passed <c>byte</c> array into a <c>Lump</c> of <typeparamref name="T"/> objects.
|
||||
/// </summary>
|
||||
/// <param name="data">Array of <c>byte</c>s to parse.</param>
|
||||
/// <param name="structLength">Number of <c>byte</c>s to copy into the elements. Negative values indicate a variable length, which is not supported by this constructor.</param>
|
||||
/// <param name="bsp">The <see cref="BSP"/> which <paramref name="data"/> came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> object for this <c>Lump</c>.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data" /> was <c>null</c>.</exception>
|
||||
/// <exception cref="NotSupportedException"><paramref name="structLength"/> is negative.</exception>
|
||||
public Lump(byte[] data, int structLength, BSP bsp = null, LumpInfo lumpInfo = default(LumpInfo)) : base(data.Length / structLength) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
if (structLength <= 0) {
|
||||
throw new NotSupportedException("Cannot use the base Lump constructor for variable length lumps (structLength was negative). Create a derived class with a new constructor instead.");
|
||||
}
|
||||
|
||||
Bsp = bsp;
|
||||
LumpInfo = lumpInfo;
|
||||
for (int i = 0; i < data.Length / structLength; ++i) {
|
||||
byte[] bytes = new byte[structLength];
|
||||
Array.Copy(data, (i * structLength), bytes, 0, structLength);
|
||||
Add((T)Activator.CreateInstance(typeof(T), new object[] { bytes, this }));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,17 @@ namespace LibBSP {
|
||||
/// <summary>
|
||||
/// List class for numbers. Can handle any integer data type except <c>ulong</c>.
|
||||
/// </summary>
|
||||
public class NumList : IList<long>, ICollection<long>, IEnumerable<long>, IList, ICollection, IEnumerable {
|
||||
public class NumList : IList<long>, ICollection<long>, IEnumerable<long>, IList, ICollection, IEnumerable, ILump {
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="BSP"/> this <see cref="ILump"/> came from.
|
||||
/// </summary>
|
||||
public BSP Bsp { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="LumpInfo"/> associated with this <see cref="ILump"/>.
|
||||
/// </summary>
|
||||
public LumpInfo LumpInfo { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enum of the types that may be used in this class.
|
||||
@@ -32,10 +42,12 @@ namespace LibBSP {
|
||||
/// <param name="data"><c>byte</c> array to parse.</param>
|
||||
/// <param name="type">The type of number to store.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> was <c>null</c>.</exception>
|
||||
public NumList(byte[] data, DataType type) {
|
||||
public NumList(byte[] data, DataType type, BSP bsp = null, LumpInfo lumpInfo = default(LumpInfo)) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
Bsp = bsp;
|
||||
LumpInfo = lumpInfo;
|
||||
this.data = data;
|
||||
this.type = type;
|
||||
}
|
||||
@@ -55,8 +67,8 @@ namespace LibBSP {
|
||||
/// <param name="data"><c>byte</c> array to parse.</param>
|
||||
/// <param name="type">The type of number to store.</param>
|
||||
/// <returns>The resulting <see cref="NumList"/>.</returns>
|
||||
public static NumList LumpFactory(byte[] data, DataType type) {
|
||||
return new NumList(data, type);
|
||||
public static NumList LumpFactory(byte[] data, DataType type, BSP bsp = null, LumpInfo lumpInfo = default(LumpInfo)) {
|
||||
return new NumList(data, type, bsp, lumpInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace LibBSP {
|
||||
#if UNITY
|
||||
@@ -21,11 +22,41 @@ namespace LibBSP {
|
||||
/// Some BSP formats lack this lump (or the information is contained in a
|
||||
/// different lump) so their cases will be left out.
|
||||
/// </summary>
|
||||
[Serializable] public struct TextureInfo {
|
||||
[Serializable] public struct TextureInfo : ILumpObject {
|
||||
|
||||
public byte[] data;
|
||||
public MapType type;
|
||||
public int version;
|
||||
/// <summary>
|
||||
/// The <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public ILump Parent { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Array of <c>byte</c>s used as the data source for this <see cref="ILumpObject"/>.
|
||||
/// </summary>
|
||||
public byte[] Data { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="LibBSP.MapType"/> to use to interpret <see cref="Data"/>.
|
||||
/// </summary>
|
||||
public MapType MapType {
|
||||
get {
|
||||
if (Parent == null || Parent.Bsp == null) {
|
||||
return MapType.Undefined;
|
||||
}
|
||||
return Parent.Bsp.version;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The version number of the <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public int LumpVersion {
|
||||
get {
|
||||
if (Parent == null) {
|
||||
return 0;
|
||||
}
|
||||
return Parent.LumpInfo.version;
|
||||
}
|
||||
}
|
||||
|
||||
// No BSP format uses these so they are fields.
|
||||
public Vector2d scale;
|
||||
@@ -33,35 +64,35 @@ namespace LibBSP {
|
||||
|
||||
public Vector3d uAxis {
|
||||
get {
|
||||
return new Vector3d(BitConverter.ToSingle(data, 0), BitConverter.ToSingle(data, 4), BitConverter.ToSingle(data, 8));
|
||||
return new Vector3d(BitConverter.ToSingle(Data, 0), BitConverter.ToSingle(Data, 4), BitConverter.ToSingle(Data, 8));
|
||||
}
|
||||
set {
|
||||
value.GetBytes().CopyTo(data, 0);
|
||||
value.GetBytes().CopyTo(Data, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3d vAxis {
|
||||
get {
|
||||
return new Vector3d(BitConverter.ToSingle(data, 16), BitConverter.ToSingle(data, 20), BitConverter.ToSingle(data, 24));
|
||||
return new Vector3d(BitConverter.ToSingle(Data, 16), BitConverter.ToSingle(Data, 20), BitConverter.ToSingle(Data, 24));
|
||||
}
|
||||
set {
|
||||
value.GetBytes().CopyTo(data, 16);
|
||||
value.GetBytes().CopyTo(Data, 16);
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2d translation {
|
||||
get {
|
||||
return new Vector2d(BitConverter.ToSingle(data, 12), BitConverter.ToSingle(data, 28));
|
||||
return new Vector2d(BitConverter.ToSingle(Data, 12), BitConverter.ToSingle(Data, 28));
|
||||
}
|
||||
set {
|
||||
BitConverter.GetBytes((float)value.x).CopyTo(data, 12);
|
||||
BitConverter.GetBytes((float)value.y).CopyTo(data, 28);
|
||||
BitConverter.GetBytes((float)value.x).CopyTo(Data, 12);
|
||||
BitConverter.GetBytes((float)value.y).CopyTo(Data, 28);
|
||||
}
|
||||
}
|
||||
|
||||
public int flags {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Source17:
|
||||
case MapType.Source18:
|
||||
case MapType.Source19:
|
||||
@@ -73,13 +104,14 @@ namespace LibBSP {
|
||||
case MapType.L4D2:
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.Vindictus: {
|
||||
return BitConverter.ToInt32(data, 64);
|
||||
return BitConverter.ToInt32(Data, 64);
|
||||
}
|
||||
case MapType.DMoMaM: {
|
||||
return BitConverter.ToInt32(data, 88);
|
||||
return BitConverter.ToInt32(Data, 88);
|
||||
}
|
||||
case MapType.Quake: {
|
||||
return BitConverter.ToInt32(data, 36);
|
||||
case MapType.Quake:
|
||||
case MapType.Undefined: {
|
||||
return BitConverter.ToInt32(Data, 36);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -88,7 +120,7 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Source17:
|
||||
case MapType.Source18:
|
||||
case MapType.Source19:
|
||||
@@ -100,15 +132,16 @@ namespace LibBSP {
|
||||
case MapType.L4D2:
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.Vindictus: {
|
||||
bytes.CopyTo(data, 64);
|
||||
bytes.CopyTo(Data, 64);
|
||||
break;
|
||||
}
|
||||
case MapType.DMoMaM: {
|
||||
bytes.CopyTo(data, 88);
|
||||
bytes.CopyTo(Data, 88);
|
||||
break;
|
||||
}
|
||||
case MapType.Quake: {
|
||||
bytes.CopyTo(data, 36);
|
||||
case MapType.Quake:
|
||||
case MapType.Undefined: {
|
||||
bytes.CopyTo(Data, 36);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -117,7 +150,7 @@ namespace LibBSP {
|
||||
|
||||
public int texture {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Source17:
|
||||
case MapType.Source18:
|
||||
case MapType.Source19:
|
||||
@@ -129,13 +162,14 @@ namespace LibBSP {
|
||||
case MapType.L4D2:
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.Vindictus: {
|
||||
return BitConverter.ToInt32(data, 68);
|
||||
return BitConverter.ToInt32(Data, 68);
|
||||
}
|
||||
case MapType.DMoMaM: {
|
||||
return BitConverter.ToInt32(data, 92);
|
||||
return BitConverter.ToInt32(Data, 92);
|
||||
}
|
||||
case MapType.Quake: {
|
||||
return BitConverter.ToInt32(data, 32);
|
||||
case MapType.Quake:
|
||||
case MapType.Undefined: {
|
||||
return BitConverter.ToInt32(Data, 32);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -144,7 +178,7 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.Source17:
|
||||
case MapType.Source18:
|
||||
case MapType.Source19:
|
||||
@@ -156,15 +190,16 @@ namespace LibBSP {
|
||||
case MapType.L4D2:
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.Vindictus: {
|
||||
bytes.CopyTo(data, 68);
|
||||
bytes.CopyTo(Data, 68);
|
||||
break;
|
||||
}
|
||||
case MapType.DMoMaM: {
|
||||
bytes.CopyTo(data, 92);
|
||||
bytes.CopyTo(Data, 92);
|
||||
break;
|
||||
}
|
||||
case MapType.Quake: {
|
||||
bytes.CopyTo(data, 32);
|
||||
case MapType.Quake:
|
||||
case MapType.Undefined: {
|
||||
bytes.CopyTo(Data, 32);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -175,17 +210,15 @@ namespace LibBSP {
|
||||
/// Creates a new <see cref="TextureInfo"/> object from a <c>byte</c> array.
|
||||
/// </summary>
|
||||
/// <param name="data"><c>byte</c> array to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data" /> was <c>null</c>.</exception>
|
||||
public TextureInfo(byte[] data, MapType type, int version = 0) {
|
||||
/// <param name="parent">The <see cref="ILump"/> this <see cref="TextureInfo"/> came from.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> was <c>null</c>.</exception>
|
||||
public TextureInfo(byte[] data, ILump parent = null) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
this.data = data;
|
||||
this.type = type;
|
||||
this.version = version;
|
||||
|
||||
Data = data;
|
||||
Parent = parent;
|
||||
scale = new Vector2d(1, 1);
|
||||
rotation = 0;
|
||||
}
|
||||
@@ -193,22 +226,21 @@ namespace LibBSP {
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="TextureInfo"/> object using the passed data.
|
||||
/// </summary>
|
||||
/// <param name="u">The U texture axis.</param>
|
||||
/// <param name="v">The V texture axis.</param>
|
||||
/// <param name="uAxis">The U texture axis.</param>
|
||||
/// <param name="vAxis">The V texture axis.</param>
|
||||
/// <param name="translation">Texture translation along both axes (in pixels).</param>
|
||||
/// <param name="scale">Texture scale along both axes.</param>
|
||||
/// <param name="flags">The flags for this <see cref="TextureInfo"/>.</param>
|
||||
/// <param name="texture">Index into the texture list for the texture this <see cref="TextureInfo"/> uses.</param>
|
||||
/// <param name="rotation">Rotation of the texutre axes.</param>
|
||||
public TextureInfo(Vector3d u, Vector3d v, Vector2d translation, Vector2d scale, int flags, int texture, double rotation) {
|
||||
this.data = new byte[40];
|
||||
this.type = MapType.Quake;
|
||||
this.version = 0;
|
||||
public TextureInfo(Vector3d uAxis, Vector3d vAxis, Vector2d translation, Vector2d scale, int flags, int texture, double rotation) {
|
||||
Data = new byte[40];
|
||||
Parent = null;
|
||||
|
||||
this.scale = scale;
|
||||
this.rotation = rotation;
|
||||
|
||||
uAxis = u;
|
||||
vAxis = v;
|
||||
this.uAxis = uAxis;
|
||||
this.vAxis = vAxis;
|
||||
this.translation = translation;
|
||||
this.flags = flags;
|
||||
this.texture = texture;
|
||||
@@ -228,27 +260,36 @@ namespace LibBSP {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Factory method to parse a <c>byte</c> array into a <c>List</c> of <see cref="TextureInfo"/> objects.
|
||||
/// Factory method to parse a <c>byte</c> array into a <see cref="Lump{TextureInfo}"/>.
|
||||
/// </summary>
|
||||
/// <param name="data">The data to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <returns>A <c>List</c> of <see cref="TextureInfo"/> objects.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> was null.</exception>
|
||||
/// <exception cref="ArgumentException">This structure is not implemented for the given maptype.</exception>
|
||||
public static List<TextureInfo> LumpFactory(byte[] data, MapType type, int version = 0) {
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
/// <returns>A <see cref="Lump{TextureInfo}"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> parameter was <c>null</c>.</exception>
|
||||
public static Lump<TextureInfo> LumpFactory(byte[] data, BSP bsp, LumpInfo lumpInfo) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
int structLength = 0;
|
||||
switch (type) {
|
||||
|
||||
return new Lump<TextureInfo>(data, GetStructLength(bsp.version, lumpInfo.version), bsp, lumpInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length of this struct's data for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.
|
||||
/// </summary>
|
||||
/// <param name="mapType">The <see cref="LibBSP.MapType"/> of the BSP.</param>
|
||||
/// <param name="lumpVersion">The version number for the lump.</param>
|
||||
/// <returns>The length, in <c>byte</c>s, of this struct.</returns>
|
||||
/// <exception cref="ArgumentException">This struct is not valid or is not implemented for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.</exception>
|
||||
public static int GetStructLength(MapType mapType, int lumpVersion = 0) {
|
||||
switch (mapType) {
|
||||
case MapType.Nightfire: {
|
||||
structLength = 32;
|
||||
break;
|
||||
return 32;
|
||||
}
|
||||
case MapType.Quake: {
|
||||
structLength = 40;
|
||||
break;
|
||||
case MapType.Quake:
|
||||
case MapType.Undefined: {
|
||||
return 40;
|
||||
}
|
||||
case MapType.Source17:
|
||||
case MapType.Source18:
|
||||
@@ -261,25 +302,15 @@ namespace LibBSP {
|
||||
case MapType.L4D2:
|
||||
case MapType.TacticalInterventionEncrypted:
|
||||
case MapType.Vindictus: {
|
||||
structLength = 72;
|
||||
break;
|
||||
return 72;
|
||||
}
|
||||
case MapType.DMoMaM: {
|
||||
structLength = 96;
|
||||
break;
|
||||
return 96;
|
||||
}
|
||||
default: {
|
||||
throw new ArgumentException("Map type " + type + " isn't supported by the Leaf lump factory.");
|
||||
throw new ArgumentException("Lump object " + MethodBase.GetCurrentMethod().DeclaringType.Name + " does not exist in map type " + mapType + " or has not been implemented.");
|
||||
}
|
||||
}
|
||||
int numObjects = data.Length / structLength;
|
||||
List<TextureInfo> lump = new List<TextureInfo>(numObjects);
|
||||
for (int i = 0; i < numObjects; ++i) {
|
||||
byte[] bytes = new byte[structLength];
|
||||
Array.Copy(data, (i * structLength), bytes, 0, structLength);
|
||||
lump.Add(new TextureInfo(bytes, type, version));
|
||||
}
|
||||
return lump;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -26,13 +26,15 @@ namespace LibBSP {
|
||||
/// Creates a new <see cref="MAPBrush"/> object using the supplied <c>string</c> array as data.
|
||||
/// </summary>
|
||||
/// <param name="lines">Data to parse.</param>
|
||||
public MAPBrush(string[] lines) {
|
||||
public MAPBrush(IList<string> lines) {
|
||||
int braceCount = 0;
|
||||
bool brushDef3 = false;
|
||||
bool inPatch = false;
|
||||
bool inTerrain = false;
|
||||
List<string> child = new List<string>();
|
||||
foreach (string line in lines) {
|
||||
for (int i = 0; i < lines.Count; ++i) {
|
||||
string line = lines[i];
|
||||
|
||||
if (line[0] == '{') {
|
||||
braceCount++;
|
||||
if (braceCount == 1 || brushDef3) { continue; }
|
||||
|
||||
@@ -116,10 +116,10 @@ namespace LibBSP {
|
||||
}
|
||||
binaryReader.Close();
|
||||
}
|
||||
return new LumpInfo();
|
||||
return default(LumpInfo);
|
||||
}
|
||||
default: {
|
||||
return null;
|
||||
return default(LumpInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,7 +132,7 @@ namespace LibBSP {
|
||||
/// <returns>A <see cref="LumpInfo"/> object containing information about the lump.</returns>
|
||||
private LumpInfo GetLumpInfoAtOffset(int offset, MapType version) {
|
||||
if (bspFile.Length < offset + 16) {
|
||||
return new LumpInfo();
|
||||
return default(LumpInfo);
|
||||
}
|
||||
byte[] input;
|
||||
using (FileStream stream = new FileStream(bspFile.FullName, FileMode.Open, FileAccess.Read)) {
|
||||
|
||||
Reference in New Issue
Block a user