Пример #1
0
            /// <summary>
            /// Collects a <see cref="LootItem"/> from an index and notifies the looters
            /// </summary>
            public void CollectLootItem(int index, Player collector)
            {
                // player trying to loot outside the loot range
                // possible hacking attempt
                if (index >= lootItems.Length)
                {
                    return;
                }
                // if the item is already looted return
                var lootItem = lootItems[index];

                if (lootItem.IsLooted)
                {
                    return;
                }
                // if the gold is 0 or the id is 0
                // its an invalid item or gold, return
                if (lootItem.CountOrGold <= 0)
                {
                    return;
                }
                // remember the gold always sits in the 0th index
                // depending on the index loot gold or item
                if (index == 0)
                {
                    collector.GainGold(lootItem.CountOrGold, true);
                }
                else
                {
                    // add the item to the inventory
                    InventoryOperationResult result;
                    var added = collector.Inventory.AddItem(lootItem.ItemId, (byte)lootItem.CountOrGold, out result);
                    // if it cannot be looted then return
                    if (result == InventoryOperationResult.Fail || result == InventoryOperationResult.NoAdditionDueToSpace)
                    {
                        return;
                    }
                    // if we didnt fully add the item?
                    if (result == InventoryOperationResult.PartialAdditionDueToSpace)
                    {
                        // update the item count
                        lootItems[index] = new LootItem(lootItem.ItemId, (byte)(lootItem.CountOrGold - added));
                        return;
                    }
                }
                // notify the looter that he or she has taken the loot item
                collector.NotifyLootItemTakenFor(lootContainer.owner, index);
                // mark the item looted
                lootItems[index].IsLooted = true;
                // looping thru the items to see whether the player has looted all of his or her items or not
                for (var i = 0; i < lootItems.Length; i++)
                {
                    // if there are items to be looted just return
                    if (!lootItems[i].IsLooted)
                    {
                        return;
                    }
                }
                // inform the collector to clear loot for the owner
                collector.NotifyLootClear(lootContainer.owner);
                // player has looted all the items so just delete the player
                this.lootContainer.RemoveLoot(collector);
            }
Пример #2
0
            /// <summary>
            /// Collects all the loot item and notifies the looter
            /// </summary>
            public void CollectAll(Player collector)
            {
                var collectedCount = 0;

                // adding items as a cluster rather than one by one
                // this will save us the overhead of sending items right after loot
                collector.BeginInventoryClusterAddition();

                var result = InventoryOperationResult.Success;

                for (var i = 0; i < lootItems.Length; i++)
                {
                    var lootItem = lootItems[i];
                    // if its already been looted ?
                    if (lootItem.IsLooted)
                    {
                        continue;
                    }
                    // if the count is 0 there is nothing to loot
                    if (lootItem.CountOrGold <= 0)
                    {
                        continue;
                    }
                    // at index 0 there is always gold
                    if (i == 0)
                    {
                        // loot the gold
                        collector.GainGold(lootItem.CountOrGold, true);
                    }
                    else
                    {
                        // add the item to the inventory
                        var added = collector.Inventory.AddItem(lootItem.ItemId, (byte)lootItem.CountOrGold, out result);
                        // if it cannot be looted then dont do anything
                        if (result == InventoryOperationResult.Fail || result == InventoryOperationResult.NoAdditionDueToSpace)
                        {
                            continue;
                        }
                        // if we didnt fully add the item?
                        if (result == InventoryOperationResult.PartialAdditionDueToSpace)
                        {
                            // update the item count
                            lootItems[i] = new LootItem(lootItem.ItemId, (byte)(lootItem.CountOrGold - added));
                            continue;
                        }
                    }
                    // ok so we added the item completely
                    // then mark it looted
                    lootItems[i].IsLooted = true;
                    collectedCount++;
                }
                // the loot may be empty only if they looted atleast one item
                if (collectedCount > 0)
                {
                    var clearLoot = true;
                    // looping thru the items to see whether the player has looted all of his or her items or not
                    for (var i = 0; i < lootItems.Length; i++)
                    {
                        // if the item is looted, continue to the next item
                        if (lootItems[i].IsLooted)
                        {
                            continue;
                        }
                        // making sure we dont clear all loot
                        clearLoot = false;
                        break;
                    }
                    // if we can clear all loot then, well, clear
                    if (clearLoot)
                    {
                        // inform the collector to clear loot for the owner
                        collector.NotifyLootClear(lootContainer.owner);
                        // player has looted all the items so just delete the player
                        this.lootContainer.RemoveLoot(collector);
                    }
                }

                if (result != InventoryOperationResult.Success)
                {
                    // we didnt loot all items on a CollectAll call
                    // so report appropriate error
                    // TODO: Report appropriate error
#if MMO_DEBUG
                    Utils.Logger.InfoFormat("Loot.CollectAll({0}). {1}.", collector.Name, result);
#endif
                }
                //sending the cluster if there are any items added to it
                collector.EndInventoryClusterAddition();
            }
Пример #3
0
        /// <summary>
        /// Generates loot items
        /// </summary>
        static LootItem[] GenerateLoot(short lootGroupId)
        {
            LootGroupData lootGroupData;

            if (!MmoWorld.Instance.ItemCache.TryGetLootGroupData(lootGroupId, out lootGroupData))
            {
                // cannot find loot group. write to logger
                Utils.Logger.ErrorFormat("[GenerateLoot]: LootGroup (Id={0}) cannot be found", lootGroupId);
                return(null);
            }

            LootItem[] generatedLootItems = null;
            var        possibleLootItems  = lootGroupData.LootItems;
            // choose the lowest possible + 1 (for money)
            var maxLootSize = 1 + Mathf.Min(possibleLootItems.Length, ServerGameSettings.MAX_ITEMS_PER_LOOT);
            var addedCount  = 0;

            // only generate gold if the chance is greater than 0
            if (lootGroupData.GoldChance > 0)
            {
                // generating a chance
                var chance = (float)Utils.Rnd.NextDouble() * 100;
                if (chance <= lootGroupData.GoldChance)
                {
                    // randomly choose between min and max gold
                    // remember to do this before generating any items
                    // because the gold will always be at index 1 whether its generated or not
                    var gold = Utils.Rnd.Next(lootGroupData.MinGold, lootGroupData.MaxGold);
                    if (gold > 0)
                    {
                        // only create the array if we have atleast one loot item
                        generatedLootItems = new LootItem[maxLootSize];
                        // adding the gold item
                        generatedLootItems[addedCount++ /* 0 */] = new LootItem(gold);
                    }
                }
            }

            for (var i = 0; i < possibleLootItems.Length && addedCount < maxLootSize; i++)
            {
                var lootItem = possibleLootItems[i];
                // if the drop chance is invalid skip the item
                if (lootItem.DropChance <= 0)
                {
                    continue;
                }
                // generating a chance
                var chance = (float)Utils.Rnd.NextDouble() * 100;
                // skip if the chance is greater
                if (chance > lootItem.DropChance)
                {
                    continue;
                }
                // if the loot array hasnt been created yet create it
                if (generatedLootItems == null)
                {
                    // only create the array if we have atleast one loot item
                    generatedLootItems = new LootItem[maxLootSize];
                    // if we havent already created the loot array
                    // the first spot wont be there but we need it to contain gold spot whether its generated or not
                    // setting it to 0 and marking it looted will let the loot skip it
                    generatedLootItems[addedCount++ /* 0 */] = new LootItem(0)
                    {
                        IsLooted = true
                    };
                }

                // adding the actual loot item
                generatedLootItems[addedCount++] = new LootItem(lootItem);
            }

            // we added atleast one item ?
            if (addedCount > 0 && generatedLootItems != null)
            {
                // resizes the array to total items size
                // this way we can eliminate empty slots and save overhead of sending the whole array to the client
                if (addedCount < generatedLootItems.Length)
                {
                    Array.Resize(ref generatedLootItems, addedCount);
                }

                // set the loot
                return(generatedLootItems);
            }
            // return an empty loot container if they are no loot generated
            return(new LootItem[0]);
        }