@@ -12,8 +12,8 @@ public partial class D2Save
1212 /// <summary>File magic value: 0xAA55AA55</summary>
1313 public const uint Magic = 0xAA55AA55 ;
1414
15- /// <summary>Current save version (96 for 1.10+ ).</summary>
16- public const uint CurrentVersion = 96 ;
15+ /// <summary>Current save version (105 for D2R 3.x ).</summary>
16+ public const uint CurrentVersion = 105 ;
1717
1818 /// <summary>Save file version.</summary>
1919 public uint Version { get ; set ; } = CurrentVersion ;
@@ -104,7 +104,7 @@ public static D2Save Read(ReadOnlySpan<byte> data, IExternalData externalData)
104104 save . Corpses = CorpseSection . Read ( ref reader , externalData , save . Version ) ;
105105
106106 // Expansion-only sections
107- if ( save . Character . Flags . HasFlag ( CharacterFlags . Expansion ) )
107+ if ( save . IsExpansion ( save . Version ) )
108108 {
109109 save . MercItems = MercItemsSection . Read ( ref reader , externalData , save . Character . MercData . HasMerc , save . Version ) ;
110110 save . IronGolem = IronGolemSection . Read ( ref reader , externalData , save . Version ) ;
@@ -171,7 +171,7 @@ public int Write(Span<byte> buffer, IExternalData externalData, uint? targetVers
171171 Corpses . Write ( ref writer , externalData , Version ) ;
172172
173173 // Expansion-only sections
174- if ( Character . Flags . HasFlag ( CharacterFlags . Expansion ) )
174+ if ( IsExpansion ( Version ) )
175175 {
176176 ( MercItems ?? new MercItemsSection ( ) ) . Write ( ref writer , externalData , Character . MercData . HasMerc , Version ) ;
177177 ( IronGolem ?? new IronGolemSection ( ) ) . Write ( ref writer , externalData , Version ) ;
@@ -227,7 +227,7 @@ public int EstimateSize()
227227 }
228228
229229 // Expansion sections
230- if ( Character . Flags . HasFlag ( CharacterFlags . Expansion ) )
230+ if ( IsExpansion ( Version ) )
231231 {
232232 // Merc items
233233 size += 4 + CountItemsRecursive ( MercItems ? . Items ) * 200 ;
@@ -283,6 +283,13 @@ public static bool VerifyChecksum(ReadOnlySpan<byte> data)
283283 return ChecksumCalculator . Verify ( data ) ;
284284 }
285285
286+ /// <summary>
287+ /// Returns true if this save is an expansion save, checking GameVersion for v104+ or CharacterFlags for older versions.
288+ /// </summary>
289+ private bool IsExpansion ( uint version ) => version >= 104
290+ ? Character . Preview . GameVersion > GameVersion . Classic
291+ : Character . Flags . HasFlag ( CharacterFlags . Expansion ) ;
292+
286293 /// <summary>
287294 /// Prepares the save data for writing to a specific version format.
288295 /// Handles conversion between 1.14 (version 96) and D2R (version 97+) formats,
@@ -381,10 +388,11 @@ private void Convert103To104()
381388 }
382389
383390 // GuildEmblemColor: keep low byte (uint -> byte)
384- Character . Preview . GuildEmblemColor = Character . Preview . GuildEmblemColor & 0xFF ;
391+ Character . Preview . GuildEmblemColor &= 0xFF ;
385392
386393 // GameVersion: derive from CharacterFlags
387394 Character . Preview . GameVersion = Character . Flags . HasFlag ( CharacterFlags . Expansion ) ? GameVersion . Expansion : GameVersion . Classic ;
395+ Character . Flags &= ~ CharacterFlags . Expansion ;
388396
389397 // SaveTimes/Experiences: slots 0-1 already populated, 2-5 remain zero (default)
390398 }
@@ -402,6 +410,11 @@ private void Convert104To103()
402410 : Character . Preview . Name ;
403411 }
404412
413+ if ( Character . Preview . GameVersion > GameVersion . Classic )
414+ {
415+ Character . Flags |= CharacterFlags . Expansion ;
416+ }
417+
405418 // GuildEmblemColor: byte -> uint (zero-extend, already correct)
406419
407420 // SaveTimes/Experiences: only [0] and [1] are used in old format
0 commit comments