Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using MCGalaxy.Blocks;
- using MCGalaxy.Network;
- using BlockID = System.UInt16;
- using MCGalaxy.Commands;
- using MCGalaxy.DB;
- namespace MCGalaxy {
- public sealed class CmdSmoothAll : Command {
- public override string name { get { return "SmoothAll"; } }
- public override string shortcut { get { return "sa"; } }
- public override string type { get { return "build"; } }
- public override bool museumUsable { get { return false; } }
- public override LevelPermission defaultRank { get { return LevelPermission.Operator; } }
- struct SmoothData
- {
- public ushort solidCount;
- public bool smoothedNear;
- }
- public override void Use(Player p, string message) {
- bool canUse = false;// = p.group.Permission >= p.level.BuildAccess.Min;
- if (OwnsMap(p, p.level)) canUse = true;
- if (p.group.Permission >= LevelPermission.Operator && p.group.Permission >= p.level.BuildAccess.Min) { canUse = true; }
- if (!canUse) {
- p.Message("&cYou can only use this command on your own maps."); return;
- }
- message = message.ToLower();
- string[] bits = message.Split(' ');
- BlockID smoothedBlock = Block.Stone;
- //GetBlock(Player p, string input, out BlockID block, bool allowSkip = false)
- if (!CommandParser.GetBlock(p, bits[0], out smoothedBlock)) { return; }
- int radius = 3;
- //GetInt(Player p, string input, string argName, ref int result, int min = int.MinValue, int max = int.MaxValue) {
- if (bits.Length >= 2) {
- if (!CommandParser.GetInt(p, bits[1], "radius", ref radius, 1, 6)) { return; }
- }
- Level lvl = p.level;
- const int maxSize = 256;
- ushort startX = 0;
- ushort startY = 0;
- ushort startZ = 0;
- ushort endX = lvl.Width;
- ushort endY = lvl.Height;
- ushort endZ = lvl.Length;
- int volume = (int)((endX-startX) * (endY-startY) * (endZ-startZ));
- p.Message("volume is {0}.", volume);
- if (volume > (maxSize * maxSize * maxSize)) {
- p.Message("%cDue to smoothing being performance-heavy, you can't smooth an area with a volume greater than {0}^3. Sorry!", maxSize);
- return;
- }
- BlockID[] smoothedMap = new BlockID[volume];
- ushort edgeBuffer = (ushort)(radius*2);
- //PEMDAS
- ushort[ , , ] yikes = new ushort[(endX-startX)+edgeBuffer*2, (endY-startY)+edgeBuffer*2, (endZ-startZ)+edgeBuffer*2];
- p.Message("length of yikes array: {0}, {1}, {2},", yikes.GetLength(0), yikes.GetLength(1), yikes.GetLength(2));
- int sideHeight = lvl.Config.EdgeLevel-1;
- const ushort mask = 1<<7;
- for( int y = (ushort)(startY+radius); y < endY+(edgeBuffer*2)-radius; y++ ) {
- for( int z = (ushort)(startZ+radius); z < endZ+(edgeBuffer*2)-radius; z++ )
- for( int x = (ushort)(startX+radius); x < endX+(edgeBuffer*2)-radius; x++ )
- {
- BlockID curBlock = lvl.GetBlock((ushort)(x-edgeBuffer), (ushort)(y-edgeBuffer), (ushort)(z-edgeBuffer));
- string blockName = Block.GetName(p, curBlock);
- //p.Message("accessing {0} at coords {1}, {2}, {3}.", blockName, (ushort)(x-edgeBuffer), (ushort)(y-edgeBuffer), (ushort)(z-edgeBuffer) );
- //p.Message("%ex y z is {0}, {1}, {2}.", x, y, z);
- //to get actual in-game coord, edgeBuffer radius from the coord
- if (curBlock == Block.Air
- || (curBlock == Block.Invalid && (y-edgeBuffer > sideHeight))
- //|| (int)(y-radius) > short.MaxValue
- )
- { continue; } //not solid
- bool smoothedBlockNear = false;
- if (curBlock = smoothedBlock) { smoothedBlockNear = true; }
- for (int cubeY = -radius; cubeY <= radius; cubeY++) {
- for (int cubeZ = -radius; cubeZ <= radius; cubeZ++) {
- for (int cubeX = -radius; cubeX <= radius; cubeX++) {
- //if its solid we add 1 solid weight to self and all neighbors
- if (smoothedBlockNear) { ++yikes[(ushort)(x + cubeX), (ushort)(y + cubeY), (ushort)(z + cubeZ)] | mask; }
- else { yikes[(ushort)(x + cubeX), (ushort)(y + cubeY), (ushort)(z + cubeZ)]++; }
- }
- }
- }
- }
- }
- p.Message("Finished calculating! Now changing blocks...");
- ushort radiusLength = (ushort)(radius*2 +1);
- ushort halfRadiusVolume = (ushort)(radiusLength*radiusLength*radiusLength/2);
- for( ushort y = startY; y < endY; y++ ) {
- for( ushort z = startZ; z < endZ; z++ )
- for( ushort x = startX; x < endX; x++ )
- {
- int index = lvl.PosToInt(x, y, z);
- BlockID thisBlock = lvl.FastGetBlock(x, y, z);
- if (thisBlock == smoothedBlock || thisBlock == Block.Air) {
- //to get actual in-game coord FROM yikes, add edgeBuffer
- if (yikes[x+edgeBuffer, y+edgeBuffer, z+edgeBuffer] > halfRadiusVolume ) {
- lvl.UpdateBlock(p, x, y, z, smoothedBlock, BlockDBFlags.Drawn, true);
- } else {
- lvl.UpdateBlock(p, x, y, z, Block.Air, BlockDBFlags.Drawn, true);
- }
- }
- }
- }
- p.Message("Finished changing blocks!");
- }
- static bool OwnsMap(Player p, Level lvl) {
- if (lvl.name.CaselessStarts(p.name)) return true;
- string[] owners = lvl.Config.RealmOwner.Replace(" ", "").Split(',');
- foreach (string owner in owners) {
- if (owner.CaselessEq(p.name)) return true;
- }
- return false;
- }
- public override void Help(Player p) {
- p.Message("%T/SmoothAll [blocktype to smooth] [intensity]");
- p.Message("%HSmooths the whole world.");
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement