public static void HandlePacketPlayerPositionRotation(Client client, PlayerPositionRotationPacket packet) { double feetY = packet.Y - client.Owner.EyeHeight; if (client.WaitForInitialPosAck) { AbsWorldCoords coords = new AbsWorldCoords(packet.X, feetY, packet.Z); if (coords == client.Owner.LoginPosition) { client.WaitForInitialPosAck = false; client.SendSecondLoginSequence(); } } else { double threshold = 0.001; double diffX = Math.Abs(client.Owner.Position.X - packet.X); double diffY = Math.Abs(client.Owner.Position.Y - feetY); double diffZ = Math.Abs(client.Owner.Position.Z - packet.Z); if (diffX < threshold && diffY < threshold && diffZ < threshold) { return; } client.Owner.MoveTo(new AbsWorldCoords(packet.X, feetY, packet.Z), packet.Yaw, packet.Pitch); client.OnGround = packet.OnGround; client.Stance = packet.Stance; client.CheckAndUpdateChunks(packet.X, packet.Z); } }
public void GlobalTimer(object state) { int time = Interlocked.Increment(ref _time); if (!WaitInitialPositionRequest && (time % 5) == 0) { int factor = 1; double rand1; double rand2; if ((rand1 = _rand.NextDouble()) > (rand2 = _rand.NextDouble())) { factor = -1; } double randX = (0.1 + rand1 * 0.2) * factor; double randZ = (0.1 + rand2 * 0.2) * factor; Position = new AbsWorldCoords(Position.X + randX, Position.Y, Position.Z + randZ); SendPacket(new PlayerPacket { OnGround = true }); SendPacket(new PlayerPositionPacket { OnGround = true, X = Position.X, Y = Position.Y, Z = Position.Z }); } if ((time % 50) == 0) { SendPacket(new KeepAlivePacket { KeepAliveID = 1 }); } }
/// <summary> /// Teleport the entity to the given destination and update all affected clients. /// </summary> /// <param name="x">The X coordinate of the target.</param> /// <param name="y">The Y coordinate of the target.</param> /// <param name="z">The Z coordinate of the target.</param> public virtual bool TeleportTo(AbsWorldCoords absCoords) { Position = absCoords; OnTeleportTo(absCoords); return(true); }
/// <summary> /// Move less than four blocks to the given destination and rotate. /// </summary> /// <param name="x">The X coordinate of the target.</param> /// <param name="y">The Y coordinate of the target.</param> /// <param name="z">The Z coordinate of the target.</param> /// <param name="yaw">The absolute yaw to which entity should change.</param> /// <param name="pitch">The absolute pitch to which entity should change.</param> public virtual void MoveTo(AbsWorldCoords absCoords, float yaw, float pitch) { //Vector3 newPosition = new Vector3(absCoords.X, absCoords.Y, absCoords.Z); AbsWorldCoords newPosition = absCoords; //Event EntityMoveEventArgs e = new EntityMoveEventArgs(this, newPosition, Position); Server.PluginManager.CallEvent(Event.EntityMove, e); if (e.EventCanceled) { return; } newPosition = e.NewPosition; //End Event sbyte oldPacketPosX = (sbyte)Math.Floor(Position.X * 32.0); sbyte oldPacketPosY = (sbyte)Math.Floor(Position.Y * 32.0); sbyte oldPacketPosZ = (sbyte)Math.Floor(Position.Z * 32.0); sbyte newPacketPosX = (sbyte)Math.Floor(newPosition.X * 32.0); sbyte newPacketPosY = (sbyte)Math.Floor(newPosition.Y * 32.0); sbyte newPacketPosZ = (sbyte)Math.Floor(newPosition.Z * 32.0); sbyte dx = (sbyte)(newPacketPosX - oldPacketPosX); sbyte dy = (sbyte)(newPacketPosY - oldPacketPosY); sbyte dz = (sbyte)(newPacketPosZ - oldPacketPosZ); Position = newPosition; this.Yaw = yaw; this.Pitch = pitch; OnMoveRotateTo(dx, dy, dz); }
/// <summary> /// Handles the respawning of the Client, called from respawn packet. /// </summary> internal void HandleRespawn() { Server.RemoveEntity(this); Position = new AbsWorldCoords( World.Spawn.WorldX, World.Spawn.WorldY + this.EyeHeight, World.Spawn.WorldZ); _client.StopUpdateChunks(); UpdateChunks(1, CancellationToken.None, false); _client.SendPacket(new RespawnPacket { LevelType = ChraftConfig.LevelType, WorldHeight = 256, GameMode = (sbyte)_client.GetOwner().GameMode, }); UpdateEntities(); //SendSpawnPosition(); _client.SendInitialPosition(); _client.SendInitialTime(); InitializeInventory(); InitializeHealth(); SendUpdateExperience(); _client.ScheduleUpdateChunks(); Server.AddEntity(this); }
public void Grow(StructBlock block) { if (!CanGrow(block)) return; for (int i = block.Coords.WorldY; i < block.Coords.WorldY + 4; i++) { block.World.SetBlockAndData(block.Coords.WorldX, i, block.Coords.WorldZ, (byte)BlockData.Blocks.Log, block.MetaData); if (block.World.GetBlockId(block.Coords.WorldX, i + 1, block.Coords.WorldZ) != (byte)BlockData.Blocks.Air) break; } // Grow leaves for (int i = block.Coords.WorldY + 2; i < block.Coords.WorldY + 5; i++) for (int j = block.Coords.WorldX - 2; j <= block.Coords.WorldX + 2; j++) for (int k = block.Coords.WorldZ - 2; k <= block.Coords.WorldZ + 2; k++) if (!block.World.ChunkExists(j >> 4, k >> 4) || (block.World.GetBlockId(j, i, k) != (byte)BlockData.Blocks.Air)) continue; else block.World.SetBlockAndData(j, i, k, (byte)BlockData.Blocks.Leaves, block.MetaData); for (int i = block.Coords.WorldX - 1; i <= block.Coords.WorldX + 1; i++) for (int j = block.Coords.WorldZ - 1; j <= block.Coords.WorldZ + 1; j++) if (!block.World.ChunkExists(i >> 4, j >> 4) || (block.World.GetBlockId(i, block.Coords.WorldY + 5, j) != (byte)BlockData.Blocks.Air)) continue; else block.World.SetBlockAndData(i, block.Coords.WorldY + 5, j, (byte)BlockData.Blocks.Leaves, block.MetaData); AbsWorldCoords absCoords = new AbsWorldCoords(block.Coords); foreach (Net.Client c in block.World.Server.GetNearbyPlayers(block.World, absCoords)) { c.SendBlockRegion(block.Coords.WorldX - 3, block.Coords.WorldY, block.Coords.WorldZ - 3, 7, 7, 7); } }
internal override void OnTeleportTo(AbsWorldCoords absCoords) { base.OnTeleportTo(absCoords); CheckDrowning(); CheckSuffocation(); TouchNearbyBlocks(); }
public FallingSand(WorldManager world, AbsWorldCoords pos) : base(world, pos) { Type = Net.Packets.AddObjectVehiclePacket.ObjectType.FallingSand; BlockId = (byte) BlockData.Blocks.Sand; Velocity = new Vector3(0, -0.4D, 0); }
/// <summary> /// Move less than four blocks to the given destination and update all affected clients. /// </summary> /// <param name="x">The X coordinate of the target.</param> /// <param name="y">The Y coordinate of the target.</param> /// <param name="z">The Z coordinate of the target.</param> public virtual void MoveTo(AbsWorldCoords absCoords) { AbsWorldCoords newPosition = absCoords; //Event EntityMoveEventArgs e = new EntityMoveEventArgs(this, newPosition, Position); Server.PluginManager.CallEvent(Event.EntityMove, e); if (e.EventCanceled) { return; } newPosition = e.NewPosition; //End Event sbyte oldPacketPosX = (sbyte)Math.Floor(Position.X * 32.0); sbyte oldPacketPosY = (sbyte)Math.Floor(Position.Y * 32.0); sbyte oldPacketPosZ = (sbyte)Math.Floor(Position.Z * 32.0); sbyte newPacketPosX = (sbyte)Math.Floor(newPosition.X * 32.0); sbyte newPacketPosY = (sbyte)Math.Floor(newPosition.Y * 32.0); sbyte newPacketPosZ = (sbyte)Math.Floor(newPosition.Z * 32.0); sbyte dx = (sbyte)(newPacketPosX - oldPacketPosX); sbyte dy = (sbyte)(newPacketPosY - oldPacketPosY); sbyte dz = (sbyte)(newPacketPosZ - oldPacketPosZ); Position = newPosition; // TODO: this doesn't prevent changing the Position by more than 4 blocks OnMoveTo(dx, dy, dz); }
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 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 void InitializePosition() { World = Server.GetDefaultWorld() as WorldManager; Position = new AbsWorldCoords( World.Spawn.WorldX, World.Spawn.WorldY + this.EyeHeight, World.Spawn.WorldZ); }
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.X, Position.Y, Position.Z), entity); }
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); } } }
private static void MobSpecificInitialisation(Mob mob, WorldManager world, AbsWorldCoords coords) { // 1 in 100 chance to spawn a skeleton riding a spider if (mob.Type == MobType.Spider && world.Server.Rand.Next(100) == 0) { LivingEntity skeleton = MobFactory.Instance.CreateMob(world, world.Server, MobType.Skeleton) as LivingEntity; skeleton.Position = coords; skeleton.Yaw = mob.Yaw; world.Server.AddEntity(skeleton); skeleton.MountEntity(mob); } }
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); }
/// <summary> /// Applies the specified velocity to this entity. /// </summary> /// <param name='velocity'> /// Velocity. /// </param> public virtual AbsWorldCoords ApplyVelocity(Vector3 velocity) { if (this.NoClip) { return(new AbsWorldCoords(this.Position.ToVector() + velocity)); } Vector3 initialVelocity = velocity; // TODO: if sneaking and onground prevent falling off edges var boundingBox = this.BoundingBox.OffsetWithClipping(ref velocity, this.World.GetCollidingBoundingBoxes(this, this.BoundingBox + velocity)); // Set the new position to the centre point of the base of the BoundingBox var newPosition = new AbsWorldCoords((boundingBox.Minimum.X + boundingBox.Maximum.X) / 2.0, boundingBox.Minimum.Y, (boundingBox.Minimum.Z + boundingBox.Maximum.Z) / 2.0); #region Update Collision States this.HasCollidedHorizontally = !initialVelocity.X.DoubleIsEqual(velocity.X) || !initialVelocity.Z.DoubleIsEqual(velocity.Z); this.HasCollidedVertically = !initialVelocity.Y.DoubleIsEqual(velocity.Y); this.HasCollided = this.HasCollidedHorizontally || this.HasCollidedVertically; this.OnGround = this.HasCollidedVertically && initialVelocity.Y < 0.0; AddFallingDistance(velocity.Y, this.OnGround); if (!initialVelocity.X.DoubleIsEqual(velocity.X)) { Velocity.X = 0.0; } if (!initialVelocity.Y.DoubleIsEqual(velocity.Y)) { Velocity.Y = 0.0; } if (!initialVelocity.Z.DoubleIsEqual(velocity.Z)) { Velocity.Z = 0.0; } #endregion TouchNearbyBlocks(); // TODO: check for proximity to fire return(newPosition); }
public override void Simulate() { int x = (int)Math.Floor(Position.X); int y = (int)Math.Floor(Position.Y); int z = (int)Math.Floor(Position.Z); byte? blockId = World.GetBlockId(x, y, z); if (blockId == null || blockId != (byte)BlockData.Blocks.Air) { Stop(); return; } if (Position.Y <= 1) { Stop(true); return; } Position = new AbsWorldCoords(Position.ToVector() + Velocity); }
public override void Simulate() { int x = (int)Math.Floor(Position.X); int y = (int)Math.Floor(Position.Y); int z = (int)Math.Floor(Position.Z); byte?blockId = World.GetBlockId(x, y, z); if (blockId == null || blockId != (byte)BlockData.Blocks.Air) { Stop(); return; } if (Position.Y <= 1) { Stop(true); return; } Position = new AbsWorldCoords(Position.ToVector() + Velocity); }
internal override void OnTeleportTo(AbsWorldCoords absCoords) { base.OnTeleportTo(absCoords); Client.StopUpdateChunks(); UpdateChunks(1, CancellationToken.None, true, false); Client.SendPacket(new PlayerPositionRotationPacket { X = absCoords.X, Y = absCoords.Y + EyeHeight, Z = absCoords.Z, Yaw = (float)Yaw, Pitch = (float)Pitch, Stance = Client.Stance, OnGround = false }); UpdateEntities(); Server.SendEntityToNearbyPlayers(World, this); Client.ScheduleUpdateChunks(); }
/// <summary> /// Handles the respawning of the Client, called from respawn packet. /// </summary> internal void HandleRespawn() { Server.RemoveEntity(this); Position = new AbsWorldCoords( World.Spawn.WorldX, World.Spawn.WorldY + this.EyeHeight, World.Spawn.WorldZ); _client.StopUpdateChunks(); UpdateChunks(1, CancellationToken.None, false); _client.SendPacket(new RespawnPacket { }); UpdateEntities(); //SendSpawnPosition(); _client.SendInitialPosition(); _client.SendInitialTime(); InitializeInventory(); InitializeHealth(); _client.ScheduleUpdateChunks(); Server.AddEntity(this); }
protected void AddExhaustionOnMovement(AbsWorldCoords coords) { var dx = coords.X - Position.X; var dy = coords.Y - Position.Y; var dz = coords.Z - Position.Z; if (IsInWater()) { var distance = (short)Math.Round(MathHelper.sqrt_double(dx * dx + dz * dz) * 10); Exhaustion += 15 * distance; } else if (Client.OnGround) { var distance = (short)Math.Round(MathHelper.sqrt_double(dx * dx + dy * dy + dz * dz) * 10); if (Data.IsSprinting) { Exhaustion += 100 * distance; } else { Exhaustion += 10 * distance; } } }
/// <summary> /// Move less than four blocks to the given destination. /// </summary> /// <param name="x">The X coordinate of the target.</param> /// <param name="y">The Y coordinate of the target.</param> /// <param name="z">The Z coordinate of the target.</param> public override void MoveTo(AbsWorldCoords absCoords) { base.MoveTo(absCoords); UpdateEntities(); }
/// <summary> /// Move less than four blocks to the given destination and rotate. /// </summary> /// <param name="x">The X coordinate of the target.</param> /// <param name="y">The Y coordinate of the target.</param> /// <param name="z">The Z coordinate of the target.</param> /// <param name="yaw">The absolute yaw to which client should change.</param> /// <param name="pitch">The absolute pitch to which client should change.</param> public override void MoveTo(AbsWorldCoords absCoords, float yaw, float pitch) { base.MoveTo(absCoords, yaw, pitch); UpdateEntities(); }
public FallingGravel(WorldManager world, AbsWorldCoords pos) : base(world, pos) { Type = Net.Packets.AddObjectVehiclePacket.ObjectType.FallingGravel; BlockId = (byte) BlockData.Blocks.Gravel; }
public void GlobalTimer(object state) { int time = Interlocked.Increment(ref _time); if (!WaitInitialPositionRequest && (time % 5) == 0) { int factor = 1; double rand1; double rand2; if ((rand1 = _rand.NextDouble()) > (rand2 = _rand.NextDouble())) factor = -1; double randX = (0.1 + rand1 * 0.2) * factor; double randZ = (0.1 + rand2 * 0.2) * factor; Position = new AbsWorldCoords(Position.X + randX, Position.Y, Position.Z + randZ); SendPacket(new PlayerPacket{OnGround = true}); SendPacket(new PlayerPositionPacket{OnGround = true, X = Position.X, Y = Position.Y, Z = Position.Z}); } if((time % 50) == 0) { SendPacket(new KeepAlivePacket{KeepAliveID = 1}); } }
/// <summary> /// Move less than four blocks to the given destination. /// </summary> /// <param name="x">The X coordinate of the target.</param> /// <param name="y">The Y coordinate of the target.</param> /// <param name="z">The Z coordinate of the target.</param> public override void MoveTo(AbsWorldCoords absCoords) { AddExhaustionOnMovement(absCoords); base.MoveTo(absCoords); UpdateEntities(); }
/// <summary> /// Ray traces the blocks along the ray. This method takes approx 0.1ms per 50-60 metres. /// </summary> /// <returns> /// The first block hit /// </returns> /// <param name='rayStart'> /// Ray start. /// </param> /// <param name='rayEnd'> /// Ray end. /// </param> internal RayTraceHitBlock RayTraceBlocks(AbsWorldCoords rayStart, AbsWorldCoords rayEnd) { UniversalCoords startCoord = UniversalCoords.FromAbsWorld(rayStart); UniversalCoords endCoord = UniversalCoords.FromAbsWorld(rayEnd); UniversalCoords previousPoint; UniversalCoords currentPoint = startCoord; Vector3 rayStartVec = rayStart.ToVector(); Vector3 rayEndVec = rayEnd.ToVector(); Vector3 stepVector = (rayEndVec - rayStartVec).Normalize(); bool xDirectionPositive = stepVector.X > 0; bool yDirectionPositive = stepVector.Y > 0; bool zDirectionPositive = stepVector.Z > 0; Vector3 currentVec = rayStartVec; previousPoint = currentPoint; RayTraceHitBlock blockTrace = null; int blockCheckCount = 0; try { // Step along the ray looking for block collisions while (true) { #region Check adjacent blocks if necessary (to prevent skipping over the corner of one) bool xChanged = currentPoint.WorldX - previousPoint.WorldX != 0; bool yChanged = currentPoint.WorldY - previousPoint.WorldY != 0; bool zChanged = currentPoint.WorldZ - previousPoint.WorldZ != 0; // When we change a coord, need to check which adjacent block also needs to be checked (to prevent missing blocks when jumping over their corners) if (xChanged && yChanged && zChanged) { // -X,Y,Z blockCheckCount++; blockTrace = DoRayTraceBlock(UniversalCoords.FromWorld(previousPoint.WorldX, currentPoint.WorldY, currentPoint.WorldZ), rayStartVec, rayEndVec); if (blockTrace != null) return blockTrace; // X,-Y,Z blockCheckCount++; blockTrace = DoRayTraceBlock(UniversalCoords.FromWorld(currentPoint.WorldX, previousPoint.WorldY, currentPoint.WorldZ), rayStartVec, rayEndVec); if (blockTrace != null) return blockTrace; // X,Y,-Z blockCheckCount++; blockTrace = DoRayTraceBlock(UniversalCoords.FromWorld(currentPoint.WorldX, currentPoint.WorldY, previousPoint.WorldZ), rayStartVec, rayEndVec); if (blockTrace != null) return blockTrace; // -X,Y,-Z blockCheckCount++; blockTrace = DoRayTraceBlock(UniversalCoords.FromWorld(previousPoint.WorldX, currentPoint.WorldY, previousPoint.WorldZ), rayStartVec, rayEndVec); if (blockTrace != null) return blockTrace; // -X,-Y,Z blockCheckCount++; blockTrace = DoRayTraceBlock(UniversalCoords.FromWorld(previousPoint.WorldX, previousPoint.WorldY, currentPoint.WorldZ), rayStartVec, rayEndVec); if (blockTrace != null) return blockTrace; // X,-Y,-Z blockCheckCount++; blockTrace = DoRayTraceBlock(UniversalCoords.FromWorld(currentPoint.WorldX, previousPoint.WorldY, previousPoint.WorldZ), rayStartVec, rayEndVec); if (blockTrace != null) return blockTrace; } else if (xChanged && zChanged) { // -X,Y,Z blockCheckCount++; blockTrace = DoRayTraceBlock(UniversalCoords.FromWorld(previousPoint.WorldX, currentPoint.WorldY, currentPoint.WorldZ), rayStartVec, rayEndVec); if (blockTrace != null) return blockTrace; // X,Y,-Z blockCheckCount++; blockTrace = DoRayTraceBlock(UniversalCoords.FromWorld(currentPoint.WorldX, currentPoint.WorldY, previousPoint.WorldZ), rayStartVec, rayEndVec); if (blockTrace != null) return blockTrace; } else if (xChanged && yChanged) { // -X,Y,Z blockCheckCount++; blockTrace = DoRayTraceBlock(UniversalCoords.FromWorld(previousPoint.WorldX, currentPoint.WorldY, currentPoint.WorldZ), rayStartVec, rayEndVec); if (blockTrace != null) return blockTrace; // X,-Y,Z blockCheckCount++; blockTrace = DoRayTraceBlock(UniversalCoords.FromWorld(currentPoint.WorldX, previousPoint.WorldY, currentPoint.WorldZ), rayStartVec, rayEndVec); if (blockTrace != null) return blockTrace; } else if (zChanged && yChanged) { // X,Y,-Z blockCheckCount++; blockTrace = DoRayTraceBlock(UniversalCoords.FromWorld(currentPoint.WorldX, currentPoint.WorldY, previousPoint.WorldZ), rayStartVec, rayEndVec); if (blockTrace != null) return blockTrace; // X,-Y,Z blockCheckCount++; blockTrace = DoRayTraceBlock(UniversalCoords.FromWorld(currentPoint.WorldX, previousPoint.WorldY, currentPoint.WorldZ), rayStartVec, rayEndVec); if (blockTrace != null) return blockTrace; } #endregion // Check the currentPoint blockCheckCount++; blockTrace = DoRayTraceBlock(currentPoint, rayStartVec, rayEndVec); if (blockTrace != null) return blockTrace; if (currentPoint == endCoord) { //Console.WriteLine("Reach endCoord with no hits"); break; } #region Get the next coordinate previousPoint = currentPoint; do { currentVec += stepVector; currentPoint = UniversalCoords.FromAbsWorld(currentVec.X, currentVec.Y, currentVec.Z); } while(previousPoint == currentPoint); // check we haven't gone past the endCoord if ((xDirectionPositive && currentPoint.WorldX > endCoord.WorldX) || (!xDirectionPositive && currentPoint.WorldX < endCoord.WorldX) || (yDirectionPositive && currentPoint.WorldY > endCoord.WorldY) || (!yDirectionPositive && currentPoint.WorldY < endCoord.WorldY) || (zDirectionPositive && currentPoint.WorldZ > endCoord.WorldZ) || (!zDirectionPositive && currentPoint.WorldZ < endCoord.WorldZ)) { //Console.WriteLine("Went past endCoord: {0}, {1}", startCoord, endCoord); break; } #endregion } } finally { //Console.WriteLine("Block check count {0}", blockCheckCount); } return null; }
protected void AddExhaustionOnMovement(AbsWorldCoords coords) { var dx = coords.X - Position.X; var dy = coords.Y - Position.Y; var dz = coords.Z - Position.Z; if (IsInWater()) { var distance = (short)Math.Round(MathHelper.sqrt_double(dx * dx + dz * dz) * 10); Exhaustion += 15 * distance; } else if (Client.OnGround) { var distance = (short)Math.Round(MathHelper.sqrt_double(dx*dx + dy*dy + dz*dz) * 10); if (Data.IsSprinting) Exhaustion += 100 * distance; else Exhaustion += 10 * distance; } }
/// <summary> /// Move less than four blocks to the given destination and rotate. /// </summary> /// <param name="x">The X coordinate of the target.</param> /// <param name="y">The Y coordinate of the target.</param> /// <param name="z">The Z coordinate of the target.</param> /// <param name="yaw">The absolute yaw to which client should change.</param> /// <param name="pitch">The absolute pitch to which client should change.</param> public override void MoveTo(AbsWorldCoords absCoords, float yaw, float pitch) { AddExhaustionOnMovement(absCoords); base.MoveTo(absCoords, yaw, pitch); UpdateEntities(); }
public static void HandlePacketPlayerPositionRotation(Client client, PlayerPositionRotationPacket packet) { double feetY = packet.Y - client.Owner.EyeHeight; if (client.WaitForInitialPosAck) { AbsWorldCoords coords = new AbsWorldCoords(packet.X, feetY, packet.Z); if (coords == client.Owner.LoginPosition) { client.WaitForInitialPosAck = false; client.SendSecondLoginSequence(); } } else { double threshold = 0.001; double diffX = Math.Abs(client.Owner.Position.X - packet.X); double diffY = Math.Abs(client.Owner.Position.Y - feetY); double diffZ = Math.Abs(client.Owner.Position.Z - packet.Z); if (diffX < threshold && diffY < threshold && diffZ < threshold) return; client.Owner.MoveTo(new AbsWorldCoords(packet.X, feetY, packet.Z), packet.Yaw, packet.Pitch); client.OnGround = packet.OnGround; client.Stance = packet.Stance; client.CheckAndUpdateChunks(packet.X, packet.Z); } }
public void Use(IClient client, string commandName, string[] tokens) { MobType type = MobType.Sheep; int amount = 1; bool validMob = false; if (tokens.Length > 1) { Int32.TryParse(tokens[1], out amount); } if (tokens.Length > 0) { int mobId; Int32.TryParse(tokens[0], out mobId); string mobName = Enum.GetName(typeof(MobType), mobId); if (mobId == 0) { if (mobId.ToString() != tokens[0]) { Enum.TryParse(tokens[0], true, out type); validMob = true; } } else if (!string.IsNullOrEmpty(mobName)) { type = (MobType)Enum.Parse(typeof(MobType), mobName); validMob = true; } } else { validMob = true; } if (amount < 1 || !validMob) { Help(client); return; } IServer server = client.GetServer(); AbsWorldCoords position = client.GetOwner().Position; IMobFactory mobFactory = server.GetMobFactory(); for (int i = 0; i < amount; i++) { var mob = mobFactory.CreateMob(client.GetOwner().GetWorld(), server, type, null); mob.Position = position; //Event EntitySpawnEventArgs e = new EntitySpawnEventArgs(mob, mob.Position); server.GetPluginManager().CallEvent(Event.EntitySpawn, e); if (e.EventCanceled) { continue; } mob.Position = e.Location; //End Event server.AddEntity(mob); } }
private static void DoSpawn(WorldManager world, HashSet <int> chunksToSpawnIn, Mob[] mobEntities, List <WeightedValue <MobType> > mobGroup, int maximumMobs, bool inWater = false) { // Based on original server spawn logic and minecraft wiki (http://www.minecraftwiki.net/wiki/Spawn) // Check that we haven't already reached the maximum number of this type of mob if (mobGroup.Count > 0 && (mobEntities.Where(e => mobGroup.Where(mob => mob.Value == e.Type).Any()).Count() <= maximumMobs * chunksToSpawnIn.Count / 256)) { foreach (var packedChunk in chunksToSpawnIn) { MobType mobType = mobGroup.SelectRandom(world.Server.Rand); UniversalCoords packSpawnPosition = GetRandomPointInChunk(world, UniversalCoords.FromPackedChunkToX(packedChunk), UniversalCoords.FromPackedChunkToZ(packedChunk)); byte?blockId = world.GetBlockId(packSpawnPosition); if (blockId == null) { continue; } BlockBase blockClass = BlockHelper.Instance.CreateBlockInstance((byte)blockId); if (!blockClass.IsOpaque && ((!inWater && blockClass.Type == BlockData.Blocks.Air) || (inWater && blockClass.IsLiquid))) // Lava is Opaque, so IsLiquid is safe to use here for water & still water { int spawnedCount = 0; int x = packSpawnPosition.WorldX; int y = packSpawnPosition.WorldY; int z = packSpawnPosition.WorldZ; for (int i = 0; i < 21; i++) { // Every 4th attempt reset the coordinates to the centre of the pack spawn if (i % 4 == 0) { x = packSpawnPosition.WorldX; y = packSpawnPosition.WorldY; z = packSpawnPosition.WorldZ; } const int distance = 6; x += world.Server.Rand.Next(distance) - world.Server.Rand.Next(distance); y += world.Server.Rand.Next(1) - world.Server.Rand.Next(1); z += world.Server.Rand.Next(distance) - world.Server.Rand.Next(distance); if (CanMobTypeSpawnAtLocation(mobType, world, x, y, z)) { AbsWorldCoords spawnPosition = new AbsWorldCoords(x + 0.5, y, z + 0.5); // Check that no player is within a radius of 24 blocks of the spawnPosition if (world.GetClosestPlayer(spawnPosition, 24.0) == null) { // Check that the squared distance is more than 576 from spawn (24 blocks) if (spawnPosition.ToVector().DistanceSquared(new AbsWorldCoords(world.Spawn).ToVector()) > 576.0) { Mob newMob = MobFactory.Instance.CreateMob(world, world.Server, mobType) as Mob; if (newMob == null) { break; } newMob.Position = spawnPosition; newMob.Yaw = world.Server.Rand.NextDouble() * 360.0; // Finally apply any mob specific rules about spawning here if (newMob.CanSpawnHere()) { //Event EntitySpawnEventArgs e = new EntitySpawnEventArgs(newMob, newMob.Position); world.Server.PluginManager.CallEvent(Event.EntitySpawn, e); if (e.EventCanceled) { continue; } newMob.Position = e.Location; //End Event ++spawnedCount; MobSpecificInitialisation(newMob, world, spawnPosition); world.Server.AddEntity(newMob); if (spawnedCount >= newMob.MaxSpawnedPerGroup) { // This chunk is full - move to the next break; } } } } } } } } } }
public FallingGravel(WorldManager world, AbsWorldCoords pos) : base(world, pos) { Type = Net.Packets.AddObjectVehiclePacket.ObjectType.FallingGravel; BlockId = (byte)BlockData.Blocks.Gravel; }
public EntitySpawnEventArgs(IEntityBase entity, AbsWorldCoords Location) : base(entity) { this.Location = Location; }
protected virtual void PushOutOfBlocks(AbsWorldCoords absWorldCoords) { UniversalCoords coords = UniversalCoords.FromAbsWorld(absWorldCoords); byte?blockId = World.GetBlockId(coords); if (blockId == null) { return; } BlockBase blockClass = BlockHelper.Instance.CreateBlockInstance((byte)blockId); if (blockClass == null) { Server.Logger.Log(LogLevel.Error, "Block class not found for block type Id {0}", blockId); return; } if (blockClass.IsOpaque && blockClass.IsSolid) { // The offset within World (int) coords Vector3 coordsOffset = new Vector3(absWorldCoords.X - (double)coords.WorldX, absWorldCoords.Y - (double)coords.WorldY, absWorldCoords.Z - (double)coords.WorldZ); double adjustment = double.MaxValue; Direction?moveDirection = null; // Calculate the smallest distance needed to move the entity out of the block coords.ForAdjacent((aCoord, direction) => { byte?adjBlockId = World.GetBlockId(aCoord); if (adjBlockId == null) { return; } var adjacentBlockClass = BlockHelper.Instance.CreateBlockInstance((byte)adjBlockId) as BlockBase; if (!(adjacentBlockClass.IsOpaque && adjacentBlockClass.IsSolid)) { switch (direction) { case Direction.South: if (coordsOffset.X < adjustment) { moveDirection = Direction.South; adjustment = coordsOffset.X; } break; case Direction.North: if (1.0 - coordsOffset.X < adjustment) { moveDirection = Direction.North; adjustment = 1.0 - coordsOffset.X; } break; case Direction.Down: if (coordsOffset.Y < adjustment) { moveDirection = Direction.Down; adjustment = coordsOffset.Y; } break; case Direction.Up: if (1.0 - coordsOffset.Y < adjustment) { moveDirection = Direction.Up; adjustment = 1.0 - coordsOffset.Y; } break; case Direction.East: if (coordsOffset.Z < adjustment) { moveDirection = Direction.East; adjustment = coordsOffset.Z; } break; case Direction.West: if (coordsOffset.Z < adjustment) { moveDirection = Direction.West; adjustment = 1.0 - coordsOffset.Z; } break; } } }); double motion = this.Server.Rand.NextDouble() * 0.2 + 0.1; if (moveDirection.HasValue) { if (moveDirection.Value == Direction.South) { this.Velocity.X = motion; } else if (moveDirection.Value == Direction.North) { this.Velocity.X = -motion; } else if (moveDirection.Value == Direction.Down) { this.Velocity.Y = -motion; } else if (moveDirection.Value == Direction.Up) { this.Velocity.Y = motion; } else if (moveDirection.Value == Direction.East) { this.Velocity.Z = -motion; } else if (moveDirection.Value == Direction.West) { this.Velocity.Z = motion; } } } }
public IPlayer GetClosestPlayer(AbsWorldCoords coords, double radius) { Client[] clients = Server.GetAuthenticatedClients() as Client[]; var radiusSqrd = radius * radius; Vector3 coordVector = coords.ToVector(); return (from c in clients.Where(client => client.Owner.World == this) let distance = coordVector.DistanceSquared(c.Owner.Position.ToVector()) where distance <= radiusSqrd orderby distance select c.Owner).FirstOrDefault(); }
public EntityMoveEventArgs(IEntityBase entity, AbsWorldCoords newPosition, AbsWorldCoords oldPosition) : base(entity) { NewPosition = newPosition; OldPosition = oldPosition; }
public FallingSand(WorldManager world, AbsWorldCoords pos) : base(world, pos) { Type = Net.Packets.AddObjectVehiclePacket.ObjectType.FallingObjects; BlockId = (byte)BlockData.Blocks.Sand; Velocity = new Vector3(0, -0.4D, 0); }
private static void DoSpawn(WorldManager world, HashSet<int> chunksToSpawnIn, Mob[] mobEntities, List<WeightedValue<MobType>> mobGroup, int maximumMobs, bool inWater = false) { // Based on original server spawn logic and minecraft wiki (http://www.minecraftwiki.net/wiki/Spawn) // Check that we haven't already reached the maximum number of this type of mob if (mobGroup.Count > 0 && (mobEntities.Where(e => mobGroup.Where(mob => mob.Value == e.Type).Any()).Count() <= maximumMobs * chunksToSpawnIn.Count / 256)) { foreach (var packedChunk in chunksToSpawnIn) { MobType mobType = mobGroup.SelectRandom(world.Server.Rand); UniversalCoords packSpawnPosition = GetRandomPointInChunk(world, UniversalCoords.FromPackedChunkToX(packedChunk), UniversalCoords.FromPackedChunkToZ(packedChunk)); byte? blockId = world.GetBlockId(packSpawnPosition); if (blockId == null) continue; BlockBase blockClass = BlockHelper.Instance.CreateBlockInstance((byte)blockId); if (!blockClass.IsOpaque && ((!inWater && blockClass.Type == BlockData.Blocks.Air) || (inWater && blockClass.IsLiquid))) // Lava is Opaque, so IsLiquid is safe to use here for water & still water { int spawnedCount = 0; int x = packSpawnPosition.WorldX; int y = packSpawnPosition.WorldY; int z = packSpawnPosition.WorldZ; for (int i = 0; i < 21; i++) { // Every 4th attempt reset the coordinates to the centre of the pack spawn if (i % 4 == 0) { x = packSpawnPosition.WorldX; y = packSpawnPosition.WorldY; z = packSpawnPosition.WorldZ; } const int distance = 6; x += world.Server.Rand.Next(distance) - world.Server.Rand.Next(distance); y += world.Server.Rand.Next(1) - world.Server.Rand.Next(1); z += world.Server.Rand.Next(distance) - world.Server.Rand.Next(distance); if (CanMobTypeSpawnAtLocation(mobType, world, x, y, z)) { AbsWorldCoords spawnPosition = new AbsWorldCoords(x + 0.5, y, z + 0.5); // Check that no player is within a radius of 24 blocks of the spawnPosition if (world.GetClosestPlayer(spawnPosition, 24.0) == null) { // Check that the squared distance is more than 576 from spawn (24 blocks) if (spawnPosition.ToVector().DistanceSquared(new AbsWorldCoords(world.Spawn).ToVector()) > 576.0) { Mob newMob = MobFactory.Instance.CreateMob(world, world.Server, mobType) as Mob; if (newMob == null) break; newMob.Position = spawnPosition; newMob.Yaw = world.Server.Rand.NextDouble()*360.0; // Finally apply any mob specific rules about spawning here if (newMob.CanSpawnHere()) { //Event EntitySpawnEventArgs e = new EntitySpawnEventArgs(newMob, newMob.Position); world.Server.PluginManager.CallEvent(Event.EntitySpawn, e); if (e.EventCanceled) continue; newMob.Position = e.Location; //End Event ++spawnedCount; MobSpecificInitialisation(newMob, world, spawnPosition); world.Server.AddEntity(newMob); if (spawnedCount >= newMob.MaxSpawnedPerGroup) { // This chunk is full - move to the next break; } } } } } } } } } }
// TODO: This should be removed in favor of the one below /// <summary> /// Sends a packet in parallel to each nearby player. /// </summary> /// <param name="world">The world containing the coordinates.</param> /// <param name="absCoords>The center coordinates.</param> /// <param name="packet">The packet to send</param> internal void SendPacketToNearbyPlayers(WorldManager world, AbsWorldCoords absCoords, Packet packet) { Client[] nearbyClients = GetNearbyPlayersInternal(world, UniversalCoords.FromAbsWorld(absCoords)).ToArray(); if (nearbyClients.Length == 0) return; packet.SetShared(Logger, nearbyClients.Length); Parallel.ForEach(nearbyClients, (client) => { client.SendPacket(packet); }); }
public BoundingBox(AbsWorldCoords minimum, AbsWorldCoords maximum) : this(minimum.ToVector(), maximum.ToVector()) { }