internal void SetPosAng(Vec3f position, Angles angles, GameClient exclude) { this.pos = position.ClampToWorldLimits(); this.ang = angles.Clamp(); if (this.isCreated && !this.IsStatic) { this.world.UpdateVobCell(this, pos); if (this is NPC) { this.world.UpdateNPCCell((NPC)this, pos); } bool updateVis; if (lastUpdatePos.GetDistancePlanar(this.pos) > 100) { updateVis = true; lastUpdatePos = this.pos; CleanClientList(); } else { updateVis = false; } if (visibleClients.Count > 0 || targetOf.Count > 0) { this.WritePosAngMessage(exclude); } if (updateVis) { UpdateClientList(); } } }
internal void UpdateVobList(World world, Vec3f pos) { int removeCount = 0, addCount = 0; PacketWriter stream = GameServer.SetupStream(ServerMessages.WorldCellMessage); // first, clean all vobs which are out of range if (visibleVobs.Count > 0) { // save the position where the count is written int removeCountBytePos = stream.Position; stream.Write(ushort.MinValue); visibleVobs.ForEach(vob => { if (vob.Position.GetDistancePlanar(pos) > World.SpawnRemoveRange) { stream.Write((ushort)vob.ID); vob.RemoveVisibleClient(this); visibleVobs.Remove(vob.ID); removeCount++; } }); // vobs were removed, write the count at the start if (removeCount > 0) { int currentByte = stream.Position; stream.Position = removeCountBytePos; stream.Write((ushort)removeCount); stream.Position = currentByte; } } else { stream.Write(ushort.MinValue); } // save the position where we wrote the count of new vobs int countBytePos = stream.Position; stream.Write(ushort.MinValue); // then look for new vobs if (visibleVobs.Count > 0) // we have to check whether we know the vob already { world.ForEachDynVobRougher(pos, World.SpawnInsertRange, vob => { if (!visibleVobs.Contains(vob.ID)) { if (pos.GetDistancePlanar(vob.Position) < World.SpawnInsertRange) { AddVisibleVob(vob); vob.AddVisibleClient(this); stream.Write((byte)vob.ScriptObject.GetVobType()); vob.WriteStream(stream); addCount++; } } }); } else // just add everything { world.ForEachDynVobRougher(pos, World.SpawnInsertRange, vob => { if (pos.GetDistancePlanar(vob.Position) < World.SpawnInsertRange) { AddVisibleVob(vob); vob.AddVisibleClient(this); stream.Write((byte)vob.ScriptObject.GetVobType()); vob.WriteStream(stream); addCount++; } }); } // vobs were added, write the correct count at the start if (addCount > 0) { int currentByte = stream.Position; stream.Position = countBytePos; stream.Write((ushort)addCount); stream.Position = currentByte; } else if (removeCount == 0) // nothing changed { return; } this.Send(stream, NetPriority.Low, NetReliability.ReliableOrdered, 'W'); }
void ChangePosDir(Vec3f oldPos, Angles oldAng, NPCMovement oldMovement) { Vec3f pos = GetPosition(); var env = this.Environment; if (env.InAir) { if (pos.Y > highestY) { highestY = pos.Y; } } else if (highestY != 0) { float dmg = 0.14f * (highestY - pos.Y) - 135; if (dmg > 0) { Logger.Log("Damage: " + dmg); //this.SetHealth(this.HP - (int)dmg); highestY = 0; } } if (lastRegPos.GetDistance(pos) > 30.0f) { lastHitMoveTime = GameTime.Ticks; lastRegPos = pos; } if (this.FightAnimation != null && this.CanCombo && this.Movement != NPCMovement.Stand) { // so the npc can instantly stop the attack and run into a direction this.ModelInst.StopAnimation(this.fightAni, false); } if (Arena.GameModes.GameMode.ActiveMode != null && Cast.Try(this.Client, out Arena.ArenaClient ac) && ac.GMJoined) { var gm = Arena.GameModes.GameMode.ActiveMode; if (pos.GetDistancePlanar(Vec3f.Null) > gm.Scenario.MaxWorldDistance || pos.Y > gm.Scenario.MaxHeight || pos.Y < gm.Scenario.MaxDepth) { ac.KillCharacter(); } } if (env.WaterLevel > 0.7f) { if (this.IsPlayer) { var client = ((Arena.ArenaClient) this.Client); client.KillCharacter(); if (Arena.GameModes.Horde.HordeMode.IsActive && this.TeamID >= 0) { Arena.GameModes.Horde.HordeMode.ActiveMode.RespawnClient(client); } } else { this.SetHealth(0); } } if (env.InAir && !this.isClimbing) { var aa = this.ModelInst.GetActiveAniFromLayer(1); if (aa != null) { this.ModelInst.StopAnimation(aa, false); } } CheckUnconsciousness(); }