Remove stuff for Doom, it's out of scope for this library. Other small cleanups and refactorings.

This commit is contained in:
Will
2016-01-20 01:01:57 -07:00
parent f5c751e217
commit 04af0a31ce
21 changed files with 134 additions and 712 deletions

View File

@@ -72,13 +72,6 @@
<Compile Include="Source\Structs\Common\Lumps\Entities.cs" />
<Compile Include="Source\Structs\Common\Lumps\NumList.cs" />
<Compile Include="Source\Structs\Common\Rect.cs" />
<Compile Include="Source\Structs\Doom\Linedef.cs" />
<Compile Include="Source\Structs\Doom\DoomMap.cs" />
<Compile Include="Source\Structs\Doom\Node.cs" />
<Compile Include="Source\Structs\Doom\Sector.cs" />
<Compile Include="Source\Structs\Doom\Segment.cs" />
<Compile Include="Source\Structs\Doom\Sidedef.cs" />
<Compile Include="Source\Structs\Doom\Thing.cs" />
<Compile Include="Source\Structs\MAP\MAPBrush.cs" />
<Compile Include="Source\Structs\MAP\MAPBrushSide.cs" />
<Compile Include="Source\Structs\MAP\MAPDisplacement.cs" />

View File

@@ -82,11 +82,6 @@ namespace LibBSP {
}
UIVertex result = new UIVertex();
switch (type) {
case MapType.Doom:
case MapType.Hexen: {
result.position = new Vector3(BitConverter.ToInt16(data, 0), BitConverter.ToInt16(data, 2));
break;
}
case MapType.MOHAA:
case MapType.Quake3:
case MapType.CoD:
@@ -151,11 +146,6 @@ namespace LibBSP {
}
int structLength = 0;
switch (type) {
case MapType.Doom:
case MapType.Hexen: {
structLength = 4;
break;
}
case MapType.Quake:
case MapType.Nightfire:
case MapType.SiN:

View File

@@ -23,8 +23,6 @@ namespace LibBSP {
STEF2 = 556942937,
MOHAA = 892416069,
// TYPE_MOHBT = 1095516506, // Similar enough to MOHAA to use the same structures and algorithm
Doom = 1145132868, // "DWAD"
Hexen = 1145132872, // "HWAD"
STEF2Demo = 1263223129,
FAKK = 1263223152,
TacticalInterventionEncrypted = 1268885814,
@@ -52,14 +50,13 @@ namespace LibBSP {
/// <summary>
/// Holds data for any and all BSP formats. Any unused lumps in a given format
/// will be left as null. Then it will be fed into a universal decompile method
/// which should be able to perform its job based on what data is stored.
/// will be left as null.
/// </summary>
public class BSP {
private MapType _version;
private BSPReader reader;
private BSPReader _reader;
// Map structures
// Quake 1/GoldSrc
@@ -95,18 +92,13 @@ namespace LibBSP {
private GameLump _gameLump;
private SourceStaticProps _staticProps;
/// <summary>
/// An XOr encryption key for encrypted map formats. Must be read and set.
/// </summary>
public byte[] key = new byte[0];
/// <summary>
/// The version of this BSP. DO NOT CHANGE THIS unless you want to force reading a BSP as a certain format.
/// </summary>
public MapType version {
get {
if (_version == MapType.Undefined) {
_version = reader.GetVersion();
_version = _reader.GetVersion();
}
return _version;
}
@@ -115,14 +107,14 @@ namespace LibBSP {
}
}
public bool bigEndian { get { return reader.bigEndian; } }
public bool bigEndian { get { return _reader.bigEndian; } }
public Entities entities {
get {
if (_entities == null) {
int index = Entity.GetIndexForLump(version);
if (index >= 0) {
_entities = Entity.LumpFactory(reader.ReadLumpNum(index, version), version);
_entities = Entity.LumpFactory(_reader.ReadLumpNum(index, version), version);
}
}
return _entities;
@@ -134,7 +126,7 @@ namespace LibBSP {
if (_planes == null) {
int index = PlaneExtensions.GetIndexForLump(version);
if (index >= 0) {
_planes = PlaneExtensions.LumpFactory(reader.ReadLumpNum(index, version), version);
_planes = PlaneExtensions.LumpFactory(_reader.ReadLumpNum(index, version), version);
}
}
return _planes;
@@ -146,7 +138,7 @@ namespace LibBSP {
if (_textures == null) {
int index = Texture.GetIndexForLump(version);
if (index >= 0) {
_textures = Texture.LumpFactory(reader.ReadLumpNum(index, version), version);
_textures = Texture.LumpFactory(_reader.ReadLumpNum(index, version), version);
}
}
return _textures;
@@ -158,7 +150,7 @@ namespace LibBSP {
if (_vertices == null) {
int index = UIVertexExtensions.GetIndexForLump(version);
if (index >= 0) {
_vertices = UIVertexExtensions.LumpFactory(reader.ReadLumpNum(index, version), version);
_vertices = UIVertexExtensions.LumpFactory(_reader.ReadLumpNum(index, version), version);
}
}
return _vertices;
@@ -170,7 +162,7 @@ namespace LibBSP {
if (_nodes == null) {
int index = Node.GetIndexForLump(version);
if (index >= 0) {
_nodes = Node.LumpFactory(reader.ReadLumpNum(index, version), version);
_nodes = Node.LumpFactory(_reader.ReadLumpNum(index, version), version);
}
}
return _nodes;
@@ -182,7 +174,7 @@ namespace LibBSP {
if (_texInfo == null) {
int index = TexInfo.GetIndexForLump(version);
if (index >= 0) {
_texInfo = TexInfo.LumpFactory(reader.ReadLumpNum(index, version), version);
_texInfo = TexInfo.LumpFactory(_reader.ReadLumpNum(index, version), version);
}
}
return _texInfo;
@@ -194,7 +186,7 @@ namespace LibBSP {
if (_faces == null) {
int index = Face.GetIndexForLump(version);
if (index >= 0) {
_faces = Face.LumpFactory(reader.ReadLumpNum(index, version), version);
_faces = Face.LumpFactory(_reader.ReadLumpNum(index, version), version);
}
}
return _faces;
@@ -206,7 +198,7 @@ namespace LibBSP {
if (_leaves == null) {
int index = Leaf.GetIndexForLump(version);
if (index >= 0) {
_leaves = Leaf.LumpFactory(reader.ReadLumpNum(index, version), version);
_leaves = Leaf.LumpFactory(_reader.ReadLumpNum(index, version), version);
}
}
return _leaves;
@@ -218,7 +210,7 @@ namespace LibBSP {
if (_edges == null) {
int index = Edge.GetIndexForLump(version);
if (index >= 0) {
_edges = Edge.LumpFactory(reader.ReadLumpNum(index, version), version);
_edges = Edge.LumpFactory(_reader.ReadLumpNum(index, version), version);
}
}
return _edges;
@@ -230,7 +222,7 @@ namespace LibBSP {
if (_models == null) {
int index = Model.GetIndexForLump(version);
if (index >= 0) {
_models = Model.LumpFactory(reader.ReadLumpNum(index, version), version);
_models = Model.LumpFactory(_reader.ReadLumpNum(index, version), version);
}
}
return _models;
@@ -242,7 +234,7 @@ namespace LibBSP {
if (_brushes == null) {
int index = Brush.GetIndexForLump(version);
if (index >= 0) {
_brushes = Brush.LumpFactory(reader.ReadLumpNum(index, version), version);
_brushes = Brush.LumpFactory(_reader.ReadLumpNum(index, version), version);
}
}
return _brushes;
@@ -254,7 +246,7 @@ namespace LibBSP {
if (_brushSides == null) {
int index = BrushSide.GetIndexForLump(version);
if (index >= 0) {
_brushSides = BrushSide.LumpFactory(reader.ReadLumpNum(index, version), version);
_brushSides = BrushSide.LumpFactory(_reader.ReadLumpNum(index, version), version);
}
}
return _brushSides;
@@ -266,7 +258,7 @@ namespace LibBSP {
if (_materials == null) {
int index = Texture.GetIndexForMaterialLump(version);
if (index >= 0) {
_materials = Texture.LumpFactory(reader.ReadLumpNum(index, version), version);
_materials = Texture.LumpFactory(_reader.ReadLumpNum(index, version), version);
}
}
return _materials;
@@ -278,7 +270,7 @@ namespace LibBSP {
if (_originalFaces == null) {
int index = Face.GetIndexForOriginalFacesLump(version);
if (index >= 0) {
_originalFaces = Face.LumpFactory(reader.ReadLumpNum(index, version), version);
_originalFaces = Face.LumpFactory(_reader.ReadLumpNum(index, version), version);
}
}
return _originalFaces;
@@ -290,7 +282,7 @@ namespace LibBSP {
if (_texDatas == null) {
int index = SourceTexData.GetIndexForLump(version);
if (index >= 0) {
_texDatas = SourceTexData.LumpFactory(reader.ReadLumpNum(index, version), version);
_texDatas = SourceTexData.LumpFactory(_reader.ReadLumpNum(index, version), version);
}
}
return _texDatas;
@@ -302,7 +294,7 @@ namespace LibBSP {
if (_dispInfos == null) {
int index = SourceDispInfo.GetIndexForLump(version);
if (index >= 0) {
_dispInfos = SourceDispInfo.LumpFactory(reader.ReadLumpNum(index, version), version);
_dispInfos = SourceDispInfo.LumpFactory(_reader.ReadLumpNum(index, version), version);
}
}
return _dispInfos;
@@ -314,7 +306,7 @@ namespace LibBSP {
if (_dispVerts == null) {
int index = SourceDispVertex.GetIndexForLump(version);
if (index >= 0) {
_dispVerts = SourceDispVertex.LumpFactory(reader.ReadLumpNum(index, version), version);
_dispVerts = SourceDispVertex.LumpFactory(_reader.ReadLumpNum(index, version), version);
}
}
return _dispVerts;
@@ -326,7 +318,7 @@ namespace LibBSP {
if (_cubemaps == null) {
int index = SourceCubemap.GetIndexForLump(version);
if (index >= 0) {
_cubemaps = SourceCubemap.LumpFactory(reader.ReadLumpNum(index, version), version);
_cubemaps = SourceCubemap.LumpFactory(_reader.ReadLumpNum(index, version), version);
}
}
return _cubemaps;
@@ -339,7 +331,7 @@ namespace LibBSP {
NumList.DataType type;
int index = NumList.GetIndexForMarkSurfacesLump(version, out type);
if (index >= 0) {
_markSurfaces = NumList.LumpFactory(reader.ReadLumpNum(index, version), type);
_markSurfaces = NumList.LumpFactory(_reader.ReadLumpNum(index, version), type);
}
}
return _markSurfaces;
@@ -352,7 +344,7 @@ namespace LibBSP {
NumList.DataType type;
int index = NumList.GetIndexForSurfEdgesLump(version, out type);
if (index >= 0) {
_surfEdges = NumList.LumpFactory(reader.ReadLumpNum(index, version), type);
_surfEdges = NumList.LumpFactory(_reader.ReadLumpNum(index, version), type);
}
}
return _surfEdges;
@@ -365,7 +357,7 @@ namespace LibBSP {
NumList.DataType type;
int index = NumList.GetIndexForMarkBrushesLump(version, out type);
if (index >= 0) {
_markBrushes = NumList.LumpFactory(reader.ReadLumpNum(index, version), type);
_markBrushes = NumList.LumpFactory(_reader.ReadLumpNum(index, version), type);
}
}
return _markBrushes;
@@ -378,7 +370,7 @@ namespace LibBSP {
NumList.DataType type;
int index = NumList.GetIndexForIndicesLump(version, out type);
if (index >= 0) {
_indices = NumList.LumpFactory(reader.ReadLumpNum(index, version), type);
_indices = NumList.LumpFactory(_reader.ReadLumpNum(index, version), type);
}
}
return _indices;
@@ -391,7 +383,7 @@ namespace LibBSP {
NumList.DataType type;
int index = NumList.GetIndexForTexTableLump(version, out type);
if (index >= 0) {
_texTable = NumList.LumpFactory(reader.ReadLumpNum(index, version), type);
_texTable = NumList.LumpFactory(_reader.ReadLumpNum(index, version), type);
}
}
return _texTable;
@@ -404,7 +396,7 @@ namespace LibBSP {
NumList.DataType type;
int index = NumList.GetIndexForDisplacementTrianglesLump(version, out type);
if (index >= 0) {
_displacementTriangles = NumList.LumpFactory(reader.ReadLumpNum(index, version), type);
_displacementTriangles = NumList.LumpFactory(_reader.ReadLumpNum(index, version), type);
}
}
return _displacementTriangles;
@@ -416,7 +408,7 @@ namespace LibBSP {
if (_gameLump == null) {
int index = GameLump.GetIndexForLump(version);
if (index >= 0) {
_gameLump = GameLump.LumpFactory(reader.ReadLumpNum(index, version), version);
_gameLump = GameLump.LumpFactory(_reader.ReadLumpNum(index, version), version);
}
}
return _gameLump;
@@ -498,9 +490,9 @@ namespace LibBSP {
/// Creates a new <c>BSP</c> instance pointing to the file at <paramref name="filePath"/>. The
/// <c>List</c>s in this class will be read and populated when accessed through their properties.
/// </summary>
/// <param name="filePath">The path to the .BSP file</param>
/// <param name="filePath">The path to the .BSP file.</param>
public BSP(string filePath) {
reader = new BSPReader(new FileInfo(filePath));
_reader = new BSPReader(new FileInfo(filePath));
this.filePath = filePath;
}
@@ -508,9 +500,9 @@ namespace LibBSP {
/// Creates a new <c>BSP</c> instance using the file referenced by <paramref name="file"/>. The
/// <c>List</c>s in this class will be read and populated when accessed through their properties.
/// </summary>
/// <param name="file">A reference to the .BSP file</param>
/// <param name="file">A reference to the .BSP file.</param>
public BSP(FileInfo file) {
reader = new BSPReader(file);
_reader = new BSPReader(file);
this.filePath = file.FullName;
}
@@ -518,7 +510,7 @@ namespace LibBSP {
/// Tells the <see cref="BSPReader"/> object to release file handles for the BSP file.
/// </summary>
public void Close() {
reader.Close();
_reader.Close();
}
/// <summary>
@@ -535,8 +527,7 @@ namespace LibBSP {
/// <returns>The <c>List&lt;<typeparamref name="T"/>&gt;</c> of objects in the lump from the index and length specified in <paramref name="o"/>.</returns>
/// <exception cref="ArgumentException">The <c>BSP</c> class contains no property corresponding to <paramref name="lumpName"/>.</exception>
/// <exception cref="ArgumentException">The <c>object</c> referenced by <paramref name="o"/> is missing one or both members with <c>IndexAttribute</c> or <c>CountAttribute</c> attributes corresponding to <paramref name="lumpName"/>.</exception>
public List<T> GetReferencedObjects<T>(object o, string lumpName)
{
public List<T> GetReferencedObjects<T>(object o, string lumpName) {
// First, find the property in this class corresponding to lumpName, and grab its "get" method
PropertyInfo targetLump = typeof(BSP).GetProperty(lumpName, BindingFlags.Public | BindingFlags.Instance);
if (targetLump == null) {

View File

@@ -3,14 +3,12 @@ using System.Collections.Generic;
namespace LibBSP {
/// <summary>
/// Holds all the data for an edge in a BSP map. Doubles as a subsector class for Doom maps, and has accessors for them.
/// Holds all the data for an edge in a BSP map.
/// </summary>
public class Edge {
public struct Edge {
public int firstVertex { get; private set; }
public int secondVertex { get; private set; }
public int NumSegs { get { return firstVertex; } private set { firstVertex = value; } }
public int FirstSeg { get { return secondVertex; } private set { secondVertex = value; } }
/// <summary>
/// Creates a new <c>Edge</c> object from a <c>byte</c> array.
@@ -19,7 +17,7 @@ namespace LibBSP {
/// <param name="type">The map type</param>
/// <exception cref="ArgumentNullException"><paramref name="data" /> was null</exception>
/// <exception cref="ArgumentException">This structure is not implemented for the given maptype</exception>
public Edge(byte[] data, MapType type) {
public Edge(byte[] data, MapType type) : this() {
if (data == null) {
throw new ArgumentNullException();
}
@@ -48,12 +46,6 @@ namespace LibBSP {
secondVertex = BitConverter.ToInt32(data, 4);
break;
}
case MapType.Doom:
case MapType.Hexen: {
firstVertex = BitConverter.ToUInt16(data, 0);
secondVertex = BitConverter.ToUInt16(data, 2);
break;
}
default: {
throw new ArgumentException("Map type " + type + " isn't supported by the Edge class.");
}
@@ -96,11 +88,6 @@ namespace LibBSP {
structLength = 8;
break;
}
case MapType.Doom:
case MapType.Hexen: {
structLength = 4;
break;
}
default: {
throw new ArgumentException("Map type " + type + " isn't supported by the Edge lump factory.");
}

View File

@@ -125,10 +125,10 @@ namespace LibBSP {
bestaxis = i;
}
}
Vector3[] out_Renamed = new Vector3[2];
out_Renamed[0] = new Vector3(baseAxes[bestaxis * 3 + 1][0], baseAxes[bestaxis * 3 + 1][1], baseAxes[bestaxis * 3 + 1][2]);
out_Renamed[1] = new Vector3(baseAxes[bestaxis * 3 + 2][0], baseAxes[bestaxis * 3 + 2][1], baseAxes[bestaxis * 3 + 2][2]);
return out_Renamed;
Vector3[] newAxes = new Vector3[2];
newAxes[0] = new Vector3(baseAxes[bestaxis * 3 + 1][0], baseAxes[bestaxis * 3 + 1][1], baseAxes[bestaxis * 3 + 1][2]);
newAxes[1] = new Vector3(baseAxes[bestaxis * 3 + 2][0], baseAxes[bestaxis * 3 + 2][1], baseAxes[bestaxis * 3 + 2][2]);
return newAxes;
}
/// <summary>

View File

@@ -70,6 +70,8 @@ namespace LibBSP {
get {
if (ContainsKey("targetname")) {
return this["targetname"];
} else if (ContainsKey("name")) {
return this["name"];
} else {
return "";
}
@@ -335,10 +337,9 @@ namespace LibBSP {
}
/// <summary>
/// Gets a string representation of this <c>Entity</c>.
/// Gets a <c>string</c> representation of this <c>Entity</c>.
/// </summary>
/// <remarks>Don't use this to export the entity to a file</remarks>
/// <returns>String representation of this <c>Entity</c></returns>
/// <returns><c>string</c> representation of this <c>Entity</c>.</returns>
public override string ToString() {
StringBuilder output = new StringBuilder();
output.Append("{\n");
@@ -356,45 +357,45 @@ namespace LibBSP {
}
/// <summary>
/// Checks if the attribute named "<paramref name="key" />" has the value "<paramref name="value" />"
/// Checks if the attribute named "<paramref name="key" />" has the value "<paramref name="value" />".
/// </summary>
/// <param name="key">The attribute to check</param>
/// <param name="value">The value to compare</param>
/// <returns><c>true</c> if the values match</returns>
/// <param name="key">The attribute to check.</param>
/// <param name="value">The value to compare.</param>
/// <returns><c>true</c> if the values match.</returns>
public bool ValueIs(string key, string value) {
return value.Equals(this[key], StringComparison.InvariantCultureIgnoreCase);
}
/// <summary>
/// Checks if the bits in "spawnflags" corresponding to the set bits set in <paramref name="bits" /> are set
/// Checks if the bits in "spawnflags" corresponding to the set bits set in <paramref name="bits" /> are set.
/// </summary>
/// <param name="bits">The bits to compare spawnflags to</param>
/// <returns><c>true</c> if all bits that were set in <paramref name="bits" /> were set in spawnflags</returns>
/// <param name="bits">The bits to compare spawnflags to.</param>
/// <returns><c>true</c> if all bits that were set in <paramref name="bits" /> were set in spawnflags.</returns>
public bool SpawnflagsSet(uint bits) {
return ((spawnflags & bits) == bits);
}
/// <summary>
/// Toggles the bits in "spawnflags" which are set in <paramref name="bits" />
/// Toggles the bits in "spawnflags" which are set in <paramref name="bits" />.
/// </summary>
/// <param name="bits">Bitmask of bits to toggle</param>
/// <param name="bits">Bitmask of bits to toggle.</param>
public void ToggleSpawnflags(uint bits) {
this["spawnflags"] = (spawnflags ^ bits).ToString();
}
/// <summary>
/// Clears the bits in "spawnflags" which are set in <paramref name="bits" />
/// Equivalent to spawnflags = (<paramref name="bits" /> ^ 0xFFFFFFFF) & spawnflags
/// Clears the bits in "spawnflags" which are set in <paramref name="bits" />.
/// Equivalent to spawnflags = (<paramref name="bits" /> ^ 0xFFFFFFFF) & spawnflags.
/// </summary>
/// <param name="bits">Bitmask of bits to clear</param>
/// <param name="bits">Bitmask of bits to clear.</param>
public void ClearSpawnflags(uint bits) {
ToggleSpawnflags(spawnflags & bits);
}
/// <summary>
/// Sets the bits in "spawnflags" which are set in <paramref name="bits" />
/// Sets the bits in "spawnflags" which are set in <paramref name="bits" />.
/// </summary>
/// <param name="bits">Bitmask of bits to set</param>
/// <param name="bits">Bitmask of bits to set.</param>
public void SetSpawnflags(uint bits) {
this["spawnflags"] = (spawnflags | bits).ToString();
}
@@ -403,9 +404,9 @@ namespace LibBSP {
/// Gets a numeric attribute as a <c>float</c>. Throws if the attribute could not be converted to a numerical value
/// and no <paramref name="failDefault"/> was provided.
/// </summary>
/// <param name="key">Name of the attribute to retrieve</param>
/// <param name="failDefault">Value to return if <paramref name="key" /> doesn't exist, or couldn't be converted</param>
/// <returns>The numeric value of the value corresponding to <paramref name="key" /></returns>
/// <param name="key">Name of the attribute to retrieve.</param>
/// <param name="failDefault">Value to return if <paramref name="key" /> doesn't exist, or couldn't be converted.</param>
/// <returns>The numeric value of the value corresponding to <paramref name="key" />.</returns>
public float GetFloat(string key, float? failDefault = null) {
try {
return Single.Parse(this[key]);
@@ -421,9 +422,9 @@ namespace LibBSP {
/// Gets a numeric attribute as an <c>int</c>. Throws if the attribute could not be converted to a numerical value
/// and no <paramref name="failDefault"/> was provided.
/// </summary>
/// <param name="key">Name of the attribute to retrieve</param>
/// <param name="failDefault">Value to return if <paramref name="key" /> doesn't exist, or couldn't be converted</param>
/// <returns>The numeric value of the value corresponding to <paramref name="key" /></returns>
/// <param name="key">Name of the attribute to retrieve.</param>
/// <param name="failDefault">Value to return if <paramref name="key" /> doesn't exist, or couldn't be converted.</param>
/// <returns>The numeric value of the value corresponding to <paramref name="key" />.</returns>
public int GetInt(string key, int? failDefault = null) {
try {
return Int32.Parse(this[key]);
@@ -437,10 +438,10 @@ namespace LibBSP {
/// <summary>
/// Gets a Vector attribute as a <c>Vector4</c>. This will only read as many values as are in the attribute, and can be
/// implicitly converted to Vector3, Vector2, or Color.
/// implicitly converted to <c>Vector3</c>, <c>Vector2</c>, or <c>Color</c>.
/// </summary>
/// <param name="key">Name of the attribute to retrieve</param>
/// <returns>Vector representation of the components of the attribute</returns>
/// <param name="key">Name of the attribute to retrieve.</param>
/// <returns>Vector representation of the components of the attribute.</returns>
public Vector4 GetVector(string key) {
float[] results = new float[4];
if (ContainsKey(key) && !string.IsNullOrEmpty(this[key])) {
@@ -460,9 +461,9 @@ namespace LibBSP {
/// Compares this <c>Entity</c> to another object. First "classname" attributes are compared, then "targetname".
/// Attributes are compared alphabetically. Targetnames are only compared if classnames match.
/// </summary>
/// <param name="obj"><c>Object</c> to compare to</param>
/// <returns>Less than zero if this entity is first, 0 if they occur at the same time, greater than zero otherwise</returns>
/// <exception cref="ArgumentException"><paramref name="obj"/> was not of type <c>Entity</c></exception>
/// <param name="obj"><c>Object</c> to compare to.</param>
/// <returns>Less than zero if this entity is first, 0 if they occur at the same time, greater than zero otherwise.</returns>
/// <exception cref="ArgumentException"><paramref name="obj"/> was not of type <c>Entity</c>.</exception>
public int CompareTo(object obj) {
if (obj == null) { return 1; }
Entity other = obj as Entity;
@@ -476,8 +477,8 @@ namespace LibBSP {
/// Compares this <c>Entity</c> to another <c>Entity</c>. First "classname" attributes are compared, then "targetname".
/// Attributes are compared alphabetically. Targetnames are only compared if classnames match.
/// </summary>
/// <param name="other"><c>Entity</c> to compare to</param>
/// <returns>Less than zero if this entity is first, 0 if they occur at the same time, greater than zero otherwise</returns>
/// <param name="other"><c>Entity</c> to compare to.</param>
/// <returns>Less than zero if this entity is first, 0 if they occur at the same time, greater than zero otherwise.</returns>
public int CompareTo(Entity other) {
if (other == null) { return 1; }
int firstTry = className.CompareTo(other.className);
@@ -487,9 +488,9 @@ namespace LibBSP {
/// <summary>
/// Factory method for an <c>Entities</c> object from a <c>byte</c> array.
/// </summary>
/// <param name="data">The data to parse</param>
/// <param name="type">The map type</param>
/// <returns>An <c>Entities</c> object, which is a <c>List</c> of <c>Entity</c>s</returns>
/// <param name="data">The data to parse.</param>
/// <param name="type">The map type.</param>
/// <returns>An <c>Entities</c> object, which is a <c>List</c> of <c>Entity</c>s.</returns>
public static Entities LumpFactory(byte[] data, MapType type) {
return new Entities(data, type);
}
@@ -497,8 +498,8 @@ namespace LibBSP {
/// <summary>
/// Gets the index for this lump in the BSP file for a specific map format.
/// </summary>
/// <param name="type">The map type</param>
/// <returns>Index for this lump, or -1 if the format doesn't have this lump or it's not implemented</returns>
/// <param name="type">The map type.</param>
/// <returns>Index for this lump, or -1 if the format doesn't have this lump or it's not implemented.</returns>
public static int GetIndexForLump(MapType type) {
switch (type) {
case MapType.Raven:
@@ -546,7 +547,7 @@ namespace LibBSP {
}
/// <summary>
/// Struct containing the fields necessary for Source entity I/O
/// Struct containing the fields necessary for Source entity I/O.
/// </summary>
public struct EntityConnection {
public string name;

View File

@@ -3,20 +3,20 @@ using System.Collections.Generic;
namespace LibBSP {
/// <summary>
/// Class representing a group of <c>Entity</c> objects. Contains helpful methods to handle Entities in the <c>List</c>
/// Class representing a group of <c>Entity</c> objects. Contains helpful methods to handle Entities in the <c>List</c>.
/// </summary>
public class Entities : List<Entity> {
/// <summary>
/// Initializes a new instance of an <c>Entities</c> object copying a passed <c>IEnumerable</c> of <c>Entity</c> objects.
/// </summary>
/// <param name="data">Collection of <c>Entity</c> objects to copy</param>
/// <param name="data">Collection of <c>Entity</c> objects to copy.</param>
public Entities(IEnumerable<Entity> data) : base(data) { }
/// <summary>
/// Initializes a new instance of an <c>Entities</c> object with a specified initial capacity.
/// </summary>
/// <param name="initialCapacity">Initial capacity of the <c>List</c> of <c>Entity</c> objects</param>
/// <param name="initialCapacity">Initial capacity of the <c>List</c> of <c>Entity</c> objects.</param>
public Entities(int initialCapacity) : base(initialCapacity) { }
/// <summary>
@@ -27,7 +27,7 @@ namespace LibBSP {
/// <summary>
/// Initializes a new <c>Entities</c> object, and parses the passed <c>byte</c> array into the <c>List</c>.
/// </summary>
/// <param name="data"><c>Byte</c>s read from a file</param>
/// <param name="data"><c>Byte</c>s read from a file.</param>
public Entities(byte[] data, MapType type) : base() {
// 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.
@@ -86,49 +86,48 @@ namespace LibBSP {
/// <summary>
/// Deletes all <c>Entity</c> with "<paramref name="key" />" set to "<paramref name="value" />".
/// </summary>
/// <param name="key">Attribute to match</param>
/// <param name="value">Desired value of attribute</param>
/// <param name="key">Attribute to match.</param>
/// <param name="value">Desired value of attribute.</param>
public void RemoveAllWithAttribute(string key, string value) {
//DeleteEnts(FindAllWithAttribute(key, value));
this.RemoveAll(entity => { return entity[key] == value; });
this.RemoveAll(entity => { return entity[key].Equals(value, StringComparison.InvariantCultureIgnoreCase); });
}
/// <summary>
/// Gets a <c>List</c> of all <c>Entity</c>s with "<paramref name="key" />" set to "<paramref name="value" />".
/// </summary>
/// <param name="key">Name of the attribute to search for</param>
/// <param name="value">Value of the attribute to search for</param>
/// <returns><c>List</c>(<c>Entity</c>) that have the specified key/value pair</returns>
/// <param name="key">Name of the attribute to search for.</param>
/// <param name="value">Value of the attribute to search for.</param>
/// <returns><c>List</c>(<c>Entity</c>) that have the specified key/value pair.</returns>
public List<Entity> GetAllWithAttribute(string key, string value) {
return FindAll(entity => { return entity[key] == value; });
return FindAll(entity => { return entity[key].Equals(value, StringComparison.InvariantCultureIgnoreCase); });
}
/// <summary>
/// Gets a <c>List</c> of <c>Entity</c>s objects with the specified targetname
/// Gets a <c>List</c> of <c>Entity</c>s objects with the specified targetname.
/// </summary>
/// <param name="targetname">Targetname attribute to find</param>
/// <returns><c>List</c>(<c>Entity</c>) with the specified targetname</returns>
/// <param name="targetname">Targetname attribute to find.</param>
/// <returns><c>List</c>(<c>Entity</c>) with the specified targetname.</returns>
public List<Entity> GetAllWithName(string targetname) {
return GetAllWithAttribute("targetname", targetname);
return FindAll(entity => { return entity.name.Equals(targetname, StringComparison.InvariantCultureIgnoreCase); });
}
/// <summary>
/// Gets the first <c>Entity</c> with "<paramref name="key" />" set to "<paramref name="value" />".
/// </summary>
/// <param name="key">Name of the attribute to search for</param>
/// <param name="value">Value of the attribute to search for</param>
/// <returns><c>Entity</c> with the specified key/value pair, or null if none exists</returns>
/// <param name="key">Name of the attribute to search for.</param>
/// <param name="value">Value of the attribute to search for.</param>
/// <returns><c>Entity</c> with the specified key/value pair, or null if none exists.</returns>
public Entity GetWithAttribute(string key, string value) {
return Find(entity => { return entity[key] == value; });
return Find(entity => { return entity[key].Equals(value, StringComparison.InvariantCultureIgnoreCase); });
}
/// <summary>
/// Gets the first <c>Entity</c> with the specified targetname.
/// </summary>
/// <param name="targetname">Targetname attribute to find</param>
/// <returns>Entity object with the specified targetname</returns>
/// <param name="targetname">Targetname attribute to find.</param>
/// <returns>Entity object with the specified targetname.</returns>
public Entity GetWithName(string targetname) {
return GetWithAttribute("targetname", targetname);
return Find(entity => { return entity.name.Equals(targetname, StringComparison.InvariantCultureIgnoreCase); });
}
}
}

View File

@@ -1,4 +1,4 @@
#if !(UNITY_2_6 || UNITY_2_6_1 || UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_4_0 || UNITY_4_0_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_5)
#if !(UNITY || UNITY_2_6 || UNITY_2_6_1 || UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_4_0 || UNITY_4_0_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_5)
using System;
using System.Collections.Generic;

View File

@@ -1,4 +1,4 @@
#if !(UNITY_2_6 || UNITY_2_6_1 || UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_4_0 || UNITY_4_0_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_5)
#if !(UNITY || UNITY_2_6 || UNITY_2_6_1 || UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_4_0 || UNITY_4_0_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_5)
using System;
namespace LibBSP {

View File

@@ -1,4 +1,4 @@
#if !(UNITY_2_6 || UNITY_2_6_1 || UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_4_0 || UNITY_4_0_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_5)
#if !(UNITY || UNITY_2_6 || UNITY_2_6_1 || UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_4_0 || UNITY_4_0_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_5)
using System;
using System.Collections.Generic;

View File

@@ -1,4 +1,4 @@
#if !(UNITY_2_6 || UNITY_2_6_1 || UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_4_0 || UNITY_4_0_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_5)
#if !(UNITY || UNITY_2_6 || UNITY_2_6_1 || UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_4_0 || UNITY_4_0_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_5)
using System;
using System.Collections;
using System.Collections.Generic;

View File

@@ -1,4 +1,4 @@
#if !(UNITY_2_6 || UNITY_2_6_1 || UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_4_0 || UNITY_4_0_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_5)
#if !(UNITY || UNITY_2_6 || UNITY_2_6_1 || UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_4_0 || UNITY_4_0_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_5)
using System;
using System.Collections;
using System.Collections.Generic;

View File

@@ -1,4 +1,4 @@
#if !(UNITY_2_6 || UNITY_2_6_1 || UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_4_0 || UNITY_4_0_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_5)
#if !(UNITY || UNITY_2_6 || UNITY_2_6_1 || UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_4_0 || UNITY_4_0_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_5)
using System;
using System.Collections;
using System.Collections.Generic;

View File

@@ -1,72 +0,0 @@
#if UNITY_2_6 || UNITY_2_6_1 || UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_4_0 || UNITY_4_0_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_5
#define UNITY
#endif
using System;
using System.Collections.Generic;
#if UNITY
using UnityEngine;
#endif
namespace LibBSP.Doom {
/// <summary>
/// Gathers all relevant information from the lumps of a Doom Map.
/// </summary>
public class DoomMap {
// Since all Doom engine maps were incorporated into the WAD, we need to keep
// track of both the location of the WAD file and the internal name of the map.
public string wadPath { get; private set; }
public string mapName { get; private set; }
public MapType version { get; private set; }
public List<Thing> things;
public List<Linedef> linedefs;
public List<Sidedef> sidedefs;
public List<UIVertex> vertices;
public List<Segment> segs;
public List<Edge> subsectors;
public List<Node> nodes;
public List<Sector> sectors;
/// <summary>
/// Gets the folder path for the WAD containing this map
/// </summary>
public string Folder {
get {
int i;
for (i = 0; i < wadPath.Length; ++i) {
if (wadPath[wadPath.Length - 1 - i] == '\\') {
break;
}
if (wadPath[wadPath.Length - 1 - i] == '/') {
break;
}
}
return wadPath.Substring(0, (wadPath.Length - i) - (0));
}
}
/// <summary>
/// Gets the name of the WAD file containing this map
/// </summary>
public string WadName {
get {
System.IO.FileInfo newFile = new System.IO.FileInfo(wadPath);
return newFile.Name.Substring(0, (newFile.Name.Length - 4) - (0));
}
}
/// <summary>
/// Creates a new <c>DoomMap</c> instance with no initial data. The <c>List</c>s in this class must be populated elsewhere.
/// </summary>
/// <param name="wadpath">The path to the .WAD file</param>
/// <param name="map">The name of the map within the WAD file</param>
/// <param name="version">The version of the map</param>
public DoomMap(string wadpath, string map, MapType version) {
this.wadPath = wadpath;
this.mapName = map;
this.version = version;
}
}
}

View File

@@ -1,108 +0,0 @@
using System;
using System.Collections.Generic;
namespace LibBSP.Doom {
/// <summary>
/// Contains all necessary information for a Doom LINEDEF object.
/// </summary>
/// <remarks>
/// The linedef is a strange animal. It roughly equates to the Planes of other
/// BSP formats, but also defines what sectors are on what side.
/// </remarks>
public struct Linedef {
public short start { get; private set; }
public short end { get; private set; }
public short flags { get; private set; }
public short action { get; private set; }
public short tag { get; private set; }
public short right { get; private set; }
public short left { get; private set; }
public byte[] arguments { get; private set; }
public bool oneSided {
get {
return (right == -1 || left == -1);
}
}
/// <summary>
/// Creates a new <c>Linedef</c> 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>
/// <exception cref="ArgumentNullException"><paramref name="data" /> was null</exception>
/// <exception cref="ArgumentException">This structure is not implemented for the given maptype</exception>
public Linedef(byte[] data, MapType type) : this() {
if (data == null) {
throw new ArgumentNullException();
}
start = BitConverter.ToInt16(data, 0);
end = BitConverter.ToInt16(data, 2);
flags = BitConverter.ToInt16(data, 4);
action = -1;
tag = -1;
right = -1;
left = -1;
arguments = new byte[5];
switch (type) {
case MapType.Doom: {
action = BitConverter.ToInt16(data, 6);
tag = BitConverter.ToInt16(data, 8);
right = BitConverter.ToInt16(data, 10);
left = BitConverter.ToInt16(data, 12);
break;
}
case MapType.Hexen: {
action = data[6];
arguments[0] = data[7];
arguments[1] = data[8];
arguments[2] = data[9];
arguments[3] = data[10];
arguments[4] = data[11];
right = BitConverter.ToInt16(data, 12);
left = BitConverter.ToInt16(data, 14);
break;
}
default: {
throw new ArgumentException("Map type " + type + " isn't supported by the Linedef class.");
}
}
}
/// <summary>
/// Factory method to parse a <c>byte</c> array into a <c>List</c> of <c>Linedef</c> objects.
/// </summary>
/// <param name="data">The data to parse</param>
/// <param name="type">The map type</param>
/// <returns>A <c>List</c> of <c>Linedef</c> 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<Linedef> LumpFactory(byte[] data, MapType type) {
if (data == null) {
throw new ArgumentNullException();
}
int structLength = 0;
switch (type) {
case MapType.Doom: {
structLength = 14;
break;
}
case MapType.Hexen: {
structLength = 16;
break;
}
default: {
throw new ArgumentException("Map type " + type + " isn't supported by the Linedef lump factory.");
}
}
List<Linedef> lump = new List<Linedef>(data.Length / structLength);
byte[] bytes = new byte[structLength];
for (int i = 0; i < data.Length / structLength; ++i) {
Array.Copy(data, i * structLength, bytes, 0, structLength);
lump.Add(new Linedef(bytes, type));
}
return lump;
}
}
}

View File

@@ -1,73 +0,0 @@
#if UNITY_2_6 || UNITY_2_6_1 || UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_4_0 || UNITY_4_0_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_5
#define UNITY
#endif
using System;
using System.Collections.Generic;
#if UNITY
using UnityEngine;
#endif
namespace LibBSP.Doom {
#if !UNITY
using Vector3 = Vector3d;
#endif
/// <summary>
/// Holds all the data for a node in a Doom map.
/// </summary>
/// <remarks>
/// This is the one lump that has a structure similar to future BSPs.
/// </remarks>
public struct Node {
// This format uses a vector head and tail for partitioning, rather
// than the 3D plane conventionally used by more modern engines.
// The "tail" is actually a change in X and Y, rather than an explicitly defined point.
public Vector3 vecHead { get; private set; }
public Vector3 vecTail { get; private set; }
// These rectangles are defined by
// Top, Bottom, Left, Right. That's YMax, YMin, XMin, XMax, in that order
public Rect RRectangle { get; private set; }
public Rect LRectangle { get; private set; }
public short RChild { get; private set; }
public short LChild { get; private set; }
/// <summary>
/// Creates a new <c>Node</c> 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>
/// <exception cref="ArgumentNullException"><paramref name="data" /> was null</exception>
public Node(byte[] data, MapType type) : this() {
if (data == null) {
throw new ArgumentNullException();
}
vecHead = new Vector3(BitConverter.ToInt16(data, 0), BitConverter.ToInt16(data, 2));
vecTail = new Vector3(BitConverter.ToInt16(data, 4), BitConverter.ToInt16(data, 6));
RRectangle = Rect.MinMaxRect(BitConverter.ToInt16(data, 12), BitConverter.ToInt16(data, 8), BitConverter.ToInt16(data, 14), BitConverter.ToInt16(data, 10));
LRectangle = Rect.MinMaxRect(BitConverter.ToInt16(data, 20), BitConverter.ToInt16(data, 16), BitConverter.ToInt16(data, 22), BitConverter.ToInt16(data, 18));
this.RChild = BitConverter.ToInt16(data, 24);
this.LChild = BitConverter.ToInt16(data, 26);
}
/// <summary>
/// Factory method to parse a <c>byte</c> array into a <c>List</c> of <c>Node</c> objects.
/// </summary>
/// <param name="data">The data to parse</param>
/// <param name="type">The map type</param>
/// <returns>A <c>List</c> of <c>Node</c> objects</returns>
/// <exception cref="ArgumentNullException"><paramref name="data" /> was null</exception>
public static List<Node> LumpFactory(byte[] data, MapType type) {
if (data == null) {
throw new ArgumentNullException();
}
int structLength = 28;
List<Node> lump = new List<Node>(data.Length / structLength);
byte[] bytes = new byte[structLength];
for (int i = 0; i < data.Length / structLength; ++i) {
Array.Copy(data, i * structLength, bytes, 0, structLength);
lump.Add(new Node(bytes, type));
}
return lump;
}
}
}

View File

@@ -1,59 +0,0 @@
using System;
using System.Collections.Generic;
namespace LibBSP.Doom {
/// <summary>
/// Contains all necessary information for a Doom SECTOR object.
/// </summary>
/// <remarks>
/// The sector defines an area, the heights of the floor and cieling
/// of the area, the floor and cieling textures, the light level, the
/// type of sector and a tag number.
/// </remarks>
public struct Sector {
public short floor { get; private set; }
public short cieling { get; private set; }
public string floorTexture { get; private set; }
public string cielingTexture { get; private set; }
public short light { get; private set; }
public short type { get; private set; }
public short tag { get; private set; }
/// <summary>
/// Creates a new <c>Sector</c> 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>
/// <exception cref="ArgumentNullException"><paramref name="data" /> was null</exception>
public Sector(byte[] data, MapType type) : this() {
this.floor = BitConverter.ToInt16(data, 0);
this.cieling = BitConverter.ToInt16(data, 2);
this.floorTexture = data.ToNullTerminatedString(4, 8);
this.cielingTexture = data.ToNullTerminatedString(12, 8);
this.light = BitConverter.ToInt16(data, 20);
this.type = BitConverter.ToInt16(data, 22);
this.tag = BitConverter.ToInt16(data, 24);
}
/// <summary>
/// Factory method to parse a <c>byte</c> array into a <c>List</c> of <c>Sector</c> objects.
/// </summary>
/// <param name="data">The data to parse</param>
/// <param name="type">The map type</param>
/// <returns>A <c>List</c> of <c>Sector</c> objects</returns>
/// <exception cref="ArgumentNullException"><paramref name="data" /> was null</exception>
public static List<Sector> LumpFactory(byte[] data, MapType type) {
int structLength = 26;
List<Sector> lump = new List<Sector>(data.Length / structLength);
byte[] bytes = new byte[structLength];
for (int i = 0; i < data.Length / structLength; ++i) {
Array.Copy(data, i * structLength, bytes, 0, structLength);
lump.Add(new Sector(bytes, type));
}
return lump;
}
}
}

View File

@@ -1,58 +0,0 @@
using System;
using System.Collections.Generic;
namespace LibBSP.Doom {
/// <summary>
/// This class holds data of a single Doom line Segment
/// </summary>
public struct Segment {
public short startVertex { get; private set; }
public short endVertex { get; private set; }
public short angle { get; private set; }
public short lineDef { get; private set; }
// 0 for right side of linedef, 1 for left
public short direction { get; private set; }
public short dist { get; private set; }
/// <summary>
/// Creates a new <c>Segment</c> 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>
/// <exception cref="ArgumentNullException"><paramref name="data" /> was null</exception>
public Segment(byte[] data, MapType type) : this() {
if (data == null) {
throw new ArgumentNullException();
}
this.startVertex = BitConverter.ToInt16(data, 0);
this.endVertex = BitConverter.ToInt16(data, 2);
this.angle = BitConverter.ToInt16(data, 4);
this.lineDef = BitConverter.ToInt16(data, 6);
this.direction = BitConverter.ToInt16(data, 8);
this.dist = BitConverter.ToInt16(data, 10);
}
/// <summary>
/// Factory method to parse a <c>byte</c> array into a <c>List</c> of <c>Segment</c> objects.
/// </summary>
/// <param name="data">The data to parse</param>
/// <param name="type">The map type</param>
/// <returns>A <c>List</c> of <c>Segment</c> objects</returns>
/// <exception cref="ArgumentNullException"><paramref name="data" /> was null</exception>
public static List<Segment> LumpFactory(byte[] data, MapType type) {
if (data == null) {
throw new ArgumentNullException();
}
int structLength = 12;
List<Segment> lump = new List<Segment>(data.Length / structLength);
byte[] bytes = new byte[structLength];
for (int i = 0; i < data.Length / structLength; ++i) {
Array.Copy(data, i * structLength, bytes, 0, structLength);
lump.Add(new Segment(bytes, type));
}
return lump;
}
}
}

View File

@@ -1,70 +0,0 @@
#if UNITY_2_6 || UNITY_2_6_1 || UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_4_0 || UNITY_4_0_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_5
#define UNITY
#endif
using System;
using System.Collections.Generic;
#if UNITY
using UnityEngine;
#endif
namespace LibBSP.Doom {
#if !UNITY
using Vector2 = Vector2d;
#endif
/// <summary>
/// Contains all necessary information for a Doom SIDEDEF object.
/// </summary>
/// <remarks>
/// The sidedef is roughly equivalent to the Face (or surface)
/// object in later BSP versions.
/// </remarks>
public struct Sidedef {
public Vector2 offsets { get; private set; }
public string highTexture { get; private set; }
public string midTexture { get; private set; }
public string lowTexture { get; private set; }
public short sector { get; private set; }
/// <summary>
/// Creates a new <c>Sidedef</c> 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>
/// <exception cref="ArgumentNullException"><paramref name="data" /> was null</exception>
public Sidedef(byte[] data, MapType type) : this() {
if (data == null) {
throw new ArgumentNullException();
}
offsets = new Vector2(BitConverter.ToInt16(data, 0), BitConverter.ToInt16(data, 2));
highTexture = data.ToNullTerminatedString(4, 8);
midTexture = data.ToNullTerminatedString(12, 8);
lowTexture = data.ToNullTerminatedString(20, 8);
sector = BitConverter.ToInt16(data, 28);
}
/// <summary>
/// Factory method to parse a <c>byte</c> array into a <c>List</c> of <c>Sidedef</c> objects.
/// </summary>
/// <param name="data">The data to parse</param>
/// <param name="type">The map type</param>
/// <returns>A <c>List</c> of <c>Sidedef</c> objects</returns>
/// <exception cref="ArgumentNullException"><paramref name="data" /> was null</exception>
public static List<Sidedef> LumpFactory(byte[] data, MapType type) {
if (data == null) {
throw new ArgumentNullException();
}
int structLength = 30;
List<Sidedef> lump = new List<Sidedef>(data.Length / structLength);
byte[] bytes = new byte[structLength];
for (int i = 0; i < data.Length / structLength; ++i) {
Array.Copy(data, i * structLength, bytes, 0, structLength);
lump.Add(new Sidedef(bytes, type));
}
return lump;
}
}
}

View File

@@ -1,104 +0,0 @@
#if UNITY_2_6 || UNITY_2_6_1 || UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_4_0 || UNITY_4_0_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_5
#define UNITY
#endif
using System;
using System.Collections.Generic;
#if UNITY
using UnityEngine;
#endif
namespace LibBSP.Doom {
#if !UNITY
using Vector2 = Vector2d;
using Vector3 = Vector3d;
#endif
/// <summary>
/// Contains all necessary information for a Doom THING object. Essentially Doom's entities.
/// </summary>
public struct Thing {
public Vector3 origin { get; private set; }
public short angle { get; private set; }
public short classNum { get; private set; }
public short flags { get; private set; }
public short id { get; private set; }
public byte action { get; private set; }
public byte[] arguments { get; private set; }
/// <summary>
/// Creates a new <c>Thing</c> 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>
/// <exception cref="ArgumentNullException"><paramref name="data" /> was null</exception>
/// <exception cref="ArgumentException">This structure is not implemented for the given maptype</exception>
public Thing(byte[] data, MapType type) : this() {
if (data == null) {
throw new ArgumentNullException();
}
switch (type) {
case MapType.Doom: {
origin = new Vector2(BitConverter.ToInt16(data, 0), BitConverter.ToInt16(data, 2));
this.angle = BitConverter.ToInt16(data, 4);
this.classNum = BitConverter.ToInt16(data, 6);
this.flags = BitConverter.ToInt16(data, 8);
break;
}
case MapType.Hexen: {
id = BitConverter.ToInt16(data, 0);
origin = new Vector3(BitConverter.ToInt16(data, 2), BitConverter.ToInt16(data, 4), BitConverter.ToInt16(data, 6));
this.angle = BitConverter.ToInt16(data, 8);
this.classNum = BitConverter.ToInt16(data, 10);
this.flags = BitConverter.ToInt16(data, 12);
action = data[14];
arguments[0] = data[15];
arguments[1] = data[16];
arguments[2] = data[17];
arguments[3] = data[18];
arguments[4] = data[19];
break;
}
default: {
throw new ArgumentException("Map type " + type + " isn't supported by the Thing class.");
}
}
}
/// <summary>
/// Factory method to parse a <c>byte</c> array into a <c>List</c> of <c>Thing</c> objects.
/// </summary>
/// <param name="data">The data to parse</param>
/// <param name="type">The map type</param>
/// <returns>A <c>List</c> of <c>Thing</c> 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<Thing> LumpFactory(byte[] data, MapType type) {
if (data == null) {
throw new ArgumentNullException();
}
int structLength = 0;
switch (type) {
case MapType.Doom: {
structLength = 10;
break;
}
case MapType.Hexen: {
structLength = 20;
break;
}
default: {
throw new ArgumentException("Map type " + type + " isn't supported by the Thing lump factory.");
}
}
List<Thing> lump = new List<Thing>(data.Length / structLength);
byte[] bytes = new byte[structLength];
for (int i = 0; i < data.Length / structLength; ++i) {
Array.Copy(data, i * structLength, bytes, 0, structLength);
lump.Add(new Thing(bytes, type));
}
return lump;
}
}
}

View File

@@ -12,15 +12,20 @@ namespace LibBSP {
private bool _bigEndian = false;
// Decryption key for Tactical Intervention; should be 32 bytes
/// <summary>
/// An XOr encryption key for encrypted map formats. Must be read and set.
/// </summary>
private byte[] key = new byte[0];
public bool bigEndian { get { return _bigEndian; } }
/// <summary>
/// Was this map determined to be in big endian format?
/// </summary>
public bool bigEndian { get { return _bigEndian; } set { _bigEndian = value; } }
/// <summary>
/// Creates a new instance of a <c>BSPReader</c> class to read the specified file.
/// </summary>
/// <param name="file"></param>
/// <param name="file">The <c>FileInfo</c> representing the file this <c>BSPReader</c> should read.</param>
public BSPReader(FileInfo file) {
if (!File.Exists(file.FullName)) {
throw new FileNotFoundException("Unable to open BSP file; file " + file.FullName + " not found.");
@@ -33,9 +38,9 @@ namespace LibBSP {
/// <summary>
/// Reads this lump in the map.
/// </summary>
/// <param name="index">The index of the lump to get</param>
/// <param name="version">The version of BSP this is</param>
/// <returns>Array of bytes read from the BSP file</returns>
/// <param name="index">The index of the lump to get.</param>
/// <param name="version">The version of BSP this is.</param>
/// <returns>Array of bytes read from the BSP file.</returns>
public byte[] ReadLumpNum(int index, MapType version) {
switch (version) {
case MapType.Quake:
@@ -105,9 +110,9 @@ namespace LibBSP {
/// Returns the lump referenced by the offset/length pair at the specified <paramref name="offset"/>,
/// read as two Int32.
/// </summary>
/// <param name="offset">The byte offset for the offset/length pair</param>
/// <param name="version">The version of BSP this is</param>
/// <returns>Array of bytes read from the BSP file</returns>
/// <param name="offset">The byte offset for the offset/length pair.</param>
/// <param name="version">The version of BSP this is.</param>
/// <returns>Array of bytes read from the BSP file.</returns>
private byte[] ReadLumpFromOffsetLengthPairAtOffset(int offset, MapType version) {
stream.Seek(offset, SeekOrigin.Begin);
byte[] input = binaryReader.ReadBytes(12);
@@ -135,12 +140,12 @@ namespace LibBSP {
}
/// <summary>
/// Reads the lump <paramref name="length"/> bytes long at <paramref name="offset"/> in the file
/// Reads the lump <paramref name="length"/> bytes long at <paramref name="offset"/> in the file.
/// </summary>
/// <param name="offset">Offset to start reading from</param>
/// <param name="length">Length of the lump to read</param>
/// <param name="version">The version of BSP this is</param>
/// <returns>Array of bytes read from the BSP file</returns>
/// <param name="offset">Offset to start reading from.</param>
/// <param name="length">Length of the lump to read.</param>
/// <param name="version">The version of BSP this is.</param>
/// <returns>Array of bytes read from the BSP file.</returns>
public byte[] ReadLump(int offset, int length, MapType version) {
stream.Seek(offset, SeekOrigin.Begin);
byte[] input = binaryReader.ReadBytes(length);
@@ -153,10 +158,10 @@ namespace LibBSP {
/// <summary>
/// Xors the <paramref name="data"/> <c>byte</c> array with the localls stored key <c>byte</c> array, starting at a certain <paramref name="index"/> in the key.
/// </summary>
/// <param name="data">The byte array to Xor</param>
/// <param name="index">The index in the key byte array to start reading from</param>
/// <returns>The input <c>byte</c> array Xored with the key <c>byte</c> array</returns>
/// <exception cref="ArgumentNullException">The passed <paramref name="data"/> parameter was null</exception>
/// <param name="data">The byte array to Xor.</param>
/// <param name="index">The index in the key byte array to start reading from.</param>
/// <returns>The input <c>byte</c> array Xored with the key <c>byte</c> array.</returns>
/// <exception cref="ArgumentNullException">The passed <paramref name="data"/> parameter was null.</exception>
private byte[] XorWithKeyStartingAtIndex(byte[] data, int index = 0) {
if (data == null) {
throw new ArgumentNullException();
@@ -175,7 +180,7 @@ namespace LibBSP {
/// Tries to get the <c>MapType</c> member most closely represented by the referenced file. If the file is
/// found to be big-endian, this will set <c>bigEndian</c> to <c>true</c>.
/// </summary>
/// <returns>The <c>MapType</c> of this BSP, <c>MapType.Undefined</c> if it could not be determined</returns>
/// <returns>The <c>MapType</c> of this BSP, <c>MapType.Undefined</c> if it could not be determined.</returns>
public MapType GetVersion() {
MapType ret = GetVersion(false);
if (ret == MapType.Undefined) {
@@ -190,8 +195,8 @@ namespace LibBSP {
/// <summary>
/// Tries to get the <c>MapType</c> member most closely represented by the referenced file.
/// </summary>
/// <param name="bigEndian">Set to <c>true</c> to attempt reading the data in big-endian byte order</param>
/// <returns>The <c>MapType</c> of this BSP, <c>MapType.Undefined</c> if it could not be determined</returns>
/// <param name="bigEndian">Set to <c>true</c> to attempt reading the data in big-endian byte order.</param>
/// <returns>The <c>MapType</c> of this BSP, <c>MapType.Undefined</c> if it could not be determined.</returns>
private MapType GetVersion(bool bigEndian) {
MapType current = MapType.Undefined;
stream.Seek(0, SeekOrigin.Begin);