Fix incorrect and missing data access in StaticProp.

Add constructor to StaticProp to copy another StaticProp using any given format.
This commit is contained in:
wfowler
2021-04-19 00:33:14 -06:00
parent 459212a861
commit 070a6565e0

View File

@@ -89,16 +89,17 @@ namespace LibBSP {
return new Vector3(BitConverter.ToSingle(Data, 0), BitConverter.ToSingle(Data, 4), BitConverter.ToSingle(Data, 8));
}
default: {
return new Vector3(float.NaN, float.NaN, float.NaN);
return new Vector3(0, 0, 0);
}
}
}
default: {
return new Vector3(float.NaN, float.NaN, float.NaN);
return new Vector3(0, 0, 0);
}
}
}
set {
byte[] bytes = value.GetBytes();
switch (MapType) {
case MapType.Source17:
case MapType.Source18:
@@ -123,7 +124,7 @@ namespace LibBSP {
case 10:
case 11:
case 12: {
value.GetBytes().CopyTo(Data, 0);
bytes.CopyTo(Data, 0);
break;
}
}
@@ -165,16 +166,17 @@ namespace LibBSP {
return new Vector3(BitConverter.ToSingle(Data, 12), BitConverter.ToSingle(Data, 16), BitConverter.ToSingle(Data, 20));
}
default: {
return new Vector3(float.NaN, float.NaN, float.NaN);
return new Vector3(0, 0, 0);
}
}
}
default: {
return new Vector3(float.NaN, float.NaN, float.NaN);
return new Vector3(0, 0, 0);
}
}
}
set {
byte[] bytes = value.GetBytes();
switch (MapType) {
case MapType.Source17:
case MapType.Source18:
@@ -199,7 +201,7 @@ namespace LibBSP {
case 10:
case 11:
case 12: {
value.GetBytes().CopyTo(Data, 12);
bytes.CopyTo(Data, 12);
break;
}
}
@@ -863,9 +865,9 @@ namespace LibBSP {
}
case 9: {
if (Data.Length == 76) {
bytes.CopyTo(Data, 36);
bytes.CopyTo(Data, 44);
} else {
bytes.CopyTo(Data, 32);
bytes.CopyTo(Data, 40);
}
break;
}
@@ -914,12 +916,12 @@ namespace LibBSP {
}
}
default: {
return new Vector3(float.NaN, float.NaN, float.NaN);
return new Vector3(0, 0, 0);
}
}
}
default: {
return new Vector3(float.NaN, float.NaN, float.NaN);
return new Vector3(0, 0, 0);
}
}
}
@@ -953,9 +955,9 @@ namespace LibBSP {
}
case 9: {
if (Data.Length == 76) {
value.GetBytes().CopyTo(Data, 48);
bytes.CopyTo(Data, 48);
} else {
value.GetBytes().CopyTo(Data, 44);
bytes.CopyTo(Data, 44);
}
break;
}
@@ -1537,6 +1539,7 @@ namespace LibBSP {
}
}
set {
byte[] bytes = value.GetBytes();
switch (MapType) {
case MapType.Source17:
case MapType.Source18:
@@ -1557,14 +1560,14 @@ namespace LibBSP {
case 10:
case 11:
case 12: {
value.GetBytes().CopyTo(Data, 64);
bytes.CopyTo(Data, 64);
break;
}
case 9: {
if (Data.Length == 76) {
value.GetBytes().CopyTo(Data, 69);
bytes.CopyTo(Data, 69);
} else {
value.GetBytes().CopyTo(Data, 64);
bytes.CopyTo(Data, 64);
}
break;
}
@@ -1666,11 +1669,14 @@ namespace LibBSP {
case 5:
case 6: {
if (Data.Length > 128) {
// Zero out the bytes
for (int i = 0; i < 128; ++i) {
Data[Data.Length - i - 1] = 0;
}
byte[] strBytes = Encoding.ASCII.GetBytes(value);
Array.Copy(strBytes, 0, Data, Data.Length - 128, Math.Min(strBytes.Length, 127));
if (value != null) {
byte[] strBytes = Encoding.ASCII.GetBytes(value);
Array.Copy(strBytes, 0, Data, Data.Length - 128, Math.Min(strBytes.Length, 127));
}
}
break;
}
@@ -1695,6 +1701,62 @@ namespace LibBSP {
Data = data;
Parent = parent;
}
/// <summary>
/// Creates a new <see cref="StaticProp"/> by copying the fields in <paramref name="source"/>, using
/// <paramref name="parent"/> to get <see cref="LibBSP.MapType"/> and <see cref="LumpInfo.version"/>
/// to use when creating the new <see cref="StaticProp"/>.
/// If the <paramref name="parent"/>'s <see cref="BSP"/>'s <see cref="LibBSP.MapType"/> is different from
/// the one from <paramref name="source"/>, it does not matter, because fields are copied by name.
/// </summary>
/// <param name="source">The <see cref="Model"/> to copy.</param>
/// <param name="parent">
/// The <see cref="ILump"/> to use as the <see cref="Parent"/> of the new <see cref="Model"/>.
/// Use <c>null</c> to use the <paramref name="source"/>'s <see cref="Parent"/> instead.
/// </param>
public StaticProp(StaticProp 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?.Bsp != null) {
// Data = new byte[GetStructLength(source.Parent.Bsp.version, source.Parent.LumpInfo.version)];
//} else {
// Data = new byte[GetStructLength(MapType.Undefined, 0)];
//}
}
Data = new byte[192]; // Maximum known length. GetStructLength doesn't have enough information currently.
Origin = source.Origin;
Angles = source.Angles;
ModelIndex = source.ModelIndex;
FirstLeafIndexIndex = source.FirstLeafIndexIndex;
NumLeafIndices = source.NumLeafIndices;
Solidity = source.Solidity;
Flags = source.Flags;
Skin = source.Skin;
MinimumFadeDistance = source.MinimumFadeDistance;
MaximumFadeDistance = source.MaximumFadeDistance;
LightingOrigin = source.LightingOrigin;
ForcedFadeScale = source.ForcedFadeScale;
MinimumDirectXLevel = source.MinimumDirectXLevel;
MaximumDirectXLevel = source.MaximumDirectXLevel;
MinimumCPULevel = source.MinimumCPULevel;
MaximumCPULevel = source.MaximumCPULevel;
MinimumGPULevel = source.MinimumGPULevel;
MaximumGPULevel = source.MaximumGPULevel;
DiffuseModulaton = source.DiffuseModulaton;
Scale = source.Scale;
Name = source.Name;
}
/// <summary>
/// Factory method to parse a <c>byte</c> array into a <see cref="StaticProps"/> object.