protected static void ReadItems() { var items = from category in pFile.BaseNode["Item"] where category.Name != "Pet" from itemType in category from item in itemType select item; Items = IterateAllToDict(items, p => { var iNode = p; ItemData item = new ItemData(); int ID = (int)Utils.ConvertNameToID(iNode.Name); item.ID = ID; if (iNode.ContainsChild("info")) { var infoNode = iNode["info"]; foreach (var node in infoNode) { switch (node.Name) { case "path": case "floatType": case "unitPrice": // Pricing of recharging??? case "icon": case "iconRaw": case "iconReward": break; case "type": item.Type = node.ValueInt8(); break; case "price": item.Price = node.ValueInt32(); break; case "timeLimited": item.TimeLimited = node.ValueBool(); break; case "cash": item.Cash = node.ValueBool(); break; case "slotMax": item.MaxSlot = node.ValueUInt16(); break; case "meso": item.Mesos = node.ValueInt32(); break; case "quest": if (node.ValueBool()) { lock (UntradeableDrops) { lock (QuestItems) { item.IsQuest = true; UntradeableDrops.Add(item.ID); QuestItems.Add(item.ID); } } } break; case "success": item.ScrollSuccessRate = node.ValueByte(); break; case "cursed": item.ScrollCurseRate = node.ValueByte(); break; case "incSTR": item.IncStr = node.ValueByte(); break; case "incDEX": item.IncDex = node.ValueByte(); break; case "incLUK": item.IncLuk = node.ValueByte(); break; case "incINT": item.IncInt = node.ValueByte(); break; case "incMHP": item.IncMHP = node.ValueByte(); break; case "incMMP": item.IncMMP = node.ValueByte(); break; case "pad": case "incPAD": item.IncWAtk = node.ValueByte(); break; case "incMAD": item.IncMAtk = node.ValueByte(); break; case "incPDD": item.IncWDef = node.ValueByte(); break; case "incMDD": item.IncMDef = node.ValueByte(); break; case "incACC": item.IncAcc = node.ValueByte(); break; case "incEVA": item.IncAvo = node.ValueByte(); break; case "incJump": item.IncJump = node.ValueByte(); break; case "incSpeed": item.IncSpeed = node.ValueByte(); break; case "rate": item.Rate = node.ValueByte(); break; case "only": if (node.ValueBool()) { lock (UntradeableDrops) { UntradeableDrops.Add(item.ID); } } break; case "time": item.RateTimes = new Dictionary <byte, List <KeyValuePair <byte, byte> > >(); foreach (var lNode in node) { string val = lNode.ValueString(); string day = val.Substring(0, 3); byte hourStart = byte.Parse(val.Substring(4, 2)); byte hourEnd = byte.Parse(val.Substring(7, 2)); byte dayid = 0; switch (day) { case "MON": dayid = 0; break; case "TUE": dayid = 1; break; case "WED": dayid = 2; break; case "THU": dayid = 3; break; case "FRI": dayid = 4; break; case "SAT": dayid = 5; break; case "SUN": dayid = 6; break; case "HOL": dayid = ItemData.HOLIDAY_DAY; break; } if (!item.RateTimes.ContainsKey(dayid)) { item.RateTimes.Add(dayid, new List <KeyValuePair <byte, byte> >()); } item.RateTimes[dayid].Add(new KeyValuePair <byte, byte>(hourStart, hourEnd)); } break; default: Console.WriteLine($"Unhandled item info node {node.Name} for id {item.ID}"); break; } } } else { item.Price = 0; item.Cash = false; item.MaxSlot = 1; item.Mesos = 0; item.IsQuest = false; item.ScrollSuccessRate = 0; item.ScrollCurseRate = 0; item.IncStr = 0; item.IncDex = 0; item.IncInt = 0; item.IncLuk = 0; item.IncMHP = 0; item.IncMMP = 0; item.IncWAtk = 0; item.IncMAtk = 0; item.IncWDef = 0; item.IncMDef = 0; item.IncAcc = 0; item.IncAvo = 0; item.IncJump = 0; item.IncSpeed = 0; item.Rate = 0; } if (iNode.ContainsChild("spec")) { var specNode = iNode["spec"]; foreach (var node in specNode) { switch (node.Name) { case "moveTo": item.MoveTo = node.ValueInt32(); break; case "hp": item.HP = node.ValueInt16(); break; case "mp": item.MP = node.ValueInt16(); break; case "hpR": item.HPRate = node.ValueInt16(); break; case "mpR": item.MPRate = node.ValueInt16(); break; case "speed": item.Speed = node.ValueInt16(); break; case "eva": item.Avoidance = node.ValueInt16(); break; case "acc": item.Accuracy = node.ValueInt16(); break; case "mad": item.MagicAttack = node.ValueInt16(); break; case "pad": item.WeaponAttack = node.ValueInt16(); break; case "pdd": item.WeaponDefense = node.ValueInt16(); break; case "thaw": item.Thaw = node.ValueInt16(); break; case "time": item.BuffTime = node.ValueInt32(); break; case "curse": case "darkness": case "poison": case "seal": case "weakness": if (node.ValueInt64() != 0) { ItemData.CureFlags flag = 0; switch (node.Name) { case "curse": flag = ItemData.CureFlags.Curse; break; case "darkness": flag = ItemData.CureFlags.Darkness; break; case "poison": flag = ItemData.CureFlags.Poison; break; case "seal": flag = ItemData.CureFlags.Seal; break; case "weakness": flag = ItemData.CureFlags.Weakness; break; } item.Cures |= flag; } break; default: Console.WriteLine($"Unhandled item spec node {node.Name} for id {item.ID}"); break; } } } else { //no spec, continue item.MoveTo = 0; item.HP = 0; item.MP = 0; item.HPRate = 0; item.MPRate = 0; item.Speed = 0; item.Avoidance = 0; item.Accuracy = 0; item.MagicAttack = 0; item.WeaponAttack = 0; item.BuffTime = 0; } if (iNode.ContainsChild("mob")) //summons { item.Summons = new List <ItemSummonInfo>(); foreach (var sNode in iNode["mob"]) { item.Summons.Add(new ItemSummonInfo { MobID = sNode["id"].ValueInt32(), Chance = sNode["prob"].ValueByte() }); } } return(item); }, x => x.ID); }
protected static void ReadEquips() { var equips = from category in pFile.BaseNode["Character"] where category.Name.EndsWith(".img") == false && category.Name != "Afterimage" from item in category select new { category.Name, item }; Equips = IterateAllToDict(equips, p => { EquipData eq = new EquipData(); var infoBlock = p.item["info"]; eq.ID = (int)Utils.ConvertNameToID(p.item.Name); foreach (var nxNode in infoBlock) { switch (nxNode.Name) { case "islot": case "vslot": case "icon": case "iconRaw": case "afterImage": case "sfx": case "attack": case "stand": case "walk": case "sample": case "chatBalloon": case "nameTag": break; // Nexon typos (= not used!) case "incMMD": // Green Jester, would've been a really good buff! case "regPOP": // Dark Lucida (Female) break; case "tuc": eq.Slots = nxNode.ValueByte(); break; case "reqLevel": eq.RequiredLevel = nxNode.ValueByte(); break; case "reqPOP": eq.RequiredFame = nxNode.ValueByte(); break; case "reqDEX": eq.RequiredDexterity = nxNode.ValueUInt16(); break; case "reqINT": eq.RequiredIntellect = nxNode.ValueUInt16(); break; case "reqLUK": eq.RequiredLuck = nxNode.ValueUInt16(); break; case "reqSTR": eq.RequiredStrength = nxNode.ValueUInt16(); break; case "reqJob": { var job = nxNode.ValueInt64(); // Sake Bottle and Tuna patch; ingame all jobs are required and the flag is -1.. if (job == -1) { eq.RequiredJob = 0xFFFF; } else { eq.RequiredJob = (ushort)job; } break; } case "price": eq.Price = nxNode.ValueInt32(); break; case "incSTR": eq.Strength = nxNode.ValueInt16(); break; case "incDEX": eq.Dexterity = nxNode.ValueInt16(); break; case "incLUK": eq.Luck = nxNode.ValueInt16();; break; case "incINT": eq.Intellect = nxNode.ValueInt16(); break; case "incMDD": eq.MagicDefense = nxNode.ValueByte(); break; case "incPDD": eq.WeaponDefense = nxNode.ValueByte(); break; case "incPAD": eq.WeaponAttack = nxNode.ValueByte(); break; case "incMAD": eq.MagicAttack = nxNode.ValueByte(); break; case "incSpeed": eq.Speed = nxNode.ValueByte(); break; case "incJump": eq.Jump = nxNode.ValueByte(); break; case "incACC": eq.Accuracy = nxNode.ValueByte(); break; case "incEVA": eq.Avoidance = nxNode.ValueByte(); break; case "incMHP": eq.HP = nxNode.ValueInt16(); break; case "incMMP": eq.MP = nxNode.ValueInt16(); break; case "quest": if (nxNode.ValueBool()) { lock (UntradeableDrops) { lock (QuestItems) { QuestItems.Add(eq.ID); if (!UntradeableDrops.Contains(eq.ID)) { UntradeableDrops.Add(eq.ID); } } } } break; case "only": if (nxNode.ValueBool()) { lock (UntradeableDrops) { if (!UntradeableDrops.Contains(eq.ID)) { UntradeableDrops.Add(eq.ID); } } } break; case "cash": eq.Cash = nxNode.ValueBool(); break; case "attackSpeed": eq.AttackSpeed = nxNode.ValueByte(); break; case "knockback": eq.KnockbackRate = nxNode.ValueByte(); break; case "timeLimited": eq.TimeLimited = nxNode.ValueBool(); break; case "recovery": eq.RecoveryRate = nxNode.ValueFloat(); break; default: Console.WriteLine($"Unhandled node {nxNode.Name} for equip {eq.ID}"); break; } } return(eq); }, x => x.ID, x => x); }