예제 #1
0
파일: StructBlock.cs 프로젝트: TheaP/c-raft
 public StructBlock(int worldX, int worldY, int worldZ, byte type, byte metaData, IWorldManager world)
 {
     _type = type;
     _coords = UniversalCoords.FromWorld(worldX, worldY, worldZ);
     _metaData = metaData;
     _world = world as WorldManager;
     _worldInterface = world;
 }
예제 #2
0
파일: StructBlock.cs 프로젝트: TheaP/c-raft
 public StructBlock(UniversalCoords coords, byte type, byte metaData, IWorldManager world)
 {
     _type = type;
     _coords = coords;
     _metaData = metaData;
     _world = world as WorldManager;
     _worldInterface = world;
 }
예제 #3
0
        public static UniversalCoords FromFace(UniversalCoords coords, BlockFace face)
        {
            int bx = coords.WorldX;
            int by = coords.WorldY;
            int bz = coords.WorldZ;

            switch (face)
            {
            case BlockFace.Self:
                break;

            case BlockFace.Up:
                by++;
                break;

            case BlockFace.Down:
                by--;
                break;

            case BlockFace.North:
                bx--;
                break;

            case BlockFace.South:
                bx++;
                break;

            case BlockFace.East:
                bz--;
                break;

            case BlockFace.West:
                bz++;
                break;

            case BlockFace.NorthEast:
                bx--;
                bz--;
                break;

            case BlockFace.NorthWest:
                bx--;
                bz++;
                break;

            case BlockFace.SouthEast:
                bx++;
                bz--;
                break;

            case BlockFace.SouthWest:
                bx++;
                bz++;
                break;
            }

            return(FromWorld(bx, by, bz));
        }
예제 #4
0
        /// <summary>
        /// Distance to coords squared. Quicker than <see cref="UniversalCoords.DistanceTo"/> but really only useful for comparing what might be closer than another coord.
        /// </summary>
        /// <returns>
        /// The to squared.
        /// </returns>
        /// <param name='coords'>
        /// Coords.
        /// </param>
        public double DistanceToSquared(UniversalCoords coords)
        {
            // Because UniversalCoords cannot store negative Y using a subtraction operator is not possible
            // UniversalCoords diff = coords - this;
            var diffX = coords.WorldX - WorldX;
            var diffY = coords.WorldY - WorldY;
            var diffZ = coords.WorldZ - WorldZ;

            return(diffX * diffX + diffY * diffY + diffZ * diffZ);
        }
예제 #5
0
파일: BlockChest.cs 프로젝트: TheaP/c-raft
        protected override byte GetDirection(LivingEntity living, StructBlock block, StructBlock targetBlock, BlockFace face)
        {
            Chunk chunk = GetBlockChunk(block);
            // Load the blocks surrounding the position (NSEW) not diagonals
            var nsewBlocks = new BlockData.Blocks[4];
            var nsewBlockPositions = new UniversalCoords[4];
            int nsewCount = 0;

            int secondChestIndex = -1;
            chunk.ForNSEW(block.Coords, uc =>
            {
                byte? nearbyBlockId = block.World.GetBlockId(uc);

                if (nearbyBlockId == null)
                    return;

                if (nearbyBlockId == (byte)BlockData.Blocks.Chest)
                    secondChestIndex = nsewCount;

                nsewBlocks[nsewCount] = (BlockData.Blocks)nearbyBlockId;
                nsewBlockPositions[nsewCount] = uc;
                nsewCount++;
            });
            byte direction = base.GetDirection(living, block, targetBlock, face);
            if (secondChestIndex != -1)
            {
                var secondChestCoords = nsewBlockPositions[secondChestIndex];
                byte secondChestDirection = chunk.GetData(secondChestCoords);
                if (secondChestDirection != direction)
                {
                    if (secondChestCoords.WorldX == block.Coords.WorldX)
                    {
                        if (direction != (byte)MetaData.Container.South && direction != (byte)MetaData.Container.North)
                            direction = (byte)MetaData.Container.South;                          
                    }
                    else
                    {
                        if (direction != (byte)MetaData.Container.East && direction != (byte)MetaData.Container.West)
                            direction = (byte)MetaData.Container.West;
                    }
                }
                else
                {

                    if (secondChestCoords.WorldX == block.Coords.WorldX && block.MetaData != (byte)MetaData.Container.North && block.MetaData != (byte)MetaData.Container.South)
                        direction = (byte)MetaData.Container.South;
                    else
                        if (block.MetaData != (byte)MetaData.Container.West && block.MetaData != (byte)MetaData.Container.East)
                            direction = (byte)MetaData.Container.West;
                }
            }

            return direction;
        }
예제 #6
0
 /// <summary>
 /// Execute the action for each adjacent coordinate in the order: South, North, Down, Up, East, West.
 /// </summary>
 /// <param name='action'>
 /// Action.
 /// </param>
 public void ForAdjacent(Action <UniversalCoords, Direction> action)
 {
     action(UniversalCoords.FromWorld(this.WorldX + 1, this.WorldY, this.WorldZ), Direction.South);
     action(UniversalCoords.FromWorld(this.WorldX - 1, this.WorldY, this.WorldZ), Direction.North);
     if (this.BlockY > 0)
     {
         action(UniversalCoords.FromWorld(this.WorldX, this.WorldY - 1, this.WorldZ), Direction.Down);
     }
     if (this.BlockY < 127)
     {
         action(UniversalCoords.FromWorld(this.WorldX, this.WorldY + 1, this.WorldZ), Direction.Up);
     }
     action(UniversalCoords.FromWorld(this.WorldX, this.WorldY, this.WorldZ - 1), Direction.East);
     action(UniversalCoords.FromWorld(this.WorldX, this.WorldY, this.WorldZ + 1), Direction.West);
 }
예제 #7
0
파일: PathFinder.cs 프로젝트: keneo/c-raft
        private int CheckOffset(UniversalCoords start, Size size)
        {
            for (int x = start.WorldX; x < start.WorldX + size.Width; x++)
            {
                for (int y = start.WorldY; y < start.WorldY + size.Height; y++)
                {
                    for (int z = start.WorldZ; z < start.WorldZ + size.Width; z++)
                    {
                        StructBlock block = (StructBlock)World.GetBlock(x, y, z);
                        if (block.Type <= 0)
                            continue;

                        BlockBase blockClass = BlockHelper.Instance.CreateBlockInstance(block.Type);
                        if (blockClass is BlockBaseDoor)
                        {
                            if (!((BlockBaseDoor)blockClass).IsOpen(block))
                            {
                                return 0;
                            }
                            continue;
                        }
                        if (blockClass.IsSolid)
                        {
                            return 0;
                        }
                        if (blockClass.IsLiquid)
                        {
                            if (!blockClass.IsOpaque) // Water
                            {
                                return -1;
                            }
                            else // Lava
                            {
                                return -2;
                            }
                        }
                    }
                }
            }

            return 1;
        }
예제 #8
0
        public void SaveText(UniversalCoords coords, Player player, string[] lines)
        {
            string folderPath = Path.Combine(player.World.SignsFolder, "x" + coords.ChunkX + "_z" + coords.ChunkZ);

            // Here it's possible that two or more different signs lead to the same folder, so we need to lock
            lock (folderLock)
            {
                if (!Directory.Exists(folderPath))
                    Directory.CreateDirectory(folderPath);
            }

            string text = string.Join(String.Empty, lines.ToArray());
            /* Here it's "impossible" that we receive two updates of the same sign at the same time. We don't need to lock also
             * because we can't write a sign not loaded (so the read of the sign file can't happen at the same time of a write) */
            using (StreamWriter sw = new StreamWriter(String.Format("{0}{1}sign_{2}_{3}_{4}.txt", folderPath, Path.DirectorySeparatorChar, coords.BlockX, coords.BlockY, coords.BlockZ)))
            {
                sw.WriteLine("{0}, {1}, {2} {3} {4}", text, player.DisplayName, coords.WorldX, coords.WorldY, coords.WorldZ);
            }


            (player.GetCurrentChunk() as Chunk).SignsText.TryAdd(coords.BlockPackedCoords, text);
            player.Server.SendPacketToNearbyPlayers(player.World, coords, new UpdateSignPacket { X = coords.WorldX, Y = coords.WorldY, Z = coords.WorldZ, Lines = lines });
        }
예제 #9
0
        /// <summary>
        /// Distance to coords squared. Quicker than <see cref="UniversalCoords.DistanceTo"/> but really only useful for comparing what might be closer than another coord.
        /// </summary>
        /// <returns>
        /// The to squared.
        /// </returns>
        /// <param name='coords'>
        /// Coords.
        /// </param>
        public double DistanceToSquared(UniversalCoords coords)
        {
            // Because UniversalCoords cannot store negative Y using a subtraction operator is not possible
            // UniversalCoords diff = coords - this;
            var diffX = coords.WorldX - WorldX;
            var diffY = coords.WorldY - WorldY;
            var diffZ = coords.WorldZ - WorldZ;

            return diffX * diffX + diffY * diffY + diffZ * diffZ;
        }
예제 #10
0
 public AbsWorldCoords(UniversalCoords coords)
 {
     X = coords.WorldX;
     Y = coords.WorldY;
     Z = coords.WorldZ;
 }
예제 #11
0
 /// <summary>
 /// The distance between this coordinate and <paramref name="coords"/>
 /// </summary>
 /// <param name="coords"></param>
 /// <returns></returns>
 public double DistanceTo(UniversalCoords coords)
 {
     return System.Math.Sqrt(this.DistanceToSquared(coords));
 }
예제 #12
0
파일: PathFinder.cs 프로젝트: keneo/c-raft
        /// <summary>
        /// Returns an integer indicating if the 
        /// </summary>
        /// <param name="startCoordinate"></param>
        /// <param name="sizeToCheck"></param>
        /// <param name="heightOffset"></param>
        /// <returns></returns>
        private PathCoordinate GetSafeCoordinate(UniversalCoords startCoordinate, Size sizeToCheck, int heightOffset)
        {
            PathCoordinate result = null;

            if (heightOffset > 0 && CheckOffset(startCoordinate.Offset(0, heightOffset, 0), sizeToCheck) == 1)
                startCoordinate = startCoordinate.Offset(0, heightOffset, 0);

            result = GetCoordinateFromCacheOrAdd(startCoordinate);

            if (result != null)
            {
                // Check down the Y axis for unsafe blocks
                int checkOffsetResult = 0;
                int loopCount = 0;

                while(startCoordinate.WorldY > 0 && (checkOffsetResult = CheckOffset(startCoordinate.Offset(0, -1, 0), sizeToCheck)) == 1)
                {
                    if (++loopCount >= 4)
                    {
                        return null;
                    }

                    startCoordinate = startCoordinate.Offset(0, -1, 0);
                    if (startCoordinate.WorldY > 0)
                    {
                        result = GetCoordinateFromCacheOrAdd(startCoordinate);
                    }
                }
                if (checkOffsetResult == -2)
                {
                    return null; // Lava
                }
            }

            return result;
        }
예제 #13
0
 protected bool RequiredChunksExist(IWorldManager world, UniversalCoords startingPoint, int xSize, int ySize, int zSize)
 {
     if (startingPoint.WorldY + ySize > 127)
         return false;
     UniversalCoords endPoint = UniversalCoords.FromWorld(startingPoint.WorldX + xSize, startingPoint.WorldY, startingPoint.WorldZ + zSize);
     if (startingPoint.ChunkX == endPoint.ChunkX && startingPoint.ChunkZ == endPoint.ChunkZ)
         return true;
     for (int x = startingPoint.ChunkX; x <= endPoint.ChunkX; x++)
         for (int z = startingPoint.ChunkZ; z <= endPoint.ChunkZ; z++)
             if (world.GetChunkFromChunkSync(x, z) == null)
                 return false;
     return true;
 }
예제 #14
0
 /// <summary>
 /// Offset the UniversalCoords by the provided values.
 /// </summary>
 /// <param name="offsetX"></param>
 /// <param name="offsetY"></param>
 /// <param name="offsetZ"></param>
 /// <returns></returns>
 public UniversalCoords Offset(int offsetX, int offsetY, int offsetZ)
 {
     Debug.Assert(this.WorldY + offsetY >= 0, "The resulting WorldY value after applying offsetY must be >= 0");
     return(UniversalCoords.FromWorld(this.WorldX + offsetX, this.WorldY + offsetY, this.WorldZ + offsetZ));
 }
예제 #15
0
파일: Interface.cs 프로젝트: TheaP/c-raft
 public void DropAll(UniversalCoords coords)
 {
     // Drop all items from the workbench
     for (short i = 0; i < SlotCount; i++)
     {
         if (!ItemHelper.IsVoid(_slots[i]))
         {
             Owner.Server.DropItem(Owner.World, coords, _slots[i]);
             this[i] = ItemHelper.Void;
         }
     }
 }
예제 #16
0
        /// <summary>
        /// Distance to coords squared. Quicker than <see cref="UniversalCoords.DistanceTo"/> but really only useful for comparing what might be closer than another coord.
        /// </summary>
        /// <returns>
        /// The to squared.
        /// </returns>
        /// <param name='coords'>
        /// Coords.
        /// </param>
        public double DistanceToSquared(UniversalCoords coords)
        {
            UniversalCoords diff = coords - this;

            return(diff.WorldX * diff.WorldX + diff.WorldY * diff.WorldY + diff.WorldZ * diff.WorldZ);
        }
예제 #17
0
 public UniversalCoords Offset(int offsetX, int offsetY, int offsetZ)
 {
     return(UniversalCoords.FromWorld(this.WorldX + offsetX, this.WorldY + offsetY, this.WorldZ + offsetZ));
 }
예제 #18
0
 public AbsWorldCoords(UniversalCoords coords)
 {
     X = coords.WorldX;
     Y = coords.WorldY;
     Z = coords.WorldZ;
 }
예제 #19
0
 /// <summary>
 /// The distance between this coordinate and <paramref name="coords"/>
 /// </summary>
 /// <param name="coords"></param>
 /// <returns></returns>
 public double DistanceTo(UniversalCoords coords)
 {
     return(System.Math.Sqrt(this.DistanceToSquared(coords)));
 }
예제 #20
0
 public static UniversalCoords operator +(UniversalCoords left, UniversalCoords right)
 {
     return(UniversalCoords.FromWorld(left.WorldX + right.WorldX, left.WorldY + right.WorldY, left.WorldZ + right.WorldZ));
 }
예제 #21
0
파일: PathFinder.cs 프로젝트: TheaP/c-raft
        private PathCoordinate GetCoordinateFromCacheOrAdd(UniversalCoords coordinate)
        {
            PathCoordinate result = null;

            if (!_coordinateCache.TryGetValue(coordinate, out result))
            {
                result = new PathCoordinate(coordinate);
                _coordinateCache[coordinate] = result;
            }

            return result;
        }
예제 #22
0
파일: PathFinder.cs 프로젝트: TheaP/c-raft
        /// <summary>
        /// Returns an integer indicating if the 
        /// </summary>
        /// <param name="startCoordinate"></param>
        /// <param name="sizeToCheck"></param>
        /// <param name="heightOffset"></param>
        /// <returns></returns>
        private PathCoordinate GetSafeCoordinate(UniversalCoords startCoordinate, Size sizeToCheck, int heightOffset)
        {
            // Given a coordinate, determine if it is safe to move to allowing Y +- 1 and taking into consideration size of space to check
            
            PathCoordinate result = null;

            if (heightOffset > 0 && CheckOffset(startCoordinate.Offset(0, heightOffset, 0), sizeToCheck) == 1)
                startCoordinate = startCoordinate.Offset(0, heightOffset, 0);

            result = GetCoordinateFromCacheOrAdd(startCoordinate);
            
            if (result != null)
            {
                // Check down the Y axis for unsafe blocks
                int checkOffsetResult = 0;
                int loopCount = 0;
                
                while(startCoordinate.WorldY > 0 && (checkOffsetResult = CheckOffset(startCoordinate.Offset(0, -1, 0), sizeToCheck)) == 1)
                {
                    if (++loopCount >= 4)
                    {
                        return null;
                    }
                    
                    startCoordinate = startCoordinate.Offset(0, -1, 0);
                    if (startCoordinate.WorldY > 0)
                    {
                        result = GetCoordinateFromCacheOrAdd(startCoordinate);
                    }
                }
                if (checkOffsetResult == -2)
                {
                    return null; // Lava
                }
            }
            
            return result;
        }
예제 #23
0
 public static AbsWorldCoords ToAbsWorld(UniversalCoords coords)
 {
     return new AbsWorldCoords(coords);
 }
예제 #24
0
 public static AbsWorldCoords ToAbsWorld(UniversalCoords coords)
 {
     return(new AbsWorldCoords(coords));
 }
예제 #25
0
        public static UniversalCoords FromFace(UniversalCoords coords, BlockFace face)
        {
            int bx = coords.WorldX;
            int by = coords.WorldY;
            int bz = coords.WorldZ;

            switch (face)
            {
                case BlockFace.Self:
                    break;

                case BlockFace.Up:
                    by++;
                    break;

                case BlockFace.Down:
                    by--;
                    break;

                case BlockFace.North:
                    bx--;
                    break;

                case BlockFace.South:
                    bx++;
                    break;

                case BlockFace.East:
                    bz--;
                    break;

                case BlockFace.West:
                    bz++;
                    break;

                case BlockFace.NorthEast:
                    bx--;
                    bz--;
                    break;

                case BlockFace.NorthWest:
                    bx--;
                    bz++;
                    break;

                case BlockFace.SouthEast:
                    bx++;
                    bz--;
                    break;

                case BlockFace.SouthWest:
                    bx++;
                    bz++;
                    break;
            }

            return FromWorld(bx, by, bz);
        }
예제 #26
0
 /// <summary>
 /// Distance to coords squared. Quicker than <see cref="UniversalCoords.DistanceTo"/> but really only useful for comparing what might be closer than another coord.
 /// </summary>
 /// <returns>
 /// The to squared.
 /// </returns>
 /// <param name='coords'>
 /// Coords.
 /// </param>
 public double DistanceToSquared(UniversalCoords coords)
 {
     UniversalCoords diff = coords - this;
     return diff.WorldX * diff.WorldX + diff.WorldY * diff.WorldY + diff.WorldZ * diff.WorldZ;
 }