mirror of
https://github.com/LazyDuchess/OpenTS2.git
synced 2025-01-22 08:11:47 -05:00
Start adding codecs for OBJM and XOBJ files
This commit is contained in:
parent
53bfe6f3f6
commit
a21b12ffd4
13 changed files with 297 additions and 0 deletions
10
Assets/Scripts/OpenTS2/Content/DBPF/ObjectModuleAsset.cs
Normal file
10
Assets/Scripts/OpenTS2/Content/DBPF/ObjectModuleAsset.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
namespace OpenTS2.Content.DBPF
|
||||
{
|
||||
/// <summary>
|
||||
/// Called cEdithObjectModule in game.
|
||||
/// </summary>
|
||||
public class ObjectModuleAsset : AbstractAsset
|
||||
{
|
||||
|
||||
}
|
||||
}
|
3
Assets/Scripts/OpenTS2/Content/DBPF/ObjectModuleAsset.cs.meta
generated
Normal file
3
Assets/Scripts/OpenTS2/Content/DBPF/ObjectModuleAsset.cs.meta
generated
Normal file
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 88d31fc370514416b28927df14c0e41d
|
||||
timeCreated: 1727972177
|
7
Assets/Scripts/OpenTS2/Content/DBPF/SimsObjectAsset.cs
Normal file
7
Assets/Scripts/OpenTS2/Content/DBPF/SimsObjectAsset.cs
Normal file
|
@ -0,0 +1,7 @@
|
|||
namespace OpenTS2.Content.DBPF
|
||||
{
|
||||
public class SimsObjectAsset : AbstractAsset
|
||||
{
|
||||
|
||||
}
|
||||
}
|
3
Assets/Scripts/OpenTS2/Content/DBPF/SimsObjectAsset.cs.meta
generated
Normal file
3
Assets/Scripts/OpenTS2/Content/DBPF/SimsObjectAsset.cs.meta
generated
Normal file
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ac6c2c1af0484515b3e9c91dc91159dc
|
||||
timeCreated: 1727122236
|
|
@ -0,0 +1,54 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using OpenTS2.Common;
|
||||
using OpenTS2.Content;
|
||||
using OpenTS2.Content.DBPF;
|
||||
using OpenTS2.Files.Utils;
|
||||
using UnityEngine;
|
||||
|
||||
namespace OpenTS2.Files.Formats.DBPF
|
||||
{
|
||||
/// <summary>
|
||||
/// Codec for what is known in game as cEdithObjectModule. Likely a container for different types of objects.
|
||||
/// </summary>
|
||||
[Codec(TypeIDs.OBJM)]
|
||||
public class ObjectModuleCodec : AbstractCodec
|
||||
{
|
||||
public override AbstractAsset Deserialize(byte[] bytes, ResourceKey tgi, DBPFFile sourceFile)
|
||||
{
|
||||
var asset = new ObjectModuleAsset();
|
||||
var stream = new MemoryStream(bytes);
|
||||
var reader = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
// Skip first 64 bytes.
|
||||
reader.Seek(SeekOrigin.Begin, 64);
|
||||
|
||||
// First int, ignored.
|
||||
reader.Seek(SeekOrigin.Current, 4);
|
||||
// Version number.
|
||||
int version = reader.ReadInt32();
|
||||
Debug.Log($"Version: 0x{version:X}");
|
||||
// Type identifier.
|
||||
uint type = reader.ReadUInt32();
|
||||
if (type != 0x4F626A4D)
|
||||
{
|
||||
// Corresponds to the string "ObjM"
|
||||
throw new NotImplementedException("ObjM file does not have `ObjM` magic bytes");
|
||||
}
|
||||
|
||||
// Next is the number of objects.
|
||||
int numObjects = reader.ReadInt32();
|
||||
Debug.Log($"numObjects: {numObjects}");
|
||||
for (var i = 0; i < numObjects; i++)
|
||||
{
|
||||
int selectorSaveType = reader.ReadInt32();
|
||||
int missingObjectSaveType = reader.ReadInt32();
|
||||
|
||||
Debug.Log($"selectorSaveType: {selectorSaveType}, missingObjectSaveType: {missingObjectSaveType}");
|
||||
break;
|
||||
}
|
||||
|
||||
return asset;
|
||||
}
|
||||
}
|
||||
}
|
3
Assets/Scripts/OpenTS2/Files/Formats/DBPF/ObjectModuleCodec.cs.meta
generated
Normal file
3
Assets/Scripts/OpenTS2/Files/Formats/DBPF/ObjectModuleCodec.cs.meta
generated
Normal file
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a49ebb5f202a4e24a7d135e40c194bc8
|
||||
timeCreated: 1727969785
|
|
@ -5,6 +5,7 @@ using OpenTS2.Common;
|
|||
using OpenTS2.Content;
|
||||
using OpenTS2.Content.DBPF;
|
||||
using OpenTS2.Files.Utils;
|
||||
using UnityEngine;
|
||||
|
||||
namespace OpenTS2.Files.Formats.DBPF
|
||||
{
|
||||
|
|
155
Assets/Scripts/OpenTS2/Files/Formats/DBPF/SimsObjectCodec.cs
Normal file
155
Assets/Scripts/OpenTS2/Files/Formats/DBPF/SimsObjectCodec.cs
Normal file
|
@ -0,0 +1,155 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using OpenTS2.Common;
|
||||
using OpenTS2.Content;
|
||||
using OpenTS2.Content.DBPF;
|
||||
using OpenTS2.Files.Utils;
|
||||
using UnityEngine;
|
||||
|
||||
namespace OpenTS2.Files.Formats.DBPF
|
||||
{
|
||||
/// <summary>
|
||||
/// Codec for what is known in game as cTSObject. Contains attributes and locations of objects.
|
||||
/// </summary>
|
||||
[Codec(TypeIDs.XOBJ)]
|
||||
public class SimsObjectCodec : AbstractCodec
|
||||
{
|
||||
public override AbstractAsset Deserialize(byte[] bytes, ResourceKey tgi, DBPFFile sourceFile)
|
||||
{
|
||||
var asset = new SimsObjectAsset();
|
||||
var stream = new MemoryStream(bytes);
|
||||
var reader = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
// Skip first 64 bytes.
|
||||
reader.Seek(SeekOrigin.Begin, 64);
|
||||
|
||||
// TODO: this is for versions = 0xAD, see if we need to handle lower.
|
||||
|
||||
// 4 skipped/unused floats
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
reader.ReadFloat();
|
||||
}
|
||||
|
||||
var tileLocationY = reader.ReadFloat();
|
||||
var tileLocationX = reader.ReadFloat();
|
||||
var level = reader.ReadInt32();
|
||||
// ignored int16
|
||||
reader.ReadUInt16();
|
||||
var elevation = reader.ReadFloat();
|
||||
var objectGroupId = reader.ReadInt32();
|
||||
var unknown = reader.ReadInt16();
|
||||
|
||||
Debug.Log($"tileLocationY: {tileLocationY}, tileLocationX: {tileLocationX}, level: {level}, " +
|
||||
$"elevation: {elevation}, objectGroupId: {objectGroupId}, unknown: {unknown}");
|
||||
|
||||
var numAttrs = reader.ReadInt16();
|
||||
var attrs = new short[numAttrs];
|
||||
for (var i = 0; i < numAttrs; i++)
|
||||
{
|
||||
attrs[i] = reader.ReadInt16();
|
||||
}
|
||||
Debug.Log($"numAttrs: {numAttrs}, attrs: [{string.Join(", ", attrs)}]");
|
||||
|
||||
var numSemiAttrs = reader.ReadInt16();
|
||||
var semiAttrs = new short[numSemiAttrs];
|
||||
for (var i = 0; i < numSemiAttrs; i++)
|
||||
{
|
||||
semiAttrs[i] = reader.ReadInt16();
|
||||
}
|
||||
Debug.Log($"numSemiAttrs: {numAttrs}, semiAttrs: [{string.Join(", ", semiAttrs)}]");
|
||||
|
||||
Debug.Log($" Data array offset: {reader.Position:X}");
|
||||
|
||||
/*
|
||||
// 8 unknown shorts called "data".
|
||||
var dataArray = new short[8];
|
||||
for (var i = 0; i < dataArray.Length; i++)
|
||||
{
|
||||
dataArray[i] = reader.ReadInt16();
|
||||
}
|
||||
Debug.Log($"dataArray: [{string.Join(", ", dataArray)}]");
|
||||
|
||||
// Next is a number of shorts that depends on the exact version of the file.
|
||||
uint numShorts = 0x57 + 6;
|
||||
for (var i = 0; i < numShorts; i++)
|
||||
{
|
||||
reader.ReadInt16();
|
||||
}
|
||||
|
||||
// Another 8 shorts, called the "tempTokenFields".
|
||||
for (var i = 0; i < 8; i++)
|
||||
{
|
||||
reader.ReadInt16();
|
||||
}
|
||||
|
||||
// Next is the number of object arrays. Each being a short array itself.
|
||||
var numObjectArrays = reader.ReadInt16();
|
||||
var shortArrays = new List<short[]>(numObjectArrays);
|
||||
for (var i = 0; i < numObjectArrays; i++)
|
||||
{
|
||||
var objectArray = new short[reader.ReadInt16()];
|
||||
for (var j = 0; j < objectArray.Length; j++)
|
||||
{
|
||||
objectArray[j] = reader.ReadInt16();
|
||||
}
|
||||
shortArrays.Add(objectArray);
|
||||
}
|
||||
Debug.Log($"numObjectArrays: {numObjectArrays}");
|
||||
|
||||
// An array of shorts. Unknown.
|
||||
var numSecondShortArray = reader.ReadInt16();
|
||||
for (var i = 0; i < numSecondShortArray; i++)
|
||||
{
|
||||
reader.ReadInt16();
|
||||
}
|
||||
Debug.Log($"numSecondShortArrays: {numSecondShortArray}");
|
||||
|
||||
var ownershipValue = reader.ReadInt32();
|
||||
Debug.Log($"ownershipValue: {ownershipValue}");
|
||||
|
||||
Debug.Log($" Position before strings: 0x{reader.Position:X}");
|
||||
// A number of material subsitution strings.
|
||||
var numMaterialSubstitues = reader.ReadInt16();
|
||||
Debug.Log($" numMaterialSubstitues: {numMaterialSubstitues}");
|
||||
for (var i = 0; i < numMaterialSubstitues; i++)
|
||||
{
|
||||
var materialSubstitute = reader.ReadVariableLengthPascalString();
|
||||
Debug.Log($"materialSubstitute: {materialSubstitute}");
|
||||
}
|
||||
|
||||
var persistentFlag = reader.ReadUInt16();
|
||||
Debug.Log($"persistentFlag: {persistentFlag}");
|
||||
|
||||
// Slots...
|
||||
var slotsFlag = reader.ReadInt16();
|
||||
Debug.Log($"slotsFlag: {slotsFlag}");
|
||||
|
||||
var numSlots = reader.ReadInt16();
|
||||
for (var i = 0; i < numSlots; i++)
|
||||
{
|
||||
var slotValue = reader.ReadInt16();
|
||||
}
|
||||
Debug.Log($"numSlots: {numSlots}");
|
||||
|
||||
var numEffects = reader.ReadInt16();
|
||||
Debug.Log($"numEffects: {numEffects}");
|
||||
|
||||
Debug.Log($"Position after numEffects: 0x{reader.Position:X}");
|
||||
|
||||
var numbOverrides = reader.ReadInt16();
|
||||
Debug.Log($"numOverides: {numbOverrides}");
|
||||
|
||||
for (int i = 0; i < numbOverrides; i++)
|
||||
{
|
||||
var overrideString1 = reader.ReadVariableLengthPascalString();
|
||||
var overrideString2 = reader.ReadVariableLengthPascalString();
|
||||
var overrideString3 = reader.ReadVariableLengthPascalString();
|
||||
Debug.Log($"{overrideString1} / {overrideString2} / {overrideString3}");
|
||||
}*/
|
||||
|
||||
return asset;
|
||||
}
|
||||
}
|
||||
}
|
3
Assets/Scripts/OpenTS2/Files/Formats/DBPF/SimsObjectCodec.cs.meta
generated
Normal file
3
Assets/Scripts/OpenTS2/Files/Formats/DBPF/SimsObjectCodec.cs.meta
generated
Normal file
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 56e83332c7cd425b96ef041bca7ee9fc
|
||||
timeCreated: 1727121939
|
|
@ -0,0 +1,26 @@
|
|||
using NUnit.Framework;
|
||||
using OpenTS2.Common;
|
||||
using OpenTS2.Content;
|
||||
using OpenTS2.Content.DBPF;
|
||||
using OpenTS2.Files.Formats.DBPF;
|
||||
|
||||
public class ObjectModuleCodecTest
|
||||
{
|
||||
private uint _groupID;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
TestMain.Initialize();
|
||||
_groupID = ContentProvider.Get().AddPackage("TestAssets/Codecs/ObjCodecs.package").GroupID;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSuccessfullyLoadsObjectModule()
|
||||
{
|
||||
var objectModuleAsset = ContentProvider.Get()
|
||||
.GetAsset<ObjectModuleAsset>(new ResourceKey(0x1, _groupID, TypeIDs.OBJM));
|
||||
|
||||
Assert.That(objectModuleAsset, Is.Not.Null);
|
||||
}
|
||||
}
|
3
Assets/Tests/OpenTS2/Files/Formats/DBPF/ObjectModuleCodecTest.cs.meta
generated
Normal file
3
Assets/Tests/OpenTS2/Files/Formats/DBPF/ObjectModuleCodecTest.cs.meta
generated
Normal file
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c290fd6845f2442c94c96b4a69ddddc3
|
||||
timeCreated: 1727972116
|
|
@ -0,0 +1,26 @@
|
|||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using OpenTS2.Common;
|
||||
using OpenTS2.Content;
|
||||
using OpenTS2.Content.DBPF;
|
||||
using OpenTS2.Files.Formats.DBPF;
|
||||
|
||||
public class SimsObjectCodecTest
|
||||
{
|
||||
private uint _groupID;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
TestMain.Initialize();
|
||||
_groupID = ContentProvider.Get().AddPackage("TestAssets/Codecs/ObjCodecs.package").GroupID;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSuccessfullyLoadsSimsObject()
|
||||
{
|
||||
var objectAsset = ContentProvider.Get().GetAsset<SimsObjectAsset>(new ResourceKey(0x158, _groupID, TypeIDs.XOBJ));
|
||||
|
||||
Assert.That(objectAsset, Is.Not.Null);
|
||||
}
|
||||
}
|
3
Assets/Tests/OpenTS2/Files/Formats/DBPF/SimsObjectCodecTest.cs.meta
generated
Normal file
3
Assets/Tests/OpenTS2/Files/Formats/DBPF/SimsObjectCodecTest.cs.meta
generated
Normal file
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 13359c34be754888864a20da2042ea57
|
||||
timeCreated: 1727122336
|
Loading…
Reference in a new issue