@@ -2021,6 +2021,7 @@ public class LayerAssetsData : LayerData
2021
2021
public UndertalePointerList < SequenceInstance > Sequences { get ; set ; }
2022
2022
public UndertalePointerList < SpriteInstance > NineSlices { get ; set ; } // Removed in 2.3.2, before never used
2023
2023
public UndertalePointerList < ParticleSystemInstance > ParticleSystems { get ; set ; }
2024
+ public UndertalePointerList < TextItemInstance > TextItems { get ; set ; }
2024
2025
2025
2026
/// <inheritdoc />
2026
2027
public void Serialize ( UndertaleWriter writer )
@@ -2034,6 +2035,8 @@ public void Serialize(UndertaleWriter writer)
2034
2035
writer . WriteUndertaleObjectPointer ( NineSlices ) ;
2035
2036
if ( writer . undertaleData . IsNonLTSVersionAtLeast ( 2023 , 2 ) )
2036
2037
writer . WriteUndertaleObjectPointer ( ParticleSystems ) ;
2038
+ if ( writer . undertaleData . IsVersionAtLeast ( 2024 , 6 ) )
2039
+ writer . WriteUndertaleObjectPointer ( TextItems ) ;
2037
2040
}
2038
2041
writer . WriteUndertaleObject ( LegacyTiles ) ;
2039
2042
writer . WriteUndertaleObject ( Sprites ) ;
@@ -2044,12 +2047,18 @@ public void Serialize(UndertaleWriter writer)
2044
2047
writer . WriteUndertaleObject ( NineSlices ) ;
2045
2048
if ( writer . undertaleData . IsNonLTSVersionAtLeast ( 2023 , 2 ) )
2046
2049
writer . WriteUndertaleObject ( ParticleSystems ) ;
2050
+ if ( writer . undertaleData . IsVersionAtLeast ( 2024 , 6 ) )
2051
+ writer . WriteUndertaleObject ( TextItems ) ;
2047
2052
}
2048
2053
}
2049
2054
2050
2055
/// <inheritdoc />
2051
2056
public void Unserialize ( UndertaleReader reader )
2052
2057
{
2058
+ // Track first pointer target to detect additional data
2059
+ long firstPointerTarget = reader . ReadUInt32 ( ) ;
2060
+ reader . Position -= 4 ;
2061
+
2053
2062
LegacyTiles = reader . ReadUndertaleObjectPointer < UndertalePointerList < Tile > > ( ) ;
2054
2063
Sprites = reader . ReadUndertaleObjectPointer < UndertalePointerList < SpriteInstance > > ( ) ;
2055
2064
if ( reader . undertaleData . IsVersionAtLeast ( 2 , 3 ) )
@@ -2059,6 +2068,10 @@ public void Unserialize(UndertaleReader reader)
2059
2068
NineSlices = reader . ReadUndertaleObjectPointer < UndertalePointerList < SpriteInstance > > ( ) ;
2060
2069
if ( reader . undertaleData . IsNonLTSVersionAtLeast ( 2023 , 2 ) )
2061
2070
ParticleSystems = reader . ReadUndertaleObjectPointer < UndertalePointerList < ParticleSystemInstance > > ( ) ;
2071
+ if ( firstPointerTarget > reader . AbsPosition && ! reader . undertaleData . IsVersionAtLeast ( 2024 , 6 ) )
2072
+ reader . undertaleData . SetGMS2Version ( 2024 , 6 ) ; // There's more data before legacy tiles, so must be 2024.6+
2073
+ if ( reader . undertaleData . IsVersionAtLeast ( 2024 , 6 ) )
2074
+ TextItems = reader . ReadUndertaleObjectPointer < UndertalePointerList < TextItemInstance > > ( ) ;
2062
2075
}
2063
2076
reader . ReadUndertaleObject ( LegacyTiles ) ;
2064
2077
reader . ReadUndertaleObject ( Sprites ) ;
@@ -2069,6 +2082,8 @@ public void Unserialize(UndertaleReader reader)
2069
2082
reader . ReadUndertaleObject ( NineSlices ) ;
2070
2083
if ( reader . undertaleData . IsNonLTSVersionAtLeast ( 2023 , 2 ) )
2071
2084
reader . ReadUndertaleObject ( ParticleSystems ) ;
2085
+ if ( reader . undertaleData . IsVersionAtLeast ( 2024 , 6 ) )
2086
+ reader . ReadUndertaleObject ( TextItems ) ;
2072
2087
}
2073
2088
}
2074
2089
@@ -2082,13 +2097,18 @@ public static uint UnserializeChildObjectCount(UndertaleReader reader)
2082
2097
uint sequencesPtr = 0 ;
2083
2098
uint nineSlicesPtr = 0 ;
2084
2099
uint partSystemsPtr = 0 ;
2100
+ uint textItemsPtr = 0 ;
2085
2101
if ( reader . undertaleData . IsVersionAtLeast ( 2 , 3 ) )
2086
2102
{
2087
2103
sequencesPtr = reader . ReadUInt32 ( ) ;
2088
2104
if ( ! reader . undertaleData . IsVersionAtLeast ( 2 , 3 , 2 ) )
2089
2105
nineSlicesPtr = reader . ReadUInt32 ( ) ;
2090
2106
if ( reader . undertaleData . IsNonLTSVersionAtLeast ( 2023 , 2 ) )
2091
2107
partSystemsPtr = reader . ReadUInt32 ( ) ;
2108
+ if ( legacyTilesPtr > reader . AbsPosition && ! reader . undertaleData . IsVersionAtLeast ( 2024 , 6 ) )
2109
+ reader . undertaleData . SetGMS2Version ( 2024 , 6 ) ; // There's more data before legacy tiles, so must be 2024.6+
2110
+ if ( reader . undertaleData . IsVersionAtLeast ( 2024 , 6 ) )
2111
+ textItemsPtr = reader . ReadUInt32 ( ) ;
2092
2112
}
2093
2113
2094
2114
reader . AbsPosition = legacyTilesPtr ;
@@ -2109,6 +2129,11 @@ public static uint UnserializeChildObjectCount(UndertaleReader reader)
2109
2129
reader . AbsPosition = partSystemsPtr ;
2110
2130
count += 1 + UndertalePointerList < ParticleSystemInstance > . UnserializeChildObjectCount ( reader ) ;
2111
2131
}
2132
+ if ( reader . undertaleData . IsVersionAtLeast ( 2024 , 6 ) )
2133
+ {
2134
+ reader . AbsPosition = textItemsPtr ;
2135
+ count += 1 + UndertalePointerList < TextItemInstance > . UnserializeChildObjectCount ( reader ) ;
2136
+ }
2112
2137
}
2113
2138
2114
2139
return count ;
@@ -2363,6 +2388,9 @@ public void Unserialize(UndertaleReader reader)
2363
2388
Rotation = reader . ReadSingle ( ) ;
2364
2389
}
2365
2390
2391
+ /// <summary>
2392
+ /// Generates a random name for this instance, as a utility for room editing.
2393
+ /// </summary>
2366
2394
//TODO: rework this method slightly.
2367
2395
public static UndertaleString GenerateRandomName ( UndertaleData data )
2368
2396
{
@@ -2525,6 +2553,9 @@ public void Unserialize(UndertaleReader reader)
2525
2553
Rotation = reader . ReadSingle ( ) ;
2526
2554
}
2527
2555
2556
+ /// <summary>
2557
+ /// Generates a random name for this instance, as a utility for room editing.
2558
+ /// </summary>
2528
2559
public static UndertaleString GenerateRandomName ( UndertaleData data )
2529
2560
{
2530
2561
return data . Strings . MakeString ( "particle_" + ( ( uint ) Random . Shared . Next ( - Int32 . MaxValue , Int32 . MaxValue ) ) . ToString ( "X8" ) ) ;
@@ -2545,6 +2576,118 @@ public void Dispose()
2545
2576
Name = null ;
2546
2577
}
2547
2578
}
2579
+
2580
+ public class TextItemInstance : UndertaleObject , INotifyPropertyChanged , IStaticChildObjCount , IStaticChildObjectsSize , IDisposable
2581
+ {
2582
+ /// <inheritdoc cref="IStaticChildObjCount.ChildObjectCount" />
2583
+ public static readonly uint ChildObjectCount = 1 ;
2584
+
2585
+ /// <inheritdoc cref="IStaticChildObjectsSize.ChildObjectsSize" />
2586
+ public static readonly uint ChildObjectsSize = 68 ;
2587
+
2588
+ public event PropertyChangedEventHandler PropertyChanged ;
2589
+ protected void OnPropertyChanged ( [ CallerMemberName ] string name = null )
2590
+ {
2591
+ PropertyChanged ? . Invoke ( this , new PropertyChangedEventArgs ( name ) ) ;
2592
+ }
2593
+
2594
+ private UndertaleResourceById < UndertaleFont , UndertaleChunkFONT > _font = new ( ) ;
2595
+
2596
+ // TODO: document these fields; some are self-explanatory but unsure on the behavior of all of them
2597
+ public UndertaleString Name { get ; set ; }
2598
+ public int X { get ; set ; }
2599
+ public int Y { get ; set ; }
2600
+ public UndertaleFont Font
2601
+ {
2602
+ get => _font . Resource ;
2603
+ set
2604
+ {
2605
+ _font . Resource = value ;
2606
+ OnPropertyChanged ( ) ;
2607
+ }
2608
+ }
2609
+ public float ScaleX { get ; set ; }
2610
+ public float ScaleY { get ; set ; }
2611
+ public float Rotation { get ; set ; }
2612
+ public uint Color { get ; set ; }
2613
+ public float OriginX { get ; set ; }
2614
+ public float OriginY { get ; set ; }
2615
+ public UndertaleString Text { get ; set ; }
2616
+ public int Alignment { get ; set ; }
2617
+ public float CharSpacing { get ; set ; }
2618
+ public float LineSpacing { get ; set ; }
2619
+ public float FrameWidth { get ; set ; }
2620
+ public float FrameHeight { get ; set ; }
2621
+ public bool Wrap { get ; set ; }
2622
+
2623
+ /// <inheritdoc />
2624
+ public void Serialize ( UndertaleWriter writer )
2625
+ {
2626
+ writer . WriteUndertaleString ( Name ) ;
2627
+ writer . Write ( X ) ;
2628
+ writer . Write ( Y ) ;
2629
+ writer . WriteUndertaleObject ( _font ) ;
2630
+ writer . Write ( ScaleX ) ;
2631
+ writer . Write ( ScaleY ) ;
2632
+ writer . Write ( Rotation ) ;
2633
+ writer . Write ( Color ) ;
2634
+ writer . Write ( OriginX ) ;
2635
+ writer . Write ( OriginY ) ;
2636
+ writer . WriteUndertaleString ( Text ) ;
2637
+ writer . Write ( Alignment ) ;
2638
+ writer . Write ( CharSpacing ) ;
2639
+ writer . Write ( LineSpacing ) ;
2640
+ writer . Write ( FrameWidth ) ;
2641
+ writer . Write ( FrameHeight ) ;
2642
+ writer . Write ( Wrap ) ;
2643
+ }
2644
+
2645
+ /// <inheritdoc />
2646
+ public void Unserialize ( UndertaleReader reader )
2647
+ {
2648
+ Name = reader . ReadUndertaleString ( ) ;
2649
+ X = reader . ReadInt32 ( ) ;
2650
+ Y = reader . ReadInt32 ( ) ;
2651
+ _font = reader . ReadUndertaleObject < UndertaleResourceById < UndertaleFont , UndertaleChunkFONT > > ( ) ;
2652
+ ScaleX = reader . ReadSingle ( ) ;
2653
+ ScaleY = reader . ReadSingle ( ) ;
2654
+ Rotation = reader . ReadSingle ( ) ;
2655
+ Color = reader . ReadUInt32 ( ) ;
2656
+ OriginX = reader . ReadSingle ( ) ;
2657
+ OriginY = reader . ReadSingle ( ) ;
2658
+ Text = reader . ReadUndertaleString ( ) ;
2659
+ Alignment = reader . ReadInt32 ( ) ;
2660
+ CharSpacing = reader . ReadSingle ( ) ;
2661
+ LineSpacing = reader . ReadSingle ( ) ;
2662
+ FrameWidth = reader . ReadSingle ( ) ;
2663
+ FrameHeight = reader . ReadSingle ( ) ;
2664
+ Wrap = reader . ReadBoolean ( ) ;
2665
+ }
2666
+
2667
+ /// <summary>
2668
+ /// Generates a random name for this instance, as a utility for room editing.
2669
+ /// </summary>
2670
+ public static UndertaleString GenerateRandomName ( UndertaleData data )
2671
+ {
2672
+ return data . Strings . MakeString ( "textitem_" + ( ( uint ) Random . Shared . Next ( - Int32 . MaxValue , Int32 . MaxValue ) ) . ToString ( "X8" ) ) ;
2673
+ }
2674
+
2675
+ /// <inheritdoc />
2676
+ public override string ToString ( )
2677
+ {
2678
+ return $ "Text item { Name ? . Content } with text \" { Text ? . Content ?? "?" } \" ";
2679
+ }
2680
+
2681
+ /// <inheritdoc/>
2682
+ public void Dispose ( )
2683
+ {
2684
+ GC . SuppressFinalize ( this ) ;
2685
+
2686
+ _font . Dispose ( ) ;
2687
+ Name = null ;
2688
+ Text = null ;
2689
+ }
2690
+ }
2548
2691
}
2549
2692
2550
2693
public enum AnimationSpeedType : uint
0 commit comments