Пример #1
0
        /// <summary>
        /// Adds a new npc to the character's client.
        /// </summary>
        /// <param name="character">The client to add npc for.</param>
        /// <param name="npc">The npc to add.</param>
        /// <param name="mainPacket">The packet composer to append bits to.</param>
        public static void AddNewNpc(Character character, Npc npc, PacketComposer mainPacket)
        {
            mainPacket.AppendBits(15, npc.Index);
            mainPacket.AppendBits(14, npc.CacheIndex);
            mainPacket.AppendBits(1, npc.UpdateFlags.UpdateRequired ? 1 : 0);
            int xPos = npc.Location.X - character.Location.X;
            int yPos = npc.Location.Y - character.Location.Y;

            if (xPos < 0)
            {
                xPos += 32;
            }
            if (yPos < 0)
            {
                yPos += 32;
            }

            mainPacket.AppendBits(5, yPos);
            mainPacket.AppendBits(5, xPos);
            mainPacket.AppendBits(3, 0);
            mainPacket.AppendBits(1, 1);
        }
Пример #2
0
        /// <summary>
        /// Constructs the npc rendering packet.
        /// </summary>
        /// <param name="character">Character to send rendered npcs to.</param>
        /// <param name="allNpcs">A list of npcs that are spawned on the server.</param>
        public NpcRenderingPacketComposer(Character character, List <Npc> allNpcs)
        {
            SetOpcode(222);
            SetType(PacketType.Short);
            InitializeBit();

            // The update block. Any updates that are pending will be added to this block.
            GenericPacketComposer updateBlock = new GenericPacketComposer();

            AppendBits(8, character.LocalNpcs.Count);

            // A bin of npcs that have been removed during local npc updating.
            List <Npc> npcBin = new List <Npc>();

            character.LocalNpcs.ForEach((npc) =>
            {
                if (GameEngine.World.NpcManager.Spawns.Values.Contains(npc) &&
                    npc.Location.WithinDistance(character.Location) &&
                    !character.UpdateFlags.Teleporting)
                {
                    UpdateMovement(npc, this);

                    // Update the npc is required, since it is conditionally valid.
                    if (npc.UpdateFlags.UpdateRequired)
                    {
                        RenderMasks.AppendMasks(npc, updateBlock);
                    }
                }
                else
                {
                    // Remove this npc, as it doesn't meet local standards.
                    npcBin.Add(npc);

                    // Signify the client that this npc needs to be removed.
                    AppendBits(1, 1);
                    AppendBits(2, 3);
                }
            });

            // Remove all binned npcs.
            npcBin.ForEach((npc) => character.LocalNpcs.Remove(npc));

            // Search for npcs that may qualify for locality.
            foreach (Npc npc in allNpcs)
            {
                // We cannot have more than 255 npcs in the client simultaneously.
                if (character.LocalNpcs.Count >= 255)
                {
                    break;
                }

                if (character.LocalNpcs.Contains(npc) || !npc.Location.WithinDistance(character.Location))
                {
                    continue;
                }

                character.LocalNpcs.Add(npc);
                AddNewNpc(character, npc, this);

                // Update the npc if required.
                if (npc.UpdateFlags.UpdateRequired)
                {
                    RenderMasks.AppendMasks(npc, updateBlock);
                }
            }

            // Finalize the composition.
            if (updateBlock.Position >= 3)
            {
                AppendBits(15, 32767);
            }

            FinishBit();

            if (updateBlock.Position > 0)
            {
                AppendBytes(updateBlock.SerializeBuffer());
            }
        }