public void LoadFromFile(string root) { skills = AllMappings.Select(pair => pair.Value).ToList(); using (FileStream stream = new FileStream(Path.Combine(root, @".\data\modifier_map.xml"), FileMode.Open, FileAccess.Read)) { using (XmlReader xr = XmlReader.Create(stream)) { XmlSerializer ser = new XmlSerializer(typeof(SkillMap)); SkillMap map = (SkillMap)ser.Deserialize(xr); this.skills = map.skills; foreach (var skill in this.skills) { if (this.AllMappings.ContainsKey(skill.from)) { continue; } this.AllMappings.Add(skill.from, skill); } } } }
public List<Modifier> GetModifiers(SkillMap map) { List<Modifier> list = new List<Modifier>(); SkillMapEntry entry = null; if (this.hit_accuracy > 0) { entry = map.AllMappings["hit_accuracy"]; list.Add(GetModifier(entry, this.hit_accuracy)); } if (this.magical_hit_accuracy > 0) { entry = map.AllMappings["magical_hit_accuracy"]; list.Add(GetModifier(entry, this.magical_hit_accuracy)); } if (this.magical_skill_boost > 0) { entry = map.AllMappings["magical_skill_boost"]; list.Add(GetModifier(entry, this.magical_skill_boost)); } if (this.parry > 0) { entry = map.AllMappings["parry"]; list.Add(GetModifier(entry, this.parry)); } if (this.dodge > 0) { entry = map.AllMappings["dodge"]; list.Add(GetModifier(entry, this.dodge)); } if (this.block > 0) { entry = map.AllMappings["block"]; list.Add(GetModifier(entry, this.block)); } if (this.critical > 0) { entry = map.AllMappings["critical"]; list.Add(GetModifier(entry, this.critical)); } if (this.min_damage > 0) { entry = map.AllMappings["min_damage"]; list.Add(GetModifier(entry, this.min_damage)); } if (this.max_damage > 0) { entry = map.AllMappings["max_damage"]; list.Add(GetModifier(entry, this.max_damage)); } if (this.damage_reduce > 0) { entry = map.AllMappings["damage_reduce"]; list.Add(GetModifier(entry, this.damage_reduce)); } if (this.magical_resist > 0) { entry = map.AllMappings["magical_resist"]; list.Add(GetModifier(entry, this.magical_resist)); } if (this.physical_defend > 0) { entry = map.AllMappings["physical_defend"]; list.Add(GetModifier(entry, this.physical_defend)); } if (!String.IsNullOrEmpty(this.stat_enchant_type) && this.stat_enchant_value > 0) { entry = map.AllMappings[this.stat_enchant_type]; Modifier modifier = GetModifier(entry, this.stat_enchant_value); modifier.bonus = true; list.Add(modifier); } var utility = Utility<Item>.Instance; List<string> bonusAttrs = new List<string>(); utility.Export(this, "bonus_attr", bonusAttrs); var clientBonuses = from bonus in bonusAttrs where bonus.Length > 1 let name = Utility.GetAttributeName(bonus) let value = Utility.GetAttributeValue(bonus) select new { Name = name, Value = value }; foreach (var bonus in clientBonuses) { string name = bonus.Name.ToLower(); if (!map.AllMappings.ContainsKey(name)) { Debug.Print("Missing bonus attribute mapping: {0}", name); continue; } entry = map.AllMappings[name]; Modifier modifier = GetModifier(entry, bonus.Value); modifier.bonus = true; list.Add(modifier); } // zp add charge modifiers a List<string> bonusAttrsChargeA = new List<string>(); utility.Export(this, "bonus_attr_a", bonusAttrsChargeA); var clientBonusesChargeA = from bonus in bonusAttrsChargeA where bonus.Length > 1 let name = Utility.GetAttributeName(bonus) let value = Utility.GetAttributeValue(bonus) select new { Name = name, Value = value }; foreach (var bonus in clientBonusesChargeA) { string name = bonus.Name.ToLower(); if (!map.AllMappings.ContainsKey(name)) { Debug.Print("Missing bonus attribute mapping: {0}", name); continue; } entry = map.AllMappings[name]; Modifier modifier = GetModifier(entry, bonus.Value); modifier.bonus = true; modifier.conditions = new ModifierConditions(); modifier.conditions.charge = new Charge(); modifier.conditions.charge.level = 1; list.Add(modifier); } // zp add charge modifiers b List<string> bonusAttrsChargeB = new List<string>(); utility.Export(this, "bonus_attr_b", bonusAttrsChargeB); var clientBonusesChargeB = from bonus in bonusAttrsChargeB where bonus.Length > 1 let name = Utility.GetAttributeName(bonus) let value = Utility.GetAttributeValue(bonus) select new { Name = name, Value = value }; foreach (var bonus in clientBonusesChargeB) { string name = bonus.Name.ToLower(); if (!map.AllMappings.ContainsKey(name)) { Debug.Print("Missing bonus attribute mapping: {0}", name); continue; } entry = map.AllMappings[name]; Modifier modifier = GetModifier(entry, bonus.Value); modifier.bonus = true; modifier.conditions = new ModifierConditions(); modifier.conditions.charge = new Charge(); modifier.conditions.charge.level = 2; list.Add(modifier); } if (this.attack_delay > 0) { entry = map.AllMappings["attack_delay"]; list.Add(GetModifier(entry, this.attack_delay)); } if (this.attack_range > 0) { entry = map.AllMappings["attack_range"]; list.Add(GetModifier(entry, (int)(this.attack_range * 1000))); } if (this.hit_count > 0) { entry = map.AllMappings["hit_count"]; list.Add(GetModifier(entry, this.hit_count)); } if (this.min_damage > 0 || this.max_damage > 0) { var meanMod = new MeanModifier(this.min_damage, this.max_damage); meanMod.name = modifiersenum.PHYSICAL_ATTACK; list.Add(meanMod); } if (list.Count == 0) return null; return list; }
public List<Modifier> GetChargeModifiersB(SkillMap map) { List<Modifier> list = new List<Modifier>(); SkillMapEntry entry = null; var utility = Utility<Item>.Instance; List<string> bonusAttrs = new List<string>(); utility.Export(this, "bonus_attr_b", bonusAttrs); var clientBonuses = from bonus in bonusAttrs let name = Utility.GetAttributeName(bonus) let value = Utility.GetAttributeValue(bonus) select new { Name = name, Value = value }; foreach (var bonus in clientBonuses) { string name = bonus.Name.ToLower(); if (!map.AllMappings.ContainsKey(name)) { Debug.Print("Missing charge bonus attribute mapping: {0}", name); continue; } entry = map.AllMappings[name]; Modifier modifier = GetModifier(entry, bonus.Value); modifier.bonus = true; list.Add(modifier); } if (list.Count == 0) return null; return list; }
static void Main(string[] args) { Utility.WriteExeDetails(); Console.WriteLine("Loading strings..."); Utility.LoadStrings(root); Console.WriteLine("Loading items..."); Utility.LoadItems(root); Console.WriteLine("Loading NPCs..."); Utility.LoadClientNpcs(root); Console.WriteLine("Loading client trade lists..."); Utility.LoadNpcGoodLists(root); Console.WriteLine("Loading quests..."); Utility.LoadQuestFile(root); Console.WriteLine("Loading NPC dialogs..."); Utility.LoadHtmlDialogs(root); string outputPath = Path.Combine(root, @".\output"); if (!Directory.Exists(outputPath)) Directory.CreateDirectory(outputPath); //var outputFile = new TradeListFile(); var settings = new XmlWriterSettings() { CheckCharacters = false, CloseOutput = false, Indent = true, IndentChars = "\t", NewLineChars = "\n", Encoding = new UTF8Encoding(false) }; string[] armorMat = { "pl", "ch", "lt", "rb" }; string[] weapons = { "orb", "dagger", "mace", "sword", "staff", "book", "2hsword", "polearm", "bow", "t_orb", "t_dagger", "t_mace", "t_sword", "t_staff", "t_book", "t_2hsword", "t_polearm", "bow" }; var disasmItems = Utility.ItemIndex.ItemList.Where(i => i.disassembly_item.HasValue && i.disassembly_item.Value && i.Category != ItemCategories.harvest); var metals = Utility.ItemIndex.ItemList.Where(i => i.Category == ItemCategories.harvest && i.Quality == ItemQualities.common && (i.name.StartsWith("metal") || i.name.StartsWith("noblemetal"))); var jewels = Utility.ItemIndex.ItemList.Where(i => i.Category == ItemCategories.harvest && i.Quality == ItemQualities.rare && i.quest == 0 && i.name.StartsWith("jewelry")); var enchants = Utility.ItemIndex.ItemList.Where(i => i.package_permitted > 0 && i.name.StartsWith("matter_enchant")); var aethers = Utility.ItemIndex.ItemList.Where(i => i.Category == ItemCategories.harvest && !i.disassembly_item.Value && i.name.StartsWith("od_")); var balaurs = Utility.ItemIndex.ItemList.Where(i => i.Quality == ItemQualities.rare && i.name.StartsWith("dr_material")); var petals = Utility.ItemIndex.ItemList.Where(i => i.Quality == ItemQualities.rare && i.name.StartsWith("harvest_dye")); var gatherables = Utility.ItemIndex.ItemList.Where(i => i.Category == ItemCategories.harvest && i.quest == 0); // don't know actually var accessoir = Utility.ItemIndex.ItemList.Where(i => i.name.StartsWith("ac_head") /*&& i.name.Contains("_p_")*/); SkillMap skillMap = new SkillMap(); skillMap.LoadFromFile(root); WrappedItemsFile wrappedItemFile = new WrappedItemsFile(); List<WrapperItem> wrappers = new List<WrapperItem>(); foreach (var item in disasmItems) { if (item.desc != null) { var wrapper = new WrapperItem(); wrapper.id = item.id; wrapper.description = item.Description; string[] nameParts = item.name.Split('_'); string last = nameParts[nameParts.Length - 1]; if (Char.IsDigit(last[0]) && last.EndsWith("day")) { string itemName = String.Join("_", nameParts, 1, nameParts.Length - 1); Item wrappedItem = Utility.ItemIndex.GetItem(itemName); if (wrappedItem == null) { var matched = Utility.ItemIndex.GetItemsByDescription("str_" + itemName); if (matched.Count() > 1 || matched.Count() == 0) Debug.Print("Wrapped item not found for: {0}", item.name); else wrappedItem = matched.First(); } if (wrappedItem != null) { wrapper.item = new WrappedItem[1]; var wi = new WrappedItem(); wi.id = wrappedItem.id; wi.min = wi.max = 1; wi.description = wrappedItem.Description; wrapper.item[0] = wi; } } else if (nameParts.Contains("copper")) { wrapper.item = new WrappedItem[1]; var wi = new WrappedItem(); wi.id = nameParts.Contains("l") ? 186000002 : 186000007; wi.min = wi.max = 1; wrapper.item[0] = wi; } else if (nameParts.Contains("silver")) { wrapper.item = new WrappedItem[1]; var wi = new WrappedItem(); wi.id = nameParts.Contains("l") ? 186000003 : 186000008; wi.min = wi.max = 1; wrapper.item[0] = wi; } else if (nameParts.Contains("gold")) { wrapper.item = new WrappedItem[1]; var wi = new WrappedItem(); wi.id = nameParts.Contains("l") ? 186000004 : 186000009; wi.min = wi.max = 1; wrapper.item[0] = wi; } else if (nameParts.Contains("platinum")) { wrapper.item = new WrappedItem[1]; var wi = new WrappedItem(); wi.id = nameParts.Contains("l") ? 186000005 : 186000010; wi.min = wi.max = 1; wrapper.item[0] = wi; } else if (nameParts.Contains("mithril") || nameParts.Contains("medal") && nameParts.Contains("Quest")) { wrapper.item = new WrappedItem[1]; var wi = new WrappedItem(); wi.id = nameParts.Contains("l", StringComparer.InvariantCultureIgnoreCase) ? 186000018 : 186000019; wi.min = wi.max = 1; wrapper.item[0] = wi; } else if (nameParts.Contains("torso") || nameParts.Contains("pants")) { string itemName = String.Join("_", nameParts, 1, nameParts.Length - 1); List<WrappedItem> armor = new List<WrappedItem>(); for (int i = 0; i < 4; i++) { string name = armorMat[i] + "_" + itemName; Item wrappedItem = Utility.ItemIndex.GetItem(name); if (wrappedItem == null) { name = "str_" + armorMat[i] + "_" + itemName; var matched = Utility.ItemIndex.GetItemsByDescription(name); if (matched.Count() > 1 || matched.Count() == 0) Debug.Print("Wrapped item not found for: {0}", name); else wrappedItem = matched.First(); } if (wrappedItem != null) { var wi = new WrappedItem(); wi.id = wrappedItem.id; wi.min = 0; wi.max = 1; wi.description = wrappedItem.Description; armor.Add(wi); } } wrapper.count = 1; wrapper.item = armor.ToArray(); } else if (nameParts[0] != "material" && nameParts.Contains("weapon")) { string itemName = String.Join("_", nameParts, 2, nameParts.Length - 2); List<WrappedItem> weaps = new List<WrappedItem>(); for (int i = 0; i < 18; i++) { string name = weapons[i] + "_" + itemName; Item wrappedItem = Utility.ItemIndex.GetItem(name); if (wrappedItem == null) { name = "str_" + weapons[i] + "_" + itemName; var matched = Utility.ItemIndex.GetItemsByDescription(name); if (matched.Count() > 1 || matched.Count() == 0) Debug.Print("Wrapped item not found for: {0}", name); else wrappedItem = matched.First(); } if (wrappedItem != null) { var wi = new WrappedItem(); wi.id = wrappedItem.id; wi.min = 0; wi.max = 1; wi.description = wrappedItem.Description; weaps.Add(wi); } } wrapper.item = weaps.ToArray(); wrapper.count = 1; } else if (nameParts.Contains("metal")) { string itemName = String.Join("_", nameParts, 1, nameParts.Length - 1); string levelSuffix = nameParts.Last(); levelSuffix = levelSuffix.Substring(0, levelSuffix.Length - 1); int level = Int32.Parse(levelSuffix) * 10; var rewards = metals.Where(m => m.level == level); List<WrappedItem> items = new List<WrappedItem>(); foreach (var metal in rewards) { var wi = new WrappedItem(); wi.id = metal.id; wi.min = 1; wi.max = 5; wi.description = metal.Description; items.Add(wi); } wrapper.count = 1; wrapper.item = items.ToArray(); } else if (nameParts.Contains("jewelry")) { string itemName = String.Join("_", nameParts, 1, nameParts.Length - 1); string levelSuffix = nameParts.Last(); levelSuffix = levelSuffix.Substring(0, levelSuffix.Length - 1); int level = Int32.Parse(levelSuffix) * 10; var rewards = jewels.Where(m => m.level == level); List<WrappedItem> items = new List<WrappedItem>(); foreach (var jewel in rewards) { var wi = new WrappedItem(); wi.id = jewel.id; wi.min = 1; wi.max = 5; wi.description = jewel.Description; items.Add(wi); } wrapper.count = 1; wrapper.item = items.ToArray(); } else if (nameParts.Contains("od") || nameParts.Contains("od02") || nameParts.Contains("od03") || nameParts.Contains("od04")) { string itemName = String.Join("_", nameParts, 1, nameParts.Length - 1); string levelSuffix = nameParts.Last(); levelSuffix = levelSuffix.Substring(0, levelSuffix.Length - 1); int level = Int32.Parse(levelSuffix) * 10; var rewards = aethers.Where(m => m.level == level); List<WrappedItem> items = new List<WrappedItem>(); foreach (var aether in rewards) { var wi = new WrappedItem(); wi.id = aether.id; wi.min = 1; wi.max = 5; wi.description = aether.Description; items.Add(wi); } wrapper.count = 1; wrapper.item = items.ToArray(); } else if (nameParts.Contains("dr") && (nameParts.Contains("material") || nameParts.Contains("material02") || nameParts.Contains("material03") || nameParts.Contains("material04"))) { string itemName = String.Join("_", nameParts, 1, nameParts.Length - 1); string levelSuffix = nameParts.Last(); levelSuffix = levelSuffix.Substring(0, levelSuffix.Length - 1); int level = Int32.Parse(levelSuffix) * 10 + 20; var rewards = balaurs.Where(m => m.level == level); List<WrappedItem> items = new List<WrappedItem>(); foreach (var material in rewards) { var wi = new WrappedItem(); wi.id = material.id; wi.min = 1; wi.max = 5; wi.description = material.Description; items.Add(wi); } wrapper.count = 1; wrapper.item = items.ToArray(); } else if (nameParts.Contains("enchant") || nameParts.Contains("enchant02") || nameParts.Contains("enchant03") || nameParts.Contains("enchant04") || nameParts.Contains("enchant05")) { string itemName = String.Join("_", nameParts, 1, nameParts.Length - 1); string levelSuffix = nameParts.Last(); if (Char.IsLetter(levelSuffix.ToCharArray().Last())) levelSuffix = levelSuffix.Substring(0, levelSuffix.Length - 1); int level = Int32.Parse(levelSuffix) - 1; var rewards = enchants.Skip(level * 10).Take(10); List<WrappedItem> items = new List<WrappedItem>(); foreach (var enchant in rewards) { var wi = new WrappedItem(); wi.id = enchant.id; wi.min = 1; wi.max = 5; wi.description = enchant.Description; items.Add(wi); } wrapper.count = 1; wrapper.item = items.ToArray(); } else if (nameParts.Contains("dye")) { string itemName = String.Join("_", nameParts, 1, nameParts.Length - 1); string levelSuffix = nameParts.Last(); if (Char.IsLetter(levelSuffix.ToCharArray().Last())) levelSuffix = levelSuffix.Substring(0, levelSuffix.Length - 1); int level = Int32.Parse(levelSuffix); List<WrappedItem> items = new List<WrappedItem>(); foreach (var dye in petals) { var wi = new WrappedItem(); wi.id = dye.id; wi.min = level; wi.max = 5; wi.description = dye.Description; items.Add(wi); } wrapper.count = 1; wrapper.item = items.ToArray(); } else if (nameParts.Contains("head")) { string itemName = String.Join("_", nameParts, 1, nameParts.Length - 1); string levelSuffix = nameParts.Last(); if (Char.IsLetter(levelSuffix.ToCharArray().Last())) levelSuffix = levelSuffix.Substring(0, levelSuffix.Length - 1); int level = Int32.Parse(levelSuffix) * 10 + 10; // don't know... } else if (nameParts.Contains("medal")) { int start = 1; if (nameParts.Contains("d")) start++; string itemName = String.Join("_", nameParts, start, nameParts.Length - 1 - start); Item wrappedItem = Utility.ItemIndex.GetItem(itemName); if (wrappedItem == null) { Debug.Print("Wrapped item not found for: {0}", item.name); } else { wrapper.item = new WrappedItem[1]; var wi = new WrappedItem(); wi.id = wrappedItem.id; wi.min = 1; wi.max = 5; wi.description = wrappedItem.Description; wrapper.item[0] = wi; } } else if (nameParts[0] == "material") { ItemQualities q = ItemQualities.junk; try { q = (ItemQualities)Enum.Parse(typeof(ItemQualities), nameParts[1], true); } catch { } if (q != ItemQualities.junk) { ItemRace raceExlude = nameParts.Contains("d") ? ItemRace.ELYOS : ItemRace.ASMODIANS; var g = gatherables.Where(i => i.Quality == q && i.quest == 0); List<WrappedItem> items = new List<WrappedItem>(); foreach (var gatherable in g) { if (gatherable.race == raceExlude || gatherable.name.StartsWith("od") || gatherable.id >= 152002001 && gatherable.id <= 152002003) continue; var wi = new WrappedItem(); wi.id = gatherable.id; wi.min = 10; wi.max = 10; wi.description = gatherable.Description; items.Add(wi); } wrapper.count = 10; wrapper.item = items.ToArray(); } else if (nameParts[1] == "flower") { List<WrappedItem> items = new List<WrappedItem>(); foreach (var dye in petals) { var wi = new WrappedItem(); wi.id = dye.id; wi.max = 1; wi.description = dye.Description; items.Add(wi); } wrapper.count = 1; wrapper.item = items.ToArray(); } else if (nameParts[1] == "weapon") { ItemRace raceExlude = nameParts.Contains("d") ? ItemRace.ELYOS : ItemRace.ASMODIANS; var fabledW = Utility.ItemIndex.ItemList.Where(i => i.level >= 50 && i.WeaponType != WeaponTypes.None && i.WeaponType != WeaponTypes.NoWeapon && i.quest == 0); var fabledWH = from w in fabledW let parts = w.name.Split('_') let suffix = parts[parts.Length - 2] where suffix == "h" select w; List<WrappedItem> items = new List<WrappedItem>(); foreach (var weap in fabledWH) { if (weap.race == raceExlude) continue; var wi = new WrappedItem(); wi.id = weap.id; wi.max = 1; wi.description = weap.Description; items.Add(wi); } wrapper.count = 1; wrapper.item = items.ToArray(); } } wrappers.Add(wrapper); } } wrappedItemFile.wrapper_item = wrappers.ToArray(); try { using (var fs = new FileStream(Path.Combine(outputPath, "wrapped_items.xml"), FileMode.Create, FileAccess.Write)) using (var writer = XmlWriter.Create(fs, settings)) { XmlSerializer ser = new XmlSerializer(typeof(WrappedItemsFile)); ser.Serialize(writer, wrappedItemFile); } } catch (Exception ex) { Debug.Print(ex.ToString()); } // var eventQuests = Utility.QuestIndex.QuestList.Where(q => q.category1 == QuestCategory1.Event); var expUtil = Utility<Quest>.Instance; foreach (var q in Utility.QuestIndex.QuestList) { string eventName = String.Empty; if (q.dev_name.StartsWith("[이벤트]일본대만_1주년")) { eventName = ItemTag.taiwan.ToString(); } else if (q.dev_name.StartsWith("[이벤트]할로윈")) { eventName = "halloween"; } else if (q.dev_name.StartsWith("[이벤트]구정") || q.dev_name.StartsWith("[이벤트]신년")) { eventName = "NewYear"; } else if (q.dev_name.StartsWith("제로코크")) { eventName = "china"; } var rewards = new List<Rewards>(); expUtil.Export(q, "reward_item", rewards); expUtil.Export(q, "selectable_reward_item", rewards); expUtil.Export(q, "reward_item_ext_", rewards); expUtil.Export(q, "selectable_reward_item_ext_", rewards); rewards = rewards.Where(r => r.BasicRewards != null || r.SelectableRewards != null).ToList(); QuestOur qOur = new QuestOur(); qOur.Rewards = rewards; qOur.AddClassRewards(q); List<QuestItemsOur> allRewards = qOur.AllRewards; q.OurQuest = qOur; if (!String.IsNullOrEmpty(eventName)) { AddQuest(eventName, q); continue; } string questName = q.Description.body; if (questName.StartsWith("[")) { int pos = questName.IndexOf(']'); questName = questName.Substring(1, pos - 1); if (questName.Contains("Daily")) { AddQuest("daily", q); continue; } } if (allRewards.Count > 0) { foreach (var br in allRewards) { Item item = Utility.ItemIndex.ItemList.Where(i => i.id == br.item_id).First(); string[] nameParts = item.name.Split('_'); if (nameParts[0] == "world" && nameParts[1] == "wrap" && nameParts[2] == "event" || nameParts[0] == "world" && nameParts[1] == "event") { eventName = nameParts[3]; } break; } } else { if (q.category2 == "STR_FACTION_GuardianOfDivine" || q.category2 == "STR_FACTION_GuardianOfTower" || q.category2 == "STR_FACTION_Army_Li" || q.category2 == "STR_FACTION_BountyHunter_Li" || q.category2 == "STR_FACTION_Army_Da" || q.category2 == "STR_FACTION_BountyHunter_Da") { eventName = "guild_order"; } else if (q.dev_name.StartsWith("7월 프로모션 퀘스트")) { eventName = ItemTag.july_promotion.ToString(); } else if (q.dev_name.StartsWith("[이벤트]해외용 임시 등록")) { eventName = "Temporary"; } } if (!String.IsNullOrEmpty(eventName)) { AddQuest(eventName, q); continue; } else { Debug.Print("Unknown event category: {0}", q.category2); } } EventsFile outputFile = new EventsFile(); outputFile.events = new List<EventData>(); ILookup<string, Item> worldEventsByName; ILookup<string, Item> worldCashByName; ILookup<string, Item> worldGiftsByName; ILookup<string, Item> eventsByName; ILookup<string, Item> cashByName; ILookup<string, Item> giftsByName; var worldItems = Utility.ItemIndex.ItemList.Where(i => i.name.StartsWith("world_")); var worldEvents = worldItems.Where(i => i.name.StartsWith("world_event_")); worldEventsByName = (from it in worldEvents let names = it.name.Split(new char[] { '_' }) let subset = names.Where(n => n.Length > 3) from name in subset select new { Name = name, Item = it }) .ToLookup(a => a.Name, a => a.Item, StringComparer.InvariantCultureIgnoreCase); var worldCash = worldItems.Where(i => i.name.StartsWith("world_cash_")); worldCashByName = (from it in worldCash let names = it.name.Split(new char[] { '_' }) let subset = names.Where(n => n.Length > 3) from name in subset select new { Name = name, Item = it }) .ToLookup(a => a.Name, a => a.Item, StringComparer.InvariantCultureIgnoreCase); var worldGifts = worldItems.Where(i => i.name.StartsWith("world_wrap_")); worldGiftsByName = (from it in worldGifts let names = it.name.Split(new char[] { '_' }) let subset = names.Where(n => n.Length > 3) from name in subset select new { Name = name, Item = it }) .ToLookup(a => a.Name, a => a.Item, StringComparer.InvariantCultureIgnoreCase); var westItems = Utility.ItemIndex.ItemList.Where(i => i.name.StartsWith("west_")); var chinaItems = Utility.ItemIndex.ItemList.Where(i => i.name.StartsWith("china_")); var eventItems = Utility.ItemIndex.ItemList.Where(i => i.name.StartsWith("event_")); eventsByName = (from it in eventItems let names = it.name.Split(new char[] { '_' }) let subset = names.Where(n => n.Length > 3) from name in subset select new { Name = name, Item = it }) .ToLookup(a => a.Name, a => a.Item, StringComparer.InvariantCultureIgnoreCase); var eventCash = Utility.ItemIndex.ItemList.Where(i => i.name.StartsWith("cash_")); cashByName = (from it in eventCash let names = it.name.Split(new char[] { '_' }) let subset = names.Where(n => n.Length > 3) from name in subset select new { Name = name, Item = it }) .ToLookup(a => a.Name, a => a.Item, StringComparer.InvariantCultureIgnoreCase); var eventGifts = Utility.ItemIndex.ItemList.Where(i => i.name.StartsWith("wrap_event_")); giftsByName = (from it in eventItems let names = it.name.Split(new char[] { '_' }) let subset = names.Where(n => n.Length > 3) from name in subset select new { Name = name, Item = it }) .ToLookup(a => a.Name, a => a.Item, StringComparer.InvariantCultureIgnoreCase); var dailyGifts = Utility.ItemIndex.ItemList.Where(i => i.name.StartsWith("wrap_daily_") || i.name.StartsWith("wrap_d_daily")); var combined = worldEvents.Union(worldCash).Union(worldGifts).Union(westItems).Union(chinaItems) .Union(eventItems).Union(eventCash).Union(eventGifts).Union(dailyGifts); var dailyItems = Utility.ItemIndex.ItemList.Where(i => i.tag == ItemTag.daily); var missing = dailyItems.Except(combined); questsByCategory.Add("deva", new List<Quest>()); // questsByCategory.Add("devaday", new List<Quest>()); questsByCategory.Add("foolsday", new List<Quest>()); questsByCategory.Add("goods", new List<Quest>()); questsByCategory.Add("july_pcbang", new List<Quest>()); questsByCategory.Add("kaspa", new List<Quest>()); questsByCategory.Add("petcard", new List<Quest>()); questsByCategory.Add("santa", new List<Quest>()); questsByCategory.Add("repeatquest", new List<Quest>()); questsByCategory.Add("season1", new List<Quest>()); questsByCategory.Add("v19promotion", new List<Quest>()); questsByCategory.Add("worldcup", new List<Quest>()); questsByCategory.Add("wondergirls", new List<Quest>()); questsByCategory.Add("west", new List<Quest>()); questsByCategory.Add("fanta", new List<Quest>()); questsByCategory.Add("shapechange", new List<Quest>()); questsByCategory.Add("social", new List<Quest>()); questsByCategory.Add("changeskin", new List<Quest>()); questsByCategory.Add("highdress", new List<Quest>()); questsByCategory.Add("weddingdress", new List<Quest>()); questsByCategory.Add("wing", new List<Quest>()); foreach (string category in questsByCategory.Keys) { var quests = questsByCategory[category]; var eventData = new EventData(); eventData.name = category; eventData.quests = new List<EventQuest>(); Dictionary<int, Item> categoryItems = null; if (category == "china") { categoryItems = chinaItems.ToDictionary(i => i.id, i => i); } else if (category == "daily") { categoryItems = dailyItems.ToDictionary(i => i.id, i => i); } else if (category == "fanta" || category == "shapechange" || category == "santa" || category == "social" || category == "changeskin" || category == "highdress" || category == "weddingdress" || category == "wing") { categoryItems = new Dictionary<int, Item>(); if (eventsByName.Contains(category)) { foreach (var item in eventsByName[category]) categoryItems.Add(item.id, item); } if (cashByName.Contains(category)) { foreach (var item in cashByName[category]) { if (!categoryItems.ContainsKey(item.id)) categoryItems.Add(item.id, item); } } if (giftsByName.Contains(category)) { foreach (var item in giftsByName[category]) { if (!categoryItems.ContainsKey(item.id)) categoryItems.Add(item.id, item); } } if (category == "fanta") eventData.name = "fanta_japen"; else if (category == "santa") eventData.name = "xmas"; else if (category == "social") eventData.name = "performance"; } else if (category == "west") { categoryItems = westItems.ToDictionary(i => i.id, i => i); } else { categoryItems = Utility.ItemIndex.ItemList.Where(i => i.tag.ToString() == category) .ToDictionary(i => i.id, i => i); if (worldEventsByName.Contains(category)) { foreach (var item in worldEventsByName[category]) categoryItems.Add(item.id, item); } if (worldCashByName.Contains(category)) { foreach (var item in worldCashByName[category]) categoryItems.Add(item.id, item); } if (worldGiftsByName.Contains(category)) { foreach (var item in worldGiftsByName[category]) categoryItems.Add(item.id, item); } } foreach (var q in quests) { var eventQuest = new EventQuest(); eventQuest.id = q.id; eventQuest.name = q.Description.body.Trim(); eventData.quests.Add(eventQuest); var rewardIds = q.OurQuest.AllRewards.Select(r => r.item_id); if (categoryItems != null) { foreach (int rewardId in rewardIds) categoryItems.Remove(rewardId); } } if (categoryItems != null) { eventData.wrapItems = new List<EventItem>(); eventData.rewardItems = new List<EventItem>(); eventData.cash = new List<EventItem>(); HashSet<int> cashIds = new HashSet<int>(); foreach (var pair in categoryItems) { var eventItem = new EventItem(); Item origItem = Utility.ItemIndex.GetItem(pair.Key); eventItem.name = Utility.StringIndex.GetString(origItem.desc).Trim(); eventItem.item_id = pair.Key; eventItem.race = origItem.race; if (origItem.extra_currency_item_count > 0) { int cashId = Utility.ItemIndex.GetItem(origItem.extra_currency_item).id; cashIds.Add(cashId); } if (origItem.cash_item == 1 || origItem.name.StartsWith("wrap_")) { eventItem.comment = Utility.StringIndex.GetString(origItem.desc_long); eventData.wrapItems.Add(eventItem); } else { eventData.rewardItems.Add(eventItem); } } if (eventData.rewardItems.Count == 0) eventData.rewardItems = null; else if (cashIds.Count > 0) { foreach (var ci in cashIds) { var cashItem = eventData.rewardItems.Where(r => r.item_id == ci).FirstOrDefault(); if (cashItem != null) { eventData.rewardItems.Remove(cashItem); } else { cashItem = new EventItem(); cashItem.item_id = ci; var origItem = Utility.ItemIndex.ItemList.Where(i => i.id == ci).FirstOrDefault(); cashItem.name = Utility.StringIndex.GetString(origItem.desc).Trim(); cashItem.race = origItem.race; } eventData.cash.Add(cashItem); } } if (eventData.wrapItems.Count == 0) eventData.wrapItems = null; } outputFile.events.Add(eventData); } //var merchants = Utility.ClientNpcIndex.NpcList.Where(n => n.cursor_type == CursorType.trade || // n.disk_type == DiskType.merchant || // n.TradeInfo != null || // n.AbyssTradeInfo != null || // n.CouponTradeInfo != null || // n.ExtraCurrencyTradeInfo != null); //foreach (var merchant in merchants) { // var dialogs = Utility.DialogFiles.Where(p => p.Key.StartsWith(merchant.name.ToLower() + '|')); // if (dialogs.Any()) { // foreach (var dialog in dialogs) { // var pg = dialog.Value.HtmlPages.Where(p => p.npcfuncs != null).FirstOrDefault(); // if (pg != null) { // var sellbuy = pg.npcfuncs.Where(f => f.GetType().Equals(typeof(trade_buy)) || // f.GetType().Equals(typeof(trade_sell)) || // f.GetType().Equals(typeof(exchange_coin)) || // f.GetType().Equals(typeof(Pet_adopt))); // if (sellbuy.Any()) { // break; // } // } // } // } //} //Utility.OriginalTradeList.TradeLists = // Utility.OriginalTradeList.TradeLists.OrderBy(t => t.npc_id).ToList(); try { using (var fs = new FileStream(Path.Combine(outputPath, "events.xml"), FileMode.Create, FileAccess.Write)) using (var writer = XmlWriter.Create(fs, settings)) { XmlSerializer ser = new XmlSerializer(typeof(EventsFile)); ser.Serialize(writer, outputFile); } } catch (Exception ex) { Debug.Print(ex.ToString()); } }
private static void ExportItemGroups(XmlWriterSettings saveSettings, string outputPath) { itemGroups = new ItemsExportFile(); var forwardItems = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase); SkillMap skillMap = new SkillMap(); skillMap.LoadFromFile(root); foreach (var item in Utility.ItemIndex.ItemList) { string[] nameParts = item.name.Split('_'); var exportItem = new ItemExport(); exportItem.itemId = item.id; exportItem.itemName = item.name; exportItem.armorType = item.ArmorType; exportItem.category = item.Category; exportItem.itemType = item.ItemType; exportItem.level = item.level; exportItem.quality = (Qualities)item.Quality; exportItem.raceInternal = item.race; exportItem.slot = item.EquipmentSlots; exportItem.weaponType = item.WeaponType; if (item.can_composite_weapon != null) exportItem.canFuse = item.can_composite_weapon.ToBoolean(CultureInfo.CurrentCulture); exportItem.itemIcon = item.icon_name; exportItem.mask = item.GetMask(); exportItem.expire_time = item.expire_time; exportItem.cash_item = item.cash_item; exportItem.cash_minute = item.cash_available_minute; exportItem.exchange_time = item.temporary_exchange_time; exportItem.race = item.race; exportItem.restricts = item.GetRestrictions(); exportItem.restricts_max = item.GetMaxRestrictions(); exportItem.modifiers = item.GetModifiers(skillMap); exportItem.originalItem = item; exportItem.tag = item.tag; if (!String.IsNullOrEmpty(item.activation_skill)) { ClientSkill skill = Utility.SkillIndex[item.activation_skill]; if (skill == null) { Debug.Print("Missing skill description: {0}", item.activation_skill); } else { // level can not be zero exportItem.skill_use = new SkillTemplate(skill.id, item.activation_level); } } Item it = Utility.ItemIndex.GetItem(item.name); if (it != null) { exportItem.desc = it.Description; } //if (exportItem.desc != null) { // if (exportItem.desc.StartsWith("Shadetouched ") || // exportItem.desc.StartsWith("Suntouched ")) { // exportItem.raceInternal = Race.All; // don't export selectable rewards // continue; // } //} if (exportItem.raceInternal != ItemRace.ALL) { // don't change } else { if (forwardItems.Contains(exportItem.itemName, StringComparer.InvariantCultureIgnoreCase)) { exportItem.raceInternal = ItemRace.ELYOS; forwardItems.Remove(exportItem.itemName); } else { bool dFound = false; bool startFound = false; int dIndex = 0; for (int i = 0; i < nameParts.Length; i++) { string np = nameParts[i]; if (!startFound && np.Length == 1) startFound = true; if (!startFound && np.Length > 1) continue; if (!dFound && np == "d") { dFound = true; dIndex = i; exportItem.raceInternal = ItemRace.ASMODIANS; continue; } if (dFound && np == "d") { if (item.ItemType != ItemTypes.draconic) { // NPC Balic items and one wrap box } } } if (exportItem.raceInternal == ItemRace.ASMODIANS) { string nameL = String.Join("_", nameParts, 0, dIndex); string nameR = String.Join("_", nameParts, dIndex + 1, nameParts.Length - dIndex - 1); string lightName = String.Concat(nameL, "_", nameR).TrimStart('_'); Item lightItem = Utility.ItemIndex.GetItem(lightName); if (lightItem != null) { // Debug.Print("Asmodian: {0}, Elyos: {1}", exportItem.itemId, lightItem.id); if (itemGroups.allNames.ContainsKey(lightName)) itemGroups.allNames[lightName].raceInternal = ItemRace.ELYOS; else forwardItems.Add(lightName.ToLower()); } else { lightName = String.Concat(nameL, "_l_", nameR).TrimStart('_'); lightItem = Utility.ItemIndex.GetItem(lightName); if (lightItem != null) { // Debug.Print("Asmodian: {0}, Elyos: {1}", exportItem.itemId, lightItem.id); if (itemGroups.allNames.ContainsKey(lightName)) itemGroups.allNames[lightName].raceInternal = ItemRace.ELYOS; else forwardItems.Add(lightName.ToLower()); } } } } } string suffix = nameParts.Last().ToLower(); bool isTaskItem = nameParts[0] == "item" && nameParts[1] == "part"; // always ends with _a or _b if (suffix.EndsWith("day")) { exportItem.rentDays = Int32.Parse(nameParts.Last().Replace("day", String.Empty)); Array.Resize(ref nameParts, nameParts.Length - 1); } else if (suffix.EndsWith("ae") || suffix.EndsWith("an") || suffix.EndsWith("ex")) { Array.Resize(ref nameParts, nameParts.Length - 1); } if (item.id == 110500631) { } if (nameParts.Length > 2) { exportItem.suffix = Utility.GetLevelFromName(nameParts.Last()); int lvl = exportItem.suffix >> 7; if (exportItem.suffix != 0) { string prior = nameParts[nameParts.Length - 2]; if (prior.Length < 3) { if (prior == "p" && lvl > 30 && nameParts[0] == "rec" && nameParts[nameParts.Length - 4] == "d") { int skillId = Utility.GetSkillIdFromName(item.name) & 0xF; if (lvl > 50) lvl = 60; exportItem.suffix = (skillId << 10) | (((int)exportItem.quality << 7) | lvl); exportItem.itemGroup = "hearts"; } else { char qPrefix = Char.ToLower(exportItem.quality.ToString()[0]); // check if _c1_c_10b, then group is "c" string before = nameParts[nameParts.Length - 3]; if (before[0] == qPrefix && (before.Length == 1 || before.Length == 2 && Char.IsDigit(before[1]))) { exportItem.itemGroup = prior; } } } else if (prior.Length == 6 && prior.EndsWith("stats") && nameParts[0] == "rec" && nameParts[4] == "dr" && lvl > 30) { int skillId = Utility.GetSkillIdFromName(item.name) & 0xF; exportItem.suffix = (skillId << 10) | (((int)exportItem.quality << 7) | lvl); exportItem.itemGroup = "hearts"; } else if (prior == "dark" || prior == "light") { // fix race, because it can contain _d_ for elyos exportItem.raceInternal = prior[0] == 'd' ? ItemRace.ASMODIANS : ItemRace.ELYOS; exportItem.itemGroup = prior; } if (nameParts[0] == "potion" || nameParts[0] == "remedy") { exportItem.itemGroup = "medicine"; } else if (nameParts[0] == "shopmaterial") { exportItem.itemGroup = "shopmaterial"; } else if (nameParts[0] == "junk") { if (nameParts[1] == "q" || nameParts[2] == "q") exportItem.itemGroup = "quest_junk"; else exportItem.itemGroup = "junk"; } else if (nameParts[0] == "key") { exportItem.itemGroup = "keys"; } else if (nameParts[0] == "test") { exportItem.itemGroup = "tests"; } else if (nameParts[0] == "jewelry") { exportItem.itemGroup = "ores"; } else if (nameParts[0] == "food" && exportItem.category != ItemCategories.harvest) { /*if (nameParts[1] == "r" || nameParts[1] == "d" && nameParts[2] == "r") exportItem.itemGroup = "food_tasty"; else */ if (nameParts[1] == "dr") { if (nameParts[2] == "r" || nameParts[2] == "d" && nameParts[3] == "r") exportItem.itemGroup = "food_draconic_tasty"; else exportItem.itemGroup = "food_draconic"; } else exportItem.itemGroup = "food"; } else if (nameParts[0] == "matter" && nameParts[1] == "option" && nameParts[2] == "r") { exportItem.itemGroup = "manastone_reward"; } else if (nameParts[0] == "matter" && nameParts[1] == "enchant") { exportItem.itemGroup = "enchant"; } else if (nameParts[0].ToLower() == "doc") { exportItem.itemGroup = "docs"; exportItem.suffix = 0; } else if (nameParts[0] == "harvest") { exportItem.itemGroup = "harvest"; exportItem.suffix = 0; } else if (nameParts[0] == "rmc") { exportItem.itemGroup = "legion_rewards"; } else if (isTaskItem) { exportItem.itemGroup = "craft_tasks"; } else if (nameParts[1] == "part") { exportItem.itemGroup = "task_rewards"; } else if (nameParts[0] == "wrap") { exportItem.itemGroup = "wrapped_rewards"; } } else if (nameParts[nameParts.Length - 2] == "m") { exportItem.isMaster = true; } else if (nameParts[0] == "stigma") { exportItem.itemGroup = "stigmas"; exportItem.suffix = 0; } else if (nameParts[0] == "skillbook") { exportItem.itemGroup = "skillbooks"; exportItem.suffix = 0; } if (exportItem.itemGroup == "c") exportItem.itemGroup = "coin_rewards"; if (exportItem.itemGroup == "g") exportItem.itemGroup = "boss"; if ((exportItem.itemGroup == "r" || exportItem.itemGroup == "R") && !exportItem.originalItem.Description.StartsWith("Level ")) { if (exportItem.originalItem.level >= 52) exportItem.raceInternal = ItemRace.ALL; exportItem.itemGroup = "random_drop"; } } else { if (nameParts[0].ToLower() == "quest") { exportItem.itemGroup = "quest_items"; exportItem.suffix = 0; } else if (nameParts[0] == "coin") { exportItem.itemGroup = "coins"; exportItem.suffix = 0; } else if (nameParts[0] == "medal") { exportItem.itemGroup = "medals"; exportItem.suffix = 0; } } if (exportItem.rentDays > 0) { exportItem.itemGroup = "rent"; } if (exportItem.tag != ItemTag.none) { exportItem.itemGroup = exportItem.tag.ToString(); } itemGroups.items.Add(exportItem); itemGroups.allNames.Add(exportItem.itemName, exportItem); } var lowerLevel = itemGroups.items.Where(i => i.level > i.minLevel); StringBuilder sb = new StringBuilder(); foreach (var it in lowerLevel) { sb.AppendFormat("{0} - {1} ({2})\r\n", it.itemId, it.desc, it.category); } var groupedLookup = itemGroups.items.ToLookup(it => it.itemGroup, it => it); var abyssGroup = groupedLookup.Where(g => g.Key == "a"); Dictionary<string, ItemRace> worldDrops = new Dictionary<string, ItemRace>() { { "Soul", ItemRace.ALL }, { "Sky", ItemRace.ALL }, { "Eldritch", ItemRace.ALL }, { "Grounded", ItemRace.ALL }, { "Angry", ItemRace.ALL }, { "Battlefield", ItemRace.ALL }, { "Zealous", ItemRace.ALL }, { "Wraith's", ItemRace.ALL }, { "Fascination", ItemRace.ALL }, { "Eternity", ItemRace.ALL }, { "Blood Seeking", ItemRace.ALL }, { "Divisive", ItemRace.ALL }, { "Celestial", ItemRace.ALL }, { "Everwatcher's", ItemRace.ALL }, { "Old Guard's", ItemRace.ALL }, { "Invader's", ItemRace.ALL }, { "Ancient Daeva's", ItemRace.ALL }, { "Carved", ItemRace.ALL }, { "Anonymous", ItemRace.ALL }, { "Reddened", ItemRace.ALL }, { "White", ItemRace.ALL }, { "Red Dragon Legion", ItemRace.ALL }, { "Rain", ItemRace.ALL }, { "Immemorial", ItemRace.ALL }, { "Departed Soul's", ItemRace.ALL }, { "Purehorn's", ItemRace.ALL }, { "Calamity", ItemRace.ALL }, { "Sleeper's", ItemRace.ALL }, { "Buried", ItemRace.ALL }, { "Immortal", ItemRace.ALL }, { "Fallen Legionary's", ItemRace.ALL }, { "Nebulous", ItemRace.ALL }, { "Reaper's", ItemRace.ALL }, { "Odious", ItemRace.ALL }, { "Protector's", ItemRace.ALL }, { "Martyr's", ItemRace.ALL }, { "Oblate", ItemRace.ALL }, { "Dimensional", ItemRace.ALL }, { "Giant Lord's", ItemRace.ALL }, { "Ancient Giant's", ItemRace.ALL }, { "Restoration", ItemRace.ALL }, { "Miracle", ItemRace.ALL }, { "Comet", ItemRace.ALL }, { "Meteor", ItemRace.ALL }, { "Ancient Hero's", ItemRace.ALL }, { "Giant's", ItemRace.ALL }, { "Elder", ItemRace.ALL }, { "Catastrophic", ItemRace.ALL }, { "Horrific", ItemRace.ALL }, { "Chaos", ItemRace.ALL }, { "Dolan", ItemRace.ALL }, { "Judgment", ItemRace.ALL }, { "Demolition", ItemRace.ALL }, { "Gracefull", ItemRace.ALL }, { "Death", ItemRace.ALL }, { "Life", ItemRace.ALL }, { "Destructive", ItemRace.ALL }, { "Storm", ItemRace.ALL }, { "Sage", ItemRace.ALL }, { "Sunset", ItemRace.ALL }, { "Angel's", ItemRace.ALL }, { "Guarded", ItemRace.ALL }, { "Dispelling", ItemRace.ALL }, { "Archbishop", ItemRace.ALL }, { "Restless", ItemRace.ALL }, { "Prayer", ItemRace.ALL }, { "Torment", ItemRace.ALL } }; foreach (var abyssSuffix in abyssGroup) { foreach (string name in worldDrops.Keys) { var abyssItems = abyssSuffix.Where(a => a.desc.StartsWith(name)); foreach (var abyssItem in abyssItems) abyssItem.itemGroup = "random_drop"; } } foreach (var entry in groupedLookup) { IEnumerable<ItemExport> group = groupedLookup[entry.Key]; ItemGroups itGroup = new ItemGroups(); if (entry.Key != null) itGroup.group = entry.Key; var suffixLookup = group.ToLookup(it => it.suffix, it => it); foreach (var suffixEntry in suffixLookup) { IEnumerable<ItemExport> suffixGroup = suffixLookup[suffixEntry.Key]; ItemSuffixes itSuffix = new ItemSuffixes(); itSuffix.suffix = suffixEntry.Key; foreach (var item in suffixGroup) { //item.itemGroup = null; //item.suffix = 0; itSuffix.items.Add(item); } itGroup.items.Add(itSuffix); } itGroup.items = itGroup.items.OrderBy(it => it.suffix).ToList(); itemGroups.grouped.Add(itGroup); } itemGroups.items.Clear(); itemGroups.allNames.Clear(); using (FileStream stream = new FileStream(Path.Combine(outputPath, "items.xml"), FileMode.Create, FileAccess.Write)) { using (XmlWriter wr = XmlWriter.Create(stream, saveSettings)) { XmlSerializer ser = new XmlSerializer(typeof(ItemsExportFile)); ser.Serialize(wr, itemGroups); } } }
public static void CreateSkillMap(string root) { Console.WriteLine("Creating mapping rules..."); var utility = Utility<Item>.Instance; SkillMap map = new SkillMap(); foreach (var our in Utility.OriginalItemTemplate.TemplateList) { var clientMatch = Utility.ItemIndex.ItemList.Where(i => i.id == our.id).FirstOrDefault(); if (clientMatch == null || our.modifiers == null) continue; List<string> bonusAttrs = new List<string>(); utility.Export(clientMatch, "bonus_attr", bonusAttrs); int modifierCount = 0; if (clientMatch.min_damage > 0 || clientMatch.max_damage > 0) modifierCount++; if (clientMatch.min_damage > 0) modifierCount++; if (clientMatch.max_damage > 0) modifierCount++; if (clientMatch.hit_accuracy > 0) modifierCount++; if (clientMatch.magical_hit_accuracy > 0) modifierCount++; if (clientMatch.parry > 0) modifierCount++; if (clientMatch.critical > 0) modifierCount++; if (clientMatch.attack_delay > 0) modifierCount++; if (clientMatch.attack_range > 0) modifierCount++; if (clientMatch.hit_count > 0) modifierCount++; if (our.modifiers[0].modifierList.Count != modifierCount + bonusAttrs.Count) continue; bool allMatched = true; var newMappings = new Dictionary<string, SkillMapEntry>(); var bonuses = our.modifiers[0].modifierList.Where(m => m.bonus).ToList(); var clientBonuses = from bonus in bonusAttrs let name = GetAttributeName(bonus) let value = GetAttributeValue(bonus) select new { Name = name, Value = value }; foreach (var clientBonus in clientBonuses) { Type type = default(Type); int value = 0; Modifier ourModifier = null; if (map.AllMappings.ContainsKey(clientBonus.Name)) { ourModifier = bonuses.Where(b => b.name.ToString() == map.AllMappings[clientBonus.Name].to) .FirstOrDefault(); if (ourModifier == null) { continue; } if (ourModifier is AddModifier) { AddModifier addMod = (AddModifier)ourModifier; value = addMod.value; type = typeof(AddModifier); } else if (ourModifier is SubModifier) { SubModifier subMod = (SubModifier)ourModifier; value = subMod.value; type = typeof(SubModifier); } else if (ourModifier is RateModifier) { RateModifier rateMod = (RateModifier)ourModifier; value = rateMod.value; type = typeof(RateModifier); } else if (ourModifier is SetModifier) { SetModifier setMod = (SetModifier)ourModifier; value = setMod.value; type = typeof(SetModifier); } else { // not implemented allMatched = false; break; } if (Math.Abs(value) != Math.Abs(clientBonus.Value)) { allMatched = false; break; } bonuses.Remove(ourModifier); // exclude from search } else { foreach (Modifier mod in bonuses) { if (mod is AddModifier) { AddModifier addMod = (AddModifier)mod; value = addMod.value; type = typeof(AddModifier); } else if (mod is SubModifier) { SubModifier subMod = (SubModifier)mod; value = subMod.value; type = typeof(SubModifier); } else if (mod is RateModifier) { RateModifier rateMod = (RateModifier)mod; value = rateMod.value; type = typeof(RateModifier); } else if (mod is SetModifier) { SetModifier setMod = (SetModifier)mod; value = setMod.value; type = typeof(SetModifier); } else { // not implemented allMatched = false; break; } if (Math.Abs(value) == Math.Abs(clientBonus.Value)) { ourModifier = mod; break; } } if (ourModifier == null) { // not found the same value allMatched = false; break; } bonuses.Remove(ourModifier); newMappings.Add(clientBonus.Name, new SkillMapEntry() { from = clientBonus.Name, to = ourModifier.name.ToString(), ModifierType = type, IsNegative = value != clientBonus.Value, }); } } if (allMatched) { foreach (var pair in newMappings) map.AllMappings.Add(pair.Key, pair.Value); } } map.SaveToFile(root); }