1- using Intersect . Logging ;
1+ using System . Diagnostics . CodeAnalysis ;
2+ using System . Runtime . CompilerServices ;
3+ using Intersect . Logging ;
24
35namespace Intersect . GameObjects . Maps ;
46
@@ -96,7 +98,7 @@ public partial class MapAutotiles
9698
9799 private readonly MapBase mMyMap ;
98100
99- public Dictionary < string , QuarterTileCls [ , ] > Layers { get ; set ; }
101+ private Dictionary < string , QuarterTileCls [ , ] > Layers { get ; set ; }
100102
101103 private readonly int _mapWidth = Options . MapWidth ;
102104 private readonly int _mapHeight = Options . MapHeight ;
@@ -114,6 +116,52 @@ public MapAutotiles(MapBase map)
114116 }
115117 }
116118
119+ public bool TryGetAutoTilesForLayer ( string layerName , [ NotNullWhen ( true ) ] out QuarterTileCls [ , ] ? quarterTiles )
120+ {
121+ if ( Layers != default )
122+ {
123+ return Layers . TryGetValue ( layerName , out quarterTiles ) ;
124+ }
125+
126+ LegacyLogging . Logger ? . Error ( $ "[{ mMyMap ? . Id . ToString ( ) ?? "No map?" } ][AutoTiles] Layers not initialized!") ;
127+ quarterTiles = null ;
128+ return quarterTiles != null ;
129+ }
130+
131+ public bool TryGetAutoTileForLayer ( string layerName , int x , int y , [ NotNullWhen ( true ) ] out QuarterTileCls ? quarterTile )
132+ {
133+ if ( TryGetAutoTilesForLayer ( layerName , out var quarterTiles ) )
134+ {
135+ return TryGetAutoTile (
136+ quarterTiles ,
137+ x ,
138+ y ,
139+ out quarterTile
140+ ) ;
141+ }
142+
143+ quarterTile = null ;
144+ return false ;
145+
146+ }
147+
148+ private bool TryGetAutoTile (
149+ QuarterTileCls [ , ] quarterTiles ,
150+ int x ,
151+ int y ,
152+ [ NotNullWhen ( true ) ] out QuarterTileCls ? quarterTile
153+ )
154+ {
155+ if ( x < 0 || _mapWidth <= x || y < 0 || _mapHeight <= y )
156+ {
157+ quarterTile = null ;
158+ return false ;
159+ }
160+
161+ quarterTile = quarterTiles [ x , y ] ;
162+ return quarterTile != null ;
163+ }
164+
117165 private void InitVxAutotileTemplate ( )
118166 {
119167 // Inner tiles (Top right subtile region)
@@ -375,9 +423,14 @@ private void InitXpAutotileTemplate()
375423 AutoSxp [ 4 ] . Y = ( Int16 ) ( _tileHeight * 3 + _tileHeight / 2 ) ;
376424 }
377425
378- private void CreateFields ( )
426+ private Dictionary < string , QuarterTileCls [ , ] > EnsureLayers ( )
379427 {
380- Layers = new Dictionary < string , QuarterTileCls [ , ] > ( ) ;
428+ if ( Layers is { } layers )
429+ {
430+ return layers ;
431+ }
432+
433+ layers = [ ] ;
381434 foreach ( var layerName in _layersAll )
382435 {
383436 var layerQuarterTiles = new QuarterTileCls [ _mapWidth , _mapHeight ] ;
@@ -388,8 +441,11 @@ private void CreateFields()
388441 layerQuarterTiles [ x , y ] = new QuarterTileCls { QuarterTile = new PointStruct [ 5 ] } ;
389442 }
390443 }
391- Layers . Add ( layerName , layerQuarterTiles ) ;
444+ layers . Add ( layerName , layerQuarterTiles ) ;
392445 }
446+
447+ Layers = layers ;
448+ return layers ;
393449 }
394450
395451 public void InitAutotiles ( MapBase [ , ] surroundingMaps )
@@ -408,10 +464,7 @@ public void InitAutotiles(MapBase[,] surroundingMaps)
408464
409465 using ( lockRef )
410466 {
411- if ( Layers == null )
412- {
413- CreateFields ( ) ;
414- }
467+ EnsureLayers ( ) ;
415468 endCreateFields = DateTime . UtcNow ;
416469
417470 foreach ( var layerName in _layersAll )
@@ -421,18 +474,33 @@ public void InitAutotiles(MapBase[,] surroundingMaps)
421474 continue ;
422475 }
423476
477+ if ( ! TryGetAutoTilesForLayer ( layerName , out var layerAutoTiles ) )
478+ {
479+ continue ;
480+ }
481+
424482 for ( var x = 0 ; x < _mapWidth ; x ++ )
425483 {
426484 for ( var y = 0 ; y < _mapHeight ; y ++ )
427485 {
486+ if ( ! TryGetAutoTile (
487+ layerAutoTiles ,
488+ x ,
489+ y ,
490+ out var autoTile
491+ ) )
492+ {
493+
494+ }
495+
428496 DateTime startCalculateAutotiles = DateTime . UtcNow ;
429497 // calculate the subtile positions and place them
430- CalculateAutotile ( x , y , layerName , surroundingMaps , layerTiles ) ;
498+ CalculateAutotile ( x , y , layerName , surroundingMaps , layerTiles , autoTile ) ;
431499 elapsedCalculateAutotile += DateTime . UtcNow - startCalculateAutotiles ;
432500
433501 DateTime startCacheRenderState = DateTime . UtcNow ;
434502 // cache the rendering state of the tiles and set them
435- CacheRenderState ( x , y , layerName ) ;
503+ CacheRenderState ( x , y , layerName , autoTile ) ;
436504 elapsedCacheRenderState += DateTime . UtcNow - startCacheRenderState ;
437505 }
438506 }
@@ -468,6 +536,11 @@ public bool UpdateAutoTiles(int x, int y, MapBase[,] surroundingMaps)
468536 continue ;
469537 }
470538
539+ if ( ! TryGetAutoTilesForLayer ( layer , out var layerAutoTiles ) )
540+ {
541+ continue ;
542+ }
543+
471544 for ( var x1 = x - 1 ; x1 < x + 2 ; x1 ++ )
472545 {
473546 if ( x1 < 0 || x1 >= _mapWidth )
@@ -477,19 +550,24 @@ public bool UpdateAutoTiles(int x, int y, MapBase[,] surroundingMaps)
477550
478551 for ( var y1 = y - 1 ; y1 < y + 2 ; y1 ++ )
479552 {
480- if ( y1 < 0 || y1 >= _mapHeight )
553+ if ( ! TryGetAutoTile (
554+ layerAutoTiles ,
555+ x ,
556+ y ,
557+ out var autoTile
558+ ) )
481559 {
482560 continue ;
483561 }
484562
485- var oldautotile = Layers [ layer ] [ x1 , y1 ] . Copy ( ) ;
563+ var oldAutoTile = autoTile . Copy ( ) ;
486564 // calculate the subtile positions and place them
487- CalculateAutotile ( x1 , y1 , layer , surroundingMaps , layerTiles ) ;
565+ CalculateAutotile ( x1 , y1 , layer , surroundingMaps , layerTiles , autoTile ) ;
488566
489567 // cache the rendering state of the tiles and set them
490- CacheRenderState ( x1 , y1 , layer ) ;
568+ CacheRenderState ( x1 , y1 , layer , autoTile ) ;
491569
492- if ( ! Layers [ layer ] [ x1 , y1 ] . Equals ( oldautotile ) )
570+ if ( ! autoTile . Equals ( oldAutoTile ) )
493571 {
494572 changed = true ;
495573 }
@@ -515,6 +593,11 @@ public void UpdateAutoTiles(int x, int y, string layerName, MapBase[,] surroundi
515593 return ;
516594 }
517595
596+ if ( ! TryGetAutoTilesForLayer ( layerName , out var layerAutoTiles ) )
597+ {
598+ return ;
599+ }
600+
518601 for ( var x1 = x - 1 ; x1 < x + 2 ; x1 ++ )
519602 {
520603 if ( x1 < 0 || x1 >= _mapWidth )
@@ -529,11 +612,21 @@ public void UpdateAutoTiles(int x, int y, string layerName, MapBase[,] surroundi
529612 continue ;
530613 }
531614
615+ if ( ! TryGetAutoTile (
616+ layerAutoTiles ,
617+ x ,
618+ y ,
619+ out var autoTile
620+ ) )
621+ {
622+ continue ;
623+ }
624+
532625 // calculate the subtile positions and place them
533- CalculateAutotile ( x1 , y1 , layerName , surroundingMaps , layerTiles ) ;
626+ CalculateAutotile ( x1 , y1 , layerName , surroundingMaps , layerTiles , autoTile ) ;
534627
535628 // cache the rendering state of the tiles and set them
536- CacheRenderState ( x1 , y1 , layerName ) ;
629+ CacheRenderState ( x1 , y1 , layerName , autoTile ) ;
537630 }
538631 }
539632 }
@@ -546,20 +639,39 @@ public void UpdateCliffAutotiles(MapBase curMap, string layerName)
546639 return ;
547640 }
548641
642+ if ( ! TryGetAutoTilesForLayer ( layerName , out var layerAutoTiles ) )
643+ {
644+ return ;
645+ }
646+
549647 foreach ( var map in curMap . GenerateAutotileGrid ( ) )
550648 {
551- if ( map ! = null )
649+ if ( map = = null )
552650 {
553- for ( var x1 = 0 ; x1 < _mapWidth ; x1 ++ )
651+ continue ;
652+ }
653+
654+ for ( var x = 0 ; x < _mapWidth ; x ++ )
655+ {
656+ for ( var y = 0 ; y < _mapHeight ; y ++ )
554657 {
555- for ( var y1 = 0 ; y1 < _mapHeight ; y1 ++ )
658+ if ( map . Layers [ layerName ] [ x , y ] . Autotile != AUTOTILE_CLIFF )
556659 {
557- if ( map . Layers [ layerName ] [ x1 , y1 ] . Autotile == AUTOTILE_CLIFF )
558- {
559- map . Autotiles . CalculateAutotile ( x1 , y1 , layerName , map . GenerateAutotileGrid ( ) , layerTiles ) ;
560- map . Autotiles . CacheRenderState ( x1 , y1 , layerName ) ;
561- }
660+ continue ;
562661 }
662+
663+ if ( ! TryGetAutoTile (
664+ layerAutoTiles ,
665+ x ,
666+ y ,
667+ out var autoTile
668+ ) )
669+ {
670+ continue ;
671+ }
672+
673+ map . Autotiles . CalculateAutotile ( x , y , layerName , map . GenerateAutotileGrid ( ) , layerTiles , autoTile ) ;
674+ map . Autotiles . CacheRenderState ( x , y , layerName , autoTile ) ;
563675 }
564676 }
565677 }
@@ -572,7 +684,17 @@ public bool UpdateAutoTile(int x, int y, string layerName, MapBase[,] surroundin
572684 return false ;
573685 }
574686
575- var oldautotile = Layers [ layerName ] [ x , y ] . Copy ( ) ;
687+ if ( ! TryGetAutoTileForLayer (
688+ layerName ,
689+ x ,
690+ y ,
691+ out var autoTile
692+ ) )
693+ {
694+ return false ;
695+ }
696+
697+ var oldAutoTile = autoTile . Copy ( ) ;
576698
577699 if ( ! mMyMap . Lock . TryAcquireLock ( $ "{ nameof ( MapAutotiles ) } .{ nameof ( UpdateAutoTile ) } (int, int, string, { nameof ( MapBase ) } [,])", out var lockRef ) )
578700 {
@@ -582,16 +704,16 @@ public bool UpdateAutoTile(int x, int y, string layerName, MapBase[,] surroundin
582704 using ( lockRef )
583705 {
584706 // calculate the subtile positions and place them
585- CalculateAutotile ( x , y , layerName , surroundingMaps , layerTiles ) ;
707+ CalculateAutotile ( x , y , layerName , surroundingMaps , layerTiles , autoTile ) ;
586708
587709 // cache the rendering state of the tiles and set them
588- CacheRenderState ( x , y , layerName ) ;
710+ CacheRenderState ( x , y , layerName , autoTile ) ;
589711 }
590712
591- return ! Layers [ layerName ] [ x , y ] . Equals ( oldautotile ) ;
713+ return ! autoTile . Equals ( oldAutoTile ) ;
592714 }
593715
594- public void CacheRenderState ( int x , int y , string layerName )
716+ public void CacheRenderState ( int x , int y , string layerName , QuarterTileCls ? autoTile = null )
595717 {
596718 // exit out early
597719 if ( x < 0 || x > _mapWidth || y < 0 || y > _mapHeight )
@@ -618,37 +740,41 @@ public void CacheRenderState(int x, int y, string layerName)
618740 return ;
619741 }
620742
621- if ( ! Layers . TryGetValue ( layerName , out var layerAutotiles ) )
743+ if ( autoTile == null && ! TryGetAutoTileForLayer (
744+ layerName ,
745+ x ,
746+ y ,
747+ out autoTile
748+ ) )
622749 {
623750 return ;
624751 }
625752
626753 var tile = layerTiles [ x , y ] ;
627- var autotile = layerAutotiles [ x , y ] ;
628754
629755 // check if it needs to be rendered as an autotile
630756 if ( tile . Autotile is AUTOTILE_NONE or AUTOTILE_FAKE )
631757 {
632758 // default to... default
633- autotile . RenderState = RENDER_STATE_NORMAL ;
759+ autoTile . RenderState = RENDER_STATE_NORMAL ;
634760
635761 //Autotile[layerName][x, y].QuarterTile = null;
636762 }
637763 else
638764 {
639- autotile . RenderState = RENDER_STATE_AUTOTILE ;
765+ autoTile . RenderState = RENDER_STATE_AUTOTILE ;
640766
641767 // cache tileset positioning
642768 for ( var quarterNum = 1 ; quarterNum < 5 ; quarterNum ++ )
643769 {
644- var quarterTile = autotile . QuarterTile [ quarterNum ] ;
645- autotile . QuarterTile [ quarterNum ] . X = ( short ) ( tile . X * _tileWidth + quarterTile . X ) ;
646- autotile . QuarterTile [ quarterNum ] . Y = ( short ) ( tile . Y * _tileHeight + quarterTile . Y ) ;
770+ var quarterTile = autoTile . QuarterTile [ quarterNum ] ;
771+ autoTile . QuarterTile [ quarterNum ] . X = ( short ) ( tile . X * _tileWidth + quarterTile . X ) ;
772+ autoTile . QuarterTile [ quarterNum ] . Y = ( short ) ( tile . Y * _tileHeight + quarterTile . Y ) ;
647773 }
648774 }
649775 }
650776
651- public void CalculateAutotile ( int x , int y , string layerName , MapBase [ , ] surroundingMaps , Tile [ , ] layerTiles )
777+ public void CalculateAutotile ( int x , int y , string layerName , MapBase [ , ] surroundingMaps , Tile [ , ] layerTiles , QuarterTileCls ? quarterTile )
652778 {
653779 // Right, so we//ve split the tile block in to an easy to remember
654780 // collection of letters. We now need to do the calculations to find
0 commit comments