public EntityTracker(World world, Entity entity, int trackRange, int interval) { this.world = world; Origin = entity; this.trackRange = trackRange; this.interval = interval; lastPosSentX = Entity.EncodePosition(Origin.X); lastPosSentY = Entity.EncodePosition(Origin.Y); lastPosSentZ = Entity.EncodePosition(Origin.Z); lastRotSentX = Entity.EncodeAngle(Origin.RotationX); lastRotSentY = Entity.EncodeAngle(Origin.RotationY); }
public virtual void OnCreated(World world, int x, int y, int z) { if (Dynamic) ActivateBlock(world, x, y, z); }
public UpdateBlockPacket(World world, int x, int y, int z) { ChunkX = x; ChunkY = (byte)y; ChunkZ = z; Type = (byte)world.GetBlockType(x, y, z); MetaData = (byte)world.GetBlockData(x, y, z); }
public Server() { World = new World(new NBTChunkSource(@"..\..\..\World1")); ConnectionHandler = new ConnectionHandler(this, 12345); }
protected int GetHighestNeighbor(World world, int x, int y, int z) { int highest = world.GetLight(Type, x - 1, y, z); highest = Math.Max(highest, world.GetLight(Type, x + 1, y, z)); highest = Math.Max(highest, world.GetLight(Type, x, y - 1, z)); highest = Math.Max(highest, world.GetLight(Type, x, y + 1, z)); highest = Math.Max(highest, world.GetLight(Type, x, y, z - 1)); highest = Math.Max(highest, world.GetLight(Type, x, y, z + 1)); return highest; }
public override void OnPlaced(World world, int x, int y, int z) { world.ChunkPool.ScheduleUpdate(500, x, y, z); }
protected void ActivateNeighbors(World world, int x, int y, int z) { ActivateBlock(world, x - 1, y, z); ActivateBlock(world, x + 1, y, z); ActivateBlock(world, x, y - 1, z); ActivateBlock(world, x, y + 1, z); ActivateBlock(world, x, y, z - 1); ActivateBlock(world, x, y, z + 1); }
public virtual void OnUpdate(World world, int x, int y, int z) { }
// Return the height of the highest tile adjacent to this tile protected int FindMaxNHeight(World world, int x, int y, int z) { int maxNHeight = 7; CheckTile(world, x - 1, y, z, ref maxNHeight); CheckTile(world, x + 1, y, z, ref maxNHeight); CheckTile(world, x, y, z - 1, ref maxNHeight); CheckTile(world, x, y, z + 1, ref maxNHeight); return maxNHeight; }
// Try filling the passed tile with water and return whether we're successful protected bool DoFlow(World world, int x, int y, int z, int metaData) { var type = world.GetBlockType(x, y, z); if (type == SourceType || type == FlowingType) return true; if (type == (int)BlockType.Air) { if (metaData == 7) return false; world.SetBlock(x, y, z, FlowingType, metaData); ActivateNeighbors(world, x, y, z); return true; } return false; }
// If the passed tile is higher than the passed height, adjust that height protected void CheckTile(World world, int x, int y, int z, ref int height) { var type = world.GetBlockType(x, y, z); if (type == FlowingType) height = Math.Min(height, GetHeight(world.GetBlockData(x, y, z))); else if (type == SourceType) height = 0; }
public ActiveChunkPool(World world, ChunkCache cache) { this.cache = cache; this.world = world; }
public LightingEngine(World world) { this.world = world; }
public virtual void OnDestroyed(World world, int x, int y, int z) { ActivateNeighbors(world, x, y, z); }
// Look for a drop on the sides of a rectangle with the passed radius and flow towards it // Also return whether we did find a drop protected bool FlowRadius(World world, int x, int y, int z, int radius, int metaData) { bool didFlow = false; int checkY = y - 1; // Flow north? for (int i = x - radius; i < x + radius; i++) { if (IsDrop(world.GetBlockType(i, checkY, z - radius))) didFlow = DoFlow(world, x, y, z - 1, metaData) || didFlow; } // Flow south? for (int i = x - radius; i < x + radius; i++) { if (IsDrop(world.GetBlockType(i, checkY, z + radius))) didFlow = DoFlow(world, x, y, z + 1, metaData) || didFlow; } // Flow west? for (int i = z - radius; i < z + radius; i++) { if (IsDrop(world.GetBlockType(x - radius, checkY, i))) didFlow = DoFlow(world, x - 1, y, z, metaData) || didFlow; } // Flow east? for (int i = z - radius; i < z + radius; i++) { if (IsDrop(world.GetBlockType(x + radius, checkY, i))) didFlow = DoFlow(world, x + 1, y, z, metaData) || didFlow; } return didFlow; }
public virtual void OnPlaced(World world, int x, int y, int z) { ActivateBlock(world, x, y, z); ActivateNeighbors(world, x, y, z); }
public override void OnUpdate(World world, int x, int y, int z) { // Get all kinds of required data var type = world.GetBlockType(x, y, z); var groundtype = world.GetBlockType(x, y - 1, z); var metaData = world.GetBlockData(x, y, z); var height = GetHeight(metaData); var isFalling = IsFalling(metaData); var onWater = groundtype == SourceType || groundtype == FlowingType; // Still water drains and has some restriction the way it can flow: // 1) It can't flow on top of water tiles // 2) It can't spread if it is falling if (type == FlowingType) { // Not falling tiles adjust their size depending on their neighbors' height if (!isFalling) { var maxNHeight = FindMaxNHeight(world, x, y, z); if (maxNHeight >= height) { // this block is higher than our highest neighbor and needs to shrink // If this already is the smallest block, disappear, otherwise shrink by 1 if (height == MaxHeight) world.SetBlockType(x, y, z, (int)BlockType.Air); else { world.SetBlockData(x, y, z, height + 1); ActivateNeighbors(world, x, y, z); ActivateBlock(world, x, y, z); } return; } else if (height != maxNHeight + 1) { // this block needs to grow // Never grow higher than the max height world.SetBlockData(x, y, z, Math.Min(MaxHeight, maxNHeight + 1)); ActivateNeighbors(world, x, y, z); ActivateBlock(world, x, y, z); } } else { // Falling water shrinks if there is no water block above it var aboveType = world.GetBlockType(x, y + 1, z); if (aboveType != FlowingType && aboveType != SourceType) { // Falling water shrinks faster than normal tiles if (height >= MaxHeight) world.SetBlockType(x, y, z, (int)BlockType.Air); else { world.SetBlockData(x, y, z, MaxHeight); ActivateNeighbors(world, x, y, z); ActivateBlock(world, x, y, z); } return; } } // Flowing water doesn't spread on top of water if (onWater) return; } // Set height of all following tiles and abort if this tile is already the smallest height++; if (height > MaxHeight) return; // Source blocks also spread on top of water bool flowDown = DoFlow(world, x, y - 1, z, 8); if (!flowDown || (onWater && type == SourceType)) { // Try flowing towards the nearest drop in 4 tiles radius if (!FlowRadius(world, x, y, z, 1, height)) if (!FlowRadius(world, x, y, z, 2, height)) if (!FlowRadius(world, x, y, z, 3, height)) if (!FlowRadius(world, x, y, z, 4, height)) { // No nearby drop down, flow in all directions DoFlow(world, x - 1, y, z, height); DoFlow(world, x + 1, y, z, height); DoFlow(world, x, y, z - 1, height); DoFlow(world, x, y, z + 1, height); } return; } if (flowDown && y == 0) return; // Schedule new update for this block if we flowed once (down or sideways) ActivateBlock(world, x, y, z); }
protected bool ActivateBlock(World world, int x, int y, int z) { int type = world.GetBlockType(x, y, z); var block = Blocks[type]; if (block != null && block.Dynamic) { world.ChunkPool.ScheduleUpdate(block.Delay, x, y, z); return true; } return false; }
public EntityHandler(World world) { this.world = world; }
public override void OnDestroyed(World world, int x, int y, int z) { Console.WriteLine("Drop item " + DropsItem); world.EntityHandler.AddEntity(new ItemEntity { TypeId = (int)BlockType.Dirt, Count = 1, X = x + 0.5, Y = y, Z = z + 0.5 }); }
public Player(PacketPipe client, World world, string name) : base(name) { Client = client; this.World = world; }
public override void OnUpdate(World world, int x, int y, int z) { world.SetBlockType(x, y + 1, z, (int)BlockType.StillWater); }
public void Run(World world) { if (Area.Size > 16 * 16 * 128) { Console.WriteLine("[LightingEngine] Tried to run a too big update"); return; } for (int x = Area.X1; x <= Area.X2; x++) { for (int z = Area.Z1; z <= Area.Z2; z++) { if (!world.IsLoaded(x, z)) continue; for (int y = Area.Y1; y <= Area.Y2; y++) { int oldLight = world.GetLight(Type, x, y, z); int newLight = 0; int blockType = world.GetBlockType(x, y, z); int lightBlocked = Math.Max(1, Block.LightAbsorbs[blockType]); int lightEmitted = 0; if (Type == LightType.Sky) { // Blocks directly hit by sky light scatter light if (world.RecievesSkyLight(x, y, z)) lightEmitted = 15; } else if (Type == LightType.Block) { lightEmitted = Block.LightEmits[blockType]; } // All light gets absorbed, no need to check neighbors if (lightBlocked >= 15 && lightEmitted == 0) newLight = 0; else { // Find the highest light from the neighbors newLight = Math.Max(0, GetHighestNeighbor(world, x, y, z) - lightBlocked); // Emitted light always takes precedence if (lightEmitted > newLight) newLight = lightEmitted; } // Light changed, scatter it to neighbors if (oldLight != newLight) { world.SetLight(Type, x, y, z, newLight); int neighborLight = Math.Max(0, newLight - 1); // Definitely update blocks we already passed in the loop engine.TryUpdateTile(Type, x - 1, y, z, neighborLight); engine.TryUpdateTile(Type, x, y - 1, z, neighborLight); engine.TryUpdateTile(Type, x, y, z - 1, neighborLight); // Only update following blocks if we aren't going to update them in this loop if (x + 1 >= Area.X2) engine.TryUpdateTile(Type, x + 1, y, z, neighborLight); if (y + 1 >= Area.Y2) engine.TryUpdateTile(Type, x, y + 1, z, neighborLight); if (z + 1 >= Area.Z2) engine.TryUpdateTile(Type, x, y, z + 1, neighborLight); } } } } }