Example #1
0
        public static TeleportEvent Serdes(TeleportEvent e, AssetMapping mapping, ISerializer s)
        {
            if (s == null)
            {
                throw new ArgumentNullException(nameof(s));
            }
            e ??= new TeleportEvent();
            e.X         = s.UInt8(nameof(X), e.X);
            e.Y         = s.UInt8(nameof(Y), e.Y);
            e.Direction = s.EnumU8(nameof(Direction), e.Direction);
            e.Unk4      = s.UInt8(nameof(Unk4), e.Unk4);
            e.Unk5      = s.UInt8(nameof(Unk5), e.Unk5);
            e.MapId     = MapId.SerdesU16(nameof(MapId), e.MapId, mapping, s);
            int zeroed = s.UInt16(null, 0);

            s.Assert(e.Unk4 == 0 ||
                     e.Unk4 == 1 ||
                     e.Unk4 == 2 ||
                     e.Unk4 == 3 ||
                     e.Unk4 == 6 ||
                     e.Unk4 == 106 ||
                     e.Unk4 == 255, "TeleportEvent: Expected field 4 to be in { 0,1,2,3,6,106,255 }");        // Always 255 in maps
            s.Assert(zeroed == 0, "TeleportEvent: Expected field 8 to be 0");
            return(e);
        }
Example #2
0
    public static CloneAutomapEvent Serdes(CloneAutomapEvent e, AssetMapping mapping, ISerializer s)
    {
        if (s == null)
        {
            throw new ArgumentNullException(nameof(s));
        }
        e ??= new CloneAutomapEvent();
        int zeroes = s.UInt8(null, 0);

        zeroes += s.UInt8(null, 0);
        zeroes += s.UInt8(null, 0);
        zeroes += s.UInt8(null, 0);
        zeroes += s.UInt8(null, 0);
        s.Assert(zeroes == 0, "CloneAutomap: Expected fields 1-5 to be 0");
        e.From = MapId.SerdesU16(nameof(From), e.From, mapping, s);
        e.To   = MapId.SerdesU16(nameof(To), e.To, mapping, s);
        return(e);
    }
Example #3
0
    public static ChangeIconEvent Serdes(ChangeIconEvent e, AssetMapping mapping, ISerializer s)
    {
        if (s == null)
        {
            throw new ArgumentNullException(nameof(s));
        }
        e ??= new ChangeIconEvent();
        e.X          = s.Int8(nameof(X), unchecked ((sbyte)e.X));           // 1
        e.Y          = s.Int8(nameof(Y), unchecked ((sbyte)e.Y));           // 2
        e.Scope      = s.EnumU8(nameof(Scope), e.Scope);                    // 3
        e.ChangeType = s.EnumU8(nameof(ChangeType), e.ChangeType);          // 4
        e.Layers     = s.EnumU8(nameof(Layers), e.Layers);                  // 5
        e.Value      = s.UInt16(nameof(Value), e.Value);                    // 6
        e.MapId      = MapId.SerdesU16(nameof(MapId), e.MapId, mapping, s); // 8

        if (e.Scope is EventScope.AbsPerm or EventScope.AbsTemp)
        {
            e.X = unchecked ((byte)e.X);
            e.Y = unchecked ((byte)e.Y);
        }

        return(e);
    }
Example #4
0
 public static TeleportEvent Serdes(TeleportEvent e, AssetMapping mapping, ISerializer s)
 {
     if (s == null)
     {
         throw new ArgumentNullException(nameof(s));
     }
     e ??= new TeleportEvent();
     e.X         = s.UInt8(nameof(X), e.X);
     e.Y         = s.UInt8(nameof(Y), e.Y);
     e.Direction = s.EnumU8(nameof(Direction), e.Direction);
     e.Unk4      = s.UInt8(nameof(Unk4), e.Unk4);
     e.Unk5      = s.UInt8(nameof(Unk5), e.Unk5);
     e.MapId     = MapId.SerdesU16(nameof(MapId), e.MapId, mapping, s);
     e.Unk8      = s.UInt16(nameof(Unk8), e.Unk8);
     ApiUtil.Assert(e.Unk4 == 0 ||
                    e.Unk4 == 1 ||
                    e.Unk4 == 2 ||
                    e.Unk4 == 3 ||
                    e.Unk4 == 6 ||
                    e.Unk4 == 106 ||
                    e.Unk4 == 255);  // Always 255 in maps
     ApiUtil.Assert(e.Unk8 == 0);
     return(e);
 }
Example #5
0
        public static SavedGame Serdes(SavedGame save, AssetMapping mapping, ISerializer s)
        {
            if (s == null)
            {
                throw new ArgumentNullException(nameof(s));
            }
            save ??= new SavedGame();

            ushort nameLength = s.UInt16("NameLength", (ushort)(save.Name?.Length ?? 0));

            save.Unk0 = s.UInt16(nameof(Unk0), save.Unk0);
            save.Name = s.FixedLengthString(nameof(Name), save.Name, nameLength);

            save.Unk1 = s.UInt32(nameof(Unk1), save.Unk1);
            var versionOffset = s.Offset;

            save.Version = s.UInt16(nameof(Version), save.Version);                 // 0
            ApiUtil.Assert(save.Version == 138);                                    // TODO: Throw error for other versions?
            save.Unk9 = s.ByteArray(nameof(Unk9), save.Unk9, 6);                    // 2

            ushort days    = s.UInt16("Days", (ushort)save.ElapsedTime.TotalDays);  // 8
            ushort hours   = s.UInt16("Hours", (ushort)save.ElapsedTime.Hours);     // A
            ushort minutes = s.UInt16("Minutes", (ushort)save.ElapsedTime.Minutes); // C

            save.ElapsedTime    = new TimeSpan(days, hours, minutes, save.ElapsedTime.Seconds, save.ElapsedTime.Milliseconds);
            save.MapId          = MapId.SerdesU16(nameof(MapId), save.MapId, mapping, s); // E
            save.PartyX         = s.UInt16(nameof(PartyX), save.PartyX);                  // 10
            save.PartyY         = s.UInt16(nameof(PartyY), save.PartyY);                  // 12
            save.PartyDirection = s.EnumU16(nameof(PartyDirection), save.PartyDirection); // 14

            save.Unknown16 = s.ByteArrayHex(nameof(Unknown16), save.Unknown16, 0x184);    // 16

            save.ActiveMembers = s.List(
                nameof(ActiveMembers),
                save.ActiveMembers,
                MaxPartySize,
                (i, x, s2) =>
            {
                var value = PartyMemberId.SerdesU8(null, save.ActiveMembers[i], mapping, s);
                s2.UInt8("dummy", 0);
                return(value);
            });

            save.Misc = s.Object(nameof(Misc), save.Misc, MiscState.Serdes); // 1A6
            save._switches.SetPacked(0,
                                     s.ByteArrayHex("Switches",
                                                    save._switches.GetPacked(0, FlagDictionary.OriginalSaveGameMax, mapping),
                                                    FlagDictionary.PackedSize(0, FlagDictionary.OriginalSaveGameMax)), mapping); // 276

            save.Unknown2C1 = s.ByteArrayHex(nameof(Unknown2C1), save.Unknown2C1, 0x5833);                                       // 0x2C1
            s.Object(nameof(Tickers), save._tickers, TickerDictionary.Serdes);                                                   // 5AF4

            save.Unknown5B9F = s.ByteArrayHex(nameof(Unknown5B9F), save.Unknown5B9F, 0x2C);
            var mapType = MapType.TwoD;

            s.List(nameof(save.Npcs), save.Npcs, (mapType, mapping), MaxNpcCount, NpcState.Serdes);

            save.Unknown5B71 = s.ByteArrayHex(
                nameof(Unknown5B71),
                save.Unknown5B71,
                (int)(0x947C + versionOffset - s.Offset)); // 5B9F

            uint   permChangesSize  = s.UInt32("PermanentMapChanges_Size", (uint)(save.PermanentMapChanges.Count * MapChange.SizeOnDisk + 2));
            ushort permChangesCount = s.UInt16("PermanentMapChanges_Count", (ushort)save.PermanentMapChanges.Count);

            ApiUtil.Assert(permChangesSize == permChangesCount * MapChange.SizeOnDisk + 2);
            save.PermanentMapChanges = (MapChangeCollection)s.List(
                nameof(PermanentMapChanges),
                save.PermanentMapChanges,
                mapping,
                permChangesCount,
                MapChange.Serdes,
                _ => new MapChangeCollection());

            uint   tempChangesSize  = s.UInt32("TemporaryMapChanges_Size", (uint)(save.TemporaryMapChanges.Count * MapChange.SizeOnDisk + 2));
            ushort tempChangesCount = s.UInt16("TemporaryMapChanges_Count", (ushort)save.TemporaryMapChanges.Count);

            ApiUtil.Assert(tempChangesSize == tempChangesCount * MapChange.SizeOnDisk + 2);

            save.TemporaryMapChanges = (MapChangeCollection)s.List(
                nameof(TemporaryMapChanges),
                save.TemporaryMapChanges,
                mapping,
                tempChangesCount,
                MapChange.Serdes,
                _ => new MapChangeCollection());

            uint   visitedEventsSize  = s.UInt32("VisitedEvents_Size", (uint)(save.VisitedEvents.Count * VisitedEvent.SizeOnDisk + 2));
            ushort visitedEventsCount = s.UInt16("VisitedEvents_Count", (ushort)save.VisitedEvents.Count);

            ApiUtil.Assert(visitedEventsSize == visitedEventsCount * VisitedEvent.SizeOnDisk + 2);
            save.VisitedEvents = s.List(nameof(VisitedEvents), save.VisitedEvents, mapping, visitedEventsCount, VisitedEvent.Serdes);

            var partyIds = save.Sheets.Keys.Select(x => x.Id).ToList();

            partyIds.Add(199); // Force extra XLD length fields to be written for empty objects to preserve compat with original game.
            partyIds.Add(299);

            // s.Object($"XldPartyCharacter.0");

            XldContainerLoader.Serdes(XldCategory.PartyCharacter, 0, (save, mapping), s, SerdesPartyCharacter, partyIds);
            XldContainerLoader.Serdes(XldCategory.PartyCharacter, 1, (save, mapping), s, SerdesPartyCharacter, partyIds);
            XldContainerLoader.Serdes(XldCategory.PartyCharacter, 2, (save, mapping), s, SerdesPartyCharacter, partyIds);

            var automapIds = save.Automaps.Keys.Select(x => x.Id).ToList(); // TODO: Allow extension somehow

            automapIds.Add(199);
            automapIds.Add(399);
            XldContainerLoader.Serdes(XldCategory.Automap, 1, (save, mapping), s, SerdesAutomap, automapIds);
            XldContainerLoader.Serdes(XldCategory.Automap, 2, (save, mapping), s, SerdesAutomap, automapIds);
            XldContainerLoader.Serdes(XldCategory.Automap, 3, (save, mapping), s, SerdesAutomap, automapIds);

            var chestIds = save.Inventories.Keys.Select(x => x.Id).ToList(); // TODO: Allow extension somehow

            chestIds.Add(199);
            chestIds.Add(599);
            XldContainerLoader.Serdes(XldCategory.Chest, 0, (save, mapping), s, SerdesChest, chestIds);
            XldContainerLoader.Serdes(XldCategory.Chest, 1, (save, mapping), s, SerdesChest, chestIds);
            XldContainerLoader.Serdes(XldCategory.Chest, 2, (save, mapping), s, SerdesChest, chestIds);
            XldContainerLoader.Serdes(XldCategory.Chest, 5, (save, mapping), s, SerdesChest, chestIds);

            var merchantIds = save.Inventories.Keys.Select(x => x.Id).ToList(); // TODO: Allow extension somehow

            merchantIds.Add(199);
            merchantIds.Add(299);
            XldContainerLoader.Serdes(XldCategory.Merchant, 0, (save, mapping), s, SerdesMerchant, merchantIds);
            XldContainerLoader.Serdes(XldCategory.Merchant, 1, (save, mapping), s, SerdesMerchant, merchantIds);
            XldContainerLoader.Serdes(XldCategory.Merchant, 2, (save, mapping), s, SerdesMerchant, merchantIds);

            var npcIds = save.Sheets.Keys.Select(x => x.Id).ToList(); // TODO: Allow extension somehow

            npcIds.Add(299);
            XldContainerLoader.Serdes(XldCategory.NpcCharacter, 0, (save, mapping), s, SerdesNpcCharacter, npcIds);
            XldContainerLoader.Serdes(XldCategory.NpcCharacter, 1, (save, mapping), s, SerdesNpcCharacter, npcIds);
            XldContainerLoader.Serdes(XldCategory.NpcCharacter, 2, (save, mapping), s, SerdesNpcCharacter, npcIds);

            s.RepeatU8("Padding", 0, 4);

            // TODO: Save additional sheets & inventories from mods.

            return(save);
        }