예제 #1
0
        public static void SaveToPrj2OnlyObjects(Stream stream, Level level, IEnumerable <ObjectInstance> objects)
        {
            using (var chunkIO = new ChunkWriter(Prj2Chunks.MagicNumber, stream, ChunkWriter.Compression.None))
            {
                // Index objects
                var objectInstanceLookup = new Dictionary <ObjectInstance, int>();
                foreach (ObjectInstance objectInstance in objects)
                {
                    objectInstanceLookup.Add(objectInstance, objectInstanceLookup.Count);
                }

                // Write settings
                LevelSettings settingsToSave = new LevelSettings();
                Room.CopyDependentLevelSettingsArgs copyInstance = new Room.CopyDependentLevelSettingsArgs(null, settingsToSave, level.Settings, false);
                foreach (ObjectInstance instance in objects)
                {
                    instance.CopyDependentLevelSettings(copyInstance);
                }
                LevelSettingsIds levelSettingIds = WriteLevelSettings(chunkIO, settingsToSave);

                // Write objects
                WriteObjects(chunkIO, objects, new Dictionary <Room, int>(), levelSettingIds, objectInstanceLookup);
                chunkIO.WriteChunkEnd();
            }
        }
예제 #2
0
        public static void SaveToPrj2(Stream stream, Level level, Filter filter = null)
        {
            _level = level;

            using (var chunkIO = new ChunkWriter(Prj2Chunks.MagicNumber, stream, ChunkWriter.Compression.None))
            {
                // Index rooms
                var rooms = new Dictionary <Room, int>();
                for (int i = 0; i < level.Rooms.Length; ++i)
                {
                    if (level.Rooms[i] != null && (filter?.RoomPredicate(level.Rooms[i]) ?? true))
                    {
                        rooms.Add(level.Rooms[i], i);
                    }
                }

                LevelSettings settingsToSave = level.Settings;
                if (filter != null && filter.FilterLevelSettings)
                {
                    settingsToSave = new LevelSettings();
                    var copyInstance = new Room.CopyDependentLevelSettingsArgs(null, settingsToSave, level.Settings, false);
                    foreach (Room room in rooms.Keys)
                    {
                        room.CopyDependentLevelSettings(copyInstance);
                    }
                }

                // Write settings
                LevelSettingsIds levelSettingIds = WriteLevelSettings(chunkIO, settingsToSave);

                // Write rooms
                WriteRooms(chunkIO, rooms, levelSettingIds);
                chunkIO.WriteChunkEnd();
            }
        }
예제 #3
0
        private static void WriteRooms(ChunkWriter chunkIO, Dictionary <Room, int> rooms, LevelSettingsIds levelSettingIds)
        {
            // Allocate object indices
            var objectInstanceLookup = new Dictionary <ObjectInstance, int>();

            foreach (Room room in rooms.Keys)
            {
                foreach (ObjectInstance objectInstance in room.AnyObjects)
                {
                    objectInstanceLookup.Add(objectInstance, objectInstanceLookup.Count);
                }
            }

            // Save
            using (var chunkRooms = chunkIO.WriteChunk(Prj2Chunks.Rooms, long.MaxValue))
            {
                foreach (Room room in rooms.Keys)
                {
                    using (var chunkRoom = chunkIO.WriteChunk(Prj2Chunks.Room, long.MaxValue))
                    {
                        LEB128.Write(chunkIO.Raw, room.NumXSectors);
                        LEB128.Write(chunkIO.Raw, room.NumZSectors);

                        // Write basic properties
                        chunkIO.WriteChunkInt(Prj2Chunks.RoomIndex, rooms.TryGetOrDefault(room, -1));
                        chunkIO.WriteChunkString(Prj2Chunks.RoomName, room.Name);
                        chunkIO.WriteChunkVector3(Prj2Chunks.RoomPosition, room.Position);
                        chunkIO.WriteChunkArrayOfBytes(Prj2Chunks.RoomTags, System.Text.Encoding.UTF8.GetBytes(string.Join(" ", room.Tags)));

                        // Write sectors
                        using (var chunkRoomSectors = chunkIO.WriteChunk(Prj2Chunks.RoomSectors))
                        {
                            for (int z = 0; z < room.NumZSectors; z++)
                            {
                                for (int x = 0; x < room.NumXSectors; x++)
                                {
                                    using (var chunkSector = chunkIO.WriteChunk(Prj2Chunks.Sector, LEB128.MaximumSize2Byte))
                                    {
                                        chunkIO.Raw.Write(x + z * room.NumXSectors);
                                        var b = room.Blocks[x, z];

                                        long combinedFlag = (b.IsAnyWall ? 1L : 0) | (b.ForceFloorSolid ? 2L : 0) | ((long)b.Flags << 2);
                                        chunkIO.WriteChunkInt(Prj2Chunks.SectorProperties, combinedFlag);
                                        using (var chunkSectorFloor = chunkIO.WriteChunk(Prj2Chunks.SectorFloor, LEB128.MaximumSize1Byte))
                                        {
                                            long flag = (b.Floor.SplitDirectionIsXEqualsZ ? 1L : 0) | ((long)b.Floor.DiagonalSplit << 1);
                                            LEB128.Write(chunkIO.Raw, flag);
                                            for (BlockEdge edge = 0; edge < BlockEdge.Count; ++edge)
                                            {
                                                LEB128.Write(chunkIO.Raw, b.Floor.GetHeight(edge));
                                            }
                                            for (BlockEdge edge = 0; edge < BlockEdge.Count; ++edge)
                                            {
                                                LEB128.Write(chunkIO.Raw, b.GetHeight(BlockVertical.Ed, edge));
                                            }
                                        }
                                        using (var chunkSectorCeiling = chunkIO.WriteChunk(Prj2Chunks.SectorCeiling, LEB128.MaximumSize1Byte))
                                        {
                                            long flag = (b.Ceiling.SplitDirectionIsXEqualsZ ? 1L : 0) | ((long)b.Ceiling.DiagonalSplit << 1);
                                            LEB128.Write(chunkIO.Raw, flag);
                                            for (BlockEdge edge = 0; edge < BlockEdge.Count; ++edge)
                                            {
                                                LEB128.Write(chunkIO.Raw, b.Ceiling.GetHeight(edge));
                                            }
                                            for (BlockEdge edge = 0; edge < BlockEdge.Count; ++edge)
                                            {
                                                LEB128.Write(chunkIO.Raw, b.GetHeight(BlockVertical.Rf, edge));
                                            }
                                        }
                                        for (BlockFace face = 0; face < BlockFace.Count; face++)
                                        {
                                            var texture = b.GetFaceTexture(face);
                                            if (texture.Texture == null)
                                            {
                                                continue;
                                            }

                                            if (texture.Texture is LevelTexture)
                                            {
                                                using (var chunkTextureLevelTexture = chunkIO.WriteChunk(Prj2Chunks.TextureLevelTexture2, LEB128.MaximumSize1Byte))
                                                {
                                                    int textureIndex = levelSettingIds.LevelTextures[(LevelTexture)texture.Texture];

                                                    LEB128.Write(chunkIO.Raw, (long)face);
                                                    chunkIO.Raw.Write(texture.TexCoord0);
                                                    chunkIO.Raw.Write(texture.TexCoord1);
                                                    chunkIO.Raw.Write(texture.TexCoord2);
                                                    chunkIO.Raw.Write(texture.TexCoord3);
                                                    chunkIO.Raw.Write(texture.ParentArea.Start);
                                                    chunkIO.Raw.Write(texture.ParentArea.End);
                                                    LEB128.Write(chunkIO.Raw, (texture.DoubleSided ? 1L : 0) | ((long)texture.BlendMode << 1));
                                                    LEB128.Write(chunkIO.Raw, textureIndex);
                                                }
                                            }
                                            else if (texture.Texture == TextureInvisible.Instance)
                                            {
                                                chunkIO.WriteChunkInt(Prj2Chunks.TextureInvisible, (long)face);
                                            }
                                            else
                                            {
                                                throw new NotSupportedException("Unsupported texture type " + texture.Texture.GetType().Name);
                                            }
                                        }
                                        chunkIO.WriteChunkEnd();
                                    }
                                }
                            }
                            chunkIO.WriteChunkEnd();
                        }

                        // Write room properties
                        chunkIO.WriteChunkVector3(Prj2Chunks.RoomAmbientLight, room.AmbientLight);
                        chunkIO.WriteChunkBool(Prj2Chunks.RoomFlagCold, room.FlagCold);
                        chunkIO.WriteChunkBool(Prj2Chunks.RoomFlagDamage, room.FlagDamage);
                        chunkIO.WriteChunkBool(Prj2Chunks.RoomFlagHorizon, room.FlagHorizon);
                        chunkIO.WriteChunkBool(Prj2Chunks.RoomFlagOutside, room.FlagOutside);
                        chunkIO.WriteChunkBool(Prj2Chunks.RoomFlagNoLensflare, room.FlagNoLensflare);
                        chunkIO.WriteChunkBool(Prj2Chunks.RoomFlagExcludeFromPathFinding, room.FlagExcludeFromPathFinding);
                        chunkIO.WriteChunkInt(Prj2Chunks.RoomType, (int)room.Type);
                        chunkIO.WriteChunkInt(Prj2Chunks.RoomTypeStrength, room.TypeStrength);
                        chunkIO.WriteChunkInt(Prj2Chunks.RoomLightEffect, (int)room.LightEffect);
                        chunkIO.WriteChunkInt(Prj2Chunks.RoomLightEffectStrength2, room.LightEffectStrength);
                        chunkIO.WriteChunkInt(Prj2Chunks.RoomReverberation, (int)room.Reverberation);
                        chunkIO.WriteChunkInt(Prj2Chunks.RoomLightInterpolationMode, (int)room.LightInterpolationMode);
                        chunkIO.WriteChunkBool(Prj2Chunks.RoomLocked, room.Locked);
                        chunkIO.WriteChunkBool(Prj2Chunks.RoomHidden, room.Hidden);
                        if (room.AlternateRoom != null && rooms.ContainsKey(room.AlternateRoom))
                        {
                            using (var chunkRoomAlternate = chunkIO.WriteChunk(Prj2Chunks.RoomAlternate, LEB128.MaximumSize1Byte))
                            {
                                chunkIO.WriteChunkInt(Prj2Chunks.AlternateGroup, room.AlternateGroup);
                                chunkIO.WriteChunkInt(Prj2Chunks.AlternateRoom, rooms[room.AlternateRoom]);
                                chunkIO.WriteChunkEnd();
                            }
                        }

                        // Write room objects
                        WriteObjects(chunkIO, room.AnyObjects, rooms, levelSettingIds, objectInstanceLookup);
                        chunkIO.WriteChunkEnd();
                    }
                }
                chunkIO.WriteChunkEnd();
            }
        }
예제 #4
0
        private static void WriteObjects(ChunkWriter chunkIO, IEnumerable <ObjectInstance> objects,
                                         Dictionary <Room, int> rooms, LevelSettingsIds levelSettingIds,
                                         Dictionary <ObjectInstance, int> objectInstanceLookup)
        {
            using (var chunkObjects = chunkIO.WriteChunk(Prj2Chunks.Objects, long.MaxValue))
            {
                foreach (var o in objects)
                {
                    if (o is MoveableInstance)
                    {
                        chunkIO.WriteChunkWithChildren(Prj2Chunks.ObjectMovable3, () =>
                        {
                            var instance = (MoveableInstance)o;
                            LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1));
                            chunkIO.Raw.Write(instance.Position);
                            chunkIO.Raw.Write(instance.RotationY);
                            LEB128.Write(chunkIO.Raw, (long?)instance.ScriptId ?? -1);
                            chunkIO.Raw.Write(instance.WadObjectId.TypeId);
                            chunkIO.Raw.Write(instance.Ocb);
                            chunkIO.Raw.Write(instance.Invisible);
                            chunkIO.Raw.Write(instance.ClearBody);
                            chunkIO.Raw.Write(instance.CodeBits);
                            chunkIO.Raw.Write(instance.Color);
                            chunkIO.WriteChunkInt(Prj2Chunks.ObjectItemLuaId, instance.LuaId);
                        });
                    }
                    else if (o is StaticInstance)
                    {
                        chunkIO.WriteChunkWithChildren(Prj2Chunks.ObjectStatic2, () =>
                        {
                            var instance = (StaticInstance)o;
                            LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1));
                            chunkIO.Raw.Write(instance.Position);
                            chunkIO.Raw.Write(instance.RotationY);
                            LEB128.Write(chunkIO.Raw, (long?)instance.ScriptId ?? -1);
                            chunkIO.Raw.Write(instance.WadObjectId.TypeId);
                            chunkIO.Raw.Write(instance.Color);
                            chunkIO.Raw.Write((int)0); // Unused 32 bit value
                            chunkIO.Raw.Write(instance.Ocb);
                            chunkIO.WriteChunkInt(Prj2Chunks.ObjectItemLuaId, instance.LuaId);
                        });
                    }
                    else if (o is CameraInstance)
                    {
                        using (var chunk = chunkIO.WriteChunk(Prj2Chunks.ObjectCamera, LEB128.MaximumSize1Byte))
                        {
                            var instance = (CameraInstance)o;
                            LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1));
                            chunkIO.Raw.Write(instance.Position);
                            LEB128.Write(chunkIO.Raw, (long?)instance.ScriptId ?? -1);
                            chunkIO.Raw.Write(instance.Fixed);
                        }
                    }
                    else if (o is FlybyCameraInstance)
                    {
                        chunkIO.WriteChunkWithChildren(Prj2Chunks.ObjectFlyBy, () =>
                        {
                            var instance = (FlybyCameraInstance)o;
                            LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1));
                            chunkIO.Raw.Write(instance.Position);
                            chunkIO.Raw.Write(instance.RotationY);
                            chunkIO.Raw.Write(instance.RotationX);
                            chunkIO.Raw.Write(instance.Roll);
                            LEB128.Write(chunkIO.Raw, (long?)instance.ScriptId ?? -1);
                            chunkIO.Raw.Write(instance.Speed);
                            chunkIO.Raw.Write(instance.Fov);
                            LEB128.Write(chunkIO.Raw, instance.Flags);
                            LEB128.Write(chunkIO.Raw, instance.Number);
                            LEB128.Write(chunkIO.Raw, instance.Sequence);
                            LEB128.Write(chunkIO.Raw, instance.Timer);
                        });
                    }
                    else if (o is SinkInstance)
                    {
                        using (var chunk = chunkIO.WriteChunk(Prj2Chunks.ObjectSink, LEB128.MaximumSize1Byte))
                        {
                            var instance = (SinkInstance)o;
                            LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1));
                            chunkIO.Raw.Write(instance.Position);
                            LEB128.Write(chunkIO.Raw, (long?)instance.ScriptId ?? -1);
                            chunkIO.Raw.Write(instance.Strength);
                        }
                    }
                    else if (o is SoundSourceInstance)
                    {
                        using (var chunk = chunkIO.WriteChunk(Prj2Chunks.ObjectSoundSourceFinal, LEB128.MaximumSize1Byte))
                        {
                            var instance = (SoundSourceInstance)o;
                            LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1));
                            chunkIO.Raw.Write(instance.Position);
                            chunkIO.Raw.Write(instance.SoundId);
                            chunkIO.Raw.Write((int)instance.PlayMode);
                            LEB128.Write(chunkIO.Raw, -1);
                        }
                    }
                    else if (o is LightInstance)
                    {
                        using (var chunk = chunkIO.WriteChunk(Prj2Chunks.ObjectLight4, LEB128.MaximumSize2Byte))
                        {
                            var instance = (LightInstance)o;
                            LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1));
                            LEB128.Write(chunkIO.Raw, (long)instance.Type);
                            chunkIO.Raw.Write(instance.Position);
                            chunkIO.Raw.Write(instance.RotationY);
                            chunkIO.Raw.Write(instance.RotationX);
                            chunkIO.Raw.Write(instance.Intensity);
                            chunkIO.Raw.Write(instance.Color);
                            chunkIO.Raw.Write(instance.InnerRange);
                            chunkIO.Raw.Write(instance.OuterRange);
                            chunkIO.Raw.Write(instance.InnerAngle);
                            chunkIO.Raw.Write(instance.OuterAngle);
                            chunkIO.Raw.Write(instance.Enabled);
                            chunkIO.Raw.Write(instance.IsObstructedByRoomGeometry);
                            chunkIO.Raw.Write(instance.IsDynamicallyUsed);
                            chunkIO.Raw.Write(instance.IsStaticallyUsed);
                            chunkIO.Raw.Write(instance.IsUsedForImportedGeometry);
                            chunkIO.Raw.Write((byte)instance.Quality);
                        }
                    }
                    else if (o is PortalInstance && rooms.ContainsKey(((PortalInstance)o).AdjoiningRoom))
                    {
                        using (var chunk = chunkIO.WriteChunk(Prj2Chunks.ObjectPortal, LEB128.MaximumSize2Byte))
                        {
                            var instance = (PortalInstance)o;
                            LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1));
                            LEB128.Write(chunkIO.Raw, instance.Area.X0);
                            LEB128.Write(chunkIO.Raw, instance.Area.Y0);
                            LEB128.Write(chunkIO.Raw, instance.Area.X1);
                            LEB128.Write(chunkIO.Raw, instance.Area.Y1);
                            LEB128.Write(chunkIO.Raw, rooms[instance.AdjoiningRoom]);
                            chunkIO.Raw.Write((byte)instance.Direction);
                            chunkIO.Raw.Write((byte)instance.Opacity);
                        }
                    }
                    else if (o is GhostBlockInstance)
                    {
                        using (var chunk = chunkIO.WriteChunk(Prj2Chunks.ObjectGhostBlock, LEB128.MaximumSize2Byte))
                        {
                            var instance = (GhostBlockInstance)o;
                            LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1));
                            LEB128.Write(chunkIO.Raw, instance.Area.X0);
                            LEB128.Write(chunkIO.Raw, instance.Area.Y0);
                            LEB128.Write(chunkIO.Raw, instance.Floor.XnZn);
                            LEB128.Write(chunkIO.Raw, instance.Floor.XnZp);
                            LEB128.Write(chunkIO.Raw, instance.Floor.XpZn);
                            LEB128.Write(chunkIO.Raw, instance.Floor.XpZp);
                            LEB128.Write(chunkIO.Raw, instance.Ceiling.XnZn);
                            LEB128.Write(chunkIO.Raw, instance.Ceiling.XnZp);
                            LEB128.Write(chunkIO.Raw, instance.Ceiling.XpZn);
                            LEB128.Write(chunkIO.Raw, instance.Ceiling.XpZp);
                        }
                    }
                    else if (o is VolumeInstance)
                    {
                        using (var chunk = chunkIO.WriteChunk(Prj2Chunks.ObjectTriggerVolumeTest, LEB128.MaximumSize2Byte))
                        {
                            var instance = (VolumeInstance)o;
                            LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1));

                            var shape = instance.Shape();
                            chunkIO.Raw.Write((byte)shape);

                            switch (shape)
                            {
                            case VolumeShape.Box:
                            {
                                var bv = instance as BoxVolumeInstance;
                                chunkIO.Raw.Write(bv.Size);
                                chunkIO.Raw.Write(bv.RotationY);
                                chunkIO.Raw.Write(bv.RotationX);
                            }
                            break;

                            case VolumeShape.Prism:
                            {
                                var pv = instance as PrismVolumeInstance;
                                chunkIO.Raw.Write(pv.Scale);
                                chunkIO.Raw.Write(pv.RotationY);
                            }
                            break;

                            case VolumeShape.Sphere:
                                chunkIO.Raw.Write((instance as SphereVolumeInstance).Scale);
                                break;
                            }

                            chunkIO.Raw.Write(instance.Position);
                            chunkIO.Raw.Write((ushort)instance.Activators);
                            chunkIO.Raw.WriteStringUTF8(instance.Scripts.Name);
                            chunkIO.Raw.WriteStringUTF8(instance.Scripts.Environment);
                            chunkIO.Raw.WriteStringUTF8(instance.Scripts.OnEnter);
                            chunkIO.Raw.WriteStringUTF8(instance.Scripts.OnInside);
                            chunkIO.Raw.WriteStringUTF8(instance.Scripts.OnLeave);
                        }
                    }
                    else if (o is TriggerInstance)
                    {
                        using (var chunk = chunkIO.WriteChunk(Prj2Chunks.ObjectTrigger2, LEB128.MaximumSize2Byte))
                        {
                            Action <ITriggerParameter> writeTriggerParameter = (ITriggerParameter parameter) =>
                            {
                                if (parameter is TriggerParameterUshort)
                                {
                                    LEB128.Write(chunkIO.Raw, 0);
                                    LEB128.Write(chunkIO.Raw, ((TriggerParameterUshort)parameter).Key);
                                }
                                else if (parameter is ObjectInstance)
                                {
                                    LEB128.Write(chunkIO.Raw, 1);
                                    LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault((ObjectInstance)parameter));
                                }
                                else if (parameter is Room)
                                {
                                    LEB128.Write(chunkIO.Raw, 2);
                                    LEB128.Write(chunkIO.Raw, rooms.TryGetOrDefault((Room)parameter));
                                }
                                else
                                {
                                    LEB128.Write(chunkIO.Raw, -1);
                                };
                            };

                            var instance = (TriggerInstance)o;
                            LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1));
                            LEB128.Write(chunkIO.Raw, instance.Area.X0);
                            LEB128.Write(chunkIO.Raw, instance.Area.Y0);
                            LEB128.Write(chunkIO.Raw, instance.Area.X1);
                            LEB128.Write(chunkIO.Raw, instance.Area.Y1);
                            chunkIO.WriteChunkInt(Prj2Chunks.ObjectTrigger2Type, (long)instance.TriggerType);
                            chunkIO.WriteChunkInt(Prj2Chunks.ObjectTrigger2TargetType, (long)instance.TargetType);
                            chunkIO.WriteChunk(Prj2Chunks.ObjectTrigger2Target, () => writeTriggerParameter(instance.Target), 32);
                            chunkIO.WriteChunk(Prj2Chunks.ObjectTrigger2Timer, () => writeTriggerParameter(instance.Timer), 32);
                            chunkIO.WriteChunk(Prj2Chunks.ObjectTrigger2Extra, () => writeTriggerParameter(instance.Extra), 32);
                            chunkIO.WriteChunkInt(Prj2Chunks.ObjectTrigger2CodeBits, instance.CodeBits);
                            chunkIO.WriteChunkBool(Prj2Chunks.ObjectTrigger2OneShot, instance.OneShot);
                            chunkIO.WriteChunkEnd();
                        }
                    }
                    else if (o is ImportedGeometryInstance)
                    {
                        chunkIO.WriteChunkWithChildren(Prj2Chunks.ObjectImportedGeometry3, () =>
                        {
                            var instance = (ImportedGeometryInstance)o;
                            LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1));
                            chunkIO.Raw.Write(instance.Position);
                            chunkIO.Raw.Write(instance.RotationY);
                            chunkIO.Raw.Write(instance.RotationX);
                            chunkIO.Raw.Write(instance.Roll);
                            chunkIO.Raw.Write(instance.Scale);
                            LEB128.Write(chunkIO.Raw, instance.Model == null ?
                                         -1 :
                                         levelSettingIds.ImportedGeometries[instance.Model]);

                            chunkIO.WriteChunkInt(Prj2Chunks.ObjectImportedGeometryLightingModel, (int)instance.LightingModel);
                            chunkIO.WriteChunkBool(Prj2Chunks.ObjectImportedGeometrySharpEdges, instance.SharpEdges);
                            chunkIO.WriteChunkBool(Prj2Chunks.ObjectImportedGeometryHidden, instance.Hidden);
                        });
                    }
                    else
                    {
                        logger.Warn("Object " + o + " not supported.");
                    }
                }
                chunkIO.WriteChunkEnd();
            };
        }
예제 #5
0
        private static LevelSettingsIds WriteLevelSettings(ChunkWriter chunkIO, LevelSettings settings)
        {
            var levelSettingIds = new LevelSettingsIds(settings);

            using (var chunkSettings = chunkIO.WriteChunk(Prj2Chunks.Settings, long.MaxValue))
            {
                chunkIO.WriteChunkString(Prj2Chunks.FontTextureFilePath, settings.FontTextureFilePath ?? "");
                chunkIO.WriteChunkString(Prj2Chunks.SkyTextureFilePath, settings.SkyTextureFilePath ?? "");
                chunkIO.WriteChunkString(Prj2Chunks.Tr5ExtraSpritesFilePath, settings.Tr5ExtraSpritesFilePath ?? "");
                using (var chunkOldWadSoundPaths = chunkIO.WriteChunk(Prj2Chunks.OldWadSoundPaths))
                {
                    chunkIO.WriteChunkEmpty(Prj2Chunks.OldWadSoundUpdateTag1_0_8);
                    foreach (WadSoundPath soundPath in settings.WadSoundPaths)
                    {
                        using (var chunkOldWadSoundPath = chunkIO.WriteChunk(Prj2Chunks.OldWadSoundPath))
                        {
                            chunkIO.WriteChunkString(Prj2Chunks.OldWadSoundPathPath, soundPath.Path);
                            chunkIO.WriteChunkEnd();
                        }
                    }
                    chunkIO.WriteChunkEnd();
                }
                chunkIO.WriteChunkString(Prj2Chunks.GameDirectory, settings.GameDirectory ?? "");
                chunkIO.WriteChunkString(Prj2Chunks.GameLevelFilePath, settings.GameLevelFilePath ?? "");
                chunkIO.WriteChunkString(Prj2Chunks.GameExecutableFilePath, settings.GameExecutableFilePath ?? "");
                chunkIO.WriteChunkBool(Prj2Chunks.GameEnableQuickStartFeature, settings.GameEnableQuickStartFeature);
                chunkIO.WriteChunkInt(Prj2Chunks.GameVersion, (long)settings.GameVersion);
                chunkIO.WriteChunkInt(Prj2Chunks.Tr5LaraType, (long)settings.Tr5LaraType);
                chunkIO.WriteChunkInt(Prj2Chunks.Tr5Weather, (long)settings.Tr5WeatherType);
                chunkIO.WriteChunkInt(Prj2Chunks.TexturePadding, (long)settings.TexturePadding);
                chunkIO.WriteChunkBool(Prj2Chunks.RemapAnimatedTextures, settings.RemapAnimatedTextures);
                chunkIO.WriteChunkBool(Prj2Chunks.Dither16BitTextures, settings.Dither16BitTextures);
                chunkIO.WriteChunkBool(Prj2Chunks.AgressiveTexturePacking, settings.AgressiveTexturePacking);
                chunkIO.WriteChunkBool(Prj2Chunks.AgressiveFloordataPacking, settings.AgressiveFloordataPacking);
                chunkIO.WriteChunkVector3(Prj2Chunks.DefaultAmbientLight, settings.DefaultAmbientLight);
                chunkIO.WriteChunkInt(Prj2Chunks.DefaultLightQuality, (long)settings.DefaultLightQuality);
                chunkIO.WriteChunkBool(Prj2Chunks.OverrideLightQuality, settings.OverrideIndividualLightQualitySettings);
                chunkIO.WriteChunkString(Prj2Chunks.ScriptDirectory, settings.ScriptDirectory ?? "");
                chunkIO.WriteChunkInt(Prj2Chunks.SoundSystem, (int)settings.SoundSystem);
                using (var chunkWads = chunkIO.WriteChunk(Prj2Chunks.Wads, long.MaxValue))
                {
                    foreach (ReferencedWad wad in settings.Wads)
                    {
                        using (var chunkWad = chunkIO.WriteChunk(Prj2Chunks.Wad))
                        {
                            chunkIO.WriteChunkString(Prj2Chunks.WadPath, wad.Path ?? "");
                            chunkIO.WriteChunkEnd();
                        }
                    }
                    chunkIO.WriteChunkEnd();
                }
                using (var chunkSounds = chunkIO.WriteChunk(Prj2Chunks.SoundsCatalogs, long.MaxValue))
                {
                    foreach (ReferencedSoundsCatalog soundRef in settings.SoundsCatalogs)
                    {
                        using (var chunkSound = chunkIO.WriteChunk(Prj2Chunks.SoundsCatalog))
                        {
                            chunkIO.WriteChunkString(Prj2Chunks.SoundsCatalogPath, soundRef.Path ?? "");
                            chunkIO.WriteChunkEnd();
                        }
                    }
                    chunkIO.WriteChunkEnd();
                }
                using (var chunkSelectedSounds = chunkIO.WriteChunk(Prj2Chunks.SelectedSounds, long.MaxValue))
                {
                    foreach (int selectedSound in settings.SelectedSounds)
                    {
                        chunkIO.WriteChunkInt(Prj2Chunks.SelectedSound, selectedSound);
                    }
                    chunkIO.WriteChunkEnd();
                }
                using (var chunkTextures = chunkIO.WriteChunk(Prj2Chunks.Textures, long.MaxValue))
                {
                    int index = 0;
                    foreach (LevelTexture texture in settings.Textures)
                    {
                        using (var chunkLevelTexture = chunkIO.WriteChunk(Prj2Chunks.LevelTexture))
                        {
                            chunkIO.WriteChunkInt(Prj2Chunks.LevelTextureIndex, index);
                            chunkIO.WriteChunkString(Prj2Chunks.LevelTexturePath, texture.Path ?? "");
                            chunkIO.WriteChunkString(Prj2Chunks.LevelTextureCustomBumpmapPath, texture.BumpPath ?? "");
                            chunkIO.WriteChunkBool(Prj2Chunks.LevelTextureConvert512PixelsToDoubleRows, texture.Convert512PixelsToDoubleRows);
                            chunkIO.WriteChunkBool(Prj2Chunks.LevelTextureReplaceMagentaWithTransparency, texture.ReplaceMagentaWithTransparency);
                            using (var chunkLevelTextureFootStepSounds = chunkIO.WriteChunk(Prj2Chunks.LevelTextureFootStepSounds))
                            {
                                chunkIO.Raw.Write(texture.FootStepSoundWidth);
                                chunkIO.Raw.Write(texture.FootStepSoundHeight);
                                for (int y = 0; y < texture.FootStepSoundHeight; ++y)
                                {
                                    for (int x = 0; x < texture.FootStepSoundWidth; ++x)
                                    {
                                        chunkIO.Raw.Write((byte)texture.GetFootStepSound(x, y));
                                    }
                                }
                            }
                            using (var chunkLevelTextureBumpmaps = chunkIO.WriteChunk(Prj2Chunks.LevelTextureBumpmaps))
                            {
                                chunkIO.Raw.Write(texture.BumpMappingWidth);
                                chunkIO.Raw.Write(texture.BumpMappingHeight);
                                for (int y = 0; y < texture.BumpMappingHeight; ++y)
                                {
                                    for (int x = 0; x < texture.BumpMappingWidth; ++x)
                                    {
                                        chunkIO.Raw.Write((byte)texture.GetBumpMapLevel(x, y));
                                    }
                                }
                            }
                            chunkIO.WriteChunkEnd();
                        }
                        levelSettingIds.LevelTextures.Add(texture, index++);
                    }
                    chunkIO.WriteChunkEnd();
                }
                using (var chunkImportedGeometries = chunkIO.WriteChunk(Prj2Chunks.ImportedGeometries, long.MaxValue))
                {
                    int index = 0;
                    foreach (ImportedGeometry importedGeometry in settings.ImportedGeometries)
                    {
                        using (var chunkImportedGeometry = chunkIO.WriteChunk(Prj2Chunks.ImportedGeometry))
                        {
                            chunkIO.WriteChunkInt(Prj2Chunks.ImportedGeometryIndex, index);
                            chunkIO.WriteChunkString(Prj2Chunks.ImportedGeometryName, importedGeometry.Info.Name);
                            chunkIO.WriteChunkString(Prj2Chunks.ImportedGeometryPath, importedGeometry.Info.Path);
                            chunkIO.WriteChunkFloat(Prj2Chunks.ImportedGeometryScale, importedGeometry.Info.Scale);
                            chunkIO.WriteChunkInt(Prj2Chunks.ImportedGeometryPosAxisFlags,
                                                  (importedGeometry.Info.SwapXY ? 1 : 0) |
                                                  (importedGeometry.Info.SwapXZ ? 2 : 0) |
                                                  (importedGeometry.Info.SwapYZ ? 4 : 0) |
                                                  (importedGeometry.Info.FlipX ? 8 : 0) |
                                                  (importedGeometry.Info.FlipY ? 16 : 0) |
                                                  (importedGeometry.Info.FlipZ ? 32 : 0));
                            chunkIO.WriteChunkInt(Prj2Chunks.ImportedGeometryTexAxisFlags, importedGeometry.Info.FlipUV_V ? 4 : 0);
                            chunkIO.WriteChunkBool(Prj2Chunks.ImportedGeometryInvertFaces, importedGeometry.Info.InvertFaces);
                            chunkIO.WriteChunkEnd();
                        }
                        levelSettingIds.ImportedGeometries.Add(importedGeometry, index++);
                    }
                    chunkIO.WriteChunkEnd();
                }
                using (var chunkAnimatedTextureSets = chunkIO.WriteChunk(Prj2Chunks.AnimatedTextureSets, long.MaxValue))
                {
                    foreach (AnimatedTextureSet set in settings.AnimatedTextureSets)
                    {
                        using (var chunkAnimatedTextureSet = chunkIO.WriteChunk(Prj2Chunks.AnimatedTextureSet))
                        {
                            chunkIO.WriteChunkString(Prj2Chunks.AnimatedTextureSetName, set.Name ?? "");
                            chunkIO.WriteChunkInt(Prj2Chunks.AnimatedTextureSetType, (int)set.AnimationType);
                            chunkIO.WriteChunkFloat(Prj2Chunks.AnimatedTextureSetFps, set.Fps);
                            chunkIO.WriteChunkInt(Prj2Chunks.AnimatedTextureSetUvRotate, set.UvRotate);
                            using (var chunkAnimatedTextureFrames = chunkIO.WriteChunk(Prj2Chunks.AnimatedTextureFrames))
                            {
                                foreach (AnimatedTextureFrame frame in set.Frames)
                                {
                                    using (var chunkAnimatedTextureFrame = chunkIO.WriteChunk(Prj2Chunks.AnimatedTextureFrame, 120))
                                    {
                                        LEB128.Write(chunkIO.Raw, levelSettingIds.LevelTextures[frame.Texture]);
                                        chunkIO.Raw.Write(frame.TexCoord0);
                                        chunkIO.Raw.Write(frame.TexCoord1);
                                        chunkIO.Raw.Write(frame.TexCoord2);
                                        chunkIO.Raw.Write(frame.TexCoord3);
                                        LEB128.Write(chunkIO.Raw, frame.Repeat);
                                    }
                                }

                                chunkIO.WriteChunkEnd();
                            }
                            chunkIO.WriteChunkEnd();
                        }
                    }
                    chunkIO.WriteChunkEnd();
                }
                using (var chunkAutoMergeStatics = chunkIO.WriteChunk(Prj2Chunks.AutoMergeStaticMeshes, UInt16.MaxValue))
                {
                    foreach (var entry in settings.AutoStaticMeshMerges)
                    {
                        using  (var chunkAutoMergeEntry = chunkIO.WriteChunk(Prj2Chunks.AutoMergeStaticMeshEntry3))
                        {
                            chunkIO.Raw.Write(entry.meshId);
                            chunkIO.Raw.Write(entry.InterpretShadesAsEffect);
                            chunkIO.Raw.Write(entry.TintAsAmbient);
                            chunkIO.Raw.Write(entry.ClearShades);
                        }
                    }
                    chunkIO.WriteChunkEnd();
                }
                using (var chunkPalette = chunkIO.WriteChunk(Prj2Chunks.Palette, UInt16.MaxValue))
                {
                    chunkIO.Raw.Write((ushort)settings.Palette.Count);
                    foreach (var color in settings.Palette)
                    {
                        chunkIO.Raw.Write(color.R);
                        chunkIO.Raw.Write(color.G);
                        chunkIO.Raw.Write(color.B);
                    }
                    chunkIO.WriteChunkEnd();
                }
                chunkIO.WriteChunkEnd();
            };

            return(levelSettingIds);
        }