2727
2828namespace OpenLoco . Gui . ViewModels
2929{
30- public record SpriteOffset (
30+ public record G1Element32Json (
3131 [ property: JsonPropertyName ( "path" ) ] string Path ,
32- [ property: JsonPropertyName ( "x" ) ] int16_t X ,
33- [ property: JsonPropertyName ( "y" ) ] int16_t Y )
32+ [ property: JsonPropertyName ( "x" ) ] int16_t XOffset ,
33+ [ property: JsonPropertyName ( "y" ) ] int16_t YOffset ,
34+ [ property: JsonPropertyName ( "zoomOffset" ) ] int16_t ? ZoomOffset ,
35+ [ property: JsonPropertyName ( "flags" ) ] G1ElementFlags ? Flags
36+ )
3437 {
35- public static SpriteOffset Zero => new SpriteOffset ( string . Empty , 0 , 0 ) ;
38+ public G1Element32Json ( )
39+ : this ( "" , 0 , 0 , null , null )
40+ { }
41+
42+ public G1Element32Json ( string path , int16_t xOffset , int16_t yOffset )
43+ : this ( path , xOffset , yOffset , null , null )
44+ { }
45+
46+ public G1Element32Json ( string path , G1Element32 g1Element )
47+ : this ( path , g1Element . XOffset , g1Element . YOffset , g1Element . ZoomOffset , g1Element . Flags )
48+ { }
49+
50+ public static G1Element32Json Zero
51+ => new G1Element32Json ( string . Empty , 0 , 0 , 0 , G1ElementFlags . None ) ;
3652 }
3753
3854 public class ImageTableViewModel : ReactiveObject , IExtraContentViewModel
@@ -236,23 +252,23 @@ public async Task ImportImages()
236252
237253 Logger . Debug ( $ "{ files . Length } files in current directory") ;
238254
239- IEnumerable < SpriteOffset > offsets ;
255+ IEnumerable < G1Element32Json > offsets ;
240256
241257 // check for offsets file
242258 var offsetsFile = Path . Combine ( dirPath , "sprites.json" ) ;
243259 if ( File . Exists ( offsetsFile ) )
244260 {
245- offsets = JsonSerializer . Deserialize < ICollection < SpriteOffset > > ( File . ReadAllText ( offsetsFile ) ) ; // sprites.json is an unnamed array so we need ICollection here, not IEnumerable
261+ offsets = JsonSerializer . Deserialize < ICollection < G1Element32Json > > ( File . ReadAllText ( offsetsFile ) ) ; // sprites.json is an unnamed array so we need ICollection here, not IEnumerable
246262 ArgumentNullException . ThrowIfNull ( offsets ) ;
247263 Logger . Debug ( "Found sprites.json file; using that" ) ;
248264 }
249265 else
250266 {
251- offsets = G1Provider . G1Elements . Select ( ( x , i ) => new SpriteOffset ( $ "{ i } .png", x . XOffset , x . YOffset ) ) ;
267+ offsets = G1Provider . G1Elements . Select ( ( x , i ) => new G1Element32Json ( $ "{ i } .png", x . XOffset , x . YOffset ) ) ;
252268 Logger . Debug ( "Didn't find sprites.json; using existing G1Element32 offsets" ) ;
253269 }
254270
255- offsets = offsets . Fill ( files . Length , SpriteOffset . Zero ) ;
271+ offsets = offsets . Fill ( files . Length , G1Element32Json . Zero ) ;
256272
257273 // clear existing images
258274 Logger . Info ( "Clearing current G1Element32s and existing object images" ) ;
@@ -271,11 +287,11 @@ public async Task ImportImages()
271287 if ( i < G1Provider . G1Elements . Count )
272288 {
273289 var g1 = G1Provider . G1Elements [ i ] ;
274- LoadSprite ( filename , 0 , offsetList [ i ] . X , offsetList [ i ] . Y , g1 . Flags , g1 . ZoomOffset ) ;
290+ LoadSprite ( filename , 0 , offsetList [ i ] . XOffset , offsetList [ i ] . YOffset , g1 . Flags , g1 . ZoomOffset ) ;
275291 }
276292 else
277293 {
278- LoadSprite ( filename , 0 , offsetList [ i ] . X , offsetList [ i ] . Y , G1ElementFlags . None , 0 ) ;
294+ LoadSprite ( filename , 0 , offsetList [ i ] . XOffset , offsetList [ i ] . YOffset , G1ElementFlags . None , 0 ) ;
279295 }
280296 }
281297
@@ -358,7 +374,7 @@ public async Task ExportImages()
358374 Logger . Info ( $ "Saving images to { dirPath } ") ;
359375
360376 var counter = 0 ;
361- var offsets = new List < SpriteOffset > ( ) ;
377+ var offsets = new List < G1Element32Json > ( ) ;
362378
363379 foreach ( var image in Images )
364380 {
@@ -370,7 +386,7 @@ public async Task ExportImages()
370386 var path = Path . Combine ( dir . Path . LocalPath , fileName ) ;
371387 await image . SaveAsPngAsync ( path ) ;
372388
373- offsets . Add ( new SpriteOffset ( fileName , g1Element . XOffset , g1Element . YOffset ) ) ;
389+ offsets . Add ( new G1Element32Json ( fileName , g1Element ) ) ;
374390 }
375391
376392 var offsetsFile = Path . Combine ( dir . Path . LocalPath , "sprites.json" ) ;
@@ -397,7 +413,7 @@ public void CropAllImages()
397413 var currG1 = G1Provider . G1Elements [ i ] ;
398414
399415 // set to bitmaps
400- UpdateImage ( image , i , ( short ) ( currG1 . XOffset + cropRegion . Left ) , ( short ) ( currG1 . YOffset + cropRegion . Top ) ) ;
416+ UpdateImage ( image , i , xOffset : ( short ) ( currG1 . XOffset + cropRegion . Left ) , yOffset : ( short ) ( currG1 . YOffset + cropRegion . Top ) ) ;
401417 }
402418 }
403419
@@ -461,29 +477,30 @@ public async Task ReplaceImage()
461477 this . RaisePropertyChanged ( nameof ( SelectedG1Element ) ) ;
462478 }
463479
464- void UpdateImage ( Image < Rgba32 > img , int index , SpriteOffset ? offset = null )
465- => UpdateImage ( img , index , offset ? . X , offset ? . Y ) ;
480+ void UpdateImage ( Image < Rgba32 > img , int index , G1Element32Json ele )
481+ => UpdateImage ( img , index , ele . Flags , ele . XOffset , ele . YOffset , ele . ZoomOffset ) ;
466482
467- void UpdateImage ( Image < Rgba32 > img , int index , short ? xOffset , short ? yOffset )
483+ void UpdateImage ( Image < Rgba32 > img , int index , G1ElementFlags ? flags = null , int16_t ? xOffset = null , int16_t ? yOffset = null , int16_t ? zoomOffset = null )
468484 {
469485 if ( index == - 1 )
470486 {
471487 return ;
472488 }
473489
490+ Images [ index ] = img ;
491+ Bitmaps [ index ] = G1ImageConversion . CreateAvaloniaImage ( img ) ;
492+
474493 var currG1 = G1Provider . G1Elements [ index ] ;
475- currG1 = currG1 with
494+ G1Provider . G1Elements [ index ] = ( currG1 with
476495 {
496+ ImageData = PaletteMap . ConvertRgba32ImageToG1Data ( img , flags ?? currG1 . Flags , SelectedPrimarySwatch , SelectedSecondarySwatch ) ,
477497 Width = ( int16_t ) img . Width ,
478498 Height = ( int16_t ) img . Height ,
479- Flags = currG1 . Flags ,
480- ImageData = PaletteMap . ConvertRgba32ImageToG1Data ( img , currG1 . Flags , SelectedPrimarySwatch , SelectedSecondarySwatch ) ,
499+ Flags = flags ?? currG1 . Flags ,
481500 XOffset = xOffset ?? currG1 . XOffset ,
482501 YOffset = yOffset ?? currG1 . YOffset ,
483- } ;
484- G1Provider . G1Elements [ index ] = currG1 ;
485- Images [ index ] = img ;
486- Bitmaps [ index ] = G1ImageConversion . CreateAvaloniaImage ( img ) ;
502+ ZoomOffset = zoomOffset ?? currG1 . ZoomOffset ,
503+ } ) ;
487504 }
488505
489506 public static string GetImageName ( IImageTableNameProvider nameProvider , int counter )
0 commit comments