private void PutObjectInContainer(BinaryReader messageDataReader)
        {
            CM_Inventory.PutObjectInContainerEvent message = CM_Inventory.PutObjectInContainerEvent.read(messageDataReader);

            uint id                  = message.i_objectId;
            uint containerID         = message.i_container;
            ContainerProperties type = (ContainerProperties)message.i_type;

            Item item;

            if (character.MoveItem(id, containerID, type != ContainerProperties.None, out item)) // in inventory
            {
                // existing item needs to be moved into world
                if (item != null)
                {
                    otherObjects.Add(item.ID, item);
                }
            }
            else if (otherObjects.TryGetValue(id, out item)) // in world
            {
                if (character.Contains(containerID))
                {
                    // moving item in world into inventory
                    item.ContainerID = containerID;
                    character.AddItem(item, type != ContainerProperties.None);
                    otherObjects.Remove(id);
                    if (type == ContainerProperties.Container)
                    {
                        foreach (Item containedItem in new List <Item>(otherObjects.Values))
                        {
                            if (containedItem.ContainerID == item.ID)
                            {
                                character.AddItem(containedItem);
                                otherObjects.Remove(containedItem.ID);
                            }
                        }
                        otherObjects.Remove(id);
                    }
                }
                else
                {
                    // moving item within world
                    item.ContainerID = containerID;
                }
            }
            else // non-existent items
            {
                item = new Item(id);
                if (character.Contains(containerID))
                {
                    // move non-existent item into inventory
                    character.AddItemToContainer(item, containerID);
                }
                else
                {
                    // move non-existent item into world
                    otherObjects.Add(item.ID, item);
                }
            }
        }
        private Tuple <List <uint>, string, int> GetDroppedInformation(int deathRecord)
        {
            uint        affectedCharacterID = character.ID;
            List <uint> droppedItems        = new List <uint>();
            List <uint> unknownItems        = new List <uint>();
            string      deathText           = null;
            int         lastDeathRecord     = deathRecord;
            int         deathTextRecord;

            int i;

            if (character.PKStatus != PKStatusEnum.PKLite_PKStatus)
            {
                // find the death text, assumes printed after all items are moved
                for (i = deathRecord + 1; i < records.Count; i++)
                {
                    using (BinaryReader messageDataReader = new BinaryReader(new MemoryStream(records[i].data)))
                    {
                        PacketOpcode opcode = Util.readUnorderedOpcode(messageDataReader);
                        if (opcode == PacketOpcode.Evt_Communication__TextboxString_ID)
                        {
                            CM_Communication.TextBoxString message = CM_Communication.TextBoxString.read(messageDataReader);

                            if (message.ChatMessageType == 0x0 && message.MessageText.ToString().StartsWith("You've lost"))
                            {
                                deathText = message.MessageText.ToString();
                                break;
                            }
                        }
                    }
                }
                if (deathText == null)
                {
                    // couldn't find death text
                    return(new Tuple <List <uint>, string, int>(new List <uint>(), null, deathRecord));
                }
            }
            else
            {
                return(new Tuple <List <uint>, string, int>(new List <uint>(), "<PKLite Death>", deathRecord));
            }

            deathTextRecord = i;

            for (--i; i > deathRecord; i--)
            {
                using (BinaryReader messageDataReader = new BinaryReader(new MemoryStream(records[i].data)))
                {
                    PacketOpcode opcode = Util.readOrderedOpcode(messageDataReader, ref affectedCharacterID);

                    if (opcode == PacketOpcode.INVENTORY_PUT_OBJ_IN_CONTAINER_EVENT)
                    {
                        CM_Inventory.PutObjectInContainerEvent message = CM_Inventory.PutObjectInContainerEvent.read(messageDataReader);

                        Debug.Assert(affectedCharacterID == character.ID);
                        if (character.Contains(message.i_container))
                        {
                            // we can pickup items after we die
                            if (lastDeathRecord == deathRecord)
                            {
                                lastDeathRecord = i;
                            }
                            unknownItems.Remove(message.i_objectId);
                        }
                        else
                        {
                            droppedItems.Add(message.i_objectId);

                            Item item;
                            if (!character.FindItem(message.i_objectId, out item))
                            {
                                // look for stack size adjustment
                                unknownItems.Add(message.i_objectId);
                            }
                        }
                    }
                    else if (opcode == PacketOpcode.PLAYER_DEATH_EVENT)
                    {
                        CM_Death.PlayerDeathEvent message = CM_Death.PlayerDeathEvent.read(messageDataReader);

                        if (message.VictimId == character.ID)
                        {
                            if (message.KillerId >= 0x50000000 && message.KillerId <= 0x5FFFFFFF)
                            {
                                character.PlayerKill = true;
                            }
                        }
                    }
                }
            }

            for (i = deathTextRecord + 1; i < records.Count && unknownItems.Count > 0; i++)
            {
                using (BinaryReader messageDataReader = new BinaryReader(new MemoryStream(records[i].data)))
                {
                    PacketOpcode opcode = Util.readOrderedOpcode(messageDataReader, ref affectedCharacterID);

                    if (opcode == PacketOpcode.STACKABLE_SET_STACKSIZE_EVENT)
                    {
                        CM_Inventory.UpdateStackSize message = CM_Inventory.UpdateStackSize.read(messageDataReader);

                        Debug.Assert(affectedCharacterID == character.ID);
                        Item item;
                        if (character.FindItem(message.item, out item) && !item.Name.Equals("Pyreal"))
                        {
                            for (int j = 0; j < droppedItems.Count; j++)
                            {
                                Item droppedItem;
                                if (!character.FindItem(droppedItems[j], out droppedItem))
                                {
                                    droppedItems[j] = item.ID;
                                    break;
                                }
                            }
                            unknownItems.RemoveAt(0);
                        }
                    }
                }
            }

            return(new Tuple <List <uint>, string, int>(droppedItems, deathText, lastDeathRecord));
        }