private void HandleChangeAttributes(GameSession session, PacketReader packet) { short lockIndex = -1; long itemUid = packet.ReadLong(); packet.Skip(8); bool useLock = packet.ReadBool(); if (useLock) { packet.Skip(1); lockIndex = packet.ReadShort(); } if (session.Player.Inventory.Items.TryGetValue(itemUid, out Item item)) { item.TimesAttributesChanged++; var newItem = new Item(item); int attributeCount = newItem.Stats.BonusAttributes.Count; var rng = new Random(); for (int i = 0; i < attributeCount; i++) { if (i == lockIndex) { continue; } // TODO: Don't RNG the same attribute twice newItem.Stats.BonusAttributes[i] = ItemStat.Of((ItemAttribute)rng.Next(35), 0.01f); } session.StateStorage[NEW_ITEM_KEY] = newItem; session.Send(ChangeAttributesPacket.PreviewNewItem(newItem)); } }
private void HandleSelectNewAttributes(GameSession session, PacketReader packet) { long itemUid = packet.ReadLong(); if (session.StateStorage.TryGetValue(NEW_ITEM_KEY, out object obj)) { if (obj is not Item item || itemUid != item.Uid) { return; } session.Player.Inventory.Replace(item); session.Send(ChangeAttributesPacket.SelectNewItem(item)); } }
private static void HandleSelectNewAttributes(GameSession session, PacketReader packet) { long itemUid = packet.ReadLong(); Inventory inventory = session.Player.Inventory; Item gear = inventory.TemporaryStorage.FirstOrDefault(x => x.Key == itemUid).Value; if (gear == null) { return; } inventory.TemporaryStorage.Remove(itemUid); inventory.Replace(gear); session.Send(ChangeAttributesPacket.AddNewItem(gear)); }
private static void HandleChangeAttributes(GameSession session, PacketReader packet) { short lockStatId = -1; bool isSpecialStat = false; long itemUid = packet.ReadLong(); packet.Skip(8); bool useLock = packet.ReadBool(); if (useLock) { isSpecialStat = packet.ReadBool(); lockStatId = packet.ReadShort(); } Inventory inventory = session.Player.Inventory; int greenCrystalTotalAmount = 0; int metacellTotalAmount = 0; int crystalFragmentTotalAmount = 0; // There are multiple ids for each type of material List <KeyValuePair <long, Item> > greenCrystals = inventory.Items.Where(x => x.Value.Tag == "GreenCrystal").ToList(); greenCrystals.ForEach(x => greenCrystalTotalAmount += x.Value.Amount); List <KeyValuePair <long, Item> > metacells = inventory.Items.Where(x => x.Value.Tag == "MetaCell").ToList(); metacells.ForEach(x => metacellTotalAmount += x.Value.Amount); List <KeyValuePair <long, Item> > crystalFragments = inventory.Items.Where(x => x.Value.Tag == "CrystalPiece").ToList(); crystalFragments.ForEach(x => crystalFragmentTotalAmount += x.Value.Amount); Item gear = inventory.Items.FirstOrDefault(x => x.Key == itemUid).Value; Item scrollLock = null; // Check if gear exist in inventory if (gear == null) { return; } string tag = ""; if (Item.IsAccessory(gear.ItemSlot)) { tag = "LockItemOptionAccessory"; } else if (Item.IsArmor(gear.ItemSlot)) { tag = "LockItemOptionArmor"; } else if (Item.IsWeapon(gear.ItemSlot)) { tag = "LockItemOptionWeapon"; } else if (Item.IsPet(gear.Id)) { tag = "LockItemOptionPet"; } if (useLock) { scrollLock = inventory.Items.FirstOrDefault(x => x.Value.Tag == tag && x.Value.Rarity == gear.Rarity).Value; // Check if scroll lock exist in inventory if (scrollLock == null) { return; } } int greenCrystalCost = 5; int metacellCosts = Math.Min(11 + gear.TimesAttributesChanged, 25); // Relation between TimesAttributesChanged to amount of crystalFragments for epic gear int[] crystalFragmentsEpicGear = { 200, 250, 312, 390, 488, 610, 762, 953, 1192, 1490, 1718, 2131, 2642, 3277, 4063 }; int crystalFragmentsCosts = crystalFragmentsEpicGear[Math.Min(gear.TimesAttributesChanged, 14)]; if (gear.Rarity > (short)RarityType.Epic) { greenCrystalCost = 25; metacellCosts = Math.Min(165 + gear.TimesAttributesChanged * 15, 375); if (gear.Rarity == (short)RarityType.Legendary) { crystalFragmentsCosts = Math.Min(400 + gear.TimesAttributesChanged * 400, 6000); } else if (gear.Rarity == (short)RarityType.Ascendant) { crystalFragmentsCosts = Math.Min(600 + gear.TimesAttributesChanged * 600, 9000); } } // Check if player has enough materials if (greenCrystalTotalAmount < greenCrystalCost || metacellTotalAmount < metacellCosts || crystalFragmentTotalAmount < crystalFragmentsCosts) { return; } gear.TimesAttributesChanged++; Item newItem = new(gear); // Get random stats except stat that is locked List <ItemStat> randomList = ItemStats.RollBonusStatsWithStatLocked(newItem, lockStatId, isSpecialStat); for (int i = 0; i < newItem.Stats.BonusStats.Count; i++) { // Check if BonusStats[i] is NormalStat and isSpecialStat is false // Check if BonusStats[i] is SpecialStat and isSpecialStat is true switch (newItem.Stats.BonusStats[i]) { case NormalStat when !isSpecialStat: case SpecialStat when isSpecialStat: ItemStat stat = newItem.Stats.BonusStats[i]; switch (stat) { case NormalStat ns when ns.ItemAttribute == (StatId)lockStatId: case SpecialStat ss when ss.ItemAttribute == (SpecialStatId)lockStatId: continue; } break; } newItem.Stats.BonusStats[i] = randomList[i]; } // Consume materials from inventory ConsumeMaterials(session, greenCrystalCost, metacellCosts, crystalFragmentsCosts, greenCrystals, metacells, crystalFragments); if (useLock) { session.Player.Inventory.ConsumeItem(session, scrollLock.Uid, 1); } inventory.TemporaryStorage[newItem.Uid] = newItem; session.Send(ChangeAttributesPacket.PreviewNewItem(newItem)); }
private static void HandleChangeAttributes(GameSession session, PacketReader packet) { short lockStatId = -1; bool isSpecialStat = false; long itemUid = packet.ReadLong(); packet.Skip(8); bool useLock = packet.ReadBool(); if (useLock) { isSpecialStat = packet.ReadBool(); lockStatId = packet.ReadShort(); if (isSpecialStat) { // Match the enum ID for ItemAttribute lockStatId += 11000; } } IInventory inventory = session.Player.Inventory; Item gear = inventory.GetFromInventoryOrEquipped(itemUid); if (gear is null) { return; } Script script = ScriptLoader.GetScript("Functions/calcGetItemRemakeIngredient"); DynValue scriptResults = script.RunFunction("calcGetItemRemakeIngredientNew", (int)gear.Type, gear.TimesAttributesChanged, gear.Rarity, gear.Level); IReadOnlyCollection <Item> ingredient1 = inventory.GetAllByTag(scriptResults.Tuple[0].String); int ingredient1Cost = (int)scriptResults.Tuple[1].Number; IReadOnlyCollection <Item> ingredient2 = inventory.GetAllByTag(scriptResults.Tuple[2].String); int ingredient2Cost = (int)scriptResults.Tuple[3].Number; IReadOnlyCollection <Item> ingredient3 = inventory.GetAllByTag(scriptResults.Tuple[4].String); int ingredient3Cost = (int)scriptResults.Tuple[5].Number; int ingredient1TotalAmount = ingredient1.Sum(x => x.Amount); int ingredient2TotalAmount = ingredient2.Sum(x => x.Amount); int ingredient3TotalAmount = ingredient3.Sum(x => x.Amount); // Check if player has enough materials if (ingredient1TotalAmount < ingredient1Cost || ingredient2TotalAmount < ingredient2Cost || ingredient3TotalAmount < ingredient3Cost) { return; } Item scrollLock = null; string tag = ""; if (Item.IsAccessory(gear.ItemSlot)) { tag = "LockItemOptionAccessory"; } else if (Item.IsArmor(gear.ItemSlot)) { tag = "LockItemOptionArmor"; } else if (Item.IsWeapon(gear.ItemSlot)) { tag = "LockItemOptionWeapon"; } else if (gear.IsPet()) { tag = "LockItemOptionPet"; } if (useLock) { scrollLock = inventory.GetAllByTag(tag) .FirstOrDefault(i => i.Rarity == gear.Rarity); // Check if scroll lock exist in inventory if (scrollLock == null) { return; } } gear.TimesAttributesChanged++; Item newItem = new(gear); // Get random stats except stat that is locked List <ItemStat> randomList = RandomStats.RollBonusStatsWithStatLocked(newItem, lockStatId, isSpecialStat); Dictionary <StatAttribute, ItemStat> newRandoms = new(); for (int i = 0; i < newItem.Stats.Randoms.Count; i++) { ItemStat stat = newItem.Stats.Randoms.ElementAt(i).Value; // Check if BonusStats[i] is BasicStat and isSpecialStat is false // Check if BonusStats[i] is SpecialStat and isSpecialStat is true switch (stat) { case BasicStat when !isSpecialStat: case SpecialStat when isSpecialStat: switch (stat) { case SpecialStat ns when ns.ItemAttribute == (StatAttribute)lockStatId: case SpecialStat ss when ss.ItemAttribute == (StatAttribute)lockStatId: newRandoms[stat.ItemAttribute] = stat; continue; } break; } newRandoms[randomList[i].ItemAttribute] = randomList[i]; } newItem.Stats.Randoms = newRandoms; // Consume materials from inventory ConsumeMaterials(session, ingredient1Cost, ingredient2Cost, ingredient3Cost, ingredient1, ingredient2, ingredient3); if (useLock) { session.Player.Inventory.ConsumeItem(session, scrollLock.Uid, 1); } inventory.TemporaryStorage[newItem.Uid] = newItem; session.Send(ChangeAttributesPacket.PreviewNewItem(newItem)); }