void SaveGameBinaryFormat_10(BinaryWriter bw) { if (cachedChunks == null) { return; } // Build a table with all voxel definitions used in modified chunks InitSaveGameStructs(); int voxelDefinitionsCount = 0; int itemDefinitionsCount = 0; int numChunks = 0; // Pack used voxel and item definitions foreach (KeyValuePair <int, CachedChunk> kv in cachedChunks) { if (kv.Value == null) { continue; } VoxelChunk chunk = kv.Value.chunk; if (chunk != null && chunk.modified) { numChunks++; if (chunk.voxels != null) { VoxelDefinition last = null; for (int k = 0; k < chunk.voxels.Length; k++) { VoxelDefinition vd = chunk.voxels [k].type; if (vd == null || vd == last || vd.isDynamic || vd.doNotSave) { continue; } last = vd; if (!saveVoxelDefinitionsDict.ContainsKey(vd)) { saveVoxelDefinitionsDict [vd] = voxelDefinitionsCount++; saveVoxelDefinitionsList.Add(vd.name); } } } if (chunk.items != null) { ItemDefinition last = null; for (int k = 0; k < chunk.items.count; k++) { Item item = chunk.items.values [k]; if (item == null) { continue; } ItemDefinition id = item.itemDefinition; if (id == null || id == last) { continue; } last = id; if (!saveItemDefinitionsDict.ContainsKey(id)) { saveItemDefinitionsDict [id] = itemDefinitionsCount++; saveItemDefinitionsList.Add(id.name); } } } if (chunk.lightSources != null) { ItemDefinition last = null; for (int k = 0; k < chunk.lightSources.Count; k++) { ItemDefinition id = chunk.lightSources [k].itemDefinition; if (id == null || id == last) { continue; } last = id; if (!saveItemDefinitionsDict.ContainsKey(id)) { saveItemDefinitionsDict [id] = itemDefinitionsCount++; saveItemDefinitionsList.Add(id.name); } } } } } // Header bw.Write(SAVE_FILE_CURRENT_FORMAT); bw.Write((byte)CHUNK_SIZE); // Character controller transform position if (characterController != null) { EncodeVector3Binary(bw, characterController.transform.position); // Character controller transform rotation EncodeVector3Binary(bw, characterController.transform.rotation.eulerAngles); } else { EncodeVector3Binary(bw, Misc.vector3zero); EncodeVector3Binary(bw, Misc.vector3zero); } // Character controller's camera local rotation if (cameraMain != null) { EncodeVector3Binary(bw, cameraMain.transform.localRotation.eulerAngles); } else { EncodeVector3Binary(bw, Misc.vector3zero); } // Add voxel definitions table int vdCount = saveVoxelDefinitionsList.Count; bw.Write((Int16)vdCount); for (int k = 0; k < vdCount; k++) { bw.Write(saveVoxelDefinitionsList [k]); } // Add item definitions table int idCount = saveItemDefinitionsList.Count; bw.Write((Int16)idCount); for (int k = 0; k < idCount; k++) { bw.Write(saveItemDefinitionsList [k]); } // Add modified chunks bw.Write(numChunks); foreach (KeyValuePair <int, CachedChunk> kv in cachedChunks) { if (kv.Value == null) { continue; } VoxelChunk chunk = kv.Value.chunk; if (chunk != null && chunk.modified) { ToggleHiddenVoxels(chunk, true); WriteChunkData_10(bw, chunk); ToggleHiddenVoxels(chunk, false); } } // Add gameobjects VoxelPlaySaveThis [] gos = FindObjectsOfType <VoxelPlaySaveThis> (); bw.Write((Int16)gos.Length); Dictionary <string, string> data = new Dictionary <string, string> (); for (int k = 0; k < gos.Length; k++) { VoxelPlaySaveThis go = gos [k]; if (string.IsNullOrEmpty(go.prefabResourcesPath)) { continue; } bw.Write(go.prefabResourcesPath); bw.Write(go.name); EncodeVector3Binary(bw, go.transform.position); EncodeVector3Binary(bw, go.transform.eulerAngles); EncodeVector3Binary(bw, go.transform.localScale); data.Clear(); go.SendMessage("OnSaveGame", data); //go.GetData (data); Int16 dataCount = (Int16)data.Count; bw.Write(dataCount); foreach (KeyValuePair <string, string> entry in data) { bw.Write(entry.Key); bw.Write(entry.Value); } } }
void LoadGameBinaryFileFormat_10(BinaryReader br, bool preservePlayerPosition = false) { // Character controller transform position & rotation Vector3 pos = DecodeVector3Binary(br); Vector3 characterRotationAngles = DecodeVector3Binary(br); Vector3 cameraLocalRotationAngles = DecodeVector3Binary(br); if (!preservePlayerPosition) { if (characterController != null) { characterController.transform.position = pos; characterController.transform.rotation = Quaternion.Euler(characterRotationAngles); cameraMain.transform.localRotation = Quaternion.Euler(cameraLocalRotationAngles); characterController.UpdateLook(); } } InitSaveGameStructs(); // Read voxel definition table int vdCount = br.ReadInt16(); for (int k = 0; k < vdCount; k++) { saveVoxelDefinitionsList.Add(br.ReadString()); } // Read item definition table int idCount = br.ReadInt16(); for (int k = 0; k < idCount; k++) { saveItemDefinitionsList.Add(br.ReadString()); } int numChunks = br.ReadInt32(); VoxelDefinition voxelDefinition = defaultVoxel; int prevVdIndex = -1; Color32 voxelColor = Misc.color32White; for (int c = 0; c < numChunks; c++) { // Read chunks // Get chunk position Vector3 chunkPosition = DecodeVector3Binary(br); VoxelChunk chunk = GetChunkUnpopulated(chunkPosition); byte isAboveSurface = br.ReadByte(); chunk.isAboveSurface = isAboveSurface == 1; chunk.back = chunk.bottom = chunk.left = chunk.right = chunk.forward = chunk.top = null; chunk.allowTrees = false; chunk.modified = true; chunk.isPopulated = true; chunk.voxelSignature = chunk.lightmapSignature = -1; chunk.renderState = ChunkRenderState.Pending; SetChunkOctreeIsDirty(chunkPosition, false); ChunkClearFast(chunk); // Read voxels int numWords = br.ReadInt16(); for (int k = 0; k < numWords; k++) { // Voxel definition int vdIndex = br.ReadInt16(); if (prevVdIndex != vdIndex) { if (vdIndex >= 0 && vdIndex < vdCount) { voxelDefinition = GetVoxelDefinition(saveVoxelDefinitionsList [vdIndex]); prevVdIndex = vdIndex; } } // RGB voxelColor.r = br.ReadByte(); voxelColor.g = br.ReadByte(); voxelColor.b = br.ReadByte(); // Voxel index int voxelIndex = br.ReadInt16(); // Repetitions int repetitions = br.ReadInt16(); byte flags = br.ReadByte(); byte hasCustomRotation = br.ReadByte(); if (voxelDefinition == null) { continue; } // Custom voxel flags if (voxelDefinition.renderType == RenderType.Custom) { flags &= 0xF; // custom voxels do not store texture rotation; their transform has the final rotation if (hasCustomRotation == 1) { Vector3 voxelAngles = DecodeVector3Binary(br); delayedVoxelCustomRotations.Add(GetVoxelPosition(chunkPosition, voxelIndex), voxelAngles); } } for (int i = 0; i < repetitions; i++) { chunk.voxels [voxelIndex + i].Set(voxelDefinition, voxelColor); if (voxelDefinition.renderType == RenderType.Water || voxelDefinition.renderType.supportsTextureRotation()) { chunk.voxels [voxelIndex + i].SetFlags(flags); } if (voxelDefinition.lightIntensity > 0) { chunk.AddLightSource(voxelIndex + i, voxelDefinition.lightIntensity); } } } // Read light sources int lightCount = br.ReadInt16(); VoxelHitInfo hitInfo = new VoxelHitInfo(); for (int k = 0; k < lightCount; k++) { // Voxel index hitInfo.voxelIndex = br.ReadInt16(); // Voxel center hitInfo.voxelCenter = GetVoxelPosition(chunkPosition, hitInfo.voxelIndex); // Normal hitInfo.normal = DecodeVector3Binary(br); hitInfo.chunk = chunk; // Item definition int itemIndex = br.ReadInt16(); if (itemIndex < 0 || itemIndex >= idCount) { continue; } string itemDefinitionName = saveItemDefinitionsList [itemIndex]; ItemDefinition itemDefinition = GetItemDefinition(itemDefinitionName); TorchAttach(hitInfo, itemDefinition); } // Read items int itemCount = br.ReadInt16(); for (int k = 0; k < itemCount; k++) { // Voxel index int itemIndex = br.ReadInt16(); if (itemIndex < 0 || itemIndex >= idCount) { continue; } string itemDefinitionName = saveItemDefinitionsList [itemIndex]; Vector3 itemPosition = DecodeVector3Binary(br); int quantity = br.ReadInt16(); ItemSpawn(itemDefinitionName, itemPosition, quantity); } } // Destroy any object with VoxelPlaySaveThis component to avoid repetitions VoxelPlaySaveThis [] gos = FindObjectsOfType <VoxelPlaySaveThis> (); for (int k = 0; k < gos.Length; k++) { DestroyImmediate(gos [k].gameObject); } // Load gameobjects int goCount = br.ReadInt16(); Dictionary <string, string> data = new Dictionary <string, string> (); for (int k = 0; k < goCount; k++) { string prefabPath = br.ReadString(); GameObject o = Resources.Load <GameObject> (prefabPath); if (o != null) { o = Instantiate <GameObject> (o) as GameObject; o.name = br.ReadString(); VoxelPlaySaveThis go = o.GetComponent <VoxelPlaySaveThis> (); if (go == null) { DestroyImmediate(o); continue; } o.transform.position = DecodeVector3Binary(br); o.transform.eulerAngles = DecodeVector3Binary(br); o.transform.localScale = DecodeVector3Binary(br); data.Clear(); Int16 dataCount = br.ReadInt16(); for (int j = 0; j < dataCount; j++) { string key = br.ReadString(); string value = br.ReadString(); data [key] = value; } go.SendMessage("OnLoadGame", data); } } }