コード例 #1
0
ファイル: CommandHelper.cs プロジェクト: lionsguard/perenthia
        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);
        }