public static bool Drop(this Item item, IActor giverActor, IActor takerActor, int quantity) { IAvatar taker = takerActor as IAvatar; IAvatar giver = giverActor as IAvatar; IActor container = null; // Ensure a container exists to recevie the item. if (taker != null && taker is Character) { container = (taker as Character).GetFirstAvailableContainer(item); } else { container = takerActor; } if (container == null) { if (taker != null) { taker.Context.Add(new RdlErrorMessage(Resources.InventoryFull)); } else if (giver != null) { giver.Context.Add(new RdlErrorMessage(Resources.CanNotDrop)); } return(false); } // Adjust quantity. if (quantity > item.Quantity()) { quantity = item.Quantity(); } // If the specified item has an IsInventoryItem property value of false then immediately // USE this item and do not add it to the taker's inventory. if (item.IsInventoryItem) { List <Item> items = new List <Item>(); if (item.IsStackable && item.Quantity() > 1 && item.Owner != null) { if (item.Owner is Npc) { for (int i = 0; i < quantity; i++) { items.Add(item.Clone() as Item); } } else { items = item.Owner.Children.Where(c => c is Item && c.GetType() == item.GetType() && c.Name.Equals(item.Name)).Select(c => c as Item).Take(quantity).ToList(); } } else { items.Add(item); } // If the container is an actual Container instance then the container must be able to hold // all of the available items. if (taker is Character) { for (int i = 0; i < items.Count; i++) { container = (taker as Character).GetFirstAvailableContainer(items[i]); if (container == null) // || !((container as Container).GetRemainingSlots(items[i]) >= quantity)) { if (taker != null) { taker.Context.Add(new RdlErrorMessage(Resources.InventoryNotEnoughSpace)); } else if (giver != null) { giver.Context.Add(new RdlErrorMessage(Resources.CanNotDrop)); // Send the item back down to the client. giver.Context.AddRange(item.ToRdl()); } return(false); } } } // Add the items to the container. for (int i = 0; i < items.Count; i++) { Item newItem = items[i]; // If giver is NPC Merchant then clone the templates rather than drop them. if (giver is IMerchant) { newItem = items[i].Clone() as Item; } // Clear the owner and save the object. if (newItem.ID == 0) { newItem.Owner = null; newItem.Save(); } // If taker is a Character then different rules apply to where stuff is dropped. if (taker is Character) { Character character = taker as Character; if (newItem is ISpell) { // Spells.Add will add the item to the child collection. character.Spells.Add((ISpell)newItem); character.Context.AddRange(character.GetRdlProperties(String.Concat(character.Spells.Prefix, character.Spells.Count - 1))); } else if (newItem is Container && character.Bags.Count < 5) { character.Bags.Add((Container)newItem); character.Context.AddRange(character.GetRdlProperties(String.Concat(character.Bags.Prefix, character.Bags.Count - 1))); } else { container = (taker as Character).GetFirstAvailableContainer(newItem); if (container != null) { newItem.Drop(container); } else { taker.Context.Add(new RdlErrorMessage(Resources.InventoryNotEnoughSpace)); } } } else { newItem.Drop(container); } if (taker != null) { taker.Context.Add(new RdlSystemMessage(RdlSystemMessage.PriorityType.Positive, String.Format(Resources.ItemAdded, newItem.AUpper()))); } if (takerActor is Place) { if (giver != null) { giver.Context.Add(new RdlSystemMessage(RdlSystemMessage.PriorityType.None, String.Format(Resources.ItemDropped, newItem.A()))); } } // Send the taker the item and a remove command so the item will be removed from the giver. if (taker != null && giver != null) { taker.Context.Add(newItem.GetRemoveCommand(giver.ID)); } if (taker != null) { taker.Context.AddRange(newItem.ToRdl()); } // Send the giver the item with the new owner and a remove command so the item will be removed. if (giver != null) { giver.Context.Add(newItem.GetRemoveCommand(giver.ID)); } if (giver != null) { giver.Context.AddRange(newItem.ToRdl()); } } } else { for (int i = 0; i < quantity; i++) { // USE the item. giver.SetTarget(taker); if (item is Spell) { // Spells need to be cast by the giver onto the taker. if (taker != null) { item.Use(giver, taker.Context); } } else { // All other items ned to be used by the taker. if (taker != null) { item.Use(taker, taker.Context); } } } } return(true); }