Example #1
0
        public void ClearPlayerCraftingData(NWPlayer player)
        {
            var model = GetPlayerCraftingData(player);

            foreach (var item in model.MainComponents)
            {
                _.CopyItem(item.Object, player.Object, TRUE);
                item.Destroy();
            }
            foreach (var item in model.SecondaryComponents)
            {
                _.CopyItem(item.Object, player.Object, TRUE);
                item.Destroy();
            }
            foreach (var item in model.TertiaryComponents)
            {
                _.CopyItem(item.Object, player.Object, TRUE);
                item.Destroy();
            }
            foreach (var item in model.EnhancementComponents)
            {
                _.CopyItem(item.Object, player.Object, TRUE);
                item.Destroy();
            }

            player.Data.Remove("CRAFTING_MODEL");
            player.DeleteLocalInt("CRAFT_BLUEPRINT_ID");
        }
Example #2
0
        private bool CheckItemCounts(NWPlayer oPC, NWPlaceable device, ICollection <CraftBlueprintComponent> componentList)
        {
            bool allComponentsFound             = false;
            Dictionary <string, int> components = new Dictionary <string, int>();

            foreach (CraftBlueprintComponent component in componentList)
            {
                components.Add(component.ItemResref, component.Quantity);
            }

            NWPlaceable tempStorage = NWPlaceable.Wrap(_.CreateObject(OBJECT_TYPE_PLACEABLE, "craft_temp_store", device.Location));

            device.SetLocalObject("CRAFT_TEMP_STORAGE", tempStorage.Object);

            foreach (NWItem item in device.InventoryItems)
            {
                if (components.ContainsKey(item.Resref) && components[item.Resref] > 0)
                {
                    components[item.Resref] = components[item.Resref] - 1;

                    _.CopyItem(item.Object, tempStorage.Object, TRUE);
                    item.Destroy();
                }

                int remainingQuantities = 0;
                foreach (int quantity in components.Values)
                {
                    remainingQuantities += quantity;
                }

                if (remainingQuantities <= 0)
                {
                    allComponentsFound = true;
                    break;
                }
            }

            if (!allComponentsFound)
            {
                foreach (NWItem item in tempStorage.InventoryItems)
                {
                    _.CopyItem(item.Object, device.Object, TRUE);
                    item.Destroy();
                }
                oPC.IsBusy = false;
            }

            return(allComponentsFound);
        }
Example #3
0
        public void OnItemCollectorClosed(NWObject container)
        {
            NWPlayer oPC = NWPlayer.Wrap(_.GetLastClosedBy());

            foreach (NWItem item in container.InventoryItems)
            {
                if (item.Resref != SubmitQuestItemResref)
                {
                    _.CopyItem(item.Object, oPC.Object, TRUE);
                }
                item.Destroy();
            }

            container.Destroy();
        }
Example #4
0
        public NWItem DeserializeItem(string base64String, NWPlaceable target)
        {
            if (target == null || !target.IsValid)
            {
                throw new ArgumentException("Invalid target placeable during item deserialization.");
            }

            NWItem item = _nwnxObject.Deserialize(base64String);

            if (item.Object == null)
            {
                throw new NullReferenceException("Unable to deserialize item.");
            }
            var result = _.CopyItem(item.Object, target.Object, TRUE);

            item.Destroy();

            return(result);
        }
Example #5
0
        public void OnChestDisturbed(NWPlaceable oChest)
        {
            NWPlayer oPC = (_.GetLastDisturbed());

            if (!oPC.IsPlayer && !oPC.IsDM)
            {
                return;
            }

            string pcName      = oPC.Name;
            NWItem oItem       = (_.GetInventoryDisturbItem());
            int    disturbType = _.GetInventoryDisturbType();

            if (disturbType == NWScript.INVENTORY_DISTURB_TYPE_ADDED)
            {
                _.CopyItem(oItem.Object, oPC.Object, NWScript.TRUE);
                oItem.Destroy();
            }
            else if (disturbType == NWScript.INVENTORY_DISTURB_TYPE_REMOVED)
            {
                SaveChestInventory(oPC, oChest, false);
                string itemName = oItem.Name;
                if (string.IsNullOrWhiteSpace(itemName))
                {
                    itemName = "money";
                }

                float minSearchSeconds = 1.5f;
                float maxSearchSeconds = 4.5f;
                float searchDelay      = _random.RandomFloat() * (maxSearchSeconds - minSearchSeconds) + minSearchSeconds;

                oPC.AssignCommand(() =>
                {
                    _.ActionPlayAnimation(NWScript.ANIMATION_LOOPING_GET_LOW, 1.0f, searchDelay);
                });

                _.ApplyEffectToObject(NWScript.DURATION_TYPE_TEMPORARY, _.EffectCutsceneImmobilize(), oPC.Object, searchDelay);

                // Notify party members in the vicinity

                NWPlayer player = (_.GetFirstPC());
                while (player.IsValid)
                {
                    if (_.GetDistanceBetween(oPC.Object, player.Object) <= 20.0f &&
                        player.Area.Equals(oPC.Area) &&
                        _.GetFactionEqual(player.Object, oPC.Object) == NWScript.TRUE)
                    {
                        player.SendMessage(pcName + " found " + itemName + ".");
                    }

                    player = (_.GetNextPC());
                }
            }
        }
Example #6
0
        public void DoAction(NWPlayer user, NWObject target, NWLocation targetLocation, params string[] args)
        {
            if (target.ObjectType != OBJECT_TYPE_ITEM)
            {
                user.SendMessage("You can only copy items with this command.");
                return;
            }

            _.CopyItem(target, user, TRUE);
            user.SendMessage("Item copied successfully.");
        }
Example #7
0
        public bool Run(params object[] args)
        {
            // Should only fire when a player walks away from the device.
            // Clean up temporary data and return all items placed inside.
            NWPlayer    player = NWPlayer.Wrap(_.GetLastClosedBy());
            NWPlaceable device = NWPlaceable.Wrap(Object.OBJECT_SELF);
            var         model  = _craft.GetPlayerCraftingData(player);

            device.DestroyAllInventoryItems();
            device.IsLocked          = false;
            model.IsAccessingStorage = false;

            foreach (var item in model.MainComponents)
            {
                _.CopyItem(item.Object, player.Object, TRUE);
                item.Destroy();
            }
            foreach (var item in model.SecondaryComponents)
            {
                _.CopyItem(item.Object, player.Object, TRUE);
                item.Destroy();
            }
            foreach (var item in model.TertiaryComponents)
            {
                _.CopyItem(item.Object, player.Object, TRUE);
                item.Destroy();
            }
            foreach (var item in model.EnhancementComponents)
            {
                _.CopyItem(item.Object, player.Object, TRUE);
                item.Destroy();
            }

            _.SetEventScript(device.Object, EVENT_SCRIPT_PLACEABLE_ON_USED, "jvm_script_1");
            _.SetEventScript(device.Object, EVENT_SCRIPT_PLACEABLE_ON_OPEN, string.Empty);
            _.SetEventScript(device.Object, EVENT_SCRIPT_PLACEABLE_ON_CLOSED, string.Empty);
            _.SetEventScript(device.Object, EVENT_SCRIPT_PLACEABLE_ON_INVENTORYDISTURBED, string.Empty);
            player.Data.Remove("CRAFTING_MODEL");
            return(true);
        }
Example #8
0
        public bool Run(params object[] args)
        {
            NWPlaceable device = NWPlaceable.Wrap(Object.OBJECT_SELF);
            NWPlayer    oPC    = NWPlayer.Wrap(_.GetLastOpenedBy());
            var         model  = _craft.GetPlayerCraftingData(oPC);

            if (model.Access != CraftingAccessType.None)
            {
                NWItem        menuItem     = NWItem.Wrap(_.CreateItemOnObject("cft_confirm", device.Object));
                NWPlaceable   storage      = NWPlaceable.Wrap(_.GetObjectByTag("craft_temp_store"));
                var           storageItems = storage.InventoryItems;
                List <NWItem> list         = null;

                if (model.Access == CraftingAccessType.MainComponent)
                {
                    menuItem.Name = "Confirm Main Components";
                    list          = model.MainComponents;
                }
                else if (model.Access == CraftingAccessType.SecondaryComponent)
                {
                    menuItem.Name = "Confirm Secondary Components";
                    list          = model.SecondaryComponents;
                }
                else if (model.Access == CraftingAccessType.TertiaryComponent)
                {
                    menuItem.Name = "Confirm Tertiary Components";
                    list          = model.TertiaryComponents;
                }
                else if (model.Access == CraftingAccessType.Enhancement)
                {
                    menuItem.Name = "Confirm Enhancement Components";
                    list          = model.EnhancementComponents;
                }

                if (list == null)
                {
                    oPC.FloatingText("Error locating component list. Notify an admin.");
                    return(false);
                }

                foreach (var item in list)
                {
                    NWItem storageItem = storageItems.Single(x => x.GlobalID == item.GlobalID);
                    _.CopyItem(storageItem.Object, device.Object, TRUE);
                }

                oPC.FloatingText("Place the components inside the container and then click the item named '" + menuItem.Name + "' to continue.");
            }

            device.IsLocked = true;
            return(true);
        }
Example #9
0
 public void ReturnItem(NWObject target, NWItem item)
 {
     if (_.GetHasInventory(item) == TRUE)
     {
         NWObject possessor = item.Possessor;
         possessor.AssignCommand(() =>
         {
             _.ActionGiveItem(item, target);
         });
     }
     else
     {
         _.CopyItem(item.Object, target.Object, TRUE);
         item.Destroy();
     }
 }
Example #10
0
        public bool Run(params object[] args)
        {
            NWPlaceable device = NWPlaceable.Wrap(Object.OBJECT_SELF);
            NWObject    oPC    = NWObject.Wrap(_.GetLastClosedBy());

            foreach (NWItem item in device.InventoryItems)
            {
                string resref = item.Resref;

                if (resref != "cft_choose_bp" && resref != "cft_craft_item")
                {
                    _.CopyItem(item.Object, oPC.Object, TRUE);
                }
                item.Destroy();
            }

            return(true);
        }
Example #11
0
        public void RunItemDecay(NWPlayer oPC, NWItem oItem, float reduceAmount)
        {
            if (reduceAmount <= 0)
            {
                return;
            }
            // Item decay doesn't run for any items if Invincible is in effect
            // Or if the item is unbreakable (e.g profession items)
            // Or if the item is not part of the valid list of base item types
            if (oPC.IsPlot ||
                oItem.GetLocalInt("UNBREAKABLE") == 1 ||
                !IsValidDurabilityType(oItem))
            {
                return;
            }

            float  durability = GetDurability(oItem);
            string sItemName  = oItem.Name;

            // Reduce by 0.001 each time it's run. Player only receives notifications when it drops a full point.
            // I.E: Dropping from 29.001 to 29.
            // Note that players only see two decimal places in-game on purpose.
            durability -= reduceAmount;
            bool displayMessage = durability % 1 == 0;

            if (displayMessage)
            {
                oPC.SendMessage(_color.Red("Your " + sItemName + " has been damaged. (" + FormatDurability(durability) + " / " + GetMaxDurability(oItem)));
            }

            if (durability <= 0.00f)
            {
                NWItem oCopy = NWItem.Wrap(_.CopyItem(oItem.Object, oPC.Object, TRUE));
                oItem.Destroy();
                SetDurability(oCopy, 0);
                oPC.SendMessage(_color.Red("Your " + sItemName + " has broken!"));
            }
            else
            {
                SetDurability(oItem, durability);
            }
        }
Example #12
0
 public void ReturnItem(NWObject target, NWItem item)
 {
     _.CopyItem(item.Object, target.Object, TRUE);
     item.Destroy();
 }
Example #13
0
        public void OnPlayerDeath()
        {
            NWPlayer oPC           = NWPlayer.Wrap(_.GetLastPlayerDied());
            string   corpseName    = oPC.Name + "'s Corpse";
            NWObject oHostileActor = NWObject.Wrap(_.GetLastHostileActor(oPC.Object));
            Location location      = oPC.Location;
            bool     hasItems      = false;

            var factionMember = _.GetFirstFactionMember(oHostileActor.Object, FALSE);

            while (_.GetIsObjectValid(factionMember) == TRUE)
            {
                _.ClearPersonalReputation(oPC.Object, factionMember);

                factionMember = _.GetNextFactionMember(oHostileActor.Object, FALSE);
            }

            _.PopUpDeathGUIPanel(oPC.Object, TRUE, TRUE, 0, RespawnMessage);

            NWPlaceable corpse = NWPlaceable.Wrap(_.CreateObject(OBJECT_TYPE_PLACEABLE, CorpsePlaceableResref, location));
            PCCorpse    entity = new PCCorpse
            {
                AreaTag     = _.GetTag(_.GetAreaFromLocation(location)),
                Name        = corpseName,
                Orientation = _.GetFacingFromLocation(location),
                PositionX   = _.GetPositionFromLocation(location).m_X,
                PositionY   = _.GetPositionFromLocation(location).m_Y,
                PositionZ   = _.GetPositionFromLocation(location).m_Z
            };

            if (oPC.Gold > 0)
            {
                corpse.AssignCommand(() =>
                {
                    _.TakeGoldFromCreature(oPC.Gold, oPC.Object);
                });

                hasItems = true;
            }

            foreach (NWItem item in oPC.InventoryItems)
            {
                if (!item.IsCursed)
                {
                    _.CopyItem(item.Object, corpse.Object, TRUE);
                    item.Destroy();
                    hasItems = true;
                }
            }

            if (!hasItems)
            {
                corpse.Destroy();
                return;
            }

            corpse.Name = corpseName;
            corpse.IdentifiedDescription = corpseName;

            foreach (NWItem corpseItem in corpse.InventoryItems)
            {
                PCCorpseItem corpseItemEntity = new PCCorpseItem
                {
                    GlobalID       = corpseItem.GlobalID,
                    NWItemObject   = _serialization.Serialize(corpseItem),
                    PCCorpseItemID = entity.PCCorpseID,
                    ItemName       = corpseItem.Name,
                    ItemTag        = corpseItem.Tag,
                    ItemResref     = corpseItem.Resref
                };
                entity.PCCorpseItems.Add(corpseItemEntity);
            }

            _db.PCCorpses.Add(entity);
            _db.SaveChanges();
            corpse.SetLocalInt("CORPSE_ID", (int)entity.PCCorpseID);
        }
Example #14
0
 private void ReturnItemToPC(NWPlayer pc, NWItem item, string message)
 {
     _.CopyItem(item.Object, pc.Object, NWScript.TRUE);
     item.Destroy();
     pc.SendMessage(message);
 }
Example #15
0
        private void HandleAddItem()
        {
            NWPlayer oPC   = NWPlayer.Wrap(_.GetLastDisturbed());
            NWItem   oItem = NWItem.Wrap(_.GetInventoryDisturbItem());

            if (oItem.Resref == "cft_confirm")
            {
                return;
            }
            var         model   = _craft.GetPlayerCraftingData(oPC);
            NWPlaceable storage = NWPlaceable.Wrap(_.GetObjectByTag("craft_temp_store"));

            List <NWItem> list          = null;
            ComponentType allowedType   = ComponentType.None;
            bool          reachedCap    = false;
            string        componentName = string.Empty;

            switch (model.Access)
            {
            case CraftingAccessType.MainComponent:
                allowedType   = (ComponentType)model.Blueprint.MainComponentTypeID;
                reachedCap    = model.Blueprint.MainMinimum * 2 < model.MainComponents.Count + 1;
                list          = model.MainComponents;
                componentName = model.Blueprint.MainComponentType.Name;
                break;

            case CraftingAccessType.SecondaryComponent:
                allowedType   = (ComponentType)model.Blueprint.SecondaryComponentTypeID;
                reachedCap    = model.Blueprint.SecondaryMinimum * 2 < model.SecondaryComponents.Count + 1;
                list          = model.SecondaryComponents;
                componentName = model.Blueprint.SecondaryComponentType.Name;
                break;

            case CraftingAccessType.TertiaryComponent:
                allowedType   = (ComponentType)model.Blueprint.TertiaryComponentTypeID;
                reachedCap    = model.Blueprint.TertiaryMinimum * 2 < model.TertiaryComponents.Count + 1;
                list          = model.TertiaryComponents;
                componentName = model.Blueprint.TertiaryComponentType.Name;
                break;

            case CraftingAccessType.Enhancement:
                allowedType   = ComponentType.Enhancement;
                reachedCap    = model.Blueprint.EnhancementSlots < model.EnhancementComponents.Count + 1;
                list          = model.EnhancementComponents;
                componentName = "Enhancement";
                break;
            }

            if (list == null)
            {
                oPC.FloatingText("There was an issue getting the item data. Notify an admin.");
                _item.ReturnItem(oPC, oItem);
                return;
            }

            if (reachedCap)
            {
                _item.ReturnItem(oPC, oItem);
                oPC.FloatingText("You cannot add any more components of that type.");
                return;
            }

            foreach (var ip in oItem.ItemProperties)
            {
                if (_.GetItemPropertyType(ip) == (int)CustomItemPropertyType.ComponentType)
                {
                    int compType = _.GetItemPropertyCostTableValue(ip);
                    if (compType == (int)allowedType)
                    {
                        NWItem copy = NWItem.Wrap(_.CopyItem(oItem.Object, storage.Object, TRUE));
                        list.Add(copy);
                        return;
                    }
                }
            }

            oPC.FloatingText("Only " + componentName + " components may be used with this component type.");
            _item.ReturnItem(oPC, oItem);
        }
Example #16
0
 private void ReturnItem(NWPlayer oPC, NWItem oItem)
 {
     _.CopyItem(oItem.Object, oPC.Object, TRUE);
     oItem.Destroy();
 }
Example #17
0
        private void HandleAddItem()
        {
            NWPlayer oPC   = (_.GetLastDisturbed());
            NWItem   oItem = (_.GetInventoryDisturbItem());

            if (oItem.Resref == "cft_confirm")
            {
                return;
            }
            if (oPC.IsBusy)
            {
                _item.ReturnItem(oPC, oItem);
                oPC.SendMessage("You are too busy right now.");
                return;
            }

            var model              = _craft.GetPlayerCraftingData(oPC);
            var mainComponent      = _data.Get <Data.Entity.ComponentType>(model.Blueprint.MainComponentTypeID);
            var secondaryComponent = _data.Get <Data.Entity.ComponentType>(model.Blueprint.SecondaryComponentTypeID);
            var tertiaryComponent  = _data.Get <Data.Entity.ComponentType>(model.Blueprint.TertiaryComponentTypeID);

            NWPlaceable storage = _.GetObjectByTag("craft_temp_store");

            List <NWItem> list                    = null;
            ComponentType allowedType             = ComponentType.None;
            bool          reachedCap              = false;
            bool          reachedEnhancementLimit = false;

            string componentName = string.Empty;

            switch (model.Access)
            {
            case CraftingAccessType.MainComponent:
                allowedType   = (ComponentType)model.Blueprint.MainComponentTypeID;
                reachedCap    = model.MainMaximum < model.MainComponents.Count + 1;
                list          = model.MainComponents;
                componentName = mainComponent.Name;
                break;

            case CraftingAccessType.SecondaryComponent:
                allowedType   = (ComponentType)model.Blueprint.SecondaryComponentTypeID;
                reachedCap    = model.SecondaryMaximum < model.SecondaryComponents.Count + 1;
                list          = model.SecondaryComponents;
                componentName = secondaryComponent.Name;
                break;

            case CraftingAccessType.TertiaryComponent:
                allowedType   = (ComponentType)model.Blueprint.TertiaryComponentTypeID;
                reachedCap    = model.TertiaryMaximum < model.TertiaryComponents.Count + 1;
                list          = model.TertiaryComponents;
                componentName = tertiaryComponent.Name;
                break;

            case CraftingAccessType.Enhancement:
                allowedType             = ComponentType.Enhancement;
                reachedCap              = model.Blueprint.EnhancementSlots < model.EnhancementComponents.Count + 1;
                reachedEnhancementLimit = model.PlayerPerkLevel / 2 <= model.EnhancementComponents.Count + 1;
                list          = model.EnhancementComponents;
                componentName = "Enhancement";
                break;
            }

            if (list == null)
            {
                _item.ReturnItem(oPC, oItem);
                oPC.FloatingText("There was an issue getting the item data. Notify an admin.");
                return;
            }

            if (reachedCap)
            {
                _item.ReturnItem(oPC, oItem);
                oPC.FloatingText("You cannot add any more components of that type.");
                return;
            }

            if (reachedEnhancementLimit)
            {
                _item.ReturnItem(oPC, oItem);
                oPC.FloatingText("Your perk level does not allow you to attach any more enhancements to this item.");
                return;
            }

            var            props            = oItem.ItemProperties.ToList();
            var            allowedItemTypes = new List <CustomItemType>();
            CustomItemType finishedItemType = _item.GetCustomItemTypeByResref(model.Blueprint.ItemResref);

            foreach (var ip in props)
            {
                if (_.GetItemPropertyType(ip) == (int)CustomItemPropertyType.ComponentItemTypeRestriction)
                {
                    int restrictionType = _.GetItemPropertyCostTableValue(ip);
                    allowedItemTypes.Add((CustomItemType)restrictionType);
                }
            }

            if (allowedItemTypes.Count > 0)
            {
                if (!allowedItemTypes.Contains(finishedItemType))
                {
                    oPC.FloatingText("This component cannot be used with this type of blueprint.");
                    _item.ReturnItem(oPC, oItem);
                    return;
                }
            }

            foreach (var ip in props)
            {
                if (_.GetItemPropertyType(ip) == (int)CustomItemPropertyType.ComponentType)
                {
                    int compType = _.GetItemPropertyCostTableValue(ip);
                    if (compType == (int)allowedType)
                    {
                        oItem.GetOrAssignGlobalID();
                        NWItem copy = (_.CopyItem(oItem.Object, storage.Object, TRUE));
                        list.Add(copy);
                        return;
                    }
                }
            }

            oPC.FloatingText("Only " + componentName + " components may be used with this component type.");
            _item.ReturnItem(oPC, oItem);
        }
Example #18
0
        public void OnCreatureDeath()
        {
            _.SetIsDestroyable(FALSE);

            NWObject self          = Object.OBJECT_SELF;
            Vector   lootPosition  = _.Vector(self.Position.m_X, self.Position.m_Y, self.Position.m_Z - 0.11f);
            Location spawnLocation = _.Location(self.Area, lootPosition, self.Facing);

            NWPlaceable container = _.CreateObject(OBJECT_TYPE_PLACEABLE, "corpse", spawnLocation);

            container.SetLocalObject("CORPSE_BODY", self);
            container.Name = self.Name + "'s Corpse";

            container.AssignCommand(() =>
            {
                _.TakeGoldFromCreature(self.Gold, self);
            });

            // Dump equipped items in container
            for (int slot = 0; slot < NUM_INVENTORY_SLOTS; slot++)
            {
                if (slot == INVENTORY_SLOT_CARMOUR ||
                    slot == INVENTORY_SLOT_CWEAPON_B ||
                    slot == INVENTORY_SLOT_CWEAPON_L ||
                    slot == INVENTORY_SLOT_CWEAPON_R)
                {
                    continue;
                }

                NWItem item = _.GetItemInSlot(slot, self);
                if (item.IsValid && !item.IsCursed && item.IsDroppable)
                {
                    NWItem copy = _.CopyItem(item, container, TRUE);

                    if (slot == INVENTORY_SLOT_HEAD ||
                        slot == INVENTORY_SLOT_CHEST)
                    {
                        copy.SetLocalObject("CORPSE_ITEM_COPY", item);
                    }
                    else
                    {
                        item.Destroy();
                    }
                }
            }

            foreach (var item in self.InventoryItems)
            {
                _.CopyItem(item, container, TRUE);
                item.Destroy();
            }

            _.DelayCommand(360.0f, () =>
            {
                if (!container.IsValid)
                {
                    return;
                }

                NWObject body = container.GetLocalObject("CORPSE_BODY");
                body.AssignCommand(() => _.SetIsDestroyable(TRUE));
                body.DestroyAllInventoryItems();
                body.Destroy();

                container.DestroyAllInventoryItems();
                container.Destroy();
            });
        }
Example #19
0
        public bool Run(params object[] args)
        {
            NWPlaceable container = Object.OBJECT_SELF;
            NWObject    owner     = container.GetLocalObject("QUEST_OWNER");

            NWPlayer player            = _.GetLastDisturbed();
            NWItem   item              = _.GetInventoryDisturbItem();
            int      disturbType       = _.GetInventoryDisturbType();
            string   crafterPlayerID   = item.GetLocalString("CRAFTER_PLAYER_ID");
            Guid?    crafterPlayerGUID = null;

            if (!string.IsNullOrWhiteSpace(crafterPlayerID))
            {
                crafterPlayerGUID = new Guid(crafterPlayerID);
            }

            if (disturbType == INVENTORY_DISTURB_TYPE_ADDED)
            {
                int                 questID  = container.GetLocalInt("QUEST_ID");
                PCQuestStatus       status   = _data.Single <PCQuestStatus>(x => x.PlayerID == player.GlobalID && x.QuestID == questID);
                PCQuestItemProgress progress = _data.SingleOrDefault <PCQuestItemProgress>(x => x.PCQuestStatusID == status.ID && x.Resref == item.Resref);
                DatabaseActionType  action   = DatabaseActionType.Update;

                if (progress == null)
                {
                    _.CopyItem(item, player, TRUE);
                    player.SendMessage(_color.Red("That item is not required for this quest."));
                }
                else if (progress.MustBeCraftedByPlayer && crafterPlayerGUID != player.GlobalID)
                {
                    _.CopyItem(item, player, TRUE);
                    player.SendMessage(_color.Red("You may only submit items which you have personally created for this quest."));
                }
                else
                {
                    progress.Remaining--;

                    if (progress.Remaining <= 0)
                    {
                        var progressCopy = progress;
                        progress = _data.Single <PCQuestItemProgress>(x => x.ID == progressCopy.ID);
                        action   = DatabaseActionType.Delete;
                    }
                    _data.SubmitDataChange(progress, action);

                    // Recalc the remaining items needed.
                    int remainingCount = _data.GetAll <PCQuestItemProgress>().Count(x => x.PCQuestStatusID == status.ID);
                    if (remainingCount <= 0)
                    {
                        _quest.AdvanceQuestState(player, owner, questID);
                    }

                    player.SendMessage("You need " + progress.Remaining + " " + item.Name + " for this quest.");
                }
                item.Destroy();

                var questItemProgresses = _data.Where <PCQuestItemProgress>(x => x.PCQuestStatusID == status.ID);
                if (!questItemProgresses.Any())
                {
                    string conversation = _.GetLocalString(owner, "CONVERSATION");
                    if (!string.IsNullOrWhiteSpace(conversation))
                    {
                        _dialog.StartConversation(player, owner, conversation);
                    }
                    else
                    {
                        player.AssignCommand(() =>
                        {
                            _.ActionStartConversation(owner, "", TRUE, FALSE);
                        });
                    }
                }
            }

            return(true);
        }