void UpdateGuidedNPCPosition(long now, long interval, float minPosDist, float minAngDist) { if (now < guidedNextUpdate) { return; } Vec3f pos = this.Position; Angles ang = this.Angles; VobEnvironment env = this.Environment; if (now - guidedNextUpdate < TimeSpan.TicksPerSecond) { // nothing really changed, only update every second if (guidedLastMovement == this.movement && pos.GetDistance(guidedLastPos) < minPosDist && !ang.DifferenceIsBigger(guidedLastAng, minAngDist) && env == guidedLastEnv) { return; } } guidedLastMovement = this.movement; guidedLastPos = pos; guidedLastAng = ang; guidedLastEnv = env; Messages.WritePosAngMessage(this, pos, ang, env); guidedNextUpdate = now + interval; //this.ScriptObject.OnPosChanged(); }
public static void ReadPosAng(PacketReader stream, GameClient client, World world) { int id = stream.ReadUShort(); if (world.TryGetVob(id, out NPC npc) && (npc.guide == client || npc.client == client)) { var oldPos = npc.Position; var oldAng = npc.Angles; var oldMovement = npc.Movement; var pos = stream.ReadCompressedPosition(); var ang = stream.ReadCompressedAngles(); int bitfield = stream.ReadShort(); bool inAir = (bitfield & 0x8000) != 0; NPCMovement movement = (NPCMovement)((bitfield >> 12) & 0x7); float waterDepth = ((bitfield >> 6) & 0x3F) / (float)0x3F; float waterLevel = (bitfield & 0x3F) / (float)0x3F; VobEnvironment env = new VobEnvironment(inAir, waterLevel, waterDepth); npc.movement = movement; npc.environment = env; npc.SetPosAng(pos, ang, client); if (npc == client.Character) { client.UpdateVobList(world, pos); } OnNPCMove?.Invoke(npc, oldPos, oldAng, oldMovement); } }
public static void WritePosAngMessage(NPC npc, Vec3f pos, Angles ang, VobEnvironment env) { PacketWriter stream = GameClient.SetupStream(ClientMessages.GuidedNPCMessage); stream.Write((ushort)npc.ID); stream.WriteCompressedPosition(pos); stream.WriteCompressedAngles(ang); // compress environment & npc movement int bitfield = env.InAir ? 0x8000 : 0; bitfield |= (int)npc.movement << 12; bitfield |= (int)(env.WaterDepth * 0x3F) << 6; bitfield |= (int)(env.WaterLevel * 0x3F); stream.Write((short)bitfield); GameClient.Send(stream, NetPriority.Low, NetReliability.Unreliable); }