/// <summary> /// Tries to repair item specified in the repair reply. /// </summary> /// <param name="repairReply"></param> /// <param name="rate"></param> /// <param name="tags"></param> /// <returns></returns> public RepairResult Repair(string repairReply, int rate, params string[] tags) { var result = new RepairResult(); // Get item id: @repair(_all):123456789 int pos = -1; if ((pos = repairReply.IndexOf(':')) == -1 || !long.TryParse(repairReply.Substring(pos + 1), out result.ItemEntityId)) { Log.Warning("NpcScript.Repair: Player '{0:X16}' (Account: {1}) sent invalid repair reply.", this.Player.EntityId, this.Player.Client.Account.Id); return result; } // Perfect repair? var all = repairReply.StartsWith("@repair_all"); // Get item result.Item = this.Player.Inventory.GetItem(result.ItemEntityId); if (result.Item == null || !tags.Any(a => result.Item.Data.HasTag(a))) { Log.Warning("NpcScript.Repair: Player '{0:X16}' (Account: {1}) tried to repair invalid item.", this.Player.EntityId, this.Player.Client.Account.Id); return result; } // Calculate points to repair result.Points = (!all ? 1000 : result.Item.OptionInfo.DurabilityMax - result.Item.OptionInfo.Durability); result.Points = (int)Math.Floor(result.Points / 1000f); // Check gold var cost = result.Item.GetRepairCost(rate, 1); if (this.Gold < cost * result.Points) { result.HadGold = false; return result; } result.HadGold = true; // TODO: Luck? // Repair x times for (int i = 0; i < result.Points; ++i) { var useRate = rate; // Holy Water if (result.Item.IsBlessed) useRate = 100 - ((100 - useRate) / 2); // Success if (this.Random(100) < useRate) { result.Item.Durability += 1000; result.Successes++; } // Fail else { // Remove blessing if (result.Item.IsBlessed) { result.Item.OptionInfo.Flags &= ~ItemFlags.Blessed; Send.ItemBlessed(this.Player, result.Item); } result.Item.OptionInfo.DurabilityMax = Math.Max(1000, result.Item.OptionInfo.DurabilityMax - 1000); if (result.Item.OptionInfo.DurabilityMax < result.Item.OptionInfo.Durability) result.Item.Durability -= 1000; result.Fails++; } } // Reduce gold, but only for successes this.Gold -= cost * result.Successes; // Update max dura if (result.Fails != 0) Send.ItemMaxDurabilityUpdate(this.Player, result.Item); // Update dura if (result.Successes != 0) Send.ItemDurabilityUpdate(this.Player, result.Item); // Send result Send.ItemRepairResult(this.Player, result.Item, result.Successes); this.Player.Keywords.Give("ExperienceRepair"); return result; }