OSDN Git Service

W.I.P. IV: More reliable entity / block scanning (full depth chunk scan), rock stats...
[automap/automap.git] / Automap / Subsystems / AutomapSystem.cs
index 200015b..faea6b5 100644 (file)
@@ -16,6 +16,7 @@ using Hjg.Pngcs.Chunks;
 using Vintagestory.API.Client;
 using Vintagestory.API.Common;
 using Vintagestory.API.Common.Entities;
+using Vintagestory.API.Config;
 using Vintagestory.API.MathTools;
 using Vintagestory.Common;
 
@@ -41,6 +42,7 @@ namespace Automap
 
                internal Dictionary<int, BlockDesignator> BlockID_Designators { get; private set;}
                internal Dictionary<AssetLocation, EntityDesignator> Entity_Designators { get; private set; }
+               internal Dictionary<int, string> RockIdCodes { get; private set; }
 
                internal bool Enabled { get; set; }
                //Run status, Chunks processed, stats, center of map....
@@ -201,6 +203,7 @@ namespace Automap
                this.EOIs = new EntitiesOfInterest( );
                this.BlockID_Designators = new Dictionary<int, BlockDesignator>( );
                this.Entity_Designators = new Dictionary<AssetLocation, EntityDesignator>( );
+               this.RockIdCodes = Helpers.ArbitrarytBlockIdHunter(ClientAPI, new AssetLocation(GlobalConstants.DefaultDomain, "rock"), EnumBlockMaterial.Stone);
 
                //Add special marker types for BlockID's of "Interest", overwrite colour, and method
 
@@ -476,7 +479,7 @@ namespace Automap
 
                foreach (var shardFile in files) {
 
-               if (shardFile.Length < 1000) continue;
+               if (shardFile.Length < 512) continue;
                var result = chunkShardRegex.Match(shardFile.Name);
                if (result.Success) {
                int X_chunk_pos = int.Parse(result.Groups["X"].Value );
@@ -537,24 +540,75 @@ namespace Automap
                /// <param name="chunkMeta">Chunk metadata</param>
                private void ProcessChunkBlocks(Vec2i key, IMapChunk mapChunk, ColumnMeta chunkMeta)
                {
-               //TODO: build stack of chunk(s) - surface down to bedrock
-               int topChunkY = mapChunk.YMax / chunkSize;
-               WorldChunk chunkData = ( Vintagestory.Common.WorldChunk )ClientAPI.World.BlockAccessor.GetChunk(key.X, topChunkY, key.Y);
 
+               int targetChunkY = mapChunk.YMax / chunkSize;//Surface ... 
+               for (; targetChunkY > 0; targetChunkY--) {
+               WorldChunk chunkData = ClientAPI.World.BlockAccessor.GetChunk(key.X, targetChunkY, key.Y) as WorldChunk;
+
+               if (chunkData == null || chunkData.BlockEntities == null) {
+               #if DEBUG
+               Logger.VerboseDebug("Chunk null or empty X{0} Y{1} Z{2}", key.X,targetChunkY,key.Y);
+               #endif
+               continue;
+               }
+
+               /*************** Chunk Entities Scanning *********************/
                if (chunkData.BlockEntities != null && chunkData.BlockEntities.Length > 0) {
                #if DEBUG
                Logger.VerboseDebug("Surface@ {0} = BlockEntities: {1}", key, chunkData.BlockEntities.Length);
+               #endif
 
-               foreach (var blockEnt in chunkData.BlockEntities) {             
-                       if (BlockID_Designators.ContainsKey(blockEnt.Block.BlockId)) 
+               foreach (var blockEnt in chunkData.BlockEntities) {
+               
+                       if (blockEnt != null && blockEnt.Block != null && BlockID_Designators.ContainsKey(blockEnt.Block.BlockId)) 
                        {
                        var designator = BlockID_Designators[blockEnt.Block.BlockId];
-                       designator.SpecialAction(ClientAPI, POIs, blockEnt.Pos.Copy(), blockEnt.Block);
+                       designator.SpecialAction(ClientAPI, POIs, blockEnt.Pos.Copy( ), blockEnt.Block);
                        }
                }
-               #endif
+               
+               }
+               /********************* Chunk/Column BLOCKs scanning ****************/
+               //Heightmap, Stats, block tally
+               chunkData.Unpack( );
+
+               int X_index, Y_index, Z_index;
+               X_index = Y_index = Z_index = 0;
+
+               do {
+               do {
+               do {
+               /* Encode packed indicie
+               (y * chunksize + z) * chunksize + x
+               */
+               var indicie = Helpers.ChunkBlockIndicie16(X_index, Y_index, Z_index);
+               int aBlockId = chunkData.Blocks[indicie];
+                                                                       
+               if (aBlockId == 0) {//Air
+               chunkMeta.AirBlocks++;
+               continue;
                }
 
+               if (RockIdCodes.ContainsKey(aBlockId)) {
+               if (chunkMeta.RockRatio.ContainsKey(aBlockId)) { chunkMeta.RockRatio[aBlockId]++; } else { chunkMeta.RockRatio.Add(aBlockId, 1); }              
+               }
+               
+               chunkMeta.NonAirBlocks++;               
+
+               //Heightmap 
+               if (chunkMeta.HeightMap[X_index, Z_index] == 0) 
+               { chunkMeta.HeightMap[X_index, Z_index] = ( ushort )(Y_index + (targetChunkY * chunkSize)); }
+
+               }
+               while (X_index++ < (chunkSize - 1));
+               X_index = 0;
+               }
+               while (Z_index++ < (chunkSize - 1));
+               Z_index = 0;
+               }
+               while (Y_index++ < (chunkSize - 1));
+
+               }
                }
 
                private void UpdateEntityMetadata( )
@@ -568,10 +622,8 @@ namespace Automap
                #endif
 
                var dMatch = Entity_Designators.SingleOrDefault(se => se.Key.Equals(loadedEntity.Value.Code));
-               if (dMatch.Value != null) {
-                       if (dMatch.Value.Enabled) {
-                       dMatch.Value.SpecialAction(ClientAPI, this.EOIs, loadedEntity.Value.LocalPos.AsBlockPos.Copy( ), loadedEntity.Value);                   
-                       }
+               if (dMatch.Value != null) {                     
+                       dMatch.Value.SpecialAction(ClientAPI, this.EOIs, loadedEntity.Value.LocalPos.AsBlockPos.Copy( ), loadedEntity.Value);                                           
                }
 
                }