Пример #1
0
        public ItemEnchantmentResult EnchantItem(
            System.Guid sessionId,
            DataModels.ClanSkill clanSkill,
            Character character,
            PlayerInventory inventory,
            ReadOnlyInventoryItem item,
            DataModels.Resources resources)
        {
            var user = gameData.GetUser(character.UserId);

            var invItem = inventory.Get(item);

            if (invItem == null)
            {
                // No such item in our inventory
                return(ItemEnchantmentResult.Error());
            }

            var i           = item.Item;
            var enchantable =
                // i.Type == (int)DataModels.ItemCategory.Pet || // in the future. :)
                i.Category == (int)DataModels.ItemCategory.Weapon ||
                i.Category == (int)DataModels.ItemCategory.Armor ||
                i.Category == (int)DataModels.ItemCategory.Ring ||
                i.Category == (int)DataModels.ItemCategory.Amulet;

            if (!enchantable)
            {
                return(ItemEnchantmentResult.NotEnchantable);
            }

            var characterSessionState = gameData.GetCharacterSessionState(sessionId, character.Id);

            if (characterSessionState.EnchantmentCooldown > DateTime.MinValue && characterSessionState.EnchantmentCooldown > DateTime.UtcNow)
            {
                return(ItemEnchantmentResult.NotReady(characterSessionState.EnchantmentCooldown));
            }

            try
            {
                //item = inventory.RemoveAttributes(item);

                var itemLvReq = (i.RequiredAttackLevel + i.RequiredDefenseLevel + i.RequiredMagicLevel + i.RequiredRangedLevel + i.RequiredSlayerLevel);
                var isStack   = item.Amount > 1;

                var itemPercent          = itemLvReq / (float)GameMath.MaxLevel;
                var itemMaxAttrCount     = Math.Max(1, (int)Math.Floor(Math.Floor(itemLvReq / 10f) / 5));
                var success              = clanSkill.Level / (float)itemLvReq;
                var targetAttributeCount = 0;
                var rng = random.NextDouble();
                if (rng <= success)
                {
                    targetAttributeCount = Math.Max(1, itemMaxAttrCount);
                }
                else if (rng <= success * 1.33f)
                {
                    targetAttributeCount = Math.Max(1, (int)Math.Floor(itemMaxAttrCount * 0.5f));
                }
                else if (rng <= success * 2f)
                {
                    targetAttributeCount = Math.Max(1, (int)Math.Floor(itemMaxAttrCount * 0.33f));
                }
                else if (rng >= 0.75f)
                {
                    targetAttributeCount = 1;
                }

                var maxEnchantments = (int)Math.Floor(Math.Max(MaximumEnchantmentCount, Math.Floor((float)clanSkill.Level / 3f)));

                targetAttributeCount = Math.Max(0, Math.Min(maxEnchantments, targetAttributeCount));

                if (targetAttributeCount == 0)
                {
                    characterSessionState.EnchantmentCooldown = GetCooldown(user, success, 0.1d);
                    return(ItemEnchantmentResult.Failed(characterSessionState.EnchantmentCooldown));
                }

                DataModels.InventoryItem enchantedItem = null;
                if (isStack)
                {
                    inventory.RemoveItem(item, 1);
                    enchantedItem = inventory.AddItemStack(item, 1);
                }
                else
                {
                    enchantedItem = invItem;
                }

                enchantedItem.Soulbound   = true;
                enchantedItem.Enchantment = FormatEnchantment(inventory.CreateRandomAttributes(enchantedItem, targetAttributeCount));

                var itemName = gameData.GetItem(item.ItemId)?.Name;

                // Really stupid naming right now.
                enchantedItem.Name = "Enchanted " + itemName;

                var multiplier = gameData.GetActiveExpMultiplierEvent()?.Multiplier ?? 1d;
                var gainedExp  = GameMath.GetEnchantingExperience(clanSkill.Level, targetAttributeCount, itemLvReq) * multiplier;

                // 1. Add exp whenever user successefully enchants an item

                clanSkill.Experience += gainedExp;

                var gainedLevels = 0;
                var nextLevel    = GameMath.ExperienceForLevel(clanSkill.Level + 1);
                while (gainedExp >= nextLevel)
                {
                    gainedExp      -= nextLevel;
                    nextLevel       = GameMath.ExperienceForLevel(clanSkill.Level + 1);
                    clanSkill.Level = clanSkill.Level + 1;
                    ++gainedLevels;
                }

                // TODO: 2. Send exp update to clients where players in same clan is regarding current state of the clan skill

                // Set a time limit on how often/frequently a player can use enchanting after they have enchanted an item.
                // Success: add n Hours based on what type of item
                // Fail: Add 10% of n Hours based on what type of item

                characterSessionState.EnchantmentCooldown = GetCooldown(user, success);

                return(new ItemEnchantmentResult()
                {
                    GainedExperience = gainedExp,
                    GainedLevels = gainedLevels,
                    EnchantedItem = DataMapper.Map <Models.InventoryItem, DataModels.InventoryItem>(enchantedItem),
                    OldItemStack = DataMapper.Map <Models.InventoryItem, DataModels.InventoryItem>(invItem),
                    Result = ItemEnchantmentResultValue.Success,
                    Cooldown = characterSessionState.EnchantmentCooldown
                });
            }
            finally
            {
                characterSessionState.LastEnchantmentTryAt = DateTime.UtcNow;
            }
        }