static void Place(Player player, Command cmd) { if (player.LastUsedBlockType != Block.Undefined) { Vector3I Pos = new Vector3I(player.Position.X / 32, player.Position.Y / 32, (player.Position.Z / 32) - 2); if (player.CanPlace(player.World.Map, Pos, player.LastUsedBlockType, BlockChangeContext.Manual) != CanPlaceResult.Allowed) { player.Message("&WYou are not allowed to build here"); return; } Player.RaisePlayerPlacedBlockEvent(player, player.WorldMap, Pos, player.WorldMap.GetBlock(Pos), player.LastUsedBlockType, BlockChangeContext.Manual); BlockUpdate blockUpdate = new BlockUpdate(null, Pos, player.LastUsedBlockType); player.World.Map.QueueUpdate(blockUpdate); player.Message("Block placed below your feet"); } else player.Message("&WError: No last used blocktype was found"); }
static void MessageBlockAdd( Player player, Vector3I[] marks, object tag ) { string Message = ( string )tag; Vector3I mark = marks[0]; if ( !player.Info.Rank.AllowSecurityCircumvention ) { SecurityCheckResult buildCheck = player.World.BuildSecurity.CheckDetailed( player.Info ); switch ( buildCheck ) { case SecurityCheckResult.BlackListed: player.Message( "Cannot add a MessageBlock to world {0}&S: You are barred from building here.", player.World.ClassyName ); return; case SecurityCheckResult.RankTooLow: player.Message( "Cannot add a MessageBlock to world {0}&S: You are not allowed to build here.", player.World.ClassyName ); return; //case SecurityCheckResult.RankTooHigh: } } if ( player.LastUsedBlockType != Block.Undefined ) { Vector3I Pos = mark; if ( player.CanPlace( player.World.Map, Pos, player.LastUsedBlockType, BlockChangeContext.Manual ) != CanPlaceResult.Allowed ) { player.Message( "&WYou are not allowed to build here" ); return; } Player.RaisePlayerPlacedBlockEvent( player, player.WorldMap, Pos, player.WorldMap.GetBlock( Pos ), player.LastUsedBlockType, BlockChangeContext.Manual ); BlockUpdate blockUpdate = new BlockUpdate( null, Pos, player.LastUsedBlockType ); player.World.Map.QueueUpdate( blockUpdate ); } else { player.Message( "&WError: No last used blocktype was found" ); return; } MessageBlock MessageBlock = new MessageBlock( player.World.Name, mark, MessageBlock.GenerateName( player.World ), player.ClassyName, Message ); MessageBlock.Range = new MessageBlockRange( mark.X, mark.X, mark.Y, mark.Y, mark.Z, mark.Z ); MessageBlockHandler.CreateMessageBlock( MessageBlock, player.World ); NormalBrush brush = new NormalBrush( Block.Air ); Logger.Log( LogType.UserActivity, "{0} created MessageBlock {1} (on world {2})", player.Name, MessageBlock.Name, player.World.Name ); player.Message( "MessageBlock created on world {0}&S with name {1}", player.World.ClassyName, MessageBlock.Name ); }
//stolen from BuildingCommands #region DrawOneBlock static void DrawOneBlock ( Player player, Map map, Block drawBlock, Vector3I coord, BlockChangeContext context, ref int blocks, ref int blocksDenied, fCraft.Drawing.UndoState undoState ) { if ( map == null ) return; if ( player == null ) throw new ArgumentNullException( "player" ); if ( !map.InBounds( coord ) ) return; Block block = map.GetBlock( coord ); if ( block == drawBlock ) return; if ( player.CanPlace( map, coord, drawBlock, context ) != CanPlaceResult.Allowed ) { blocksDenied++; return; } map.QueueUpdate( new BlockUpdate( null, coord, drawBlock ) ); Player.RaisePlayerPlacedBlockEvent( player, map, coord, block, drawBlock, context ); if ( !undoState.IsTooLargeToUndo ) { if ( !undoState.Add( coord, block ) ) { player.Message( "NOTE: This draw command is too massive to undo." ); player.LastDrawOp = null; } } blocks++; }
static void DoorAdd( 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 sh = Math.Min( marks[0].Z, marks[1].Z ); int eh = Math.Max( marks[0].Z, marks[1].Z ); int volume = ( ex - sx + 1 ) * ( ey - sy + 1 ) * ( eh - sh + 1 ); if ( volume > 30 ) { player.Message( "Doors are only allowed to be {0} blocks", 30 ); return; } if ( !player.Info.Rank.AllowSecurityCircumvention ) { SecurityCheckResult buildCheck = player.World.BuildSecurity.CheckDetailed( player.Info ); switch ( buildCheck ) { case SecurityCheckResult.BlackListed: player.Message( "Cannot add a door to world {0}&S: You are barred from building here.", player.World.ClassyName ); return; case SecurityCheckResult.RankTooLow: player.Message( "Cannot add a door to world {0}&S: You are not allowed to build here.", player.World.ClassyName ); return; //case SecurityCheckResult.RankTooHigh: } } List<Vector3I> blocks = new List<Vector3I>(); for ( int x = sx; x < ex; x++ ) { for ( int y = sy; y < ey; y++ ) { for ( int z = sh; z < eh; z++ ) { if ( player.CanPlace( player.World.Map, new Vector3I( x, y, z ), Block.Wood, BlockChangeContext.Manual ) != CanPlaceResult.Allowed ) { player.Message( "Cannot add a door to world {0}&S: Build permissions in this area replied with 'denied'.", player.World.ClassyName ); return; } blocks.Add( new Vector3I( x, y, z ) ); } } } Door door = new Door( player.World.Name, blocks.ToArray(), fCraft.Doors.Door.GenerateName( player.World ), player.ClassyName ); door.Range = new DoorRange( sx, ex, sy, ey, sh, eh ); DoorHandler.CreateDoor( door, player.World ); Logger.Log( LogType.UserActivity, "{0} created door {1} (on world {2})", player.Name, door.Name, player.World.Name ); player.Message( "Door created on world {0}&S with name {1}", player.World.ClassyName, door.Name ); }
private static void DisPlace(Player player, CommandReader cmd) { Block block; if (cmd.Count <= 2) { player.Message(CdDisPlace.Usage); return; } string tryBlock = cmd.Next(); if (!Map.GetBlockByName(tryBlock, false, out block)) { player.Message("Invalid block name/id: {0}", tryBlock); return; } int dis; string tryInt = cmd.Next(); if (!int.TryParse(tryInt, out dis)) { player.Message("Invalid distance: {0}", tryInt); return; } dis = dis*32; byte rot = player.Position.R; byte ud = player.Position.L; if (225 < ud || ud < 32) { if (225 <= rot || rot <= 32) { Vector3I Pos = new Vector3I(player.Position.X/32, (player.Position.Y - dis)/32, (player.Position.Z - 32)/32); Pos.X = Math.Min(player.WorldMap.Width - 1, Math.Max(0, Pos.X)); Pos.Y = Math.Min(player.WorldMap.Length - 1, Math.Max(0, Pos.Y)); Pos.Z = Math.Min(player.WorldMap.Height - 1, Math.Max(0, Pos.Z)); if (player.CanPlace(player.World.Map, Pos, block, BlockChangeContext.Drawn) != CanPlaceResult.Allowed) { player.Message("&WYou are not allowed to build here"); return; } Player.RaisePlayerPlacedBlockEvent(player, player.WorldMap, Pos, player.WorldMap.GetBlock(Pos), block, BlockChangeContext.Drawn); BlockUpdate blockUpdate = new BlockUpdate(null, Pos, block); player.World.Map.QueueUpdate(blockUpdate); player.Message("Block placed at {0} ({1} blocks away from you)", Pos, dis/32); } else if (33 <= rot && rot <= 96) { Vector3I Pos = new Vector3I((player.Position.X + dis)/32, player.Position.Y/32, (player.Position.Z - 32) / 32); Pos.X = Math.Min(player.WorldMap.Width - 1, Math.Max(0, Pos.X)); Pos.Y = Math.Min(player.WorldMap.Length - 1, Math.Max(0, Pos.Y)); Pos.Z = Math.Min(player.WorldMap.Height - 1, Math.Max(0, Pos.Z)); if (player.CanPlace(player.World.Map, Pos, block, BlockChangeContext.Drawn) != CanPlaceResult.Allowed) { player.Message("&WYou are not allowed to build here"); return; } Player.RaisePlayerPlacedBlockEvent(player, player.WorldMap, Pos, player.WorldMap.GetBlock(Pos), block, BlockChangeContext.Drawn); BlockUpdate blockUpdate = new BlockUpdate(null, Pos, block); player.World.Map.QueueUpdate(blockUpdate); player.Message("Block placed at {0} ({1} blocks away from you)", Pos, dis/32); } else if (97 <= rot && rot <= 160) { Vector3I Pos = new Vector3I(player.Position.X/32, (player.Position.Y + dis)/32, (player.Position.Z - 32) / 32); Pos.X = Math.Min(player.WorldMap.Width - 1, Math.Max(0, Pos.X)); Pos.Y = Math.Min(player.WorldMap.Length - 1, Math.Max(0, Pos.Y)); Pos.Z = Math.Min(player.WorldMap.Height - 1, Math.Max(0, Pos.Z)); if (player.CanPlace(player.World.Map, Pos, block, BlockChangeContext.Drawn) != CanPlaceResult.Allowed) { player.Message("&WYou are not allowed to build here"); return; } Player.RaisePlayerPlacedBlockEvent(player, player.WorldMap, Pos, player.WorldMap.GetBlock(Pos), block, BlockChangeContext.Drawn); BlockUpdate blockUpdate = new BlockUpdate(null, Pos, block); player.World.Map.QueueUpdate(blockUpdate); player.Message("Block placed at {0} ({1} blocks away from you)", Pos, dis/32); } else if (161 <= rot && rot <= 224) { Vector3I Pos = new Vector3I((player.Position.X - dis)/32, player.Position.Y/32, (player.Position.Z - 32) / 32); Pos.X = Math.Min(player.WorldMap.Width - 1, Math.Max(0, Pos.X)); Pos.Y = Math.Min(player.WorldMap.Length - 1, Math.Max(0, Pos.Y)); Pos.Z = Math.Min(player.WorldMap.Height - 1, Math.Max(0, Pos.Z)); if (player.CanPlace(player.World.Map, Pos, block, BlockChangeContext.Drawn) != CanPlaceResult.Allowed) { player.Message("&WYou are not allowed to build here"); return; } Player.RaisePlayerPlacedBlockEvent(player, player.WorldMap, Pos, player.WorldMap.GetBlock(Pos), block, BlockChangeContext.Drawn); BlockUpdate blockUpdate = new BlockUpdate(null, Pos, block); player.World.Map.QueueUpdate(blockUpdate); player.Message("Block placed at {0} ({1} blocks away from you)", Pos, dis/32); } else { player.Message("Error occurred, please try again."); return; } } else { if (192 <= ud && ud <= 224) { Vector3I Pos = new Vector3I(player.Position.X/32, player.Position.Y/32, (player.Position.Z - 32 + dis) / 32); Pos.X = Math.Min(player.WorldMap.Width - 1, Math.Max(0, Pos.X)); Pos.Y = Math.Min(player.WorldMap.Length - 1, Math.Max(0, Pos.Y)); Pos.Z = Math.Min(player.WorldMap.Height - 1, Math.Max(0, Pos.Z)); if (player.CanPlace(player.World.Map, Pos, block, BlockChangeContext.Drawn) != CanPlaceResult.Allowed) { player.Message("&WYou are not allowed to build here"); return; } Player.RaisePlayerPlacedBlockEvent(player, player.WorldMap, Pos, player.WorldMap.GetBlock(Pos), block, BlockChangeContext.Drawn); BlockUpdate blockUpdate = new BlockUpdate(null, Pos, block); player.World.Map.QueueUpdate(blockUpdate); player.Message("Block placed at {0} ({1} blocks away from you)", Pos, dis / 32); } else if (33 <= ud && ud <= 65) { Vector3I Pos = new Vector3I(player.Position.X/32, player.Position.Y/32, (player.Position.Z - 32 - dis) / 32); Pos.X = Math.Min(player.WorldMap.Width - 1, Math.Max(0, Pos.X)); Pos.Y = Math.Min(player.WorldMap.Length - 1, Math.Max(0, Pos.Y)); Pos.Z = Math.Min(player.WorldMap.Height - 1, Math.Max(0, Pos.Z)); if (player.CanPlace(player.World.Map, Pos, block, BlockChangeContext.Drawn) != CanPlaceResult.Allowed) { player.Message("&WYou are not allowed to build here"); return; } Player.RaisePlayerPlacedBlockEvent(player, player.WorldMap, Pos, player.WorldMap.GetBlock(Pos), block, BlockChangeContext.Drawn); BlockUpdate blockUpdate = new BlockUpdate(null, Pos, block); player.World.Map.QueueUpdate(blockUpdate); player.Message("Block placed at {0} ({1} blocks away from you)", Pos, dis/32); } else { player.Message("Error occurred, please try again."); return; } } }
/// <summary> /// Initializes a new instance of the <see cref="Particle"/> class. /// </summary> /// <param name="world">The world.</param> /// <param name="pos">The initial position.</param> /// <param name="direction">The direction in which the particle is flying.</param> /// <param name="owner">The owner of the particle.</param> /// <param name="block">The block type of the particle.</param> /// <param name="behavior">The partcle behavior. Includes how fare and fast it moves, what happens if it hits a player an obstacle etc.</param> public Particle(World world, Vector3I pos, Vector3F direction, Player owner, Block block, IParticleBehavior behavior) : base(world) { _direction = direction.Normalize(); if (_direction == Vector3F.Zero) throw new ArgumentException("direction vector cannot be zero"); _stepDelay = behavior.ProcessingStepsPerSecond <= 0 || behavior.ProcessingStepsPerSecond > 20 ? 50 : 1000 / behavior.ProcessingStepsPerSecond; _pos = pos; _startingPos = pos; _currentStep = 0; _owner = owner; _block = block; _restDistance = behavior.MaxDistance; _behavior = behavior; lock (_world.SyncRoot) { //draw it once right now if (null != _map && ReferenceEquals(_map, _world.Map)) { _prevBlock = _map.GetBlock(pos); if (Block.Undefined != _prevBlock) //out of bounds! if (owner.CanPlace(_map, pos, Block.Wood, BlockChangeContext.Manual) == CanPlaceResult.Allowed) UpdateMap(new BlockUpdate(null, pos, block)); } } }
//true if not stopped public bool VisitBlock(World world, Vector3I pos, Block block, Player owner, ref int restDistance, IList<BlockUpdate> updates, Block sending) { if (Block.TNT == block) //explode it { world.AddPhysicsTask(new TNTTask(world, pos, owner, false, true), _r.Next(150, 300)); } if (Block.Air != block && Block.Water != block && Block.Lava != block) if (owner.CanPlace(world.Map, pos, Block.Wood, BlockChangeContext.Manual) == CanPlaceResult.Allowed) updates.Add(new BlockUpdate(null, pos, Block.Air)); return true; }
static void Place(Player player, Command cmd) { Block block; if (player.LastUsedBlockType == Block.Undefined) { block = Block.Stone; } else { block = player.LastUsedBlockType; } Vector3I Pos = new Vector3I(player.Position.X / 32, player.Position.Y / 32, (player.Position.Z / 32) - 2); if (player.CanPlace(player.World.Map, Pos, player.GetBind(block), BlockChangeContext.Manual) != CanPlaceResult.Allowed) { player.Message("&WYou are not allowed to build here"); return; } Player.RaisePlayerPlacedBlockEvent(player, player.WorldMap, Pos, player.WorldMap.GetBlock(Pos), block, BlockChangeContext.Manual); BlockUpdate blockUpdate = new BlockUpdate(null, Pos, block); player.World.Map.QueueUpdate(blockUpdate); player.Message("Block placed below your feet"); }
unsafe internal static void ReplaceCallback( Player player, Position[] marks, object drawArgs ) { ReplaceArgs args = (ReplaceArgs)drawArgs; byte* specialTypes = stackalloc byte[args.Types.Length]; int specialTypeCount = args.Types.Length; for( int i = 0; i < args.Types.Length; i++ ) { specialTypes[i] = (byte)args.Types[i]; } bool doExclude = args.DoExclude; // find start/end coordinates 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 sh = Math.Min( marks[0].H, marks[1].H ); int eh = Math.Max( marks[0].H, marks[1].H ); int volume = (ex - sx + 1) * (ey - sy + 1) * (eh - sh + 1); if( !player.CanDraw( volume ) ) { 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, volume ); return; } player.UndoBuffer.Clear(); bool cannotUndo = false; int blocks = 0, blocksDenied = 0; for( int x = sx; x <= ex; x += DrawStride ) { for( int y = sy; y <= ey; y += DrawStride ) { for( int h = sh; h <= eh; h++ ) { for( int y3 = 0; y3 < DrawStride && y + y3 <= ey; y3++ ) { for( int x3 = 0; x3 < DrawStride && x + x3 <= ex; x3++ ) { byte block = player.World.Map.GetBlockByte( x + x3, y + y3, h ); bool skip = !args.DoExclude; for( int i = 0; i < specialTypeCount; i++ ) { if( block == specialTypes[i] ) { skip = args.DoExclude; break; } } if( skip ) continue; if( player.CanPlace( x + x3, y + y3, h, args.ReplacementBlock, false ) != CanPlaceResult.Allowed ) { blocksDenied++; continue; } player.World.Map.QueueUpdate( new BlockUpdate( null, x + x3, y + y3, h, args.ReplacementBlock ) ); Server.RaisePlayerPlacedBlockEvent( player, (short)x, (short)y, (short)h, (Block)block, args.ReplacementBlock, false ); if( blocks < MaxUndoCount ) { player.UndoBuffer.Enqueue( new BlockUpdate( null, x + x3, y + y3, h, block ) ); } else if( !cannotUndo ) { player.UndoBuffer.Clear(); player.UndoBuffer.TrimExcess(); player.MessageNow( "NOTE: This draw command is too massive to undo." ); cannotUndo = true; if( player.Can( Permission.ManageWorlds ) ) { player.MessageNow( "Reminder: You can use &H/wflush&S to accelerate draw commands." ); } } blocks++; } } } } } Logger.Log( "{0} replaced {1} blocks {2} ({3}) with {4} (on world {5})", LogType.UserActivity, player.Name, blocks, (doExclude ? "except" : "of"), args.Types.JoinToString(), args.ReplacementBlock, player.World.Name ); DrawingFinished( player, "replaced", blocks, blocksDenied ); }
static void DrawOneBlock( Player player, byte drawBlock, int x, int y, int h, ref int blocks, ref int blocksDenied, ref bool cannotUndo ) { if( !player.World.Map.InBounds( x, y, h ) ) return; byte block = player.World.Map.GetBlockByte( x, y, h ); if( block == drawBlock ) return; if( player.CanPlace( x, y, h, (Block)drawBlock, false ) != CanPlaceResult.Allowed ) { blocksDenied++; return; } // this would've been an easy way to do block tracking for draw commands BUT // if i set "origin" to player, he will not receive the block update. I tried. player.World.Map.QueueUpdate( new BlockUpdate( null, x, y, h, drawBlock ) ); Server.RaisePlayerPlacedBlockEvent( player, (short)x, (short)y, (short)h, (Block)block, (Block)drawBlock, false ); //player.SendDelayed( PacketWriter.MakeSetBlock( x, y, h, drawBlock ) ); if( blocks < MaxUndoCount ) { player.UndoBuffer.Enqueue( new BlockUpdate( null, x, y, h, block ) ); } else if( !cannotUndo ) { player.UndoBuffer.Clear(); player.UndoBuffer.TrimExcess(); player.MessageNow( "NOTE: This draw command is too massive to undo." ); if( player.Can( Permission.ManageWorlds ) ) { player.MessageNow( "Reminder: You can use &H/wflush&S to accelerate draw commands." ); } cannotUndo = true; } blocks++; }
protected override int PerformInternal() { //lock is done already if (Block.Undefined == _prevBlock) //created out of bounds, dont continue { return(0); } //fix for portal gun if (_owner.orangePortal.Count > 0) { if (_pos == _owner.orangePortal[0] || _pos == _owner.orangePortal[1]) { return(0); } } if (_owner.bluePortal.Count > 0) { if (_pos == _owner.bluePortal[0] || _pos == _owner.bluePortal[1]) { return(0); } } //delete at the previous position, restore water unconditionally, lava only when bullet is still there to prevent restoration of explosion lava if (_prevBlock != Block.Water) { _prevBlock = Block.Air; } //edit: lazyfix, dont restore lava coz tnt. if (Block.Undefined != _prevBlock) { if (_owner.CanPlace(_map, _pos, Block.Plank, BlockChangeContext.Manual) == CanPlaceResult.Allowed) { UpdateMap(new BlockUpdate(null, _pos, _prevBlock)); } } List <BlockUpdate> updates = new List <BlockUpdate>(); for (int i = 0; i < _behavior.MovesPerProcessingStep && _restDistance > 0; ++i) { _pos = Move(); _prevBlock = _map.GetBlock(_pos); if (Block.Undefined == _prevBlock) { _restDistance = 0; break; } _behavior.ModifyDirection(ref _direction, _prevBlock); //e.g. if you want it to be dependent on gravity or change direction depending on current block etc if (_behavior.VisitBlock(_world, _pos, _prevBlock, _owner, ref _restDistance, updates, _block) && _behavior.CanKillPlayer) { CheckHitPlayers(updates); } } bool cont = _restDistance > 0; if (cont) //check if the last update was for the current position and replace it with the particle { int idx = updates.Count - 1; if (idx >= 0 && updates[idx].X == _pos.X && updates[idx].Y == _pos.Y && updates[idx].Z == _pos.Z) { if (_owner.CanPlace(_map, _pos, Block.Plank, BlockChangeContext.Manual) == CanPlaceResult.Allowed) { updates[idx] = new BlockUpdate(null, _pos, _block); } } else { if (_owner.CanPlace(_map, _pos, Block.Plank, BlockChangeContext.Manual) == CanPlaceResult.Allowed) { updates.Add(new BlockUpdate(null, _pos, _block)); } } } for (int i = 0; i < updates.Count; ++i) { UpdateMap(updates[i]); } return(cont ? _stepDelay : 0); }
static void DoorAdd( 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 sh = Math.Min( marks[0].Z, marks[1].Z ); int eh = Math.Max( marks[0].Z, marks[1].Z ); int volume = ( ex - sx + 1 ) * ( ey - sy + 1 ) * ( eh - sh + 1 ); if ( volume > maxDoorBlocks ) { player.Message( "Doors are only allowed to be {0} blocks", maxDoorBlocks ); return; } if ( !player.Info.Rank.AllowSecurityCircumvention ) { SecurityCheckResult buildCheck = player.World.BuildSecurity.CheckDetailed( player.Info ); switch ( buildCheck ) { case SecurityCheckResult.BlackListed: player.Message( "Cannot add a door to world {0}&S: You are barred from building here.", player.World.ClassyName ); return; case SecurityCheckResult.RankTooLow: player.Message( "Cannot add a door to world {0}&S: You are not allowed to build here.", player.World.ClassyName ); return; //case SecurityCheckResult.RankTooHigh: } } for ( int x = sx; x < ex; x++ ) { for ( int y = sy; y < ey; y++ ) { for ( int z = sh; z < eh; z++ ) { if ( player.CanPlace( player.World.Map, new Vector3I( x, y, z ), Block.Wood, BlockChangeContext.Manual ) != CanPlaceResult.Allowed ) { player.Message( "Cannot add a door to world {0}&S: Build permissions in this area replied with 'denied'.", player.World.ClassyName ); return; } } } } Zone door = ( Zone )tag; door.Create( new BoundingBox( marks[0], marks[1] ), player.Info ); player.WorldMap.Zones.Add( door ); Logger.Log( LogType.UserActivity, "{0} created door {1} (on world {2})", player.Name, door.Name, player.World.Name ); player.Message( "Door created: {0}x{1}x{2}", door.Bounds.Dimensions.X, door.Bounds.Dimensions.Y, door.Bounds.Dimensions.Z ); }