@ -4,16 +4,13 @@ using System.Runtime.InteropServices; 
			
		
	
		
		
			
				
					
					public  partial  class  Terrain public  partial  class  Terrain  
			
		
	
		
		
			
				
					
					{ {  
			
		
	
		
		
			
				
					
						// These mirror the modes / shapes in 'terrain_editing_controls.gd'.  	// These mirror the modes / shapes in 'terrain_editing_controls.gd'.   
			
		
	
		
		
			
				
					
						enum  ToolMode  {  Height ,  Flatten ,  Paint  }  	enum  ToolMode  {  Height ,  Flatten ,  Paint ,  Erase }   
			
				
				
			
		
	
		
		
	
		
		
			
				
					
						enum  ToolShape  {  Corner ,  Circle ,  Square  }  	enum  ToolShape  {  Corner ,  Circle ,  Square  }   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
						// Set by the terrain editing plugin.  	// Set by the terrain editing plugin.   
			
		
	
		
		
			
				
					
						// Enables access to the in-editor undo/redo system.  	// Enables access to the in-editor undo/redo system.   
			
		
	
		
		
			
				
					
						public  EditorUndoRedoManager  EditorUndoRedo  {  get ;  set ;  }  	public  EditorUndoRedoManager  EditorUndoRedo  {  get ;  set ;  }   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
						// Dummy value to satisfy the overly careful compiler.   
			
		
	
		
		
			
				
					
						static  bool  _d ummy  =  false ;   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
						Material  _ editToolMaterial ;  	Material  _ editToolMaterial ;   
			
		
	
		
		
			
				
					
						public  override  void  _ EnterTree ( )  	public  override  void  _ EnterTree ( )   
			
		
	
		
		
			
				
					
						{  	{   
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -78,16 +75,22 @@ public partial class Terrain 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
							// TODO: Allow click-dragging which doesn't affect already changed tiles / corners.  		// TODO: Allow click-dragging which doesn't affect already changed tiles / corners.   
			
		
	
		
		
			
				
					
							// TODO: Use ArrayMesh instead of ImmediateMesh.  		// TODO: Use ArrayMesh instead of ImmediateMesh.   
			
		
	
		
		
			
				
					
							// TODO: Support texture blending somehow.   
			
		
	
		
		
			
				
					
							// TODO: Clear empty chunks.   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
							// Holds onto all the tiles and which of their corners corners will be affected by this edit operation.  		// Data structure for holding tiles to be modified .   
			
				
				
			
		
	
		
		
			
				
					
							var  tilesToChange  =  new  Dictionary < TilePos ,  Corners < bool > > ( ) ;  		var  tilesToChange  =  new  Dictionary < TilePos ,  TileModification > ( ) ;   
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
							// Don't look at this black magic. The Dictionary type should have this by default I swear!   		// Utility function to set 'Affected' for the specified position and corner.    
			
				
				
			
		
	
		
		
			
				
					
							// Basically, this returns a reference to an entry in the dictionary that can be modified directly.  		void  SetCornerAffected ( ( TilePos  Position ,  Corner  Corner )  pair )   
			
				
				
			
		
	
		
		
			
				
					
							ref  Corners < bool >  Tile ( TilePos  position )  = >  ref  CollectionsMarshal . GetValueRefOrAddDefault ( tilesToChange ,  position ,  out  _d ummy ) ;  			= >  tilesToChange . GetOrAddNew ( pair . Position ) . Affected [ pair . Corner ]  =  true  ;   
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
							if  ( toolMode  = =  ToolMode . Paint )  {  		// Utility function to get the height for the specified position and corner.   
			
				
				
			
		
	
		
		
			
				
					
								// In PAINT mode, only full tiles are ever affected.  		short  GetCornerHeight ( ( TilePos  Position ,  Corner  Corner )  pair )   
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
								= >  Data . GetTileOrDefault ( pair . Position ) . Height [ pair . Corner ] ;   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
							if  ( toolMode  is  ToolMode . Paint  or  ToolMode . Erase )  {   
			
		
	
		
		
			
				
					
								// In PAINT or ERASE mode, only full tiles are ever affected.   
			
		
	
		
		
			
				
					
								// So this makes populating 'tilesToChange' very straight-forward.  			// So this makes populating 'tilesToChange' very straight-forward.   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
								var  tiles  =  toolShape  switch  {  			var  tiles  =  toolShape  switch  {   
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -100,23 +103,21 @@ public partial class Terrain 
			
		
	
		
		
			
				
					
								} ;  			} ;   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
								foreach  ( var  pos  in  tiles )  			foreach  ( var  pos  in  tiles )   
			
		
	
		
		
			
				
					
									tilesToChange . Add ( pos ,  new ( true ) ) ;  				tilesToChange . Add ( pos ,  new ( ) {  Affected  =  new ( true )  }  ) ;   
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
							}  else  if  ( toolShape  = =  ToolShape . Corner )  {  		}  else  if  ( toolShape  = =  ToolShape . Corner )  {   
			
		
	
		
		
			
				
					
								// With the CORNER shape, only a single corner is affected.  			// With the CORNER shape, only a single corner is affected.   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
								// Modify selected corner itself.  			// Modify selected corner itself.   
			
		
	
		
		
			
				
					
								Tile ( hover . Position ) [ hover . Corner ]  =  true ;  			SetCornerAffected ( hover ) ;   
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
								// If the 'connected_toggle' button is active, move "connected" corners.  			// If the 'connected_toggle' button is active, move "connected" corners.   
			
		
	
		
		
			
				
					
								// This is a simplified version of the code below that only affects the 3 neighboring corners.  			// This is a simplified version of the code below that only affects the 3 neighboring corners.   
			
		
	
		
		
			
				
					
								if  ( isConnected )  {  			if  ( isConnected )  {   
			
		
	
		
		
			
				
					
									var  height  =  Data . GetTileOrDefault ( hover . Position ) . Height [ hover . Corner ] ;  				var  height  =  GetCornerHeight ( hover ) ;   
			
				
				
			
		
	
		
		
			
				
					
									foreach  ( var  neighbor  in  GetNeighbors ( hover . Position ,  hover . Corner ) )  {  				foreach  ( var  neighbor  in  GetNeighbors ( hover . Position ,  hover . Corner ) )   
			
				
				
			
		
	
		
		
			
				
					
										var  neighborHeight  =  Data . GetTileOrDefault ( neighbor . Position ) . Height [ neighbor . Corner ] ;  					if  ( GetCornerHeight ( neighbor )  = =  height )   
			
				
				
			
		
	
		
		
			
				
					
										if  ( neighborHeight  ! =  height )  continue ;  						SetCornerAffected ( neighbor ) ;   
			
				
				
			
		
	
		
		
			
				
					
										Tile ( neighbor . Position ) [ neighbor . Corner ]  =  true ;   
			
		
	
		
		
			
				
					
									}   
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
								}  			}   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
							}  else  {  		}  else  {   
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -129,7 +130,7 @@ public partial class Terrain 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
								// Modify selected tiles themselves.  			// Modify selected tiles themselves.   
			
		
	
		
		
			
				
					
								foreach  ( var  pos  in  tiles )  			foreach  ( var  pos  in  tiles )   
			
		
	
		
		
			
				
					
									tilesToChange . Add ( pos ,  new ( true ) ) ;  				tilesToChange . Add ( pos ,  new ( ) {  Affected  =  new ( true )  }  ) ;   
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
								// If the 'connected_toggle' button is active, move "connected" corners.  			// If the 'connected_toggle' button is active, move "connected" corners.   
			
		
	
		
		
			
				
					
								// Connected corners are the ones that are at the same height as ones already being moved.  			// Connected corners are the ones that are at the same height as ones already being moved.   
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -137,12 +138,10 @@ public partial class Terrain 
			
		
	
		
		
			
				
					
									var  tile  =  Data . GetTileOrDefault ( pos ) ;  				var  tile  =  Data . GetTileOrDefault ( pos ) ;   
			
		
	
		
		
			
				
					
									foreach  ( var  corner  in  Enum . GetValues < Corner > ( ) )  {  				foreach  ( var  corner  in  Enum . GetValues < Corner > ( ) )  {   
			
		
	
		
		
			
				
					
										var  height  =  tile . Height [ corner ] ;  					var  height  =  tile . Height [ corner ] ;   
			
		
	
		
		
			
				
					
										foreach  ( var  neighbor  in  GetNeighbors ( pos ,  corner ) )  {  					foreach  ( var  neighbor  in  GetNeighbors ( pos ,  corner ) )   
			
				
				
			
		
	
		
		
			
				
					
											if  ( tiles . Contains ( neighbor . Position ) )  continue ;  						if  ( ! tiles . Contains ( neighbor . Position ) )   
			
				
				
			
		
	
		
		
			
				
					
											var  neighborHeight  =  Data . GetTileOrDefault ( neighbor . Position ) . Height [ neighbor . Corner ] ;  							if  ( GetCornerHeight ( neighbor )  = =  height )   
			
				
				
			
		
	
		
		
			
				
					
											if  ( neighborHeight  ! =  height )  continue ;  								SetCornerAffected ( neighbor ) ;   
			
				
				
			
		
	
		
		
			
				
					
											Tile ( neighbor . Position ) [ neighbor . Corner ]  =  true ;   
			
		
	
		
		
			
				
					
										}   
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
									}  				}   
			
		
	
		
		
			
				
					
								}  			}   
			
		
	
		
		
			
				
					
					
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -152,68 +151,52 @@ public partial class Terrain 
			
		
	
		
		
			
				
					
							if  ( ev  is  InputEventMouseButton  {  ButtonIndex :  MouseButton . Left ,  Pressed :  true  } )  {  		if  ( ev  is  InputEventMouseButton  {  ButtonIndex :  MouseButton . Left ,  Pressed :  true  } )  {   
			
		
	
		
		
			
				
					
								prevent_default  =  true ;  			prevent_default  =  true ;   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
								string  action ;  			// Fill with current tile data.   
			
				
				
			
		
	
		
		
			
				
					
								StringName  method ;  			foreach  ( var  ( pos ,  modified )  in  tilesToChange )   
			
				
				
			
		
	
		
		
			
				
					
								Variant [ ]  doArgs ;  				modified . Original  =  modified . New  =  Data . GetTileOrDefault ( pos ) ;   
			
				
				
			
		
	
		
		
			
				
					
								Variant [ ]  undoArgs ;   
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
								string  action ;   
			
		
	
		
		
			
				
					
								if  ( toolMode  = =  ToolMode . Paint )  {  			if  ( toolMode  = =  ToolMode . Paint )  {   
			
		
	
		
		
			
				
					
									// TODO: Support blending somehow.   
			
		
	
		
		
			
				
					
									var  tilesPrevious  =  new  List < ( TilePos ,  byte ) > ( ) ;   
			
		
	
		
		
			
				
					
									var  tilesChanged   =  new  List < ( TilePos ,  byte ) > ( ) ;   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
									foreach  ( var  ( pos ,  corners )  in  tilesToChange )  {   
			
		
	
		
		
			
				
					
										var  tile  =  Data . GetTileOrDefault ( pos ) ;   
			
		
	
		
		
			
				
					
										tilesPrevious . Add ( ( pos ,  tile . TexturePrimary ) ) ;   
			
		
	
		
		
			
				
					
										tilesChanged . Add ( ( pos ,  texture ) ) ;   
			
		
	
		
		
			
				
					
									}   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
									action  =  "Paint terrain" ;  				action  =  "Paint terrain" ;   
			
		
	
		
		
			
				
					
									method    =  nameof ( DoModifyTerrainTexture ) ;  				foreach  ( var  ( _ ,  modified )  in  tilesToChange )   
			
				
				
			
		
	
		
		
			
				
					
									doArgs    =  [  PackTextureData ( tilesChanged )  ] ;  					modified . New . TexturePrimary  =  texture ;   
			
				
				
			
		
	
		
		
			
				
					
									undoArgs  =  [  PackTextureData ( tilesPrevious )  ] ;  			}  else  if  ( toolMode  = =  ToolMode . Erase )  {   
			
				
				
			
		
	
		
		
			
				
					
								}  else  {  				action  =  "Erase terrain" ;   
			
				
				
			
		
	
		
		
			
				
					
									var  tilesPrevious  =  new  List < ( TilePos ,  Corners < short > ) > ( ) ;  				foreach  ( var  ( _ ,  modified )  in  tilesToChange )   
			
				
				
			
		
	
		
		
			
				
					
									var  tilesChanged   =  new  List < ( TilePos ,  Corners < short > ) > ( ) ;  					modified . New  =  default ;   
			
				
				
			
		
	
		
		
			
				
					
					
			}  else  if  ( isFlatten )  {   
			
				
				
			
		
	
		
		
			
				
					
									var  amount  =  isFlatten  ?  Data . GetTileOrDefault ( hover . Position ) . Height [ hover . Corner ]  				action      =  "Flatten terrain" ;   
			
				
				
			
		
	
		
		
			
				
					
									           :  isRaise    ?  ( short ) + 1  :  ( short ) - 1 ;  				var  amount  =  GetCornerHeight ( hover ) ;   
			
				
				
			
		
	
		
		
			
				
					
					
				foreach  ( var  ( _ ,  modified )  in  tilesToChange )  {   
			
				
				
			
		
	
		
		
			
				
					
									foreach  ( var  ( pos ,  corners )  in  tilesToChange )  {  					ref  var  height  =  ref  modified . New . Height ;   
			
				
				
			
		
	
		
		
			
				
					
										var  tile  =  Data . GetTileOrDefault ( pos ) ;  					if  ( modified . Affected . TopLeft     )  height . TopLeft      =  amount ;   
			
				
				
			
		
	
		
		
			
				
					
										tilesPrevious . Add ( ( pos ,  tile . Height ) ) ;  					if  ( modified . Affected . TopRight    )  height . TopRight     =  amount ;   
			
				
				
			
		
	
		
		
			
				
					
					
					if  ( modified . Affected . BottomRight )  height . BottomRight  =  amount ;   
			
				
				
			
		
	
		
		
			
				
					
										var  newHeight  =  tile . Height ;  					if  ( modified . Affected . BottomLeft  )  height . BottomLeft   =  amount ;   
			
				
				
			
		
	
		
		
			
				
					
										if  ( isFlatten )  {   
			
		
	
		
		
			
				
					
											if  ( corners . TopLeft     )  newHeight . TopLeft       =  amount ;   
			
		
	
		
		
			
				
					
											if  ( corners . TopRight    )  newHeight . TopRight      =  amount ;   
			
		
	
		
		
			
				
					
											if  ( corners . BottomRight )  newHeight . BottomRight   =  amount ;   
			
		
	
		
		
			
				
					
											if  ( corners . BottomLeft  )  newHeight . BottomLeft    =  amount ;   
			
		
	
		
		
			
				
					
										}  else  {   
			
		
	
		
		
			
				
					
											if  ( corners . TopLeft     )  newHeight . TopLeft      + =  amount ;   
			
		
	
		
		
			
				
					
											if  ( corners . TopRight    )  newHeight . TopRight     + =  amount ;   
			
		
	
		
		
			
				
					
											if  ( corners . BottomRight )  newHeight . BottomRight  + =  amount ;   
			
		
	
		
		
			
				
					
											if  ( corners . BottomLeft  )  newHeight . BottomLeft   + =  amount ;   
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
									}  				}   
			
		
	
		
		
			
				
					
										tilesChanged . Add ( ( pos ,  newHeight ) ) ;  			}  else  {   
			
				
				
			
		
	
		
		
	
		
		
			
				
					
									action      =  isRaise  ?  "Raise terrain"  :  "Lower terrain" ;   
			
		
	
		
		
			
				
					
									var  amount  =  isRaise  ?        ( short ) + 1  :        ( short ) - 1 ;   
			
		
	
		
		
			
				
					
									foreach  ( var  ( _ ,  modified )  in  tilesToChange )  {   
			
		
	
		
		
			
				
					
										ref  var  height  =  ref  modified . New . Height ;   
			
		
	
		
		
			
				
					
										if  ( modified . Affected . TopLeft     )  height . TopLeft      + =  amount ;   
			
		
	
		
		
			
				
					
										if  ( modified . Affected . TopRight    )  height . TopRight     + =  amount ;   
			
		
	
		
		
			
				
					
										if  ( modified . Affected . BottomRight )  height . BottomRight  + =  amount ;   
			
		
	
		
		
			
				
					
										if  ( modified . Affected . BottomLeft  )  height . BottomLeft   + =  amount ;   
			
		
	
		
		
			
				
					
									}  				}   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
									action  =  isFlatten  ?  "Flatten terrain"   
			
		
	
		
		
			
				
					
									       :  isRaise    ?  "Raise terrain"   
			
		
	
		
		
			
				
					
									                   :  "Lower Terrain" ;   
			
		
	
		
		
			
				
					
									method    =  nameof ( DoModifyTerrainHeight ) ;   
			
		
	
		
		
			
				
					
									doArgs    =  [  PackHeightData ( tilesChanged )  ] ;   
			
		
	
		
		
			
				
					
									undoArgs  =  [  PackHeightData ( tilesPrevious )  ] ;   
			
		
	
		
		
			
				
					
								}  			}   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
								if  ( EditorUndoRedo  is  EditorUndoRedoManager  undo )  {  			if  ( EditorUndoRedo  is  EditorUndoRedoManager  undo )  {   
			
		
	
		
		
			
				
					
									undo . CreateAction ( action ,  backwardUndoOps :  false ) ;  				undo . CreateAction ( action ,  backwardUndoOps :  false ) ;   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
									undo . AddDoMethod ( this ,  method ,  doArgs ) ;  				var    doData  =  Pack ( tilesToChange . Select ( e  = >  ( e . Key ,  e . Value . New ) ) ) ;   
			
				
				
			
		
	
		
		
	
		
		
			
				
					
									var  undoData  =  Pack ( tilesToChange . Select ( e  = >  ( e . Key ,  e . Value . Original ) ) ) ;   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
									undo . AddDoMethod ( this ,  nameof ( DoModifyTerrain ) ,  doData ) ;   
			
		
	
		
		
			
				
					
									undo . AddDoMethod ( this ,  nameof ( UpdateMeshAndShape ) ) ;  				undo . AddDoMethod ( this ,  nameof ( UpdateMeshAndShape ) ) ;   
			
		
	
		
		
			
				
					
									undo . AddDoMethod ( this ,  GodotObject . MethodName . NotifyPropertyListChanged ) ;  				undo . AddDoMethod ( this ,  GodotObject . MethodName . NotifyPropertyListChanged ) ;   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
									undo . AddUndoMethod ( this ,  method ,  undoArgs ) ;  				undo . AddUndoMethod ( this ,  nameof ( DoModifyTerrain ) ,  undoData ) ;   
			
				
				
			
		
	
		
		
	
		
		
			
				
					
									undo . AddUndoMethod ( this ,  nameof ( UpdateMeshAndShape ) ) ;  				undo . AddUndoMethod ( this ,  nameof ( UpdateMeshAndShape ) ) ;   
			
		
	
		
		
			
				
					
									undo . AddUndoMethod ( this ,  GodotObject . MethodName . NotifyPropertyListChanged ) ;  				undo . AddUndoMethod ( this ,  GodotObject . MethodName . NotifyPropertyListChanged ) ;   
			
		
	
		
		
			
				
					
					
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -221,27 +204,28 @@ public partial class Terrain 
			
		
	
		
		
			
				
					
								}  			}   
			
		
	
		
		
			
				
					
							}  		}   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
							UpdateEditToolMesh ( tilesToChange ) ;  		UpdateEditToolMesh ( tilesToChange . Select ( e  = >  ( e . Key ,  e . Value . Affected ) ) ) ;   
			
				
				
			
		
	
		
		
	
		
		
			
				
					
							return  prevent_default ;  		return  prevent_default ;   
			
		
	
		
		
			
				
					
						}  	}   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
						public  void  EditorUnfocus ( )  	class  TileModification   
			
				
				
			
		
	
		
		
			
				
					
							= >  ClearEditToolMesh ( ) ;   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
						public  void  DoModifyTerrainHeight ( byte [ ]  data )   
			
		
	
		
		
	
		
		
			
				
					
						{  	{   
			
		
	
		
		
			
				
					
							foreach  ( var  ( pos ,  corners )  in  UnpackHeightData ( data ) )  		public  Corners < bool >  Affected ;   
			
				
				
			
		
	
		
		
			
				
					
								Data [ pos ] . Height  =  corners ;  		public  Tile  Original ;   
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
							public  Tile  New ;   
			
		
	
		
		
			
				
					
						}  	}   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
						public  void  DoModifyTerrainTexture ( byte [ ]  data )  	public  void  EditorUnfocus ( )   
			
				
				
			
		
	
		
		
	
		
		
			
				
					
							= >  ClearEditToolMesh ( ) ;   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
						public  void  DoModifyTerrain ( byte [ ]  data )   
			
		
	
		
		
			
				
					
						{  	{   
			
		
	
		
		
			
				
					
							foreach  ( var  ( pos ,  texture )  in  UnpackTextureData ( data ) )  		foreach  ( var  ( pos ,  til e )  in  Unpack ( data ) )   
			
				
				
			
		
	
		
		
			
				
					
								Data [ pos ] . TexturePrimary  =  texture ;  			Data [ pos ]  =  til e ;   
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
						}  	}   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
						void  UpdateEditToolMesh ( Dictionary < TilePos ,  Corners < bool > >  tiles )  	void  UpdateEditToolMesh ( IEnumerable < ( TilePos ,  Corners < bool > ) >  tiles )   
			
				
				
			
		
	
		
		
	
		
		
			
				
					
						{  	{   
			
		
	
		
		
			
				
					
							var  mesh  =  GetOrCreateMesh ( "EditToolMesh" ) ;  		var  mesh  =  GetOrCreateMesh ( "EditToolMesh" ) ;   
			
		
	
		
		
			
				
					
							mesh . ClearSurfaces ( ) ;  		mesh . ClearSurfaces ( ) ;   
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -297,56 +281,46 @@ public partial class Terrain 
			
		
	
		
		
			
				
					
							= >  _ offsetLookup [ corner ] . Select ( e  = >  ( new  TilePos ( pos . X  +  e . X ,  pos . Z  +  e . Z ) ,  e . Opposite ) ) ;  		= >  _ offsetLookup [ corner ] . Select ( e  = >  ( new  TilePos ( pos . X  +  e . X ,  pos . Z  +  e . Z ) ,  e . Opposite ) ) ;   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
						static  byte [ ]  PackHeightData  ( IEnumerable < ( TilePos  Position ,  Corners < short >  Corners ) >  data )  	static  byte [ ]  Pack ( IEnumerable < ( TilePos  Position ,  Tile  tile ) >  data )   
			
				
				
			
		
	
		
		
	
		
		
			
				
					
						{  	{   
			
		
	
		
		
			
				
					
							using  var  stream  =  new  MemoryStream ( ) ;  		using  var  stream  =  new  MemoryStream ( ) ;   
			
		
	
		
		
			
				
					
							using  var  writer  =  new  BinaryWriter ( stream ) ;  		using  var  writer  =  new  BinaryWriter ( stream ) ;   
			
		
	
		
		
			
				
					
							foreach  ( var  ( pos ,  corners )  in  data )  {  		foreach  ( var  ( pos ,  tile )  in  data )  {   
			
				
				
			
		
	
		
		
	
		
		
			
				
					
								writer . Write ( pos . X ) ;  			writer . Write ( pos . X ) ;   
			
		
	
		
		
			
				
					
								writer . Write ( pos . Z ) ;  			writer . Write ( pos . Z ) ;   
			
		
	
		
		
			
				
					
								writer . Write ( corners . TopLeft ) ;  			writer . Write ( tile . Height . TopLeft ) ;   
			
				
				
			
		
	
		
		
			
				
					
								writer . Write ( corners . TopRight ) ;  			writer . Write ( tile . Height . TopRight ) ;   
			
				
				
			
		
	
		
		
			
				
					
								writer . Write ( corners . BottomRight ) ;  			writer . Write ( tile . Height . BottomRight ) ;   
			
				
				
			
		
	
		
		
			
				
					
								writer . Write ( corners . BottomLeft ) ;  			writer . Write ( tile . Height . BottomLeft ) ;   
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
								writer . Write ( tile . TexturePrimary ) ;   
			
		
	
		
		
			
				
					
								writer . Write ( tile . TextureSecondary ) ;   
			
		
	
		
		
			
				
					
								writer . Write ( tile . TextureBlend ) ;   
			
		
	
		
		
			
				
					
							}  		}   
			
		
	
		
		
			
				
					
							return  stream . ToArray ( ) ;  		return  stream . ToArray ( ) ;   
			
		
	
		
		
			
				
					
						}  	}   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
						static  IEnumerable < ( TilePos  Position ,  Corners < short >  Corners ) >  UnpackHeightData  ( byte [ ]  data )  	static  IEnumerable < ( TilePos  Position ,  Tile  tile ) >  Unpack ( byte [ ]  data )   
			
				
				
			
		
	
		
		
	
		
		
			
				
					
						{  	{   
			
		
	
		
		
			
				
					
							using  var  stream  =  new  MemoryStream ( data ) ;  		using  var  stream  =  new  MemoryStream ( data ) ;   
			
		
	
		
		
			
				
					
							using  var  reader  =  new  BinaryReader ( stream ) ;  		using  var  reader  =  new  BinaryReader ( stream ) ;   
			
		
	
		
		
			
				
					
							while  ( stream . Position  <  stream . Length )  {  		while  ( stream . Position  <  stream . Length )  {   
			
		
	
		
		
			
				
					
								var  x  =  reader . ReadInt32 ( ) ;  			var  x  =  reader . ReadInt32 ( ) ;   
			
		
	
		
		
			
				
					
								var  y  =  reader . ReadInt32 ( ) ;  			var  y  =  reader . ReadInt32 ( ) ;   
			
		
	
		
		
			
				
					
								var  corners  =  new  Corners < short > (  
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
								var  height  =  new  Corners < short > (   
			
		
	
		
		
			
				
					
									reader . ReadInt16 ( ) ,  reader . ReadInt16 ( ) ,  				reader . ReadInt16 ( ) ,  reader . ReadInt16 ( ) ,   
			
		
	
		
		
			
				
					
									reader . ReadInt16 ( ) ,  reader . ReadInt16 ( ) ) ;  				reader . ReadInt16 ( ) ,  reader . ReadInt16 ( ) ) ;   
			
		
	
		
		
			
				
					
								yield  return  ( new ( x ,  y ) ,  corners ) ;   
			
		
	
		
		
			
				
					
							}   
			
		
	
		
		
			
				
					
						}   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
						static  byte [ ]  PackTextureData ( IEnumerable < ( TilePos  Position ,  byte  Texture ) >  data )  			var  texPrimary    =  reader . ReadByte ( ) ;   
			
				
				
			
		
	
		
		
			
				
					
						{  			var  texSecondary  =  reader . ReadByte ( ) ;   
			
				
				
			
		
	
		
		
			
				
					
							using  var  stream  =  new  MemoryStream ( ) ;  			var  texBlend      =  reader . ReadByte ( ) ;   
			
				
				
			
		
	
		
		
			
				
					
							using  var  writer  =  new  BinaryWriter ( stream ) ;   
			
		
	
		
		
			
				
					
							foreach  ( var  ( pos ,  texture )  in  data )  {   
			
		
	
		
		
			
				
					
								writer . Write ( pos . X ) ;   
			
		
	
		
		
			
				
					
								writer . Write ( pos . Z ) ;   
			
		
	
		
		
			
				
					
								writer . Write ( texture ) ;   
			
		
	
		
		
			
				
					
							}   
			
		
	
		
		
			
				
					
							return  stream . ToArray ( ) ;   
			
		
	
		
		
			
				
					
						}   
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
						static  IEnumerable < ( TilePos  Position ,  byte  Texture ) >  UnpackTextureData ( byte [ ]  data )  			yield  return  ( new ( x ,  y ) ,  new ( ) {   
			
				
				
			
		
	
		
		
			
				
					
						{  				Height  =  height ,   
			
				
				
			
		
	
		
		
			
				
					
							using  var  stream  =  new  MemoryStream ( data ) ;  				TexturePrimary    =  texPrimary ,   
			
				
				
			
		
	
		
		
			
				
					
							using  var  reader  =  new  BinaryReader ( stream ) ;  				TextureSecondary  =  texSecondary ,   
			
				
				
			
		
	
		
		
			
				
					
							while  ( stream . Position  <  stream . Length )  {  				TextureBlend      =  texBlend ,   
			
				
				
			
		
	
		
		
			
				
					
								var  x  =  reader . ReadInt32 ( ) ;  			} ) ;   
			
				
				
			
		
	
		
		
			
				
					
								var  y  =  reader . ReadInt32 ( ) ;   
			
		
	
		
		
			
				
					
								var  texture  =  reader . ReadByte ( ) ;   
			
		
	
		
		
			
				
					
								yield  return  ( new ( x ,  y ) ,  texture ) ;   
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
							}  		}   
			
		
	
		
		
			
				
					
						}  	}   
			
		
	
		
		
			
				
					
					} }