diff --git a/LibBSP/Source/Structs/BSP/Face.cs b/LibBSP/Source/Structs/BSP/Face.cs
index b6c2f49..9dbab67 100644
--- a/LibBSP/Source/Structs/BSP/Face.cs
+++ b/LibBSP/Source/Structs/BSP/Face.cs
@@ -13,16 +13,22 @@ using System.Reflection;
namespace LibBSP {
#if UNITY
+ using Color = UnityEngine.Color32;
using Vector2 = UnityEngine.Vector2;
+ using Vector3 = UnityEngine.Vector3;
using Plane = UnityEngine.Plane;
#if !OLDUNITY
using Vertex = UnityEngine.UIVertex;
#endif
#elif GODOT
+ using Color = Godot.Color;
using Vector2 = Godot.Vector2;
+ using Vector3 = Godot.Vector3;
using Plane = Godot.Plane;
#else
+ using Color = System.Drawing.Color;
using Vector2 = System.Numerics.Vector2;
+ using Vector3 = System.Numerics.Vector3;
using Plane = System.Numerics.Plane;
#endif
@@ -219,6 +225,62 @@ namespace LibBSP {
}
}
+ ///
+ /// Does the lie on a node?
+ ///
+ public bool IsOnNode {
+ get {
+ switch (MapType) {
+ 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.TacticalInterventionEncrypted:
+ case MapType.DMoMaM: {
+ return Data[3] > 0;
+ }
+ case MapType.Vindictus: {
+ return Data[5] > 0;
+ }
+ case MapType.Source17: {
+ return Data[35] > 0;
+ }
+ default: {
+ return false;
+ }
+ }
+ }
+ set {
+ switch (MapType) {
+ 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.TacticalInterventionEncrypted:
+ case MapType.DMoMaM: {
+ Data[3] = (byte)(value ? 1 : 0);
+ break;
+ }
+ case MapType.Vindictus: {
+ Data[5] = (byte)(value ? 1 : 0);
+ break;
+ }
+ case MapType.Source17: {
+ Data[35] = (byte)(value ? 1 : 0);
+ break;
+ }
+ }
+ }
+ }
+
///
/// For formats which use s, enumerates the indices referenced
/// by this . A negative index means the is used backward from
@@ -677,7 +739,32 @@ namespace LibBSP {
}
}
}
-
+
+ ///
+ /// Gets or sets the index of the used for lightmaps by this .
+ ///
+ public int LightmapTextureInfoIndex {
+ get {
+ switch (MapType) {
+ case MapType.Nightfire: {
+ return BitConverter.ToInt32(Data, 32);
+ }
+ default: {
+ return -1;
+ }
+ }
+ }
+ set {
+ byte[] bytes = BitConverter.GetBytes(value);
+ switch (MapType) {
+ case MapType.Nightfire: {
+ bytes.CopyTo(Data, 32);
+ break;
+ }
+ }
+ }
+ }
+
///
/// Gets or sets the index of the using this .
///
@@ -737,6 +824,65 @@ namespace LibBSP {
}
}
+ ///
+ /// Gets or sets the surface fog volume ID of this .
+ ///
+ public int SurfaceFogVolumeID {
+ get {
+ switch (MapType) {
+ 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.TacticalInterventionEncrypted:
+ case MapType.DMoMaM: {
+ return BitConverter.ToInt16(Data, 14);
+ }
+ case MapType.Vindictus: {
+ return BitConverter.ToInt32(Data, 24);
+ }
+ case MapType.Source17: {
+ return BitConverter.ToInt16(Data, 46);
+ }
+ default: {
+ return -1;
+ }
+ }
+ }
+ set {
+ byte[] bytes = BitConverter.GetBytes(value);
+ switch (MapType) {
+ 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.TacticalInterventionEncrypted:
+ case MapType.DMoMaM: {
+ Data[14] = bytes[0];
+ Data[15] = bytes[1];
+ break;
+ }
+ case MapType.Vindictus: {
+ bytes.CopyTo(Data, 24);
+ break;
+ }
+ case MapType.Source17: {
+ Data[46] = bytes[0];
+ Data[47] = bytes[1];
+ break;
+ }
+ }
+ }
+ }
+
///
/// Gets the original which was split to create this .
///
@@ -855,6 +1001,47 @@ namespace LibBSP {
}
}
+ ///
+ /// Gets or sets the Effect used by this face.
+ ///
+ public int Effect {
+ get {
+ switch (MapType) {
+ case MapType.Quake3:
+ case MapType.Raven:
+ case MapType.MOHAA:
+ case MapType.STEF2:
+ case MapType.STEF2Demo:
+ case MapType.FAKK: {
+ return BitConverter.ToInt32(Data, 4);
+ }
+
+ default: {
+ return -1;
+ }
+ }
+ }
+ set {
+ byte[] bytes = BitConverter.GetBytes(value);
+ switch (MapType) {
+ case MapType.Quake3:
+ case MapType.Raven:
+ case MapType.MOHAA:
+ case MapType.STEF2:
+ case MapType.STEF2Demo:
+ case MapType.FAKK: {
+ bytes.CopyTo(Data, 4);
+ break;
+ }
+
+ case MapType.Nightfire: {
+ bytes.CopyTo(Data, 20);
+ break;
+ }
+ }
+ }
+ }
+
///
/// For formats which use triangle corner indices, enumerates the indices of
/// objects used by this .
@@ -953,7 +1140,7 @@ namespace LibBSP {
case MapType.CoD2: {
Data[10] = bytes[0];
Data[11] = bytes[1];
- return;
+ break;
}
case MapType.Nightfire: {
bytes.CopyTo(Data, 16);
@@ -962,7 +1149,7 @@ namespace LibBSP {
case MapType.CoD4: {
Data[18] = bytes[0];
Data[19] = bytes[1];
- return;
+ break;
}
case MapType.Quake3:
case MapType.Raven:
@@ -976,14 +1163,324 @@ namespace LibBSP {
}
}
}
+
+ ///
+ /// Gets or sets the average light colors for this in a Source v17 BSP.
+ ///
+ public Color[] AverageLightColors {
+ get {
+ switch (MapType) {
+ case MapType.Source17: {
+ Color[] colors = new Color[8];
+ for (int i = 0; i < colors.Length; ++i) {
+ colors[i] = ColorExtensions.FromArgb(Data[(i * 4) + 3], Data[(i * 4)], Data[(i * 4) + 1], Data[(i * 4) + 2]);
+ }
+ return colors;
+ }
+ default: {
+ return new Color[0];
+ }
+ }
+ }
+ set {
+ switch (MapType) {
+ case MapType.Source17: {
+ for (int i = 0; i < value.Length; ++i) {
+ value[i].GetBytes().CopyTo(Data, i * 4);
+ }
+ break;
+ }
+ }
+ }
+ }
///
/// Gets or sets the flags for lightmap style used by this .
///
- public int LightStyle {
+ public byte[] LightmapStyles {
get {
switch (MapType) {
+ case MapType.Quake:
+ case MapType.Quake2:
+ case MapType.Daikatana: {
+ byte[] bytes = new byte[4];
+ Array.Copy(Data, 12, bytes, 0, bytes.Length);
+ return bytes;
+ }
+ case MapType.SiN: {
+ byte[] bytes = new byte[16];
+ Array.Copy(Data, 12, bytes, 0, bytes.Length);
+ return bytes;
+ }
+ 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.TacticalInterventionEncrypted:
+ case MapType.DMoMaM: {
+ byte[] bytes = new byte[4];
+ Array.Copy(Data, 16, bytes, 0, bytes.Length);
+ return bytes;
+ }
+ case MapType.SoF: {
+ byte[] bytes = new byte[4];
+ Array.Copy(Data, 22, bytes, 0, bytes.Length);
+ return bytes;
+ }
+ case MapType.Vindictus: {
+ byte[] bytes = new byte[8];
+ if (LumpVersion == 2) {
+ Array.Copy(Data, 28, bytes, 0, bytes.Length);
+ } else {
+ Array.Copy(Data, 24, bytes, 0, bytes.Length);
+ }
+ return bytes;
+ }
case MapType.Nightfire: {
+ byte[] bytes = new byte[4];
+ Array.Copy(Data, 40, bytes, 0, bytes.Length);
+ return bytes;
+ }
+ case MapType.Source17: {
+ byte[] bytes = new byte[8];
+ Array.Copy(Data, 48, bytes, 0, bytes.Length);
+ return bytes;
+ }
+ default: {
+ return new byte[0];
+ }
+ }
+ }
+ set {
+ switch (MapType) {
+ case MapType.Quake:
+ case MapType.Quake2:
+ case MapType.Daikatana: {
+ Array.Copy(value, 0, Data, 12, Math.Min(value.Length, 4));
+ break;
+ }
+ case MapType.SiN: {
+ Array.Copy(value, 0, Data, 12, Math.Min(value.Length, 16));
+ break;
+ }
+ 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.TacticalInterventionEncrypted:
+ case MapType.DMoMaM: {
+ Array.Copy(value, 0, Data, 16, Math.Min(value.Length, 4));
+ break;
+ }
+ case MapType.SoF: {
+ Array.Copy(value, 0, Data, 22, Math.Min(value.Length, 4));
+ break;
+ }
+ case MapType.Vindictus: {
+ if (LumpVersion == 2) {
+ Array.Copy(value, 0, Data, 28, Math.Min(value.Length, 8));
+ } else {
+ Array.Copy(value, 0, Data, 24, Math.Min(value.Length, 8));
+ }
+ break;
+ }
+ case MapType.Nightfire: {
+ Array.Copy(value, 0, Data, 40, Math.Min(value.Length, 4));
+ break;
+ }
+ case MapType.Source17: {
+ Array.Copy(value, 0, Data, 48, Math.Min(value.Length, 8));
+ break;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Gets or sets the flags for day lightmap style used by this in a Source v17 BSP.
+ ///
+ public byte[] DayLightStyle {
+ get {
+ switch (MapType) {
+ case MapType.Source17: {
+ byte[] bytes = new byte[8];
+ Array.Copy(Data, 56, bytes, 0, bytes.Length);
+ return bytes;
+ }
+ default: {
+ return new byte[0];
+ }
+ }
+ }
+ set {
+ switch (MapType) {
+ case MapType.Source17: {
+ Array.Copy(value, 0, Data, 56, Math.Min(value.Length, 8));
+ break;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Gets or sets the flags for night lightmap style used by this in a Source v17 BSP.
+ ///
+ public byte[] NightLightStyle {
+ get {
+ switch (MapType) {
+ case MapType.Source17: {
+ byte[] bytes = new byte[8];
+ Array.Copy(Data, 64, bytes, 0, bytes.Length);
+ return bytes;
+ }
+ default: {
+ return new byte[0];
+ }
+ }
+ }
+ set {
+ switch (MapType) {
+ case MapType.Source17: {
+ Array.Copy(value, 0, Data, 64, Math.Min(value.Length, 8));
+ break;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Gets or sets the offset or index into the lightmap data this uses.
+ ///
+ public int Lightmap {
+ get {
+ switch (MapType) {
+ case MapType.CoD:
+ case MapType.CoD2: {
+ return BitConverter.ToInt16(Data, 2);
+ }
+ case MapType.Quake:
+ case MapType.Quake2:
+ case MapType.Daikatana: {
+ return BitConverter.ToInt32(Data, 16);
+ }
+ 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.TacticalInterventionEncrypted:
+ case MapType.DMoMaM: {
+ return BitConverter.ToInt32(Data, 20);
+ }
+ case MapType.SiN:
+ case MapType.SoF:
+ case MapType.Quake3:
+ case MapType.MOHAA:
+ case MapType.STEF2:
+ case MapType.STEF2Demo:
+ case MapType.FAKK: {
+ return BitConverter.ToInt32(Data, 28);
+ }
+ case MapType.Raven: {
+ return BitConverter.ToInt32(Data, 36);
+ }
+ case MapType.Vindictus: {
+ if (LumpVersion == 2) {
+ return BitConverter.ToInt32(Data, 36);
+ } else {
+ return BitConverter.ToInt32(Data, 32);
+ }
+ }
+ case MapType.Nightfire: {
+ return BitConverter.ToInt32(Data, 44);
+ }
+ case MapType.Source17: {
+ return BitConverter.ToInt32(Data, 72);
+ }
+ default: {
+ return -1;
+ }
+ }
+ }
+ set {
+ byte[] bytes = BitConverter.GetBytes(value);
+ switch (MapType) {
+ case MapType.CoD:
+ case MapType.CoD2: {
+ Data[2] = bytes[0];
+ Data[3] = bytes[1];
+ break;
+ }
+ case MapType.Quake:
+ case MapType.Quake2:
+ case MapType.Daikatana: {
+ bytes.CopyTo(Data, 16);
+ break;
+ }
+ case MapType.SiN:
+ case MapType.SoF:
+ case MapType.Quake3:
+ case MapType.STEF2:
+ case MapType.STEF2Demo:
+ case MapType.FAKK: {
+ bytes.CopyTo(Data, 28);
+ break;
+ }
+ 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.TacticalInterventionEncrypted:
+ case MapType.DMoMaM: {
+ bytes.CopyTo(Data, 20);
+ break;
+ }
+ case MapType.Raven: {
+ bytes.CopyTo(Data, 36);
+ break;
+ }
+ case MapType.Vindictus: {
+ if (LumpVersion == 2) {
+ bytes.CopyTo(Data, 36);
+ } else {
+ bytes.CopyTo(Data, 32);
+ }
+ break;
+ }
+ case MapType.Nightfire: {
+ bytes.CopyTo(Data, 44);
+ break;
+ }
+ case MapType.Source17: {
+ bytes.CopyTo(Data, 72);
+ break;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Gets or sets the second index into the lightmap data this uses, in a BSP.
+ ///
+ public int Lightmap2 {
+ get {
+ switch (MapType) {
+ case MapType.Raven: {
return BitConverter.ToInt32(Data, 40);
}
default: {
@@ -994,21 +1491,21 @@ namespace LibBSP {
set {
byte[] bytes = BitConverter.GetBytes(value);
switch (MapType) {
- case MapType.Nightfire: {
+ case MapType.Raven: {
bytes.CopyTo(Data, 40);
break;
}
}
}
}
-
+
///
- /// Gets or sets the offset into the lightmap data this uses.
+ /// Gets or sets the third index into the lightmap data this uses, in a BSP.
///
- public int LightMapOffset {
+ public int Lightmap3 {
get {
switch (MapType) {
- case MapType.Nightfire: {
+ case MapType.Raven: {
return BitConverter.ToInt32(Data, 44);
}
default: {
@@ -1019,16 +1516,506 @@ namespace LibBSP {
set {
byte[] bytes = BitConverter.GetBytes(value);
switch (MapType) {
- case MapType.Nightfire: {
+ case MapType.Raven: {
bytes.CopyTo(Data, 44);
break;
}
}
}
}
-
+
///
- /// Gets the size of the used by this .
+ /// Gets or sets the fourth index into the lightmap data this uses, in a BSP.
+ ///
+ public int Lightmap4 {
+ get {
+ switch (MapType) {
+ case MapType.Raven: {
+ return BitConverter.ToInt32(Data, 48);
+ }
+ default: {
+ return -1;
+ }
+ }
+ }
+ set {
+ byte[] bytes = BitConverter.GetBytes(value);
+ switch (MapType) {
+ case MapType.Raven: {
+ bytes.CopyTo(Data, 48);
+ break;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Gets or sets the area of this .
+ ///
+ public float Area {
+ get {
+ switch (MapType) {
+ 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.TacticalInterventionEncrypted:
+ case MapType.DMoMaM: {
+ return BitConverter.ToSingle(Data, 24);
+ }
+ case MapType.Vindictus: {
+ if (LumpVersion == 2) {
+ return BitConverter.ToSingle(Data, 40);
+ } else {
+ return BitConverter.ToSingle(Data, 36);
+ }
+ }
+ case MapType.Source17: {
+ return BitConverter.ToSingle(Data, 76);
+ }
+ default: {
+ return -1;
+ }
+ }
+ }
+ set {
+ byte[] bytes = BitConverter.GetBytes(value);
+ switch (MapType) {
+ 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.TacticalInterventionEncrypted:
+ case MapType.DMoMaM: {
+ bytes.CopyTo(Data, 24);
+ break;
+ }
+ case MapType.Vindictus: {
+ if (LumpVersion == 2) {
+ bytes.CopyTo(Data, 40);
+ } else {
+ bytes.CopyTo(Data, 36);
+ }
+ break;
+ }
+ case MapType.Source17: {
+ bytes.CopyTo(Data, 76);
+ break;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Gets the lightmap texture mins used by this .
+ ///
+ public Vector2 LightmapStart {
+ get {
+ switch (MapType) {
+ 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.TacticalInterventionEncrypted:
+ case MapType.DMoMaM: {
+ return new Vector2(BitConverter.ToInt32(Data, 28), BitConverter.ToInt32(Data, 32));
+ }
+ case MapType.Quake3:
+ case MapType.MOHAA:
+ case MapType.STEF2:
+ case MapType.STEF2Demo:
+ case MapType.FAKK: {
+ return new Vector2(BitConverter.ToInt32(Data, 32), BitConverter.ToInt32(Data, 36));
+ }
+ case MapType.Vindictus: {
+ if (LumpVersion == 2) {
+ return new Vector2(BitConverter.ToInt32(Data, 44), BitConverter.ToInt32(Data, 48));
+ } else {
+ return new Vector2(BitConverter.ToInt32(Data, 40), BitConverter.ToInt32(Data, 44));
+ }
+ }
+ case MapType.Raven: {
+ return new Vector2(BitConverter.ToInt32(Data, 52), BitConverter.ToInt32(Data, 56));
+ }
+ case MapType.Source17: {
+ return new Vector2(BitConverter.ToInt32(Data, 80), BitConverter.ToInt32(Data, 84));
+ }
+ default: {
+ return new Vector2(0, 0);
+ }
+ }
+ }
+ set {
+ switch (MapType) {
+ 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.TacticalInterventionEncrypted:
+ case MapType.DMoMaM: {
+ value.GetBytes().CopyTo(Data, 28);
+ break;
+ }
+ case MapType.Quake3:
+ case MapType.MOHAA:
+ case MapType.STEF2:
+ case MapType.STEF2Demo:
+ case MapType.FAKK: {
+ value.GetBytes().CopyTo(Data, 32);
+ break;
+ }
+ case MapType.Vindictus: {
+ if (LumpVersion == 2) {
+ value.GetBytes().CopyTo(Data, 44);
+ } else {
+ value.GetBytes().CopyTo(Data, 40);
+ }
+ break;
+ }
+ case MapType.Raven: {
+ value.GetBytes().CopyTo(Data, 52);
+ break;
+ }
+ case MapType.Source17: {
+ value.GetBytes().CopyTo(Data, 80);
+ break;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Gets the second lightmap texture mins used by this , in a BSP.
+ ///
+ public Vector2 Lightmap2Start {
+ get {
+ switch (MapType) {
+ case MapType.Raven: {
+ return new Vector2(BitConverter.ToInt32(Data, 60), BitConverter.ToInt32(Data, 64));
+ }
+ default: {
+ return new Vector2(0, 0);
+ }
+ }
+ }
+ set {
+ switch (MapType) {
+ case MapType.Raven: {
+ value.GetBytes().CopyTo(Data, 60);
+ break;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Gets the third lightmap texture mins used by this , in a BSP.
+ ///
+ public Vector2 Lightmap3Start {
+ get {
+ switch (MapType) {
+ case MapType.Raven: {
+ return new Vector2(BitConverter.ToInt32(Data, 68), BitConverter.ToInt32(Data, 72));
+ }
+ default: {
+ return new Vector2(0, 0);
+ }
+ }
+ }
+ set {
+ switch (MapType) {
+ case MapType.Raven: {
+ value.GetBytes().CopyTo(Data, 68);
+ break;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Gets the fourth lightmap texture mins used by this , in a BSP.
+ ///
+ public Vector2 Lightmap4Start {
+ get {
+ switch (MapType) {
+ case MapType.Raven: {
+ return new Vector2(BitConverter.ToInt32(Data, 76), BitConverter.ToInt32(Data, 80));
+ }
+ default: {
+ return new Vector2(0, 0);
+ }
+ }
+ }
+ set {
+ switch (MapType) {
+ case MapType.Raven: {
+ value.GetBytes().CopyTo(Data, 76);
+ break;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Gets the lightmap texture size used by this in luxels.
+ ///
+ public Vector2 LightmapSize {
+ get {
+ switch (MapType) {
+ 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.TacticalInterventionEncrypted:
+ case MapType.DMoMaM: {
+ return new Vector2(BitConverter.ToInt32(Data, 36), BitConverter.ToInt32(Data, 40));
+ }
+ case MapType.Quake3:
+ case MapType.MOHAA:
+ case MapType.STEF2:
+ case MapType.STEF2Demo:
+ case MapType.FAKK: {
+ return new Vector2(BitConverter.ToInt32(Data, 40), BitConverter.ToInt32(Data, 44));
+ }
+ case MapType.Vindictus: {
+ if (LumpVersion == 2) {
+ return new Vector2(BitConverter.ToInt32(Data, 52), BitConverter.ToInt32(Data, 56));
+ } else {
+ return new Vector2(BitConverter.ToInt32(Data, 48), BitConverter.ToInt32(Data, 52));
+ }
+ }
+ case MapType.Raven: {
+ return new Vector2(BitConverter.ToInt32(Data, 84), BitConverter.ToInt32(Data, 88));
+ }
+ case MapType.Source17: {
+ return new Vector2(BitConverter.ToInt32(Data, 88), BitConverter.ToInt32(Data, 92));
+ }
+ default: {
+ return new Vector2(0, 0);
+ }
+ }
+ }
+ set {
+ switch (MapType) {
+ 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.TacticalInterventionEncrypted:
+ case MapType.DMoMaM: {
+ value.GetBytes().CopyTo(Data, 36);
+ break;
+ }
+ case MapType.Quake3:
+ case MapType.MOHAA:
+ case MapType.STEF2:
+ case MapType.STEF2Demo:
+ case MapType.FAKK: {
+ value.GetBytes().CopyTo(Data, 40);
+ break;
+ }
+ case MapType.Vindictus: {
+ if (LumpVersion == 2) {
+ value.GetBytes().CopyTo(Data, 52);
+ } else {
+ value.GetBytes().CopyTo(Data, 48);
+ }
+ break;
+ }
+ case MapType.Raven: {
+ value.GetBytes().CopyTo(Data, 84);
+ break;
+ }
+ case MapType.Source17: {
+ value.GetBytes().CopyTo(Data, 88);
+ break;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Gets or sets the lightmap origin for this .
+ ///
+ public Vector3 LightmapOrigin {
+ get {
+ switch (MapType) {
+ case MapType.Quake3:
+ case MapType.MOHAA:
+ case MapType.STEF2:
+ case MapType.STEF2Demo:
+ case MapType.FAKK: {
+ return new Vector3(BitConverter.ToSingle(Data, 48), BitConverter.ToSingle(Data, 52), BitConverter.ToSingle(Data, 56));
+ }
+ case MapType.Raven: {
+ return new Vector3(BitConverter.ToSingle(Data, 92), BitConverter.ToSingle(Data, 96), BitConverter.ToSingle(Data, 100));
+ }
+ default: {
+ return new Vector3(0, 0, 0);
+ }
+ }
+ }
+ set {
+ switch (MapType) {
+ case MapType.Quake3:
+ case MapType.MOHAA:
+ case MapType.STEF2:
+ case MapType.STEF2Demo:
+ case MapType.FAKK: {
+ value.GetBytes().CopyTo(Data, 48);
+ break;
+ }
+ case MapType.Raven: {
+ value.GetBytes().CopyTo(Data, 92);
+ break;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Gets or sets the lightmap U axis for this .
+ ///
+ public Vector3 LightmapUAxis {
+ get {
+ switch (MapType) {
+ case MapType.Quake3:
+ case MapType.MOHAA:
+ case MapType.STEF2:
+ case MapType.STEF2Demo:
+ case MapType.FAKK: {
+ return new Vector3(BitConverter.ToSingle(Data, 60), BitConverter.ToSingle(Data, 64), BitConverter.ToSingle(Data, 68));
+ }
+ case MapType.Raven: {
+ return new Vector3(BitConverter.ToSingle(Data, 104), BitConverter.ToSingle(Data, 108), BitConverter.ToSingle(Data, 112));
+ }
+ default: {
+ return new Vector3(0, 0, 0);
+ }
+ }
+ }
+ set {
+ switch (MapType) {
+ case MapType.Quake3:
+ case MapType.MOHAA:
+ case MapType.STEF2:
+ case MapType.STEF2Demo:
+ case MapType.FAKK: {
+ value.GetBytes().CopyTo(Data, 60);
+ break;
+ }
+ case MapType.Raven: {
+ value.GetBytes().CopyTo(Data, 104);
+ break;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Gets or sets the lightmap V Axis for this .
+ ///
+ public Vector3 LightmapVAxis {
+ get {
+ switch (MapType) {
+ case MapType.Quake3:
+ case MapType.MOHAA:
+ case MapType.STEF2:
+ case MapType.STEF2Demo:
+ case MapType.FAKK: {
+ return new Vector3(BitConverter.ToSingle(Data, 72), BitConverter.ToSingle(Data, 76), BitConverter.ToSingle(Data, 80));
+ }
+ case MapType.Raven: {
+ return new Vector3(BitConverter.ToSingle(Data, 116), BitConverter.ToSingle(Data, 120), BitConverter.ToSingle(Data, 124));
+ }
+ default: {
+ return new Vector3(0, 0, 0);
+ }
+ }
+ }
+ set {
+ switch (MapType) {
+ case MapType.Quake3:
+ case MapType.MOHAA:
+ case MapType.STEF2:
+ case MapType.STEF2Demo:
+ case MapType.FAKK: {
+ value.GetBytes().CopyTo(Data, 72);
+ break;
+ }
+ case MapType.Raven: {
+ value.GetBytes().CopyTo(Data, 116);
+ break;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Gets or sets the normal for this .
+ ///
+ public Vector3 Normal {
+ get {
+ switch (MapType) {
+ case MapType.Quake3:
+ case MapType.MOHAA:
+ case MapType.STEF2:
+ case MapType.STEF2Demo:
+ case MapType.FAKK: {
+ return new Vector3(BitConverter.ToSingle(Data, 84), BitConverter.ToSingle(Data, 88), BitConverter.ToSingle(Data, 92));
+ }
+ case MapType.Raven: {
+ return new Vector3(BitConverter.ToSingle(Data, 128), BitConverter.ToSingle(Data, 132), BitConverter.ToSingle(Data, 136));
+ }
+ default: {
+ return new Vector3(0, 0, 0);
+ }
+ }
+ }
+ set {
+ switch (MapType) {
+ case MapType.Quake3:
+ case MapType.MOHAA:
+ case MapType.STEF2:
+ case MapType.STEF2Demo:
+ case MapType.FAKK: {
+ value.GetBytes().CopyTo(Data, 84);
+ break;
+ }
+ case MapType.Raven: {
+ value.GetBytes().CopyTo(Data, 128);
+ break;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Gets or sets the size of the used by this .
///
public Vector2 PatchSize {
get {
@@ -1044,7 +2031,7 @@ namespace LibBSP {
return new Vector2(BitConverter.ToInt32(Data, 140), BitConverter.ToInt32(Data, 144));
}
default: {
- return new Vector2(float.NaN, float.NaN);
+ return new Vector2(0, 0);
}
}
}
@@ -1055,17 +2042,195 @@ namespace LibBSP {
case MapType.STEF2Demo:
case MapType.MOHAA:
case MapType.FAKK: {
- byte[] bytes = BitConverter.GetBytes((int)value.X());
- bytes.CopyTo(Data, 96);
- bytes = BitConverter.GetBytes((int)value.Y());
- bytes.CopyTo(Data, 100);
+ value.GetBytes().CopyTo(Data, 96);
break;
}
case MapType.Raven: {
- byte[] bytes = BitConverter.GetBytes((int)value.X());
- bytes.CopyTo(Data, 140);
- bytes = BitConverter.GetBytes((int)value.Y());
- bytes.CopyTo(Data, 144);
+ value.GetBytes().CopyTo(Data, 140);
+ break;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Gets or sets number of primitives for this .
+ ///
+ public int NumPrimitives {
+ get {
+ switch (MapType) {
+ 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.TacticalInterventionEncrypted:
+ case MapType.DMoMaM: {
+ return BitConverter.ToInt16(Data, 48);
+ }
+ case MapType.Vindictus: {
+ if (LumpVersion == 2) {
+ return BitConverter.ToInt32(Data, 64);
+ } else {
+ return BitConverter.ToInt32(Data, 60);
+ }
+ }
+ default: {
+ return -1;
+ }
+ }
+ }
+ set {
+ byte[] bytes = BitConverter.GetBytes(value);
+ switch (MapType) {
+ 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.TacticalInterventionEncrypted:
+ case MapType.DMoMaM: {
+ Data[48] = bytes[0];
+ Data[49] = bytes[1];
+ break;
+ }
+ case MapType.Vindictus: {
+ if (LumpVersion == 2) {
+ bytes.CopyTo(Data, 64);
+ } else {
+ bytes.CopyTo(Data, 60);
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Gets or sets first primitive used by this .
+ ///
+ public int FirstPrimitive {
+ get {
+ switch (MapType) {
+ 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.TacticalInterventionEncrypted:
+ case MapType.DMoMaM: {
+ return BitConverter.ToInt16(Data, 50);
+ }
+ case MapType.Vindictus: {
+ if (LumpVersion == 2) {
+ return BitConverter.ToInt32(Data, 68);
+ } else {
+ return BitConverter.ToInt32(Data, 64);
+ }
+ }
+ default: {
+ return -1;
+ }
+ }
+ }
+ set {
+ byte[] bytes = BitConverter.GetBytes(value);
+ switch (MapType) {
+ 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.TacticalInterventionEncrypted:
+ case MapType.DMoMaM: {
+ Data[50] = bytes[0];
+ Data[51] = bytes[1];
+ break;
+ }
+ case MapType.Vindictus: {
+ if (LumpVersion == 2) {
+ bytes.CopyTo(Data, 68);
+ } else {
+ bytes.CopyTo(Data, 64);
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Gets or sets the smoothing groups for this .
+ ///
+ public int SmoothingGroups {
+ get {
+ switch (MapType) {
+ 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.TacticalInterventionEncrypted:
+ case MapType.DMoMaM: {
+ return BitConverter.ToInt16(Data, 52);
+ }
+ case MapType.Vindictus: {
+ if (LumpVersion == 2) {
+ return BitConverter.ToInt32(Data, 72);
+ } else {
+ return BitConverter.ToInt32(Data, 68);
+ }
+ }
+ case MapType.Source17: {
+ return BitConverter.ToInt32(Data, 100);
+ }
+ default: {
+ return -1;
+ }
+ }
+ }
+ set {
+ byte[] bytes = BitConverter.GetBytes(value);
+ switch (MapType) {
+ 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.TacticalInterventionEncrypted:
+ case MapType.DMoMaM: {
+ Data[52] = bytes[0];
+ Data[53] = bytes[1];
+ break;
+ }
+ case MapType.Vindictus: {
+ if (LumpVersion == 2) {
+ bytes.CopyTo(Data, 72);
+ } else {
+ bytes.CopyTo(Data, 68);
+ }
+ break;
+ }
+ case MapType.Source17: {
+ bytes.CopyTo(Data, 100);
break;
}
}
@@ -1087,6 +2252,79 @@ namespace LibBSP {
Parent = parent;
}
+ ///
+ /// Creates a new by copying the fields in , using
+ /// to get and
+ /// to use when creating the new .
+ /// If the 's 's is different from
+ /// the one from , it does not matter, because fields are copied by name.
+ ///
+ /// The to copy.
+ ///
+ /// The to use as the of the new .
+ /// Use null to use the 's instead.
+ ///
+ public Face(Face source, ILump parent) {
+ Parent = parent;
+
+ if (parent != null && parent.Bsp != null) {
+ if (source.Parent != null && source.Parent.Bsp != null && source.Parent.Bsp.version == parent.Bsp.version && source.LumpVersion == parent.LumpInfo.version) {
+ Data = new byte[source.Data.Length];
+ Array.Copy(source.Data, Data, source.Data.Length);
+ return;
+ } else {
+ Data = new byte[GetStructLength(parent.Bsp.version, parent.LumpInfo.version)];
+ }
+ } else {
+ if (source.Parent != null && source.Parent.Bsp != null) {
+ Data = new byte[GetStructLength(source.Parent.Bsp.version, source.Parent.LumpInfo.version)];
+ } else {
+ Data = new byte[GetStructLength(MapType.Undefined, 0)];
+ }
+ }
+
+ PlaneIndex = source.PlaneIndex;
+ PlaneSide = source.PlaneSide;
+ IsOnNode = source.IsOnNode;
+ FirstEdgeIndexIndex = source.FirstEdgeIndexIndex;
+ NumEdgeIndices = source.NumEdgeIndices;
+ TextureIndex = source.TextureIndex;
+ FirstVertexIndex = source.FirstVertexIndex;
+ NumVertices = source.NumVertices;
+ MaterialIndex = source.MaterialIndex;
+ TextureInfoIndex = source.TextureInfoIndex;
+ LightmapTextureInfoIndex = source.LightmapTextureInfoIndex;
+ DisplacementIndex = source.DisplacementIndex;
+ SurfaceFogVolumeID = source.SurfaceFogVolumeID;
+ OriginalFaceIndex = source.OriginalFaceIndex;
+ Type = source.Type;
+ Effect = source.Effect;
+ FirstIndexIndex = source.FirstIndexIndex;
+ NumIndices = source.NumIndices;
+ AverageLightColors = source.AverageLightColors;
+ LightmapStyles = source.LightmapStyles;
+ DayLightStyle = source.DayLightStyle;
+ NightLightStyle = source.NightLightStyle;
+ Lightmap = source.Lightmap;
+ Lightmap2 = source.Lightmap2;
+ Lightmap3 = source.Lightmap3;
+ Lightmap4 = source.Lightmap4;
+ Area = source.Area;
+ LightmapStart = source.LightmapStart;
+ Lightmap2Start = source.Lightmap2Start;
+ Lightmap3Start = source.Lightmap3Start;
+ Lightmap4Start = source.Lightmap4Start;
+ LightmapSize = source.LightmapSize;
+ LightmapOrigin = source.LightmapOrigin;
+ LightmapUAxis = source.LightmapUAxis;
+ LightmapVAxis = source.LightmapVAxis;
+ Normal = source.Normal;
+ PatchSize = source.PatchSize;
+ NumPrimitives = source.NumPrimitives;
+ FirstPrimitive = source.FirstPrimitive;
+ SmoothingGroups = source.SmoothingGroups;
+ }
+
///
/// Factory method to parse a byte array into a .
///