Advertisement
Guest User

Untitled

a guest
Oct 13th, 2019
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.39 KB | None | 0 0
  1. using System;
  2. using MCGalaxy.Blocks;
  3. using MCGalaxy.Network;
  4. using BlockID = System.UInt16;
  5. using MCGalaxy.Commands;
  6. using MCGalaxy.DB;
  7.  
  8. namespace MCGalaxy {
  9.    
  10.     public sealed class CmdSmoothAll : Command {
  11.         public override string name { get { return "SmoothAll"; } }
  12.         public override string shortcut { get { return "sa"; } }
  13.         public override string type { get { return "build"; } }
  14.         public override bool museumUsable { get { return false; } }
  15.         public override LevelPermission defaultRank { get { return LevelPermission.Operator; } }
  16.         struct SmoothData
  17.         {
  18.             public ushort solidCount;
  19.             public bool smoothedNear;
  20.         }
  21.         public override void Use(Player p, string message) {
  22.             bool canUse = false;// = p.group.Permission >= p.level.BuildAccess.Min;
  23.            
  24.             if (OwnsMap(p, p.level)) canUse = true;
  25.            
  26.             if (p.group.Permission >= LevelPermission.Operator && p.group.Permission >= p.level.BuildAccess.Min) { canUse = true; }
  27.            
  28.             if (!canUse) {
  29.                 p.Message("&cYou can only use this command on your own maps."); return;
  30.             }
  31.            
  32.             message = message.ToLower();
  33.             string[] bits = message.Split(' ');
  34.            
  35.             BlockID smoothedBlock = Block.Stone;
  36.             //GetBlock(Player p, string input, out BlockID block, bool allowSkip = false)
  37.             if (!CommandParser.GetBlock(p, bits[0], out smoothedBlock)) { return; }
  38.             int radius = 3;
  39.             //GetInt(Player p, string input, string argName, ref int result, int min = int.MinValue, int max = int.MaxValue) {
  40.             if (bits.Length >= 2) {
  41.                 if (!CommandParser.GetInt(p, bits[1], "radius", ref radius, 1, 6)) { return; }
  42.             }
  43.             Level lvl = p.level;
  44.             const int maxSize = 256;
  45.             ushort startX = 0;
  46.             ushort startY = 0;
  47.             ushort startZ = 0;
  48.            
  49.             ushort endX = lvl.Width;
  50.             ushort endY = lvl.Height;
  51.             ushort endZ = lvl.Length;
  52.            
  53.             int volume = (int)((endX-startX) * (endY-startY) * (endZ-startZ));
  54.             p.Message("volume is {0}.", volume);
  55.             if (volume > (maxSize * maxSize * maxSize)) {
  56.                 p.Message("%cDue to smoothing being performance-heavy, you can't smooth an area with a volume greater than {0}^3. Sorry!", maxSize);
  57.                 return;
  58.             }
  59.            
  60.             BlockID[] smoothedMap = new BlockID[volume];
  61.            
  62.             ushort edgeBuffer = (ushort)(radius*2);
  63.             //PEMDAS
  64.             ushort[ , , ] yikes = new ushort[(endX-startX)+edgeBuffer*2, (endY-startY)+edgeBuffer*2, (endZ-startZ)+edgeBuffer*2];
  65.             p.Message("length of yikes array: {0}, {1}, {2},", yikes.GetLength(0), yikes.GetLength(1), yikes.GetLength(2));
  66.             int sideHeight = lvl.Config.EdgeLevel-1;
  67.            
  68.             const ushort mask = 1<<7;
  69.            
  70.             for( int y = (ushort)(startY+radius); y < endY+(edgeBuffer*2)-radius; y++ ) {
  71.                 for( int z = (ushort)(startZ+radius); z < endZ+(edgeBuffer*2)-radius; z++ )
  72.                     for( int x = (ushort)(startX+radius); x < endX+(edgeBuffer*2)-radius; x++ )
  73.                 {
  74.                     BlockID curBlock = lvl.GetBlock((ushort)(x-edgeBuffer), (ushort)(y-edgeBuffer), (ushort)(z-edgeBuffer));
  75.                     string blockName = Block.GetName(p, curBlock);
  76.                     //p.Message("accessing {0} at coords {1}, {2}, {3}.", blockName, (ushort)(x-edgeBuffer), (ushort)(y-edgeBuffer), (ushort)(z-edgeBuffer) );
  77.                     //p.Message("%ex y z is {0}, {1}, {2}.", x, y, z);
  78.                    
  79.                    
  80.                                                     //to get actual in-game coord, edgeBuffer radius from the coord
  81.                     if (curBlock == Block.Air
  82.                     || (curBlock == Block.Invalid && (y-edgeBuffer > sideHeight))
  83.                     //|| (int)(y-radius) > short.MaxValue
  84.                     )
  85.                     { continue; } //not solid
  86.                    
  87.                     bool smoothedBlockNear = false;
  88.                     if (curBlock = smoothedBlock) { smoothedBlockNear = true; }
  89.  
  90.                     for (int cubeY = -radius; cubeY <= radius; cubeY++) {
  91.                         for (int cubeZ = -radius; cubeZ <= radius; cubeZ++) {
  92.                             for (int cubeX = -radius; cubeX <= radius; cubeX++) {
  93.                                
  94.                                 //if its solid we add 1 solid weight to self and all neighbors
  95.                                
  96.                                 if (smoothedBlockNear) { ++yikes[(ushort)(x + cubeX), (ushort)(y + cubeY), (ushort)(z + cubeZ)] | mask; }
  97.                                 else { yikes[(ushort)(x + cubeX), (ushort)(y + cubeY), (ushort)(z + cubeZ)]++; }
  98.                             }
  99.                         }
  100.                     }
  101.                 }
  102.             }
  103.             p.Message("Finished calculating! Now changing blocks...");
  104.             ushort radiusLength = (ushort)(radius*2 +1);
  105.             ushort halfRadiusVolume = (ushort)(radiusLength*radiusLength*radiusLength/2);
  106.            
  107.             for( ushort y = startY; y < endY; y++ ) {
  108.                 for( ushort z = startZ; z < endZ; z++ )
  109.                     for( ushort x = startX; x < endX; x++ )
  110.                 {
  111.                     int index = lvl.PosToInt(x, y, z);
  112.                    
  113.                     BlockID thisBlock = lvl.FastGetBlock(x, y, z);
  114.                    
  115.                     if (thisBlock == smoothedBlock || thisBlock == Block.Air) {
  116.                         //to get actual in-game coord FROM yikes, add edgeBuffer
  117.                         if (yikes[x+edgeBuffer, y+edgeBuffer, z+edgeBuffer] > halfRadiusVolume ) {
  118.                             lvl.UpdateBlock(p, x, y, z, smoothedBlock, BlockDBFlags.Drawn, true);
  119.                         } else {
  120.                             lvl.UpdateBlock(p, x, y, z, Block.Air, BlockDBFlags.Drawn, true);
  121.                         }
  122.                     }
  123.                    
  124.                 }
  125.             }
  126.             p.Message("Finished changing blocks!");
  127.         }      
  128.        
  129.         static bool OwnsMap(Player p, Level lvl) {
  130.             if (lvl.name.CaselessStarts(p.name)) return true;
  131.             string[] owners = lvl.Config.RealmOwner.Replace(" ", "").Split(',');
  132.            
  133.             foreach (string owner in owners) {
  134.                 if (owner.CaselessEq(p.name)) return true;
  135.             }
  136.             return false;
  137.         }
  138.        
  139.         public override void Help(Player p) {
  140.             p.Message("%T/SmoothAll [blocktype to smooth] [intensity]");
  141.             p.Message("%HSmooths the whole world.");
  142.  
  143.         }
  144.     }
  145. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement