public static void ConvertMap(MapListEntry map) { var mobiles = new List <SavedGameObject>(); var mapDir = $"maps/{map.name}"; foreach (var mobFile in Tig.FS.Search($"{mapDir}/*.mob")) { using var reader = Tig.FS.OpenBinaryReader(mobFile); mobiles.Add(SavedGameObject.Load(reader)); } mobiles.Sort((a, b) => a.Id.guid.CompareTo(b.Id.guid)); using var stream = new FileStream($"{map.id}_{map.name}_mobiles.json", FileMode.Create); using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions { Indented = true }); writer.WriteStartArray(); foreach (var mobile in mobiles) { WriteMobile(writer, mobile); } writer.WriteEndArray(); }
public static SavedGameObject Load(BinaryReader reader) { var header = reader.ReadUInt32(); if (header != 0x77) { throw new Exception($"Expected object header 0x77, but got 0x{header:X}"); } var protoId = reader.ReadObjectId(); if (!protoId.IsPrototype) { throw new Exception($"Expected a prototype id, but got type {protoId.Type} instead."); } ObjectId objId = reader.ReadObjectId(); // Null IDs are allowed for sector objects if (!objId.IsPermanent && !objId.IsNull) { throw new Exception($"Expected an object id of type Permanent, but got type {objId.Type} instead."); } var typeCode = (ObjectType)reader.ReadUInt32(); var result = new SavedGameObject { ProtoId = protoId.protoId, Id = objId, Type = typeCode }; // Initialize and load bitmaps var bitmapLen = ObjectFields.GetBitmapBlockCount(result.Type); var propCount = reader.ReadUInt16(); var propCollBitmap = new uint[bitmapLen]; reader.Read(MemoryMarshal.Cast <uint, byte>(propCollBitmap)); // Validate that the property bitmap has the same number of bits enabled as the number of serialized properties var enabledBitCount = CountPropBitmap(propCollBitmap); if (enabledBitCount != propCount) { throw new Exception($"Mismatch between serialized property count {propCount} " + $"and enabled bits in property bitmap {enabledBitCount}"); } var properties = new Dictionary <obj_f, object>(); foreach (var field in ObjectFields.GetTypeFields(typeCode)) { ref readonly var fieldDef = ref ObjectFields.GetFieldDef(field);
private static void GameObjectDeserialization(List <GameObjectData> gameObjects) { foreach (GameObjectData data in gameObjects) { // TODO: handle dynamic gameObjects bool fromPrefab = !String.IsNullOrEmpty(data.guid); if (fromPrefab) { GameObject prefab = system.FindPrefab(data.guid); if (prefab != null) { // We disable prefab to postpone unity callbacks bool initState = prefab.activeSelf; prefab.SetActive(false); GameObject go = GameObject.Instantiate(prefab, data.position, data.rotation); SavedGameObject dgo = go.GetComponent <SavedGameObject>(); if (dgo == null) { Debug.LogError(String.Format("SaveSystem: While loading save file, gameobject with GUID{0} did not have a DatabaseGameObject component, the object will be destroyed.", data.guid)); GameObject.Destroy(go); continue; } else { dgo.guid = data.guid; } go.transform.localScale = data.scale; go.name = data.name; gameobjectsByInstanceID.Add(data.InstanceID, go); allGameObjects.Add(go); prefab.SetActive(initState); } else { Debug.LogError(String.Format("SaveSystem: While loading save file, gameobject with GUID{0} was not found in the database.", data.guid)); continue; } } } }
private static void WriteMobile(Utf8JsonWriter writer, SavedGameObject mobile) { writer.WriteStartObject(); var proto = GameSystems.Proto.GetProtoById(mobile.ProtoId); var displayName = GameSystems.MapObject.GetDisplayName(proto); writer.WriteString("$comment", displayName); writer.WriteString("type", mobile.Type.ToString()); writer.WriteString("id", mobile.Id.guid.ToString()); writer.WriteNumber("protoId", mobile.ProtoId); ObjectSerializer.WriteProperties(writer, mobile.Properties, $"'{displayName}' ({mobile.Type})"); writer.WriteEndObject(); }
public GameObjectData(SavedGameObject dgo) { InstanceID = dgo.gameObject.GetInstanceID(); Transform tr = dgo.transform; position = tr.position; rotation = tr.rotation; scale = tr.localScale; if (dgo.transform.parent != null) { ParentInstanceID = tr.parent.GetInstanceID(); } guid = dgo.guid; name = dgo.name; }