Defines a 3D bounding box, in integer cartesian coordinates
Beispiel #1
0
 public void Create( BoundingBox bounds, PlayerInfo createdBy ) {
     if( bounds == null ) throw new ArgumentNullException( "bounds" );
     if( createdBy == null ) throw new ArgumentNullException( "createdBy" );
     CreatedDate = DateTime.UtcNow;
     Bounds = bounds;
     CreatedBy = createdBy;
 }
Beispiel #2
0
 /// <summary> Returns a BoundingBox object that describes the space shared between this and another box.
 /// Returns BoundingBox.Empty if there is no intersection. </summary>
 /// <param name="other"></param>
 /// <returns></returns>
 public BoundingBox GetIntersection( BoundingBox other ) {
     if( other == null ) throw new ArgumentNullException( "other" );
     if( Insersects( other ) ) {
         return new BoundingBox( Math.Max( XMin, other.XMin ),
                                 Math.Max( YMin, other.YMin ),
                                 Math.Max( HMin, other.HMin ),
                                 Math.Min( XMax, other.XMax ),
                                 Math.Min( YMax, other.YMax ),
                                 Math.Min( HMax, other.HMax ) );
     } else {
         return Empty;
     }
 }
Beispiel #3
0
		static void KillExplosion(Player player, Vector3I coords) {
			foreach (Player p in world.Players) {
				if (p == player)
					continue;
				Vector3I cpPos = p.Position.ToBlockCoords();
				Vector3I cpPosMax = new Vector3I(cpPos.X + 2, cpPos.Y + 2, cpPos.Z + 2);
				Vector3I cpPosMin = new Vector3I(cpPos.X - 2, cpPos.Y - 2, cpPos.Z - 2);
				BoundingBox bounds = new BoundingBox(cpPosMin, cpPosMax);
				
				if (bounds.Contains(coords) && p.Team != player.Team)
					Kill(player, p, " &cexploded ");
			}
		}
Beispiel #4
0
        public Zone( [NotNull] string raw, [CanBeNull] World world )
            : this()
        {
            if( raw == null ) throw new ArgumentNullException( "raw" );
            string[] parts = raw.Split( ',' );

            string[] header = parts[0].Split( ' ' );
            Name = header[0];
            Bounds = new BoundingBox( Int32.Parse( header[1] ), Int32.Parse( header[2] ), Int32.Parse( header[3] ),
                                      Int32.Parse( header[4] ), Int32.Parse( header[5] ), Int32.Parse( header[6] ) );

            Rank buildRank = Rank.Parse( header[7] );
            // if all else fails, fall back to lowest class
            if( buildRank == null ) {
                if( world != null ) {
                    Controller.MinRank = world.BuildSecurity.MinRank;
                } else {
                    Controller.ResetMinRank();
                }
                Logger.Log( LogType.Error,
                            "Zone: Error parsing zone definition: unknown rank \"{0}\". Permission reset to default ({1}).",
                            header[7], Controller.MinRank.Name );
            } else {
                Controller.MinRank = buildRank;
            }

            // Part 2:
            foreach( string player in parts[1].Split( ' ' ) ) {
                if( !Player.IsValidName( player ) ) continue;
                PlayerInfo info = PlayerDB.FindPlayerInfoExact( player );
                if( info == null ) continue; // player name not found in the DB (discarded)
                Controller.Include( info );
            }

            // Part 3: excluded list
            foreach( string player in parts[2].Split( ' ' ) ) {
                if( !Player.IsValidName( player ) ) continue;
                PlayerInfo info = PlayerDB.FindPlayerInfoExact( player );
                if( info == null ) continue; // player name not found in the DB (discarded)
                Controller.Exclude( info );
            }

            // Part 4: extended header
            if( parts.Length > 3 ) {
                string[] xheader = parts[3].Split( ' ' );
                CreatedBy = PlayerDB.FindPlayerInfoExact( xheader[0] );
                if( CreatedBy != null ) CreatedDate = DateTime.Parse( xheader[1] );
                EditedBy = PlayerDB.FindPlayerInfoExact( xheader[2] );
                if( EditedBy != null ) EditedDate = DateTime.Parse( xheader[3] );
            }
        }
Beispiel #5
0
        public Zone([NotNull] string raw, [CanBeNull] World world)
            : this() {
            if (raw == null) throw new ArgumentNullException("raw");
            string[] parts = raw.Split(',');

            string[] header = parts[0].Split(' ');
            Name = header[0];
            Bounds = new BoundingBox(Int32.Parse(header[1]),
                                     Int32.Parse(header[2]),
                                     Int32.Parse(header[3]),
                                     Int32.Parse(header[4]),
                                     Int32.Parse(header[5]),
                                     Int32.Parse(header[6]));

            // If no ranks are loaded (e.g. MapConverter/MapRenderer)(
            if (RankManager.Ranks.Count > 0) {
                Rank buildRank = Rank.Parse(header[7]);
                // if all else fails, fall back to lowest class
                if (buildRank == null) {
                    if (world != null) {
                        Controller.MinRank = world.BuildSecurity.MinRank;
                    } else {
                        Controller.ResetMinRank();
                    }
                    Logger.Log(LogType.Error,
                               "Zone: Error parsing zone definition: unknown rank \"{0}\". Permission reset to default ({1}).",
                               header[7],
                               Controller.MinRank.Name);
                } else {
                    Controller.MinRank = buildRank;
                }
            }

            // If PlayerDB is not loaded (e.g. ConfigGUI)
            if (PlayerDB.IsLoaded) {
                // Part 2:
                if (parts[1].Length > 0) {
                    foreach (string playerName in parts[1].Split(' ')) {
                        if (!Player.IsValidPlayerName(playerName)) {
                            Logger.Log(LogType.Warning,
                                       "Invalid entry in zone \"{0}\" whitelist: {1}",
                                       Name,
                                       playerName);
                            continue;
                        }
                        PlayerInfo info = PlayerDB.FindPlayerInfoExact(playerName);
                        if (info == null) {
                            Logger.Log(LogType.Warning,
                                       "Unrecognized player in zone \"{0}\" whitelist: {1}",
                                       Name,
                                       playerName);
                            continue; // player name not found in the DB (discarded)
                        }
                        Controller.Include(info);
                    }
                }

                // Part 3: excluded list
                if (parts[2].Length > 0) {
                    foreach (string playerName in parts[2].Split(' ')) {
                        if (!Player.IsValidPlayerName(playerName)) {
                            Logger.Log(LogType.Warning,
                                       "Invalid entry in zone \"{0}\" blacklist: {1}",
                                       Name,
                                       playerName);
                            continue;
                        }
                        PlayerInfo info = PlayerDB.FindPlayerInfoExact(playerName);
                        if (info == null) {
                            Logger.Log(LogType.Warning,
                                       "Unrecognized player in zone \"{0}\" whitelist: {1}",
                                       Name,
                                       playerName);
                            continue; // player name not found in the DB (discarded)
                        }
                        Controller.Exclude(info);
                    }
                }
            } else {
                RawWhitelist = parts[1];
                RawBlacklist = parts[2];
            }

            // Part 4: extended header
            if (parts.Length > 3) {
                string[] xheader = parts[3].Split(' ');
                if (xheader[0] == "-") {
                    CreatedBy = null;
                    CreatedDate = DateTime.MinValue;
                } else {
                    CreatedBy = xheader[0];
                    CreatedDate = DateTime.Parse(xheader[1]);
                }

                if (xheader[2] == "-") {
                    EditedBy = null;
                    EditedDate = DateTime.MinValue;
                } else {
                    EditedBy = xheader[2];
                    EditedDate = DateTime.Parse(xheader[3]);
                }
            }
        }
Beispiel #6
0
 void MakeIslandBase( Island island ) {
     foreach( Sphere sphere in island.Spheres ) {
         Vector3I origin = new Vector3I( (int)Math.Floor( sphere.Origin.X - sphere.Radius ),
                                         (int)Math.Floor( sphere.Origin.Y - sphere.Radius ),
                                         (int)Math.Floor( sphere.Origin.Z - sphere.Radius * 2 ) );
         BoundingBox box = new BoundingBox( origin,
                                            (int)Math.Ceiling( sphere.Radius ) * 2 + 8,
                                            (int)Math.Ceiling( sphere.Radius ) * 2 + 8,
                                            (int)Math.Ceiling( sphere.Radius ) + 4 );
         for( int x = box.XMin; x <= box.XMax; x++ ) {
             for( int y = box.YMin; y <= box.YMax; y++ ) {
                 for( int z = box.ZMin; z <= box.ZMax; z++ ) {
                     Vector3I coord = new Vector3I( x, y, z );
                     Vector3F displacement = sphere.Origin - coord;
                     if( (displacement.X * displacement.X * 2) / (sphere.Radius * sphere.Radius) +
                         (displacement.Y * displacement.Y * 2) / (sphere.Radius * sphere.Radius) +
                         (displacement.Z * displacement.Z) / (sphere.Radius * sphere.Radius * 4) <= 1 ) {
                         map.SetBlock( coord + island.Offset, Block.Stone );
                     }
                 }
             }
         }
     }
 }
Beispiel #7
0
 void MakeIslandHemisphere( Vector3I offset, Sphere sphere ) {
     Vector3I origin = new Vector3I( (int)Math.Floor( sphere.Origin.X - sphere.Radius ),
                                     (int)Math.Floor( sphere.Origin.Y - sphere.Radius ),
                                     (int)Math.Floor( sphere.Origin.Z - sphere.Radius ) );
     BoundingBox box = new BoundingBox( origin,
                                        (int)Math.Ceiling( sphere.Radius )*2,
                                        (int)Math.Ceiling( sphere.Radius )*2,
                                        (int)Math.Ceiling( sphere.Radius ) );
     for( int x = box.XMin; x <= box.XMax; x++ ) {
         for( int y = box.YMin; y <= box.YMax; y++ ) {
             for( int z = box.ZMin; z <= box.ZMax; z++ ) {
                 Vector3I coord = new Vector3I( x, y, z );
                 if( sphere.DistanceTo( coord ) < sphere.Radius ) {
                     map.SetBlock( coord + offset, Block.Stone );
                 }
             }
         }
     }
 }
Beispiel #8
0
        public Zone([NotNull] string raw, [CanBeNull] World world)
            : this()
        {
            if (raw == null)
            {
                throw new ArgumentNullException("raw");
            }
            string[] parts = raw.Split(',');

            string[] header = parts[0].Split(' ');
            Name   = header[0];
            Bounds = new BoundingBox(Int32.Parse(header[1]), Int32.Parse(header[2]), Int32.Parse(header[3]),
                                     Int32.Parse(header[4]), Int32.Parse(header[5]), Int32.Parse(header[6]));

            // If no ranks are loaded (e.g. MapConverter/MapRenderer)(
            if (RankManager.Ranks.Count > 0)
            {
                Rank buildRank = Rank.Parse(header[7]);
                // if all else fails, fall back to lowest class
                if (buildRank == null)
                {
                    if (world != null)
                    {
                        Controller.MinRank = world.BuildSecurity.MinRank;
                    }
                    else
                    {
                        Controller.ResetMinRank();
                    }
                    Logger.Log(LogType.Error,
                               "Zone: Error parsing zone definition: unknown rank \"{0}\". Permission reset to default ({1}).",
                               header[7], Controller.MinRank.Name);
                }
                else
                {
                    Controller.MinRank = buildRank;
                }
            }

            // If PlayerDB is not loaded (e.g. ConfigGUI)
            if (PlayerDB.IsLoaded)
            {
                // Part 2:
                if (parts[1].Length > 0)
                {
                    foreach (string playerName in parts[1].Split(' '))
                    {
                        if (!Player.IsValidPlayerName(playerName))
                        {
                            Logger.Log(LogType.Warning,
                                       "Invalid entry in zone \"{0}\" whitelist: {1}", Name, playerName);
                            continue;
                        }
                        PlayerInfo info = PlayerDB.FindPlayerInfoExact(playerName);
                        if (info == null)
                        {
                            Logger.Log(LogType.Warning,
                                       "Unrecognized player in zone \"{0}\" whitelist: {1}", Name, playerName);
                            continue; // player name not found in the DB (discarded)
                        }
                        Controller.Include(info);
                    }
                }

                // Part 3: excluded list
                if (parts[2].Length > 0)
                {
                    foreach (string playerName in parts[2].Split(' '))
                    {
                        if (!Player.IsValidPlayerName(playerName))
                        {
                            Logger.Log(LogType.Warning,
                                       "Invalid entry in zone \"{0}\" blacklist: {1}", Name, playerName);
                            continue;
                        }
                        PlayerInfo info = PlayerDB.FindPlayerInfoExact(playerName);
                        if (info == null)
                        {
                            Logger.Log(LogType.Warning,
                                       "Unrecognized player in zone \"{0}\" whitelist: {1}", Name, playerName);
                            continue; // player name not found in the DB (discarded)
                        }
                        Controller.Exclude(info);
                    }
                }
            }
            else
            {
                RawWhitelist = parts[1];
                RawBlacklist = parts[2];
            }

            // Part 4: extended header
            if (parts.Length > 3)
            {
                string[] xheader = parts[3].Split(' ');
                if (xheader[0] == "-")
                {
                    CreatedBy   = null;
                    CreatedDate = DateTime.MinValue;
                }
                else
                {
                    CreatedBy   = xheader[0];
                    CreatedDate = DateTime.Parse(xheader[1]);
                }

                if (xheader[2] == "-")
                {
                    EditedBy   = null;
                    EditedDate = DateTime.MinValue;
                }
                else
                {
                    EditedBy   = xheader[2];
                    EditedDate = DateTime.Parse(xheader[3]);
                }
            }
        }
Beispiel #9
0
        static void CopyCallback( Player player, Vector3I[] marks, object tag ) {
            int sx = Math.Min( marks[0].X, marks[1].X );
            int ex = Math.Max( marks[0].X, marks[1].X );
            int sy = Math.Min( marks[0].Y, marks[1].Y );
            int ey = Math.Max( marks[0].Y, marks[1].Y );
            int sz = Math.Min( marks[0].Z, marks[1].Z );
            int ez = Math.Max( marks[0].Z, marks[1].Z );
            BoundingBox bounds = new BoundingBox( sx, sy, sz, ex, ey, ez );

            int volume = bounds.Volume;
            if( !player.CanDraw( volume ) ) {
                player.MessageNow( "You are only allowed to run commands that affect up to {0} blocks. This one would affect {1} blocks.",
                                   player.Info.Rank.DrawLimit, volume );
                return;
            }

            // remember dimensions and orientation
            CopyState copyInfo = new CopyState( marks[0], marks[1] );

            Map map = player.WorldMap;
            World playerWorld = player.World;
            if( playerWorld == null ) PlayerOpException.ThrowNoWorld( player );

            for( int x = sx; x <= ex; x++ ) {
                for( int y = sy; y <= ey; y++ ) {
                    for( int z = sz; z <= ez; z++ ) {
                        copyInfo.Blocks[x - sx, y - sy, z - sz] = map.GetBlock( x, y, z );
                    }
                }
            }

            copyInfo.OriginWorld = playerWorld.Name;
            copyInfo.CopyTime = DateTime.UtcNow;
            player.SetCopyState( copyInfo );

            player.MessageNow( "{0} blocks copied into slot #{1}, origin at {2} corner. You can now &H/Paste",
                               volume,
                               player.CopySlot + 1,
                               copyInfo.OriginCorner );

            Logger.Log( LogType.UserActivity,
                        "{0} copied {1} blocks from world {2} (between {3} and {4}).",
                        player.Name, volume, playerWorld.Name,
                        bounds.MinVertex, bounds.MaxVertex );
        }
Beispiel #10
0
        static void MeasureCallback( Player player, Vector3I[] marks, object tag ) {
            BoundingBox box = new BoundingBox( marks[0], marks[1] );
            player.Message( "Measure: {0} x {1} wide, {2} tall, {3} blocks.",
                            box.Width,
                            box.Length,
                            box.Height,
                            box.Volume );
            player.Message( "  Located between {0} and {1}",
                            box.MinVertex,
                            box.MaxVertex );

            Map map = player.WorldMap;
            Dictionary<Block, int> blockCounts = new Dictionary<Block, int>();
            foreach( Block block in Enum.GetValues( typeof( Block ) ) ) {
                blockCounts[block] = 0;
            }
            for( int x = box.XMin; x <= box.XMax; x++ ) {
                for( int y = box.YMin; y <= box.YMax; y++ ) {
                    for( int z = box.ZMin; z <= box.ZMax; z++ ) {
                        Block block = map.GetBlock( x, y, z );
                        blockCounts[block]++;
                    }
                }
            }
            var topBlocks = blockCounts.Where( p => p.Value > 0 )
                                       .OrderByDescending( p => p.Value )
                                       .Take( TopBlocksToList )
                                       .ToArray();
            var blockString = topBlocks.JoinToString( p => String.Format( "{0}: {1} ({2}%)",
                                                                          p.Key,
                                                                          p.Value,
                                                                          (p.Value * 100L) / box.Volume ) );
            player.Message( "  Top {0} block types: {1}",
                            topBlocks.Length, blockString );
        }
Beispiel #11
0
        /// <summary> Creates an empty new map of given dimensions.
        /// Dimensions cannot be changed after creation. </summary>
        /// <param name="world"> World that owns this map. May be null, and may be changed later. </param>
        /// <param name="width"> Width (horizontal, Notch's X). </param>
        /// <param name="length"> Length (horizontal, Notch's Z). </param>
        /// <param name="height"> Height (vertical, Notch's Y). </param>
        /// <param name="initBlockArray"> If true, the Blocks array will be created. </param>
        public Map( World world, int width, int length, int height, bool initBlockArray )
        {
            if( !IsValidDimension( width ) ) throw new ArgumentException( "Invalid map dimension.", "width" );
            if( !IsValidDimension( length ) ) throw new ArgumentException( "Invalid map dimension.", "length" );
            if( !IsValidDimension( height ) ) throw new ArgumentException( "Invalid map dimension.", "height" );
            DateCreated = DateTime.UtcNow;
            DateModified = DateCreated;
            Guid = Guid.NewGuid();

            Metadata = new MetadataCollection<string>();
            Metadata.Changed += OnMetaOrZoneChange;

            Zones = new ZoneCollection();
            Zones.Changed += OnMetaOrZoneChange;

            World = world;

            Width = width;
            Length = length;
            Height = height;
            Bounds = new BoundingBox( Vector3I.Zero, Width, Length, Height );
            Volume = Bounds.Volume;

            if( initBlockArray ) {
                Blocks = new byte[Volume];
            }

            LifeZones = new Dictionary<string, Life2DZone>();

            ResetSpawn();
        }
Beispiel #12
0
 /// <summary> Checks if another bounding box is wholly contained inside this one. </summary>
 public bool Contains( BoundingBox other ) {
     if( other == null ) throw new ArgumentNullException( "other" );
     return XMin >= other.XMin && XMax <= other.XMax &&
            YMin >= other.YMin && YMax <= other.YMax &&
            HMin >= other.HMin && HMax <= other.HMax;
 }
Beispiel #13
0
 /// <summary> Checks whether this bounding box intersects/touches another one. </summary>
 public bool Insersects( BoundingBox other ) {
     if( other == null ) throw new ArgumentNullException( "other" );
     return XMin > other.XMax || XMax < other.XMin ||
            YMin > other.YMax || YMax < other.YMin ||
            HMin > other.HMax || HMax < other.HMin;
 }
Beispiel #14
0
        unsafe internal static void PasteCallback( Player player, Position[] marks, object tag ) {
            CopyInformation info = player.CopyInformation;

            PasteArgs args = (PasteArgs)tag;
            byte* specialTypes = stackalloc byte[args.BlockTypes.Length];
            int specialTypeCount = args.BlockTypes.Length;
            for( int i = 0; i < args.BlockTypes.Length; i++ ) {
                specialTypes[i] = (byte)args.BlockTypes[i];
            }
            Map map = player.World.Map;

            BoundingBox bounds = new BoundingBox( marks[0], info.WidthX, info.WidthY, info.Height );

            int pasteVolume = bounds.GetIntersection( map.Bounds ).Volume;
            if( !player.CanDraw( pasteVolume ) ) {
                player.MessageNow( "You are only allowed to run draw commands that affect up to {0} blocks. This one would affect {1} blocks.",
                                   player.Info.Rank.DrawLimit,
                                   pasteVolume );
                return;
            }

            if( bounds.XMin < 0 || bounds.XMax > map.WidthX - 1 ) {
                player.MessageNow( "Warning: Not enough room horizontally (X), paste cut off." );
            }
            if( bounds.YMin < 0 || bounds.YMax > map.WidthY - 1 ) {
                player.MessageNow( "Warning: Not enough room horizontally (Y), paste cut off." );
            }
            if( bounds.HMin < 0 || bounds.HMax > map.Height - 1 ) {
                player.MessageNow( "Warning: Not enough room vertically, paste cut off." );
            }

            player.UndoBuffer.Clear();

            int blocks = 0, blocksDenied = 0;
            bool cannotUndo = false;

            for( int x = bounds.XMin; x <= bounds.XMax; x += DrawStride ) {
                for( int y = bounds.YMin; y <= bounds.YMax; y += DrawStride ) {
                    for( int h = bounds.HMin; h <= bounds.HMax; h++ ) {
                        for( int y3 = 0; y3 < DrawStride && y + y3 <= bounds.YMax; y3++ ) {
                            for( int x3 = 0; x3 < DrawStride && x + x3 <= bounds.XMax; x3++ ) {
                                byte block = info.Buffer[x + x3 - bounds.XMin, y + y3 - bounds.YMin, h - bounds.HMin];

                                if( args.DoInclude ) {
                                    bool skip = true;
                                    for( int i = 0; i < specialTypeCount; i++ ) {
                                        if( block == specialTypes[i] ) {
                                            skip = false;
                                            break;
                                        }
                                    }
                                    if( skip ) continue;
                                } else if( args.DoExclude ) {
                                    bool skip = false;
                                    for( int i = 0; i < specialTypeCount; i++ ) {
                                        if( block == specialTypes[i] ) {
                                            skip = true;
                                            break;
                                        }
                                    }
                                    if( skip ) continue;
                                }
                                DrawOneBlock( player, block, x + x3, y + y3, h, ref blocks, ref blocksDenied, ref cannotUndo );
                            }
                        }
                    }
                }
            }

            Logger.Log( "{0} pasted {1} blocks to {2}.", LogType.UserActivity,
                        player.Name, blocks, player.World.Name );
            DrawingFinished( player, "pasted", blocks, blocksDenied );
        }
Beispiel #15
0
        public Zone(string raw, World world)
        {
            string[] parts = raw.Split(',');

            string[] header = parts[0].Split(' ');
            Name   = header[0];
            Bounds = new BoundingBox(Int32.Parse(header[1]), Int32.Parse(header[2]), Int32.Parse(header[3]),
                                     Int32.Parse(header[4]), Int32.Parse(header[5]), Int32.Parse(header[6]));

            Rank buildRank = RankManager.ParseRank(header[7]);

            // if all else fails, fall back to lowest class
            if (buildRank == null)
            {
                if (world != null)
                {
                    Controller.MinRank = world.BuildSecurity.MinRank;
                }
                else
                {
                    Controller.MinRank = null;
                }
                Logger.Log("Zone: Error parsing zone definition: unknown rank \"{0}\". Permission reset to default ({1}).", LogType.Error,
                           header[7], Controller.MinRank.Name);
            }
            else
            {
                Controller.MinRank = buildRank;
            }


            // Part 2:
            foreach (string player in parts[1].Split(' '))
            {
                if (!Player.IsValidName(player))
                {
                    continue;
                }
                PlayerInfo info = PlayerDB.FindPlayerInfoExact(player);
                if (info == null)
                {
                    continue;                // player name not found in the DB (discarded)
                }
                Controller.Include(info);
            }

            // Part 3: excluded list
            foreach (string player in parts[2].Split(' '))
            {
                if (!Player.IsValidName(player))
                {
                    continue;
                }
                PlayerInfo info = PlayerDB.FindPlayerInfoExact(player);
                if (info == null)
                {
                    continue;                // player name not found in the DB (discarded)
                }
                Controller.Exclude(info);
            }

            Controller.UpdatePlayerListCache();

            // Part 4: extended header
            if (parts.Length > 3)
            {
                string[] xheader = parts[3].Split(' ');
                CreatedBy = PlayerDB.FindPlayerInfoExact(xheader[0]);
                if (CreatedBy != null)
                {
                    CreatedDate = DateTime.Parse(xheader[1]);
                }
                EditedBy = PlayerDB.FindPlayerInfoExact(xheader[2]);
                if (EditedBy != null)
                {
                    EditedDate = DateTime.Parse(xheader[3]);
                }
            }
        }
        static void CenterCallback(Player player, Vector3I[] marks, object tag)
        {
            if (player.LastUsedBlockType != Block.Undefined)
            {
                int sx = Math.Min(marks[0].X, marks[1].X), ex = Math.Max(marks[0].X, marks[1].X),
                sy = Math.Min(marks[0].Y, marks[1].Y), ey = Math.Max(marks[0].Y, marks[1].Y),
                sz = Math.Min(marks[0].Z, marks[1].Z), ez = Math.Max(marks[0].Z, marks[1].Z);

                BoundingBox bounds = new BoundingBox(sx, sy, sz, ex, ey, ez);
                Vector3I cPos = new Vector3I((bounds.XMin + bounds.XMax) / 2,
                    (bounds.YMin + bounds.YMax) / 2,
                    (bounds.ZMin + bounds.ZMax) / 2);
                int blocksDrawn = 0,
                blocksSkipped = 0;
                UndoState undoState = player.DrawBegin(null);

                World playerWorld = player.World;
                if (playerWorld == null) PlayerOpException.ThrowNoWorld(player);
                Map map = player.WorldMap;
                DrawOneBlock(player, player.World.Map, player.LastUsedBlockType, cPos,
                          BlockChangeContext.Drawn,
                          ref blocksDrawn, ref blocksSkipped, undoState);
                DrawingFinished(player, "Placed", blocksDrawn, blocksSkipped);
            }else{
                player.Message("&WCannot deduce desired block. Click a block or type out the block name.");
            }
        }
        public override bool Prepare(Vector3I[] marks)
        {
            if (marks == null)
                throw new ArgumentNullException("marks");
            if (marks.Length < 1)
                throw new ArgumentException("At least one mark needed.", "marks");

            Vector3I mark2 = new Vector3I((_cellSize + 1) * _maze.XSize + 1 + marks[0].X,
                (_cellSize + 1) * _maze.YSize + 1 + marks[0].Y,
                (_cellSize + 1) * _maze.ZSize + 1 + marks[0].Z);

            Marks = marks;

            // Warn if paste will be cut off
            if (mark2.X >= Map.Width)
            {
                Player.Message("Error: Not enough room horizontally (X)");
                return false;
            }
            if (mark2.Y >= Map.Length)
            {
                Player.Message("Error: Not enough room horizontally (Y)");
                return false;
            }
            if (mark2.Z >= Map.Height)
            {
                Player.Message("Error: Not enough room vertically (Z)");
                return false;
            }

            Bounds = new BoundingBox(marks[0], mark2);

            Brush = this;
            Coords = Bounds.MinVertex;

            StartTime = DateTime.UtcNow;
            Context = BlockChangeContext.Drawn;
            BlocksTotalEstimate = Bounds.Volume;
            return true;
        }
Beispiel #18
0
 internal static void MeasureCallback( Player player, Position[] marks, object tag ) {
     BoundingBox box = new BoundingBox( marks[0], marks[1] );
     player.Message( "Measure: {0} x {1} wide, {2} tall, {3} blocks.",
                     box.WidthX,
                     box.WidthY,
                     box.Height,
                     box.Volume );
     player.Message( "Measure: Located between ({0},{1},{2}) and ({3},{4},{5}).",
                     box.XMin,
                     box.YMin,
                     box.HMin,
                     box.XMax,
                     box.YMax,
                     box.HMax );
 }
Beispiel #19
0
        /// <summary> Creates an empty new map of given dimensions.
        /// Dimensions cannot be changed after creation. </summary>
        /// <param name="world"> World that owns this map. May be null, and may be changed later. </param>
        /// <param name="width"> Width (horizontal, Notch's X). </param>
        /// <param name="length"> Length (horizontal, Notch's Z). </param>
        /// <param name="height"> Height (vertical, Notch's Y). </param>
        /// <param name="initBlockArray"> If true, the Blocks array will be created. </param>
        /// <exception cref="ArgumentOutOfRangeException"> Width, length, or height is not between 16 and 2048. </exception>
        /// <exception cref="ArgumentException"> Map volume exceeds Int32.MaxValue. </exception>
        public Map([CanBeNull] World world, int width, int length, int height, bool initBlockArray) {
            if (!IsValidDimension(width)) throw new ArgumentOutOfRangeException("width", "Invalid map width.");
            if (!IsValidDimension(length)) throw new ArgumentOutOfRangeException("length", "Invalid map length.");
            if (!IsValidDimension(height)) throw new ArgumentOutOfRangeException("height", "Invalid map height.");
            if ((long)width*length*height > Int32.MaxValue) {
                throw new ArgumentException("Map volume exceeds Int32.MaxValue.");
            }
            DateCreated = DateTime.UtcNow;
            DateModified = DateCreated;
            Guid = Guid.NewGuid();

            Metadata = new MetadataCollection<string>();
            Metadata.Changed += OnMetaOrZoneChange;

            Zones = new ZoneCollection();
            Zones.Changed += OnMetaOrZoneChange;

            World = world;

            Width = width;
            Length = length;
            Height = height;
            Bounds = new BoundingBox(Vector3I.Zero, Width, Length, Height);
            Volume = Bounds.Volume;

            if (initBlockArray) {
                Blocks = new byte[Volume];
            }

            ResetSpawn();
        }
Beispiel #20
0
        public Zone( NbtCompound tag ) {
            NbtCompound boundsTag = tag.Get<NbtCompound>( "Bounds" );
            if( boundsTag == null ) {
                throw new SerializationException( "Bounds missing from zone definition tag." );
            }
            Bounds = new BoundingBox( boundsTag );

            NbtCompound controllerTag = tag.Get<NbtCompound>( "Controller" );
            if( controllerTag == null ) {
                throw new SerializationException( "Controller missing from zone definition tag." );
            }
            Controller = new SecurityController( controllerTag );

            var createdByTag = tag.Get<NbtString>( "CreatedBy" );
            var createdDateTag = tag.Get<NbtLong>( "CreatedDate" );
            if( createdByTag != null && createdDateTag != null ) {
                CreatedBy = createdByTag.Value;
                CreatedDate = DateTimeUtil.TryParseDateTime( createdDateTag.Value );
            }

            var editedByTag = tag.Get<NbtString>( "EditedBy" );
            var editedDateTag = tag.Get<NbtLong>( "EditedDate" );
            if( editedByTag != null && editedDateTag != null ) {
                EditedBy = editedByTag.Value;
                EditedDate = DateTimeUtil.TryParseDateTime( editedDateTag.Value );
            }
        }
Beispiel #21
0
        static void RestoreCallback( Player player, Vector3I[] marks, object tag ) {
            BoundingBox selection = new BoundingBox( marks[0], marks[1] );
            Map map = (Map)tag;

            if( !player.CanDraw( selection.Volume ) ) {
                player.MessageNow(
                    "You are only allowed to restore up to {0} blocks at a time. This would affect {1} blocks.",
                    player.Info.Rank.DrawLimit,
                    selection.Volume );
                return;
            }

            int blocksDrawn = 0,
                blocksSkipped = 0;
            UndoState undoState = player.DrawBegin( null );

            World playerWorld = player.World;
            if( playerWorld == null ) PlayerOpException.ThrowNoWorld( player );
            Map playerMap = player.WorldMap;
            Vector3I coord = new Vector3I();
            for( coord.X = selection.XMin; coord.X <= selection.XMax; coord.X++ ) {
                for( coord.Y = selection.YMin; coord.Y <= selection.YMax; coord.Y++ ) {
                    for( coord.Z = selection.ZMin; coord.Z <= selection.ZMax; coord.Z++ ) {
                        DrawOneBlock( player, playerMap, map.GetBlock( coord ), coord,
                                      RestoreContext,
                                      ref blocksDrawn, ref blocksSkipped, undoState );
                    }
                }
            }

            Logger.Log( LogType.UserActivity,
                        "{0} restored {1} blocks on world {2} (@{3},{4},{5} - {6},{7},{8}) from file {9}.",
                        player.Name, blocksDrawn,
                        playerWorld.Name,
                        selection.XMin, selection.YMin, selection.ZMin,
                        selection.XMax, selection.YMax, selection.ZMax,
                        map.Metadata["fCraft.Temp", "FileName"] );

            DrawingFinished( player, "Restored", blocksDrawn, blocksSkipped );
        }
Beispiel #22
0
        public Zone( [NotNull] XContainer root ) {
            if( root == null ) throw new ArgumentNullException( "root" );
            Name = root.Element( "name" ).Value;

            if( root.Element( "created" ) != null ) {
                XElement created = root.Element( "created" );
                CreatedBy = created.Attribute( "by" ).Value;
                DateTime createdDate;
                created.Attribute( "on" ).Value.ToDateTime( out createdDate );
                CreatedDate = createdDate;
            }

            if( root.Element( "edited" ) != null ) {
                XElement edited = root.Element( "edited" );
                EditedBy = edited.Attribute( "by" ).Value;
                DateTime editedDate;
                edited.Attribute( "on" ).Value.ToDateTime( out editedDate );
                EditedDate = editedDate;
            }

            XElement temp = root.Element( BoundingBox.XmlRootName );
            if( temp == null ) throw new SerializationException( "No BoundingBox specified for zone." );
            Bounds = new BoundingBox( temp );

            temp = root.Element( SecurityController.XmlRootName );
            if( temp == null ) throw new SerializationException( "No SecurityController specified for zone." );
            Controller = new SecurityController( temp, PlayerDB.IsLoaded );
        }
Beispiel #23
0
        public Zone( [NotNull] XContainer root )
        {
            if ( root == null )
                throw new ArgumentNullException( "root" );
            // ReSharper disable PossibleNullReferenceException
            Name = root.Element( "name" ).Value;

            if ( root.Element( "created" ) != null ) {
                XElement created = root.Element( "created" );
                CreatedBy = created.Attribute( "by" ).Value;
                CreatedDate = DateTime.Parse( created.Attribute( "on" ).Value );
            }

            if ( root.Element( "edited" ) != null ) {
                XElement edited = root.Element( "edited" );
                EditedBy = edited.Attribute( "by" ).Value;
                EditedDate = DateTime.Parse( edited.Attribute( "on" ).Value );
            }

            XElement temp = root.Element( BoundingBox.XmlRootElementName );
            if ( temp == null )
                throw new FormatException( "No BoundingBox specified for zone." );
            Bounds = new BoundingBox( temp );

            temp = root.Element( SecurityController.XmlRootElementName );
            if ( temp == null )
                throw new FormatException( "No SecurityController specified for zone." );
            Controller = new SecurityController( temp, true );
            // ReSharper restore PossibleNullReferenceException
        }
Beispiel #24
0
        public Zone( [NotNull] string raw, [CanBeNull] World world )
            : this() {
            if( raw == null ) throw new ArgumentNullException( "raw" );
            string[] parts = raw.Split( ',' );

            string[] header = parts[0].Split( ' ' );
            Name = header[0];
            Bounds = new BoundingBox( Int32.Parse( header[1] ), Int32.Parse( header[2] ), Int32.Parse( header[3] ),
                                      Int32.Parse( header[4] ), Int32.Parse( header[5] ), Int32.Parse( header[6] ) );

            Rank buildRank = Rank.Parse( header[7] );


			if (header.Length > 8) {
				// Part 5: Zone color
				try {
					bool zoneShow;
					if (bool.TryParse(header[8], out zoneShow)) {
						ShowZone = zoneShow;
					}
					Color = header[9];
					short zoneAlpha;
					if (short.TryParse(header[10], out zoneAlpha)) {
						Alpha = zoneAlpha;
					}
				} catch (Exception ex) {
					Logger.Log(LogType.Error, "Could not load Zone Colors for {0}", Name);
					Logger.Log(LogType.Error, ex.StackTrace);
				}
			}

            if (header[0].Contains("Door_")) {
                buildRank = RankManager.DefaultRank;
            }
            // if all else fails, fall back to lowest class... ignore door instances
            if (buildRank == null && !header[0].Contains("Door_")) {
                if (world != null) {
                    Controller.MinRank = world.BuildSecurity.MinRank;
                } else {
                    Controller.ResetMinRank();
                }
                Logger.Log(LogType.Error,
                            "Zone: Error parsing zone definition: unknown rank \"{0}\". Permission reset to default ({1}). Ignore this message if you have recently changed rank permissions.",
                            header[7], Controller.MinRank.Name);
            } else {
                Controller.MinRank = buildRank;
            }

            if( PlayerDB.IsLoaded ) {
                // Part 2:
                if( parts[1].Length > 0 ) {
                    foreach( string playerName in parts[1].Split( ' ' ) ) {
                        if (!Player.IsValidPlayerName(playerName))
                        {
                            Logger.Log( LogType.Warning,
                                        "Invalid entry in zone \"{0}\" whitelist: {1}", Name, playerName );
                            continue;
                        }
                        PlayerInfo info = PlayerDB.FindPlayerInfoExact( playerName );
                        if( info == null ) {
                            Logger.Log( LogType.Warning,
                                        "Unrecognized player in zone \"{0}\" whitelist: {1}", Name, playerName );
                            continue; // player name not found in the DB (discarded)
                        }
                        Controller.Include( info );
                    }
                }

                // Part 3: excluded list
                if( parts[2].Length > 0 ) {
                    foreach( string playerName in parts[2].Split( ' ' ) ) {
                        if (!Player.IsValidPlayerName(playerName))
                        {
                            Logger.Log( LogType.Warning,
                                        "Invalid entry in zone \"{0}\" blacklist: {1}", Name, playerName );
                            continue;
                        }
                        PlayerInfo info = PlayerDB.FindPlayerInfoExact( playerName );
                        if( info == null ) {
                            Logger.Log( LogType.Warning,
                                        "Unrecognized player in zone \"{0}\" whitelist: {1}", Name, playerName );
                            continue; // player name not found in the DB (discarded)
                        }
                        Controller.Exclude( info );
                    }
                }
            } else {
                RawWhitelist = parts[1];
                RawBlacklist = parts[2];
            }

            // Part 4: extended header
            if( parts.Length > 3 ) {
                string[] xheader = parts[3].Split( ' ' );                
                if( xheader[0] == "-" ) {
                    CreatedBy = null;
                    CreatedDate = DateTime.MinValue;
                } else {
                    CreatedBy = xheader[0];
                    CreatedDate = DateTime.Parse( xheader[1] );
                }

                if( xheader[2] == "-" ) {
                    EditedBy = null;
                    EditedDate = DateTime.MinValue;
                } else {
                    EditedBy = xheader[2];
                    EditedDate = DateTime.Parse( xheader[3] );
                }
            }
        }