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; }
public StructBlock(UniversalCoords coords, byte type, byte metaData, IWorldManager world) { _type = type; _coords = coords; _metaData = metaData; _world = world as WorldManager; _worldInterface = world; }
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)); }
/// <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); }
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; }
/// <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); }
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; }
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 }); }
/// <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; }
public AbsWorldCoords(UniversalCoords coords) { X = coords.WorldX; Y = coords.WorldY; Z = coords.WorldZ; }
/// <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)); }
/// <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; }
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; }
/// <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)); }
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; } } }
/// <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); }
public UniversalCoords Offset(int offsetX, int offsetY, int offsetZ) { return(UniversalCoords.FromWorld(this.WorldX + offsetX, this.WorldY + offsetY, this.WorldZ + offsetZ)); }
/// <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))); }
public static UniversalCoords operator +(UniversalCoords left, UniversalCoords right) { return(UniversalCoords.FromWorld(left.WorldX + right.WorldX, left.WorldY + right.WorldY, left.WorldZ + right.WorldZ)); }
private PathCoordinate GetCoordinateFromCacheOrAdd(UniversalCoords coordinate) { PathCoordinate result = null; if (!_coordinateCache.TryGetValue(coordinate, out result)) { result = new PathCoordinate(coordinate); _coordinateCache[coordinate] = result; } return result; }
/// <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; }
public static AbsWorldCoords ToAbsWorld(UniversalCoords coords) { return new AbsWorldCoords(coords); }
public static AbsWorldCoords ToAbsWorld(UniversalCoords coords) { return(new AbsWorldCoords(coords)); }
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); }
/// <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; }