private static void HandleUpdateCatalysts(GameSession session, PacketReader packet) { long itemUid = packet.ReadLong(); bool addCatalyst = packet.ReadBool(); if (!session.Player.Inventory.HasItem(itemUid) && !session.Player.Inventory.ItemIsEquipped(itemUid)) { return; } ItemEnchant itemEnchant = session.Player.ItemEnchant; if (itemEnchant is null) { return; } if (!itemEnchant.UpdateAdditionalCatalysts(itemUid, addCatalyst)) { EnchantHelper.ExcessCatalystError(session, itemEnchant); return; } session.Send(ItemEnchantPacket.UpdateCharges(itemEnchant)); }
private static void SetEnchantStats(GameSession session, ItemEnchant itemEnchantStats, Item item) { Dictionary <StatAttribute, ItemStat> statDiff = GetEnchantStatDiff(item.Stats.Enchants, itemEnchantStats.Stats); foreach (ItemStat stat in itemEnchantStats.Stats.Values) { if (!item.Stats.Enchants.ContainsKey(stat.ItemAttribute)) { item.Stats.Enchants[stat.ItemAttribute] = new BasicStat(stat.ItemAttribute, stat.Rate, StatAttributeType.Rate); continue; } item.Stats.Enchants[stat.ItemAttribute].Flat = stat.Flat; item.Stats.Enchants[stat.ItemAttribute].Rate = stat.Rate; } item.EnchantLevel++; item.EnchantExp = 0; item.Charges -= itemEnchantStats.Rates.ChargesAdded; if (item.EnchantLevel > 11) { string message = $"3,{item.Uid},{ChatLinkType.Enchant},{session.Player.Name}"; //unk what 3 is MapleServer.BroadcastPacketAll(ItemLinkPacket.SendLinkItem(new() { item })); MapleServer.BroadcastPacketAll(ChatPacket.Send(session.Player, message, ChatType.ItemEnchant)); } session.Send(ItemEnchantPacket.EnchantSuccess(item, statDiff.Values.ToList())); //TODO: If item is equipped, update stats }
public static void ExcessCatalystError(GameSession session, ItemEnchant itemEnchant) { int npcId = itemEnchant.Type switch { EnchantType.Ophelia => 11000508, _ => 11000510 }; ScriptMetadata scriptMetadata = ScriptMetadataStorage.GetNpcScriptMetadata(npcId); NpcScript npcScript = scriptMetadata?.NpcScripts.FirstOrDefault(x => x.Id == 31); if (npcScript is null) { return; } Script script = ScriptLoader.GetScript($"Npcs/{npcId}", session); DynValue excessCatalystFunction = script.RunFunction("getExcessCatalystEventId"); if (excessCatalystFunction is null) { return; } int eventId = (int)excessCatalystFunction.Number; if (eventId == 0) { return; } HandleNpcTalkEventType(session, npcScript, eventId); }
public static void TalkError(GameSession session, ItemEnchant itemEnchant) { int npcId = itemEnchant.Type switch { EnchantType.Ophelia => 11000508, _ => 11000510 }; ScriptMetadata scriptMetadata = ScriptMetadataStorage.GetNpcScriptMetadata(npcId); NpcScript npcScript = scriptMetadata?.NpcScripts.FirstOrDefault(x => x.Id == 31); if (npcScript is null) { return; } Script script = ScriptLoader.GetScript($"Npcs/{npcId}", session); int eventId = (int)script.RunFunction("getProcessEventId", PlayerHasIngredients(itemEnchant, session.Player.Inventory), PlayerHasRequiredCatalysts(itemEnchant)).Number; if (eventId == 0) { return; } HandleNpcTalkEventType(session, npcScript, eventId); }
private static void HandlePeachyEnchant(GameSession session, PacketReader packet) { long itemUid = packet.ReadLong(); IInventory inventory = session.Player.Inventory; Item item = inventory.GetFromInventoryOrEquipped(itemUid); if (item is null) { return; } ItemEnchant itemEnchantStats = session.Player.ItemEnchant; if (itemEnchantStats.Level != item.EnchantLevel && itemEnchantStats.ItemUid != item.Uid) { itemEnchantStats = GetEnchantInfo(item, EnchantType.Peachy); } // Check if player has enough ingredients if (!EnchantHelper.PlayerHasIngredients(itemEnchantStats, inventory) || !EnchantHelper.PlayerHasRequiredCatalysts(itemEnchantStats)) { session.Send(ItemEnchantPacket.Notice((short)ItemEnchantError.NotEnoughMaterials)); EnchantHelper.TalkError(session, itemEnchantStats); return; } foreach (EnchantIngredient ingredient in itemEnchantStats.Ingredients) { inventory.ConsumeByTag(session, ingredient.Tag.ToString(), ingredient.Amount); } foreach (long catalystUids in itemEnchantStats.CatalystItemUids) { inventory.ConsumeItem(session, catalystUids, 1); } int neededEnchants = GetNeededEnchantExp(item.EnchantLevel); int expGained = (int)Math.Ceiling((double)(10000 / neededEnchants)); item.EnchantExp += expGained; if (item.EnchantExp >= 10000) { item.EnchantExp = 0; SetEnchantStats(session, itemEnchantStats, item); } itemEnchantStats.Success = true; itemEnchantStats.Level++; itemEnchantStats.CatalystItemUids.Clear(); session.Send(ItemEnchantPacket.UpdateExp(item)); }
private static void HandleOpheliaEnchant(GameSession session, PacketReader packet) { long itemUid = packet.ReadLong(); IInventory inventory = session.Player.Inventory; Item item = inventory.GetFromInventoryOrEquipped(itemUid); if (item is null) { return; } ItemEnchant itemEnchantStats = session.Player.ItemEnchant; if (itemEnchantStats.Level != item.EnchantLevel && itemEnchantStats.ItemUid != item.Uid) { itemEnchantStats = GetEnchantInfo(item, EnchantType.Ophelia); } // Check if player has enough ingredients if (!EnchantHelper.PlayerHasIngredients(itemEnchantStats, inventory) || !EnchantHelper.PlayerHasRequiredCatalysts(itemEnchantStats)) { session.Send(ItemEnchantPacket.Notice((short)ItemEnchantError.NotEnoughMaterials)); EnchantHelper.TalkError(session, itemEnchantStats); return; } foreach (EnchantIngredient ingredient in itemEnchantStats.Ingredients) { inventory.ConsumeByTag(session, ingredient.Tag.ToString(), ingredient.Amount); } foreach (long catalystUids in itemEnchantStats.CatalystItemUids) { inventory.ConsumeItem(session, catalystUids, 1); } Random random = Random.Shared; double randomResult = random.NextDouble(); if (itemEnchantStats.Rates.TotalSuccessRate() < (float)(randomResult * 100)) { FailEnchant(session, itemEnchantStats, item); itemEnchantStats.Success = false; return; } // Enchant success itemEnchantStats.Success = true; itemEnchantStats.Level++; SetEnchantStats(session, itemEnchantStats, item); }
public static PacketWriter EnchantFail(Item item, ItemEnchant enchantInfo) { PacketWriter pWriter = PacketWriter.Of(SendOp.ItemEnchant); pWriter.Write(ItemEnchantPacketMode.EnchantFail); pWriter.WriteLong(item.Uid); pWriter.WriteItem(item); pWriter.WriteInt(); pWriter.WriteInt(); pWriter.WriteLong(); pWriter.WriteInt(enchantInfo.PityCharges); return(pWriter); }
public static bool PlayerHasIngredients(ItemEnchant itemEnchantStats, IInventory inventory) { foreach (EnchantIngredient ingredient in itemEnchantStats.Ingredients) { IReadOnlyCollection <Item> ingredientTotal = inventory.GetAllByTag(ingredient.Tag.ToString()); if (ingredientTotal.Sum(x => x.Amount) < ingredient.Amount) { return(false); } } return(true); }
public static PacketWriter UpdateCharges(ItemEnchant itemEnchant) { PacketWriter pWriter = PacketWriter.Of(SendOp.ItemEnchant); pWriter.Write(ItemEnchantPacketMode.UpdateCharges); pWriter.WriteInt(itemEnchant.Rates.ChargesAdded); pWriter.WriteInt(itemEnchant.CatalystItemUids.Count); pWriter.WriteInt(itemEnchant.CatalystItemUids.Count); foreach (long uid in itemEnchant.CatalystItemUids) { pWriter.WriteLong(uid); } WriteEnchantRates(pWriter, itemEnchant.Rates); return(pWriter); }
private static void HandleUpdateCharges(GameSession session, PacketReader packet) { int chargeCount = packet.ReadInt(); ItemEnchant itemEnchant = session.Player.ItemEnchant; Player player = session.Player; Item item = player.Inventory.GetFromInventoryOrEquipped(itemEnchant.ItemUid); if (item == null || item.Charges < chargeCount) { return; } player.ItemEnchant.UpdateCharges(chargeCount); session.Send(ItemEnchantPacket.UpdateCharges(session.Player.ItemEnchant)); }
public static PacketWriter BeginEnchant(EnchantType type, Item item, ItemEnchant enchantInfo, Dictionary <StatAttribute, ItemStat> stats) { PacketWriter pWriter = PacketWriter.Of(SendOp.ItemEnchant); pWriter.Write(ItemEnchantPacketMode.BeginEnchant); pWriter.Write(type); pWriter.WriteLong(item.Uid); pWriter.WriteByte((byte)enchantInfo.Ingredients.Count); foreach (EnchantIngredient ingredient in enchantInfo.Ingredients) { pWriter.WriteInt(); pWriter.Write(ingredient.Tag); pWriter.WriteInt(ingredient.Amount); } pWriter.WriteShort(); pWriter.WriteInt(enchantInfo.Stats.Count); foreach (ItemStat stat in stats.Values) { pWriter.Write(stat.ItemAttribute); pWriter.WriteInt(stat.Flat); pWriter.WriteFloat(stat.Rate); } if (type is EnchantType.Ophelia) { WriteEnchantRates(pWriter, enchantInfo.Rates); pWriter.WriteLong(); pWriter.WriteLong(); pWriter.WriteByte(1); } // Item copies required if (type is EnchantType.Ophelia or EnchantType.Peachy) { pWriter.WriteInt(enchantInfo.CatalystAmountRequired > 0 ? item.Id : 0); pWriter.WriteShort((short)(enchantInfo.CatalystAmountRequired > 0 ? item.Rarity : 0)); pWriter.WriteInt(enchantInfo.CatalystAmountRequired > 0 ? item.Amount : 0); } return(pWriter); }
private static void FailEnchant(GameSession session, ItemEnchant itemEnchantStats, Item item) { item.Charges -= itemEnchantStats.Rates.ChargesAdded; item.Charges += itemEnchantStats.PityCharges; session.Send(ItemEnchantPacket.EnchantFail(item, itemEnchantStats)); }
public static bool PlayerHasRequiredCatalysts(ItemEnchant itemEnchantStats) { return(itemEnchantStats.CatalystAmountRequired <= itemEnchantStats.CatalystItemUids.Count); }