public StructBlock(int worldX, int worldY, int worldZ, byte type, byte metaData, WorldManager world) { Type = type; Coords = UniversalCoords.FromWorld(worldX, worldY, worldZ); MetaData = metaData; World = world; }
internal unsafe byte this[UniversalCoords coords] { get { fixed (byte* types = Types) return types[coords.SectionPackedCoords]; } set { fixed (byte* types = Types) { byte oldValue = types[coords.SectionPackedCoords]; if (oldValue != value) { //if (value != (byte)BlockData.Blocks.Air) types[coords.SectionPackedCoords] = value; if (value == (byte)BlockData.Blocks.Air) { if (_NonAirBlocks > 0) --_NonAirBlocks; } else ++_NonAirBlocks; } } } }
/// <summary> /// Opens the Workbench and specifies where items should be dropped if exiting the workbench with items still in it. /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="z"></param> public virtual void Open(UniversalCoords coords) { _useProvidedDropCoordinates = true; _DropCoords = coords; this.Open(); }
public StructBlock(UniversalCoords coords, byte type, byte metaData, WorldManager world) { Type = type; Coords = coords; MetaData = metaData; World = world; }
public StructBlock(UniversalCoords coords, byte type, byte metaData, IWorldManager world) { _type = type; _coords = coords; _metaData = metaData; _world = world as WorldManager; _worldInterface = world; }
public List <PathCoordinate> CreatePathToCoordinate(EntityBase entityFrom, AbsWorldCoords coordinate, double maxDistance = 24.0) { PathCoordinate start = GetCoordinateFromCacheOrAdd(entityFrom.BlockPosition); PathCoordinate end = GetCoordinateFromCacheOrAdd(UniversalCoords.FromAbsWorld(coordinate.X - (entityFrom.Width * 0.5), coordinate.Y, coordinate.Z - (entityFrom.Width * 0.5))); Size size = new Size((int)Math.Floor(entityFrom.Width + 1.0), (int)Math.Floor(entityFrom.Height + 1.0)); return(GeneratePath(start, end, size, maxDistance)); }
public PathCoordinate(UniversalCoords coords) { Coordinate = coords; DistanceToNext = 0; DistanceToTarget = 0; DistanceFromStart = 0; PreviousCoordinate = null; }
public static bool IsDoubleChest(Chunk chunk, UniversalCoords coords) { if (chunk == null) { return(false); } return(chunk.IsNSEWTo(coords, (byte)BlockData.Blocks.Chest)); }
protected override void DoDeath(EntityBase killedBy) { if (!Data.Sheared) { Server.DropItem(World, UniversalCoords.FromAbsWorld(Position.X, Position.Y, Position.Z), new Interfaces.ItemStack((short)BlockData.Blocks.Wool, 1, (short)Data.WoolColor)); } base.DoDeath(killedBy); }
protected override void DoDeath(EntityBase killedBy) { Inventory.DropAll(UniversalCoords.FromAbsWorld(Position)); StopFireBurnTimer(); StopSuffocationTimer(); StopDrowningTimer(); DropExperienceOrbs(); }
public void Interact(EntityBase entity, StructBlock block) { Player player = entity as Player; if (player == null) return; if (player.CurrentInterface != null) return; byte? blockId = block.World.GetBlockId(block.Coords); if (blockId == null || !BlockHelper.Instance((byte)blockId).IsAir) { // Cannot open a chest if no space is above it return; } Chunk chunk = GetBlockChunk(block); // Double chest? if (chunk.IsNSEWTo(block.Coords, block.Type)) { // Is this chest the "North or East", or the "South or West" BlockData.Blocks[] nsewBlocks = new BlockData.Blocks[4]; UniversalCoords[] nsewBlockPositions = new UniversalCoords[4]; int nsewCount = 0; chunk.ForNSEW(block.Coords, (uc) => { nsewBlocks[nsewCount] = (BlockData.Blocks)block.World.GetBlockId(uc); nsewBlockPositions[nsewCount] = uc; nsewCount++; }); if ((byte)nsewBlocks[0] == block.Type) // North { player.CurrentInterface = new LargeChestInterface(block.World, nsewBlockPositions[0], block.Coords); } else if ((byte)nsewBlocks[2] == block.Type) // East { player.CurrentInterface = new LargeChestInterface(block.World, nsewBlockPositions[2], block.Coords); } else if ((byte)nsewBlocks[1] == block.Type) // South { player.CurrentInterface = new LargeChestInterface(block.World, block.Coords, nsewBlockPositions[1]); } else if ((byte)nsewBlocks[3] == block.Type) // West { player.CurrentInterface = new LargeChestInterface(block.World, block.Coords, nsewBlockPositions[3]); } } else { player.CurrentInterface = new SmallChestInterface(block.World, block.Coords); } player.CurrentInterface.Associate(player); player.CurrentInterface.Open(); }
public static void Open(Player player, UniversalCoords coords) { PersistentContainer container = Instance(player.World, coords); if (container == null) { return; } Chunk chunk = player.World.GetChunk(coords) as Chunk; if (chunk == null) { return; } BlockData.Blocks block = chunk.GetType(coords); switch (block) { case BlockData.Blocks.Furnace: case BlockData.Blocks.Burning_Furnace: player.CurrentInterface = new FurnaceInterface(player.World, coords); break; case BlockData.Blocks.Dispenser: player.CurrentInterface = new DispenserInterface(player.World, coords); break; case BlockData.Blocks.Chest: if (container is LargeChestContainer) { UniversalCoords[] doubleChestCoords = GetDoubleChestCoords(player.World, coords); if (doubleChestCoords == null) { return; } if (container.Coords == doubleChestCoords[0]) { player.CurrentInterface = new LargeChestInterface(player.World, doubleChestCoords[0], doubleChestCoords[1]); } else { player.CurrentInterface = new LargeChestInterface(player.World, doubleChestCoords[1], doubleChestCoords[0]); } } else { player.CurrentInterface = new SmallChestInterface(player.World, coords); } break; default: return; } player.CurrentInterface.Associate(player); container.AddInterface((PersistentContainerInterface)player.CurrentInterface); player.CurrentInterface.Open(); }
protected override void DoDeath(EntityBase killedBy) { sbyte count = (sbyte)Server.Rand.Next(2); if (count > 0) { Server.DropItem(World, UniversalCoords.FromAbsWorld(Position.X, Position.Y, Position.Z), new Interfaces.ItemStack((short)BlockData.Items.Leather, count, 0)); } base.DoDeath(killedBy); }
protected override void DoDeath(EntityBase killedBy) { if (!Data.Sheared) { var item = ItemHelper.GetInstance(BlockData.Blocks.Wool); item.Count = 1; item.Durability = (short)Data.WoolColor; Server.DropItem(World, UniversalCoords.FromAbsWorld(Position.X, Position.Y, Position.Z), item); } base.DoDeath(killedBy); }
protected override double BlockPathWeight(UniversalCoords coords) { if (this.World.GetBlockId(coords.WorldX, coords.WorldY - 1, coords.WorldZ) == (byte)BlockData.Blocks.Grass) { return(10.0); } else { return(this.World.GetBlockLightBrightness(coords) - 0.5); // stay out of lower half of brightness spectrum } }
protected override double BlockPathWeight(UniversalCoords coords) { if (this.World.GetBlockId(coords.WorldX, coords.WorldY - 1, coords.WorldZ) == (byte)BlockData.Blocks.Grass) { return 10.0; } else { return this.World.GetBlockLightBrightness(coords) - 0.5; // stay out of lower half of brightness spectrum } }
internal virtual void OnTeleportTo(AbsWorldCoords absCoords) { UniversalCoords coords = UniversalCoords.FromAbsWorld(absCoords); foreach (Client c in Server.GetNearbyPlayersInternal(World, coords)) { if (!ToSkip(c)) { c.SendTeleportTo(this); } } }
protected override void DoDeath(EntityBase killedBy) { sbyte count = (sbyte)Server.Rand.Next(2); if (count > 0) { var item = ItemHelper.GetInstance(BlockData.Items.Bow_String); item.Count = count; Server.DropItem(World, UniversalCoords.FromAbsWorld(Position.X, Position.Y, Position.Z), item); } base.DoDeath(killedBy); }
public static PersistentContainer Instance(WorldManager world, UniversalCoords coords) { PersistentContainer container; Chunk chunk = world.GetChunk(coords) as Chunk; if (chunk == null) return null; BlockData.Blocks block = chunk.GetType(coords); if (!chunk.Containers.ContainsKey(coords.BlockPackedCoords)) { switch (block) { case BlockData.Blocks.Furnace: case BlockData.Blocks.Burning_Furnace: container = new FurnaceContainer(); container.Initialize(world, coords); (container as FurnaceContainer).StartBurning(); break; case BlockData.Blocks.Dispenser: container = new DispenserContainer(); container.Initialize(world, coords); break; case BlockData.Blocks.Chest: // Double chest? if (IsDoubleChest(chunk, coords)) { UniversalCoords[] doubleChestCoords = GetDoubleChestCoords(world, coords); if (doubleChestCoords == null) return null; chunk.Containers.TryRemove(doubleChestCoords[0].BlockPackedCoords, out container); chunk.Containers.TryRemove(doubleChestCoords[1].BlockPackedCoords, out container); container = new LargeChestContainer(doubleChestCoords[1]); container.Initialize(world, doubleChestCoords[0]); chunk.Containers.TryAdd(doubleChestCoords[0].BlockPackedCoords, container); chunk.Containers.TryAdd(doubleChestCoords[1].BlockPackedCoords, container); } else { container = new SmallChestContainer(); container.Initialize(world, coords); } break; default: return null; } chunk.Containers.TryAdd(coords.BlockPackedCoords, container); } else { chunk.Containers.TryGetValue(coords.BlockPackedCoords, out container); } return container; }
private PathCoordinate GetCoordinateFromCacheOrAdd(UniversalCoords coordinate) { PathCoordinate result = null; if (!_coordinateCache.TryGetValue(coordinate, out result)) { result = new PathCoordinate(coordinate); _coordinateCache[coordinate] = result; } return(result); }
internal virtual void OnMoveRotateTo(sbyte x, sbyte y, sbyte z) { UniversalCoords coords = UniversalCoords.FromAbsWorld(Position); foreach (Client c in Server.GetNearbyPlayersInternal(World, coords)) { if (!ToSkip(c)) { c.SendMoveRotateBy(this, x, y, z, PackedYaw, PackedPitch); } } }
public bool Remove(UniversalCoords coords) { Chunk chunk; Interlocked.Increment(ref Changes); bool result = Chunks.TryRemove(coords.ChunkPackedCoords, out chunk); if(result) chunk.Dispose(); return result; }
public static void HandlePacketUpdateSign(Client client, UpdateSignPacket packet) { BlockData.Blocks blockId = (BlockData.Blocks)client.Owner.World.GetBlockId(packet.X, packet.Y, packet.Z); UniversalCoords coords = UniversalCoords.FromWorld(packet.X, packet.Y, packet.Z); if (blockId == BlockData.Blocks.Sign_Post) { BlockSignPost sign = (BlockSignPost)BlockHelper.Instance.CreateBlockInstance((byte)blockId); sign.SaveText(coords, client.Owner, packet.Lines); } }
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; } } }
public static void HandlePacketPlayerDigging(Client client, PlayerDiggingPacket packet) { Player player = client.Owner; UniversalCoords coords = UniversalCoords.FromWorld(packet.X, packet.Y, packet.Z); Chunk chunk = player.World.GetChunk(coords) as Chunk; if (chunk == null) { return; } byte type = (byte)chunk.GetType(coords); byte data = chunk.GetData(coords); switch (packet.Action) { case PlayerDiggingPacket.DigAction.StartDigging: #if DEBUG UniversalCoords oneUp = UniversalCoords.FromWorld(coords.WorldX, coords.WorldY + 1, coords.WorldZ); client.SendMessage(String.Format("SkyLight: {0}", player.World.GetSkyLight(oneUp))); client.SendMessage(String.Format("BlockLight: {0}", player.World.GetBlockLight(oneUp))); client.SendMessage(String.Format("Opacity: {0}", player.World.GetChunk(oneUp, false, false).GetOpacity(oneUp))); client.SendMessage(String.Format("Height: {0}", player.World.GetHeight(oneUp))); client.SendMessage(String.Format("Data: {0}", player.World.GetBlockData(oneUp))); //this.SendMessage() #endif if (BlockHelper.Instance.IsSingleHit(type)) { goto case PlayerDiggingPacket.DigAction.FinishDigging; } if (BlockHelper.Instance.CreateBlockInstance(type) is BlockLeaves && player.Inventory.ActiveItem.Type == (short)BlockData.Items.Shears) { goto case PlayerDiggingPacket.DigAction.FinishDigging; } if (player.GameMode == 1) { goto case PlayerDiggingPacket.DigAction.FinishDigging; } break; case PlayerDiggingPacket.DigAction.FinishDigging: StructBlock block = new StructBlock(coords, type, data, player.World); BlockHelper.Instance.CreateBlockInstance(type).Destroy(player, block); break; case PlayerDiggingPacket.DigAction.DropItem: player.DropActiveSlotItem(); break; } }
public void DropAll(UniversalCoords coords) { // Drop all items from the workbench for (short i = 0; i < SlotCount; i++) { ItemStack stack = Slots[i]; if (!stack.IsVoid()) { Owner.Server.DropItem(Owner.World, coords, stack); this[i] = ItemStack.Void; } } }
public Chunk this[UniversalCoords coords] { get { Chunk chunk; Chunks.TryGetValue(coords.ChunkPackedCoords, out chunk); return(chunk); } private set { Chunks.AddOrUpdate(coords.ChunkPackedCoords, value, (key, oldValue) => value); } }
public Chunk this[UniversalCoords coords] { get { Chunk chunk; Chunks.TryGetValue(coords.ChunkPackedCoords, out chunk); return chunk; } private set { Chunks.AddOrUpdate(coords.ChunkPackedCoords, value, (key, oldValue) => value); } }
protected override void DoDeath(EntityBase killedBy) { sbyte count = (sbyte)Server.Rand.Next(2); if (count > 0) { var item = ItemHelper.GetInstance(BlockData.Items.Raw_Porkchop); item.Count = count; Server.DropItem(World, UniversalCoords.FromAbsWorld(Position.X, Position.Y, Position.Z), item); } base.DoDeath(killedBy); // TODO: if death by fire drop cooked pork }
protected override void DoDeath(EntityBase killedBy) { var killedByMob = killedBy as Mob; UniversalCoords coords = UniversalCoords.FromAbsWorld(Position.X, Position.Y, Position.Z); sbyte count = (sbyte)Server.Rand.Next(2); if (count > 0) { ItemInventory itm = ItemHelper.GetInstance(BlockData.Items.EnderPearl); itm.Count = count; Server.DropItem(World, coords, itm); } base.DoDeath(killedBy); }
protected BaseFallingPhysics(WorldManager world, AbsWorldCoords pos) { World = world; Position = pos; EntityId = world.Server.AllocateEntity(); CreateEntityPacket entity = new CreateEntityPacket { EntityId = EntityId }; World.Server.SendPacketToNearbyPlayers(World, UniversalCoords.FromAbsWorld(Position), entity); }
public void Grow(StructBlock block, Chunk chunk) { if (!CanGrow(block, chunk)) { return; } UniversalCoords oneUp = UniversalCoords.FromWorld(block.Coords.WorldX, block.Coords.WorldY + 1, block.Coords.WorldZ); byte blockAboveId = (byte)chunk.GetType(oneUp); byte? blockAboveLight = chunk.World.GetEffectiveLight(oneUp); if (blockAboveLight == null) { return; } if (blockAboveLight < 4 && BlockHelper.Instance.CreateBlockInstance(blockAboveId).Opacity > 2) { if (block.World.Server.Rand.Next(3) == 0) { chunk.SetBlockAndData(block.Coords, (byte)BlockData.Blocks.Dirt, 0); } return; } if (blockAboveLight >= 9) { int x = block.Coords.WorldX + block.World.Server.Rand.Next(2) - 1; int y = block.Coords.WorldY + block.World.Server.Rand.Next(4) - 3; int z = block.Coords.WorldZ + block.World.Server.Rand.Next(2) - 1; Chunk nearbyChunk = block.World.GetChunkFromWorld(x, z) as Chunk; if (nearbyChunk == null) { return; } byte newBlockId = (byte)nearbyChunk.GetType(x & 0xF, y, z & 0xF); if (newBlockId != (byte)BlockData.Blocks.Dirt) { return; } byte?newBlockAboveLight = nearbyChunk.World.GetEffectiveLight(UniversalCoords.FromWorld(x, y + 1, z)); if (newBlockAboveLight != null && (newBlockAboveLight >= 4 && BlockHelper.Instance.CreateBlockInstance(newBlockId).Opacity <= 2)) { nearbyChunk.SetBlockAndData(x & 0xF, y, z & 0xF, (byte)BlockData.Blocks.Grass, 0); } } }
public virtual void Initialize(WorldManager world, UniversalCoords coords) { World = world; Coords = coords; Slots = new ItemInventory[SlotsCount]; DataFile = string.Format("x{0}y{1}z{2}.dat", Coords.WorldX, Coords.WorldY, Coords.WorldZ); string chunkFolder = string.Format("x{0}z{1}", Coords.ChunkX, Coords.ChunkZ); ContainerFolder = Path.Combine(DataPath, chunkFolder); if (!Directory.Exists(ContainerFolder)) { Directory.CreateDirectory(ContainerFolder); } Load(); }
protected override void DoClose() { base.DoClose(); // Drop all items from the workbench if (_useProvidedDropCoordinates) { base.DropAll(_DropCoords); } else { base.DropAll(UniversalCoords.FromAbsWorld(Owner.Position)); } }
protected void SendMetadataUpdate(bool notifyYourself = true) { UniversalCoords coords = UniversalCoords.FromAbsWorld(Position); foreach ( Client c in World.Server.GetNearbyPlayersInternal(World, coords) ) { if (ToSkip(c) && !notifyYourself) { continue; } c.SendEntityMetadata(this); } }
protected override bool CanBePlacedOn(EntityBase who, StructBlock block, StructBlock targetBlock, BlockFace targetSide) { if (block.Coords.WorldY > 125) { return(false); } UniversalCoords blockAbove = UniversalCoords.FromWorld(block.Coords.WorldX, block.Coords.WorldY + 1, block.Coords.WorldZ); if (block.World.GetBlockId(blockAbove) != (byte)BlockData.Blocks.Air) { return(false); } return(base.CanBePlacedOn(who, block, targetBlock, targetSide)); }
public Chunk this[int chunkX, int chunkZ] { get { Chunk chunk; int packedCoords = UniversalCoords.FromChunkToPackedChunk(chunkX, chunkZ); Chunks.TryGetValue(packedCoords, out chunk); return(chunk); } private set { int packedCoords = UniversalCoords.FromChunkToPackedChunk(chunkX, chunkZ); Chunks.AddOrUpdate(packedCoords, value, (key, oldValue) => value); } }
protected override void UpdateWorld(StructBlock block, bool isDestroyed = false) { base.UpdateWorld(block, isDestroyed); if (isDestroyed) { return; } if ((block.MetaData & 8) != 0 && block.Coords.WorldY < 127) { UniversalCoords upperBlock = UniversalCoords.FromWorld(block.Coords.WorldX, block.Coords.WorldY + 1, block.Coords.WorldZ); StructBlock upperHalf = new StructBlock(upperBlock, (byte)Type, (byte)(block.MetaData | 8), block.World); BlockHelper.Instance.CreateBlockInstance((byte)Type).Spawn(upperHalf); } }
public bool Remove(UniversalCoords coords) { Chunk chunk; Interlocked.Increment(ref Changes); bool result = Chunks.TryRemove(coords.ChunkPackedCoords, out chunk); if (result) { chunk.Dispose(); } return(result); }
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 = World.GetBlock(x, y, z); if (block.Type <= 0) continue; BlockBase blockClass = BlockHelper.Instance(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 static void Destroy(WorldManager world, UniversalCoords coords) { PersistentContainer container = Instance(world, coords); if (container == null) return; Chunk chunk = world.GetChunk(coords) as Chunk; if (chunk == null) return; PersistentContainer unused; container.Destroy(); chunk.Containers.TryRemove(container.Coords.BlockPackedCoords, out unused); if (container is LargeChestContainer) chunk.Containers.TryRemove((container as LargeChestContainer).SecondCoords.BlockPackedCoords, out unused); }
public static void Close(PersistentContainerInterface containerInterface, UniversalCoords coords) { PersistentContainer container = Instance(containerInterface.World, coords); if (container == null) return; container.RemoveInterface(containerInterface); Chunk chunk = container.World.GetChunk(coords) as Chunk; if (chunk == null) return; PersistentContainer unused; if (container is LargeChestContainer && container.IsUnused()) { chunk.Containers.TryRemove(container.Coords.BlockPackedCoords, out unused); chunk.Containers.TryRemove((container as LargeChestContainer).SecondCoords.BlockPackedCoords, out unused); } else if (container is SmallChestContainer && container.IsUnused()) chunk.Containers.TryRemove(container.Coords.BlockPackedCoords, out unused); }
public static void Open(Player player, UniversalCoords coords) { PersistentContainer container = Instance(player.World, coords); if (container == null) return; Chunk chunk = player.World.GetChunk(coords) as Chunk; if (chunk == null) return; BlockData.Blocks block = chunk.GetType(coords); switch (block) { case BlockData.Blocks.Furnace: case BlockData.Blocks.Burning_Furnace: player.CurrentInterface = new FurnaceInterface(player.World, coords); break; case BlockData.Blocks.Dispenser: player.CurrentInterface = new DispenserInterface(player.World, coords); break; case BlockData.Blocks.Chest: if (container is LargeChestContainer) { UniversalCoords[] doubleChestCoords = GetDoubleChestCoords(player.World, coords); if (doubleChestCoords == null) return; if (container.Coords == doubleChestCoords[0]) player.CurrentInterface = new LargeChestInterface(player.World, doubleChestCoords[0], doubleChestCoords[1]); else player.CurrentInterface = new LargeChestInterface(player.World, doubleChestCoords[1], doubleChestCoords[0]); } else { player.CurrentInterface = new SmallChestInterface(player.World, coords); } break; default: return; } player.CurrentInterface.Associate(player); container.AddInterface((PersistentContainerInterface)player.CurrentInterface); player.CurrentInterface.Open(); }
/// <summary> /// Drops an item at the given location. /// </summary> /// <param name="world">The world in which the coordinates reside.</param> /// <param name="coords">The target coordinate</param> /// <param name="stack">The stack to be dropped</param> /// <param name="velocity">An optional velocity (the velocity will be clamped to -0.4 and 0.4 on each axis)</param> /// <returns>The entity ID of the item drop.</returns> public int DropItem(IWorldManager world, UniversalCoords coords, IItemInventory stack, Vector3 velocity = new Vector3()) { if (ItemHelper.IsVoid(stack)) return -1; int entityId = AllocateEntity(); bool sendVelocity = false; if (velocity != Vector3.Origin) { velocity = new Vector3(velocity.X.Clamp(-0.4, 0.4), velocity.Y.Clamp(-0.4, 0.4), velocity.Z.Clamp(-0.4, 0.4)); sendVelocity = true; } AddEntity(new ItemEntity(this, entityId) { World = world as WorldManager, Position = new AbsWorldCoords(new Vector3(coords.WorldX + 0.5, coords.WorldY, coords.WorldZ + 0.5)), // Put in the middle of the block (ignoring Y) ItemId = stack.Type, Count = stack.Count, Velocity = velocity, Durability = stack.Durability }); if (sendVelocity) SendPacketToNearbyPlayers(world as WorldManager, coords, new EntityVelocityPacket { EntityId = entityId, VelocityX = (short)(velocity.X * 8000), VelocityY = (short)(velocity.Y * 8000), VelocityZ = (short)(velocity.Z * 8000) }); return entityId; }
public Chunk(WorldManager world, UniversalCoords coords, int maxSections) : this(world, coords) { _Sections = new Section[maxSections]; _MaxSections = maxSections; }
public void SetSkyLight(UniversalCoords coords, byte value) { SkyLight.setNibble(coords.BlockPackedCoords, value); }
public IEnumerable<IEntityBase> GetNearbyEntities(IWorldManager world, UniversalCoords coords) { return GetNearbyEntitiesInternal(world as WorldManager, coords); }
/// <summary> /// Yields an enumerable of nearby entities, including players. Thread-safe. /// </summary> /// <param name="world">The world containing the coordinates.</param> /// <param name="x">The center X coordinate.</param> /// <param name="y">The center Y coordinate.</param> /// <param name="z">The center Z coordinate.</param> /// <returns>A lazy enumerable of nearby entities.</returns> /*public IEnumerable<EntityBase> GetNearbyEntities(WorldManager world, AbsWorldCoords coords) { int radius = ChraftConfig.SightRadius << 4; foreach (EntityBase e in GetEntities()) { if (e.World == world && Math.Abs(coords.X - e.Position.X) <= radius && Math.Abs(coords.Y - e.Position.Y) <= radius && Math.Abs(coords.Z - e.Position.Z) <= radius) yield return e; } }*/ /// <summary> /// Yields an enumerable of nearby entities, including players. Thread-safe. /// </summary> /// <param name="world">The world containing the coordinates.</param> /// <param name="x">The center X coordinate.</param> /// <param name="y">The center Y coordinate.</param> /// <param name="z">The center Z coordinate.</param> /// <returns>A lazy enumerable of nearby entities.</returns> internal IEnumerable<EntityBase> GetNearbyEntitiesInternal(WorldManager world, UniversalCoords coords) { int radius = ChraftConfig.MaxSightRadius; foreach (EntityBase e in GetEntities()) { int entityChunkX = (int)Math.Floor(e.Position.X) >> 4; int entityChunkZ = (int)Math.Floor(e.Position.Z) >> 4; if (e.World == world && Math.Abs(coords.ChunkX - entityChunkX) <= radius && Math.Abs(coords.ChunkZ - entityChunkZ) <= radius) yield return e; } }
// TODO: This should be removed in favor of the one below /// <summary> /// Yields an enumerable of nearby players, thread-safe. /// </summary> /// <param name="world">The world containing the coordinates.</param> /// <param name="absCoords">The center coordinates.</param> /// <returns>A lazy enumerable of nearby players.</returns> /*public IEnumerable<Client> GetNearbyPlayers(WorldManager world, AbsWorldCoords absCoords) { int radius = ChraftConfig.SightRadius << 4; foreach (Client c in GetAuthenticatedClients()) { if (c.Owner.World == world && Math.Abs(absCoords.X - c.Owner.Position.X) <= radius && Math.Abs(absCoords.Z - c.Owner.Position.Z) <= radius) yield return c; } }*/ public IEnumerable<IClient> GetNearbyPlayers(IWorldManager world, UniversalCoords coords) { return GetNearbyPlayersInternal(world as WorldManager, coords); }
/// <summary> /// Sends packets in parallel to each nearby player. /// </summary> /// <param name="world">The world containing the coordinates.</param> /// <param name="coords">The center coordinates.</param> /// <param name="packets">The list of packets to send</param> internal void SendPacketsToNearbyPlayers(WorldManager world, UniversalCoords coords, List<Packet> packets, Client excludedClient = null) { Client[] nearbyClients = GetNearbyPlayersInternal(world, coords).ToArray(); if (nearbyClients.Length == 0) return; foreach (Packet packet in packets) packet.SetShared(Logger, nearbyClients.Length); Parallel.ForEach(nearbyClients, (client) => { if (excludedClient != client) { foreach (Packet packet in packets) client.SendPacket(packet); } else { foreach (Packet packet in packets) packet.Release(); } }); }
public Chunk(WorldManager world, UniversalCoords coords) { LightToRecalculate = true; World = world; Coords = coords; if(_Sections == null) _Sections = new Section[_MaxSections = 16]; }
public static bool IsDoubleChest(Chunk chunk, UniversalCoords coords) { if (chunk == null) return false; return chunk.IsNSEWTo(coords,(byte) BlockData.Blocks.Chest); }
/// <summary> /// Yields an enumerable of nearby entities, including players. Thread-safe. /// </summary> /// <param name="world">The world containing the coordinates.</param> /// <param name="x">The center X coordinate.</param> /// <param name="y">The center Y coordinate.</param> /// <param name="z">The center Z coordinate.</param> /// <returns>A lazy enumerable of nearby entities.</returns> public Dictionary<int, IEntityBase> GetNearbyEntitiesDict(IWorldManager world, UniversalCoords coords) { int radius = ChraftConfig.MaxSightRadius; Dictionary<int, IEntityBase> dict = new Dictionary<int, IEntityBase>(); foreach (EntityBase e in GetEntities()) { int entityChunkX = (int)Math.Floor(e.Position.X) >> 4; int entityChunkZ = (int)Math.Floor(e.Position.Z) >> 4; if (e.World == world && Math.Abs(coords.ChunkX - entityChunkX) <= radius && Math.Abs(coords.ChunkZ - entityChunkZ) <= radius) { dict.Add(e.EntityId, e); } } return dict; }
public static UniversalCoords[] GetDoubleChestCoords(WorldManager world, UniversalCoords coords) { Chunk chunk = world.GetChunk(coords) as Chunk; if (chunk == null || !IsDoubleChest(chunk, coords)) return null; // Is this chest the "North or East", or the "South or West" BlockData.Blocks[] nsewBlocks = new BlockData.Blocks[4]; UniversalCoords[] nsewBlockPositions = new UniversalCoords[4]; int nsewCount = 0; byte? blockId; chunk.ForNSEW(coords, uc => { blockId = world.GetBlockId(uc) ?? 0; nsewBlocks[nsewCount] = (BlockData.Blocks)blockId; nsewBlockPositions[nsewCount] = uc; nsewCount++; }); UniversalCoords firstCoords; UniversalCoords secondCoords; if ((byte)nsewBlocks[0] == (byte)BlockData.Blocks.Chest) // North { firstCoords = nsewBlockPositions[0]; secondCoords = coords; } else if ((byte)nsewBlocks[2] == (byte)BlockData.Blocks.Chest) // East { firstCoords = nsewBlockPositions[2]; secondCoords = coords; } else if ((byte)nsewBlocks[1] == (byte)BlockData.Blocks.Chest) // South { firstCoords = coords; secondCoords = nsewBlockPositions[1]; } else// if ((byte)nsewBlocks[3] == (byte)BlockData.Blocks.Chest) // West { firstCoords = coords; secondCoords = nsewBlockPositions[3]; } return new UniversalCoords[] { firstCoords, secondCoords }; }
/*public IEnumerable<IEntityBase> GetNearbyLivings(IWorldManager world, AbsWorldCoords coords) { int radius = ChraftConfig.SightRadius << 4; foreach (EntityBase entity in GetEntities()) { if (!(entity is LivingEntity)) continue; if (entity.World == world && Math.Abs(coords.X - entity.Position.X) <= radius && Math.Abs(coords.Y - entity.Position.Y) <= radius && Math.Abs(coords.Z - entity.Position.Z) <= radius) yield return (entity as LivingEntity); } }*/ internal IEnumerable<LivingEntity> GetNearbyLivingsInternal(WorldManager world, UniversalCoords coords) { int radius = ChraftConfig.MaxSightRadius; foreach (EntityBase entity in GetEntities()) { if (!(entity is LivingEntity)) continue; int entityChunkX = (int)Math.Floor(entity.Position.X) >> 4; int entityChunkZ = (int)Math.Floor(entity.Position.Z) >> 4; if (entity.World == world && Math.Abs(coords.ChunkX - entityChunkX) <= radius && Math.Abs(coords.ChunkZ - entityChunkZ) <= radius) yield return (entity as LivingEntity); } }
public bool IsAir(UniversalCoords coords) { Section section = _Sections[coords.BlockY >> 4]; return BlockHelper.Instance.IsAir(section[coords.BlockPackedCoords]); }
public IEnumerable<ILivingEntity> GetNearbyLivings(IWorldManager world, UniversalCoords coords) { return GetNearbyLivingsInternal(world as WorldManager, coords); }
/// <summary> /// Yields an enumerable of nearby players, thread-safe. /// </summary> /// <param name="world">The world containing the coordinates.</param> /// <param name="coords">The center coordinates.</param> /// <returns>A lazy enumerable of nearby players.</returns> internal IEnumerable<Client> GetNearbyPlayersInternal(WorldManager world, UniversalCoords coords) { int radius = ChraftConfig.MaxSightRadius; foreach (Client c in GetAuthenticatedClients()) { int playerChunkX = (int)Math.Floor(c.Owner.Position.X) >> 4; int playerChunkZ = (int)Math.Floor(c.Owner.Position.Z) >> 4; if (c.Owner.World == world && Math.Abs(coords.ChunkX - playerChunkX) <= radius && Math.Abs(coords.ChunkZ - playerChunkZ) <= radius) yield return c; } }
public void RecalculateHeight(UniversalCoords coords) { RecalculateHeight(coords.BlockX, coords.BlockZ); }