Example #1
0
        public static SandboxPlacement DeserializePlacement(EndianStream stream)
        {
            var placement = new SandboxPlacement();

            placement.PlacementFlags    = stream.ReadUInt16();
            placement.Unknown_1         = stream.ReadUInt16();
            placement.ObjectDatumHandle = stream.ReadUInt32();
            placement.GizmoDatumHandle  = stream.ReadUInt32();
            placement.BudgetIndex       = stream.ReadInt32();
            placement.Position          = DeserializeVector3(stream);
            placement.RightVector       = DeserializeVector3(stream);
            placement.UpVector          = DeserializeVector3(stream);
            placement.Unknown_2         = stream.ReadUInt32();
            placement.Unknown_3         = stream.ReadUInt32();
            placement.EngineFlags       = stream.ReadUInt16();
            placement.Flags             = stream.ReadUInt8();
            placement.Team            = stream.ReadUInt8();
            placement.Extra           = stream.ReadUInt8();
            placement.RespawnTime     = stream.ReadUInt8();
            placement.ObjectType      = stream.ReadUInt8();
            placement.ZoneShape       = stream.ReadUInt8();
            placement.ZoneRadiusWidth = stream.ReadFloat();
            placement.ZoneDepth       = stream.ReadFloat();
            placement.ZoneTop         = stream.ReadFloat();
            placement.ZoneBottom      = stream.ReadFloat();
            return(placement);
        }
Example #2
0
            public static SandboxPlacement Deserialize(StreamHelper streamHelper)
            {
                SandboxPlacement placmeent = new SandboxPlacement();

                placmeent.offset = streamHelper.Position;

                placmeent.placementFlags    = (PlacementFlags)streamHelper.ReadUInt16();
                placmeent.unknown1          = streamHelper.ReadInt16();
                placmeent.objectDatumHandle = streamHelper.ReadInt32();
                placmeent.gizmoDatumHandle  = streamHelper.ReadInt32();
                placmeent.budgetIndex       = streamHelper.ReadInt32();
                placmeent.position          = streamHelper.ReadVector3();
                placmeent.rightVector       = streamHelper.ReadVector3();
                placmeent.upVector          = streamHelper.ReadVector3();
                placmeent.unknown2          = streamHelper.ReadInt32();
                placmeent.unknown3          = streamHelper.ReadInt32();
                placmeent.engineFlags       = streamHelper.ReadInt16();
                placmeent.flags             = (Flags)streamHelper.ReadUInt8();
                placmeent.team            = (Teams)streamHelper.ReadUInt8();
                placmeent.extra           = streamHelper.ReadUInt8();
                placmeent.respawnTime     = streamHelper.ReadUInt8();
                placmeent.objectType      = streamHelper.ReadUInt8();
                placmeent.zoneShape       = (ZoneShapes)streamHelper.ReadUInt8();
                placmeent.zoneRadiusWidth = streamHelper.ReadFloat();
                placmeent.zoneDepth       = streamHelper.ReadFloat();
                placmeent.zoneTop         = streamHelper.ReadFloat();
                placmeent.zoneBottom      = streamHelper.ReadFloat();

                return(placmeent);
            }
Example #3
0
 public static void SerializePlacement(EndianStream stream, SandboxPlacement placement)
 {
     stream.WriteUInt16(placement.PlacementFlags);
     stream.WriteUInt16(placement.Unknown_1);
     stream.WriteUInt32(placement.ObjectDatumHandle);
     stream.WriteUInt32(placement.GizmoDatumHandle);
     stream.WriteInt32(placement.BudgetIndex);
     SerializeVector3(stream, placement.Position);
     SerializeVector3(stream, placement.RightVector);
     SerializeVector3(stream, placement.UpVector);
     stream.WriteUInt32(placement.Unknown_2);
     stream.WriteUInt32(placement.Unknown_3);
     stream.WriteUInt16(placement.EngineFlags);
     stream.WriteUInt8(placement.Flags);
     stream.WriteUInt8(placement.Team);
     stream.WriteUInt8(placement.Extra);
     stream.WriteUInt8(placement.RespawnTime);
     stream.WriteUInt8(placement.ObjectType);
     stream.WriteUInt8(placement.ZoneShape);
     stream.WriteFloat(placement.ZoneRadiusWidth);
     stream.WriteFloat(placement.ZoneDepth);
     stream.WriteFloat(placement.ZoneTop);
     stream.WriteFloat(placement.ZoneBottom);
 }
        public static void RemoveInvisSpawns(string srcFileName, string destFileName)
        {
            var tagMap = LoadTagMap();


            UsermapConversion.addStatus("Opening " + srcFileName);

            using (var srcStream = new EndianStream(File.Open(srcFileName, FileMode.Open, FileAccess.ReadWrite), EndianStream.EndianType.LittleEndian))
                using (var outStream = new EndianStream(File.Open(destFileName, FileMode.Create, FileAccess.ReadWrite), EndianStream.EndianType.LittleEndian))
                {
                    SandboxMap srcMap = Usermap.DeserializeSandboxMap(srcStream);

                    if (!File.Exists(GetCanvasFileName(srcMap.MapId)))
                    {
                        return;
                    }

                    using (var canvasStream = new EndianStream(File.OpenRead(GetCanvasFileName(srcMap.MapId)), EndianStream.EndianType.LittleEndian))
                    {
                        var canvasMap = Usermap.DeserializeSandboxMap(canvasStream);

                        UsermapConversion.addStatus("Map has a " + srcMap.TotalObjectCount + " total objects and " + srcMap.BudgetEntryCount + " budget entries and " + srcMap.ScnrObjectCount + " scenario objects");

                        var newBudgetEntries = new List <BudgetEntry>();
                        var newPlacements    = new List <SandboxPlacement>();

                        var totalObjectCount = srcMap.TotalObjectCount;
                        var budgetEntryCount = srcMap.BudgetEntryCount;

                        // copy everything 1:1, then remove invis spawns
                        for (int i = 0; i < 640; i++)
                        {
                            newPlacements.Add(srcMap.Placements[i].Clone());
                        }

                        for (int i = 0; i < 256; i++)
                        {
                            newBudgetEntries.Add(srcMap.Budget[i].Clone());
                        }

                        // Find empty placement from canvasMap to use for replacing the invis spawn placements
                        var placementFlagsForRemovedInvisSpawns = ushort.Parse("29", NumberStyles.HexNumber);
                        SandboxPlacement emptyPlacement         = null;
                        for (int i = 0; i < 640; i++)
                        {
                            var canvasPlacement = canvasMap.Placements[i];

                            //UsermapConversion.addStatus(canvasPlacement.PlacementFlags.ToString("X") + " " + canvasPlacement.Unknown_1.ToString("X") + " " + canvasPlacement.ObjectDatumHandle.ToString("X") + " " + canvasPlacement.GizmoDatumHandle.ToString("X") + " " + canvasPlacement.BudgetIndex + " " + canvasPlacement.Unknown_2.ToString("X") + " " + canvasPlacement.Unknown_3.ToString("X") + " " + canvasPlacement.EngineFlags.ToString("X") + " " + canvasPlacement.Flags.ToString("X") + " " + canvasPlacement.Team + " " + canvasPlacement.Extra + " " + canvasPlacement.RespawnTime + " " + canvasPlacement.ObjectType + " " + canvasPlacement.ZoneShape + " " + canvasPlacement.ZoneRadiusWidth + " " + canvasPlacement.ZoneDepth + " " + canvasPlacement.ZoneTop + " " + canvasPlacement.ZoneBottom + " " + +i);
                            //UsermapConversion.addStatus(canvasPlacement.PlacementFlags.ToString("X") + " " + canvasPlacement.Unknown_1.ToString("X") + " " + canvasPlacement.ObjectDatumHandle.ToString("X") + " " + canvasPlacement.GizmoDatumHandle.ToString("X") + " " + canvasPlacement.BudgetIndex + " " + canvasPlacement.Position + " " + canvasPlacement.RightVector + " " + canvasPlacement.UpVector + " " + canvasPlacement.Unknown_2.ToString("X") + " " + canvasPlacement.Unknown_3.ToString("X") + " " + canvasPlacement.EngineFlags.ToString("X") + " " + canvasPlacement.Flags.ToString("X") + " " + canvasPlacement.Team + " " + canvasPlacement.Extra + " " + canvasPlacement.RespawnTime + " " + canvasPlacement.ObjectType + " " + canvasPlacement.ZoneShape + " " + canvasPlacement.ZoneRadiusWidth + " " + canvasPlacement.ZoneDepth + " " + canvasPlacement.ZoneTop + " " + canvasPlacement.ZoneBottom + " " + + i);

                            if (canvasPlacement.BudgetIndex == -1 && placementFlagsForRemovedInvisSpawns == canvasPlacement.PlacementFlags) // this is to find empty placements. The first objects in each file have a placementflags set to 29 (hex), despite budgetindex being -1. I am not yet sure which one is needed moar here, I'll go with the default empty one for now
                            {
                                UsermapConversion.addStatus("Empty reference placement found at index " + i);
                                UsermapConversion.addStatus(canvasPlacement.PlacementFlags.ToString("X") + " " + canvasPlacement.Unknown_1.ToString("X") + " " + canvasPlacement.ObjectDatumHandle.ToString("X") + " " + canvasPlacement.GizmoDatumHandle.ToString("X") + " " + canvasPlacement.BudgetIndex + " " + canvasPlacement.Unknown_2.ToString("X") + " " + canvasPlacement.Unknown_3.ToString("X") + " " + canvasPlacement.EngineFlags.ToString("X") + " " + canvasPlacement.Flags.ToString("X") + " " + canvasPlacement.Team + " " + canvasPlacement.Extra + " " + canvasPlacement.RespawnTime + " " + canvasPlacement.ObjectType + " " + canvasPlacement.ZoneShape + " " + canvasPlacement.ZoneRadiusWidth + " " + canvasPlacement.ZoneDepth + " " + canvasPlacement.ZoneTop + " " + canvasPlacement.ZoneBottom + " " + +i);
                                emptyPlacement = canvasPlacement.Clone();
                                break;
                            }
                        }

                        var emptyBudgetEntry = new BudgetEntry() // Values found by analyzing actual empty entries in sandbox.map files
                        {
                            TagIndex      = 0xFFFFFFFF,
                            RuntimeMin    = 0,
                            RuntimeMax    = 0,
                            CountOnMap    = 0,
                            DesignTimeMax = 255,
                            Cost          = -1
                        };


                        /*for (int i = 0; i < 256; i++)
                         * {
                         *  var canvasBudgetEntry = canvasMap.Budget[i];
                         *  UsermapConversion.addStatus(canvasBudgetEntry.TagIndex.ToString("X")+" "+canvasBudgetEntry.RuntimeMin + " " + canvasBudgetEntry.RuntimeMax + " " + canvasBudgetEntry.CountOnMap + " " + canvasBudgetEntry.DesignTimeMax + " " + canvasBudgetEntry.Cost+ " " + i);
                         * }*/

                        var invisSpawnTagIndex = uint.Parse("2EA6", NumberStyles.HexNumber);

                        for (int i = 0; i < 640; i++)
                        {
                            var placement = newPlacements[i];

                            if (placement.BudgetIndex == -1)
                            {
                                continue;
                            }

                            if (newBudgetEntries.ElementAtOrDefault(placement.BudgetIndex) != null)
                            {
                                var tagIndex = newBudgetEntries[placement.BudgetIndex].TagIndex;
                                if (tagIndex == invisSpawnTagIndex)
                                {
                                    UsermapConversion.addStatus("Found invisible spawn at placement index " + i + ", budget index " + placement.BudgetIndex + ", removing now. Likely remaining invis spawn points: " + newBudgetEntries[placement.BudgetIndex].CountOnMap--);
                                    //totalObjectCount--; // Don't reduce total object count, as apparently it isn't really influenced by how many objects are actually spawned. Weird as it sounds. Or maybe it just isn't influenced by these invis spawns. Either way, better withotu changing it for now.
                                    newPlacements[i] = emptyPlacement.Clone();
                                }
                            }
                        }

                        for (int i = 0; i < 256; i++)
                        {
                            var budgetEntry = newBudgetEntries[i];
                            if (budgetEntry.TagIndex == invisSpawnTagIndex)
                            {
                                newBudgetEntries[i] = emptyBudgetEntry.Clone();
                                //budgetEntryCount--; // Let's try not changing it once.
                            }
                        }



                        srcStream.SeekTo(0);
                        srcStream.Stream.CopyTo(outStream.Stream);

                        outStream.SeekTo(0x30);
                        srcStream.SeekTo(0x30);
                        outStream.WriteBytes(srcStream.ReadBytes(0x108)); //chdr
                        outStream.WriteBytes(srcStream.ReadBytes(0x140)); //map

                        outStream.SeekTo(0x242);
                        outStream.WriteInt16(srcMap.ScnrObjectCount);
                        outStream.WriteInt16((short)totalObjectCount);
                        outStream.WriteInt16((short)budgetEntryCount);

                        outStream.SeekTo(0x278);
                        foreach (var placement in newPlacements)
                        {
                            Usermap.SerializePlacement(outStream, placement);
                        }

                        outStream.SeekTo(0xD498);
                        foreach (var entry in newBudgetEntries)
                        {
                            Usermap.SerializeBudgetEntry(outStream, entry);
                        }
                    }
                }
        }
Example #5
0
        public static MapVariant Deserialize(StreamHelper streamHelper)
        {
            MapVariant mapVariant = new MapVariant();

            streamHelper.Skip(4); //mapVariant._blf = streamHelper.ReadInt32();
            mapVariant.blfUnknown = streamHelper.ReadBytes(0x2C);
            streamHelper.Skip(4); //mapVariant.chdr = streamHelper.ReadInt32();
            mapVariant.chdrHeaderUnknown1     = streamHelper.ReadBytes(0x14);
            mapVariant.chdrHeaderName         = streamHelper.ReadUTF16(0x20);
            mapVariant.chdrHeaderDescription  = streamHelper.ReadAscii(0x80);
            mapVariant.chdrHeaderAuthor       = streamHelper.ReadAscii(0x10);
            mapVariant.chdrHeaderSize         = streamHelper.ReadInt64();
            mapVariant.chdrHeaderCreationDate = streamHelper.ReadInt64();
            mapVariant.chdrHeaderUnknown2     = streamHelper.ReadInt64();
            mapVariant.chdrHeaderUnknown3     = streamHelper.ReadInt32();
            mapVariant.chdrHeaderUnknown4     = streamHelper.ReadInt32();
            mapVariant.chdrHeaderUnknown5     = streamHelper.ReadInt32();
            mapVariant.chdrHeaderUnknown6     = streamHelper.ReadInt32();
            mapVariant.chdrHeaderMapID        = streamHelper.ReadInt32();
            mapVariant.chdrHeaderUnknown7     = streamHelper.ReadInt32();
            mapVariant.chdrHeaderUnknown8     = streamHelper.ReadInt32();
            mapVariant.chdrHeaderUnknown9     = streamHelper.ReadBytes(0xC);
            streamHelper.Skip(4);//mapVariant.mapv = streamHelper.ReadInt32();
            mapVariant.mapvHeaderUnknown1     = streamHelper.ReadBytes(0x14);
            mapVariant.mapvHeaderName         = streamHelper.ReadUTF16(0x20);
            mapVariant.mapvHeaderDescription  = streamHelper.ReadAscii(0x80);
            mapVariant.mapvHeaderAuthor       = streamHelper.ReadAscii(0x10);
            mapVariant.mapvHeaderSize         = streamHelper.ReadInt64();
            mapVariant.mapvHeaderCreationDate = streamHelper.ReadInt64();
            mapVariant.mapvHeaderUnknown2     = streamHelper.ReadInt64();
            mapVariant.mapvHeaderUnknown3     = streamHelper.ReadInt32();
            mapVariant.mapvHeaderUnknown4     = streamHelper.ReadInt32();
            mapVariant.mapvHeaderUnknown5     = streamHelper.ReadInt32();
            mapVariant.mapvHeaderUnknown6     = streamHelper.ReadInt32();
            mapVariant.mapvHeaderMapID        = streamHelper.ReadInt32();
            mapVariant.mapvHeaderUnknown7     = streamHelper.ReadInt32();
            mapVariant.mapvHeaderUnknown8     = streamHelper.ReadInt32();
            mapVariant.mapvHeaderUnknown9     = streamHelper.ReadBytes(0xC);

            mapVariant.scnrObjectsCount       = streamHelper.ReadInt16();
            mapVariant.totalObjectsCount      = streamHelper.ReadInt16();
            mapVariant.budgetEntriesCount     = streamHelper.ReadInt16();
            mapVariant.sandboxPlacementsCount = streamHelper.ReadInt16();
            mapVariant.mapID         = streamHelper.ReadInt32();
            mapVariant.worldBoundsX  = streamHelper.ReadVector2();
            mapVariant.worldBoundsY  = streamHelper.ReadVector2();
            mapVariant.worldBoundsZ  = streamHelper.ReadVector2();
            mapVariant.unknown1      = streamHelper.ReadInt32();
            mapVariant.maxBudget     = streamHelper.ReadFloat();
            mapVariant.currentBudget = streamHelper.ReadFloat();
            mapVariant.unknown2      = streamHelper.ReadInt32();
            mapVariant.unknown3      = streamHelper.ReadInt32();

            mapVariant.sandboxPlacements = new List <SandboxPlacement>();
            for (int i = 0; i < 640; i++)
            {
                mapVariant.sandboxPlacements.Add(SandboxPlacement.Deserialize(streamHelper));
            }

            mapVariant.unknown4 = streamHelper.ReadBytes(0x38);

            mapVariant.budgetEntries = new List <BudgetEntry>();
            for (int i = 0; i < 256; i++)
            {
                mapVariant.budgetEntries.Add(BudgetEntry.Deserialize(streamHelper));
            }

            mapVariant.unknownPad = streamHelper.ReadBytes(0x140);

            streamHelper.Skip(4); //mapVariant._eof = streamHelper.ReadInt32();

            mapVariant.unknown5 = streamHelper.ReadBytes(0xC);
            mapVariant.emptyPad = streamHelper.ReadBytes(0xE1C);

            return(mapVariant);
        }