/// <summary> /// If new SalvageYield table is empty then copy values from old Salvage table /// </summary> public void Update() { int count = 0; var newSalvage = GameServer.Database.SelectAllObjects <SalvageYield>(); if (newSalvage == null || newSalvage.Count == 0) { log.InfoFormat("Updating the SalvageYield table...", count); var oldSalvage = GameServer.Database.SelectAllObjects <DBSalvage>(); foreach (DBSalvage salvage in oldSalvage) { SalvageYield salvageYield = new SalvageYield(); salvageYield.ID = ++count; // start at 1 salvageYield.ObjectType = salvage.ObjectType; salvageYield.SalvageLevel = salvage.SalvageLevel; salvageYield.MaterialId_nb = salvage.Id_nb; salvageYield.Count = 0; salvageYield.Realm = salvage.Realm; salvageYield.PackageID = SalvageYield.LEGACY_SALVAGE_ID; GameServer.Database.AddObject(salvageYield); } } if (count > 0) { log.InfoFormat("Copied {0} entries from Salvage to SalvageYield.", count); } }
/// <summary> /// Return the material yield for this salvage. /// </summary> public static int GetMaterialYield(GamePlayer player, InventoryItem item, SalvageYield salvageYield, ItemTemplate rawMaterial) { int maxCount = 0; if (rawMaterial == null) { return(0); } if (ServerProperties.Properties.USE_NEW_SALVAGE) { maxCount = GetCountForSalvage(item, salvageYield, rawMaterial); } else { maxCount = (int)(item.Price * 0.45 / rawMaterial.Price); // crafted item return max 45% of the item value in material if (item.IsCrafted) { maxCount = (int)Math.Ceiling((double)maxCount / 2); } } int playerPercent = player.GetCraftingSkillValue(CraftingMgr.GetSecondaryCraftingSkillToWorkOnItem(item)) * 100 / CraftingMgr.GetItemCraftLevel(item); if (playerPercent > 100) { playerPercent = 100; } else if (playerPercent < 75) { playerPercent = 75; } int minCount = (int)(((maxCount - 1) / 25f) * playerPercent) - ((3 * maxCount) - 4); //75% => min = 1; 100% => min = maxCount; salvageYield.Count = Util.Random(minCount, maxCount); return(salvageYield.Count); }
/// <summary> /// Begin salvaging an inventory item /// </summary> /// <param name="item"></param> /// <param name="player"></param> /// <returns></returns> public static int BeginWork(GamePlayer player, InventoryItem item) { SalvageYield salvageYield = null; if (!IsAllowedToBeginWork(player, item)) { return(0); } int salvageLevel = CraftingMgr.GetItemCraftLevel(item) / 100; if (salvageLevel > 9) { salvageLevel = 9; // max 9 } string sql = ""; if (item.SalvageYieldID == 0) { sql = "ObjectType=" + item.Object_Type + " AND SalvageLevel=" + salvageLevel; } else { sql = "ID=" + item.SalvageYieldID; } if (ServerProperties.Properties.USE_SALVAGE_PER_REALM) { // Some items use realm, some do not, so allow a find of either a set realm, or 0 sql += " AND (Realm=" + item.Realm + " OR Realm=0)"; } salvageYield = GameServer.Database.SelectObject <SalvageYield>(sql); ItemTemplate material = null; if (salvageYield != null && string.IsNullOrEmpty(salvageYield.MaterialId_nb) == false) { material = GameServer.Database.FindObjectByKey <ItemTemplate>(salvageYield.MaterialId_nb); if (material == null) { player.Out.SendMessage("Can't find material (" + material.Id_nb + ") needed to salvage this item!", eChatType.CT_Important, eChatLoc.CL_SystemWindow); log.ErrorFormat("Salvage Error for ID: {0}: Material not found: {1}", salvageYield.ID, material.Id_nb); } } if (material == null) { if (salvageYield == null && item.SalvageYieldID > 0) { player.Out.SendMessage("This items salvage recipe (" + item.SalvageYieldID + ") not implemented yet.", eChatType.CT_Important, eChatLoc.CL_SystemWindow); log.ErrorFormat("SalvageYield ID {0} not found for item: {1}", item.SalvageYieldID, item.Name); } else if (salvageYield == null) { player.Out.SendMessage("Salvage recipe not found for this item.", eChatType.CT_System, eChatLoc.CL_SystemWindow); log.ErrorFormat("Salvage Lookup Error: ObjectType: {0}, Item: {1}", item.Object_Type, item.Name); } return(0); } if (player.IsMoving || player.IsStrafing) { player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client.Account.Language, "Salvage.BeginWork.InterruptSalvage"), eChatType.CT_System, eChatLoc.CL_SystemWindow); return(0); } if (player.IsStealthed) { player.Stealth(false); } player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client.Account.Language, "Salvage.BeginWork.BeginSalvage", item.Name), eChatType.CT_System, eChatLoc.CL_SystemWindow); // clone the yield entry and update values to work with this salvage (not saved to the DB) SalvageYield yield = salvageYield.Clone() as SalvageYield; if (item.SalvageYieldID == 0 || yield.Count == 0) { // Calculated salvage values int count = GetMaterialYield(player, item, yield, material); if (count < 1) { player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client.Account.Language, "Salvage.BeginWork.NoSalvage", item.Name + ". The material returned amount is zero"), eChatType.CT_System, eChatLoc.CL_SystemWindow); return(0); } } player.Out.SendTimerWindow(LanguageMgr.GetTranslation(player.Client.Account.Language, "Salvage.BeginWork.Salvaging", item.Name), yield.Count); player.CraftTimer = new RegionTimer(player); player.CraftTimer.Callback = new RegionTimerCallback(Proceed); player.CraftTimer.Properties.setProperty(AbstractCraftingSkill.PLAYER_CRAFTER, player); player.CraftTimer.Properties.setProperty(SALVAGED_ITEM, item); player.CraftTimer.Properties.setProperty(SALVAGE_YIELD, yield); player.CraftTimer.Start(yield.Count * 1000); return(1); }
/// <summary> /// Calculate the count per Object_Type /// </summary> public static int GetCountForSalvage(InventoryItem item, SalvageYield salvage, ItemTemplate rawMaterial) { long maxCount = 0; if (rawMaterial == null) { return(0); } #region Weapons switch ((eObjectType)item.Object_Type) { case eObjectType.RecurvedBow: case eObjectType.CompositeBow: case eObjectType.Longbow: case eObjectType.Crossbow: case eObjectType.Staff: case eObjectType.Fired: maxCount += 36; break; case eObjectType.Thrown: case eObjectType.CrushingWeapon: case eObjectType.SlashingWeapon: case eObjectType.ThrustWeapon: case eObjectType.Flexible: case eObjectType.Blades: case eObjectType.Blunt: case eObjectType.Piercing: case eObjectType.Sword: case eObjectType.Hammer: case eObjectType.LeftAxe: case eObjectType.Axe: case eObjectType.HandToHand: { int dps = item.DPS_AF; if (dps > 520) { maxCount += 10; } else { maxCount += 5; } break; } case eObjectType.TwoHandedWeapon: case eObjectType.PolearmWeapon: case eObjectType.LargeWeapons: case eObjectType.CelticSpear: case eObjectType.Scythe: case eObjectType.Spear: { int dps = item.DPS_AF; if (dps > 520) { maxCount += 15; } else { maxCount += 10; } } break; case eObjectType.Shield: switch (item.Type_Damage) { case 1: maxCount += 5; break; case 2: maxCount += 8; break; case 3: maxCount += 12; break; default: maxCount += 5; break; } break; case eObjectType.Instrument: switch (item.Type_Damage) { case 1: maxCount += 5; break; case 2: maxCount += 8; break; case 3: maxCount += 12; break; default: maxCount += 5; break; } break; #endregion Weapons #region Armor case eObjectType.Cloth: case eObjectType.Leather: case eObjectType.Reinforced: case eObjectType.Studded: case eObjectType.Scale: case eObjectType.Chain: case eObjectType.Plate: switch (item.Item_Type) { case Slot.HELM: maxCount += 12; break; case Slot.TORSO: maxCount += 17; break; case Slot.LEGS: maxCount += 15; break; case Slot.ARMS: maxCount += 10; break; case Slot.HANDS: maxCount += 6; break; case Slot.FEET: maxCount += 5; break; default: maxCount += 5; break; } break; } #endregion Armor #region Modifications if (maxCount < 1) { maxCount = (int)(item.Price * 0.45 / rawMaterial.Price); } int toadd = 0; if (item.Quality > 97 && !item.IsCrafted) { for (int i = 97; i < item.Quality;) { toadd += 3; i++; } } if (item.Price > 300000 && !item.IsCrafted) { long i = item.Price; i = item.Price / 100000; toadd += (int)i; } if (toadd > 0) { maxCount += toadd; } #region SpecialFix MerchantList if (item.Bonus8 > 0) { if (item.Bonus8Type == 0 || item.Bonus8Type.ToString() == "") { maxCount = item.Bonus8; } } #endregion SpecialFix MerchantList if (item.Condition != item.MaxCondition && item.Condition < item.MaxCondition) { long usureoverall = (maxCount * ((item.Condition / 5) / 1000)) / 100; // assume that all items have 50000 base con maxCount = usureoverall; } if (maxCount < 1) { maxCount = 1; } else if (maxCount > 500) { maxCount = 500; } #endregion Modifications return((int)maxCount); }
/// <summary> /// Called when craft time is finished /// </summary> /// <param name="timer"></param> /// <returns></returns> protected static int Proceed(RegionTimer timer) { GamePlayer player = timer.Properties.getProperty <GamePlayer>(AbstractCraftingSkill.PLAYER_CRAFTER, null); InventoryItem itemToSalvage = timer.Properties.getProperty <InventoryItem>(SALVAGED_ITEM, null); SalvageYield yield = timer.Properties.getProperty <SalvageYield>(SALVAGE_YIELD, null); int materialCount = yield.Count; if (player == null || itemToSalvage == null || yield == null || materialCount == 0) { player.Out.SendMessage("Error retrieving salvage data for this item!", eChatType.CT_Important, eChatLoc.CL_SystemWindow); log.Error("Salvage: There was a problem getting back salvage info from the craft timer."); return(0); } ItemTemplate rawMaterial = null; if (string.IsNullOrEmpty(yield.MaterialId_nb) == false) { rawMaterial = GameServer.Database.FindObjectByKey <ItemTemplate>(yield.MaterialId_nb); } if (rawMaterial == null) { player.Out.SendMessage("Error finding the raw material needed to salvage this item!", eChatType.CT_Important, eChatLoc.CL_SystemWindow); log.Error("Salvage: Error finding raw material " + yield.MaterialId_nb); return(0); } player.CraftTimer.Stop(); player.Out.SendCloseTimerWindow(); if (!player.Inventory.RemoveItem(itemToSalvage)) // clean the free of the item to salvage { player.Out.SendMessage("Error finding the item to salvage!", eChatType.CT_Important, eChatLoc.CL_SystemWindow); return(0); } InventoryLogging.LogInventoryAction(player, "(salvage)", eInventoryActionType.Craft, itemToSalvage.Template, itemToSalvage.Count); Dictionary <int, int> changedSlots = new Dictionary <int, int>(5); // value: < 0 = new item count; > 0 = add to old lock (player.Inventory) { int count = materialCount; foreach (InventoryItem item in player.Inventory.GetItemRange(eInventorySlot.FirstBackpack, eInventorySlot.LastBackpack)) { if (item == null) { continue; } if (item.Id_nb != rawMaterial.Id_nb) { continue; } if (item.Count >= item.MaxCount) { continue; } int countFree = item.MaxCount - item.Count; if (count > countFree) { changedSlots.Add(item.SlotPosition, countFree); // existing item should be changed count -= countFree; } else { changedSlots.Add(item.SlotPosition, count); // existing item should be changed count = 0; break; } } if (count > 0) // Add new object { eInventorySlot firstEmptySlot = player.Inventory.FindFirstEmptySlot(eInventorySlot.FirstBackpack, eInventorySlot.LastBackpack); changedSlots.Add((int)firstEmptySlot, -count); // Create the item in the free slot (always at least one) count = 0; } } InventoryItem newItem = null; player.Inventory.BeginChanges(); Dictionary <int, int> .Enumerator enumerator = changedSlots.GetEnumerator(); while (enumerator.MoveNext()) { KeyValuePair <int, int> de = enumerator.Current; int countToAdd = de.Value; if (countToAdd > 0) // Add to exiting item { newItem = player.Inventory.GetItem((eInventorySlot)de.Key); player.Inventory.AddCountToStack(newItem, countToAdd); InventoryLogging.LogInventoryAction("(salvage)", player, eInventoryActionType.Craft, newItem.Template, countToAdd); } else { newItem = GameInventoryItem.Create <ItemTemplate>(rawMaterial); newItem.Count = -countToAdd; player.Inventory.AddItem((eInventorySlot)de.Key, newItem); InventoryLogging.LogInventoryAction("(salvage)", player, eInventoryActionType.Craft, newItem.Template, newItem.Count); } } player.Inventory.CommitChanges(); player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client.Account.Language, "Salvage.Proceed.GetBackMaterial", materialCount, rawMaterial.Name, itemToSalvage.Name), eChatType.CT_Important, eChatLoc.CL_SystemWindow); return(0); }
public void OnCommand(GameClient client, string[] args) { if (args.Length < 2) { DisplaySyntax(client); return; } try { #region List if (args[1].ToLower() == "list") { List <string> list = new List <string>(); int count = 0; foreach (int value in Enum.GetValues(typeof(eCraftingSkill))) { if (++count < 16) // get rid of duplicate due to _Last { list.Add(value + " = " + Enum.GetName(typeof(eCraftingSkill), value)); } } client.Out.SendCustomTextWindow(LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.Crafting.SkillDescription"), list); return; } #endregion List #region Salvage if (args[1].ToLower() == "salvageinfo") { List <string> list = new List <string>(); int salvageID = Convert.ToInt32(args[2]); SalvageYield salvage = GameServer.Database.SelectObject <SalvageYield>("ID=" + salvageID); if (salvage == null) { DisplayMessage(client, "SalvageYield ID not found!"); return; } ItemTemplate template = GameServer.Database.FindObjectByKey <ItemTemplate>(salvage.MaterialId_nb); string materialName = "Not Found!"; if (template != null) { materialName = template.Name; } list.Add("SalvageYield ID: " + salvageID); list.Add(" ObjectType: " + (salvage.ObjectType == 0 ? "Unused" : salvage.ObjectType.ToString())); list.Add(" SalvageLevel: " + (salvage.SalvageLevel == 0 ? "Unused" : salvage.SalvageLevel.ToString())); list.Add(" Material: " + materialName + " (" + salvage.MaterialId_nb + ")"); list.Add(" Count: " + (salvage.Count == 0 ? "Calculated" : salvage.Count.ToString())); list.Add(" Realm: " + (salvage.Realm == 0 ? "Any" : GlobalConstants.RealmToName((eRealm)salvage.Realm))); list.Add(" PackageID: " + salvage.PackageID); client.Out.SendCustomTextWindow("SalvageYield ID " + salvageID, list); return; } if (args[1].ToLower() == "salvageadd" || args[1].ToLower() == "salvageupdate") { try { int salvageID = Convert.ToInt32(args[2]); string material = args[3]; int count = Convert.ToInt32(args[4]); byte realm = 0; string package = ""; if (args.Length > 5) { realm = Convert.ToByte(args[5]); } if (args.Length > 6) { package = args[6]; } ItemTemplate template = GameServer.Database.FindObjectByKey <ItemTemplate>(material); if (template == null) { DisplayMessage(client, "Material id_nb " + material + " not found!"); return; } SalvageYield salvage = GameServer.Database.SelectObject <SalvageYield>("ID=" + salvageID); if (args[1].ToLower() == "salvageadd") { if (salvage != null) { DisplayMessage(client, "This SalvageYield ID already exists, use salvageupdate to change it."); return; } salvage = new SalvageYield(); if (salvageID > 0) { salvage.ID = salvageID; } salvage.MaterialId_nb = material; salvage.Count = Math.Max(1, count); salvage.Realm = realm; if (package == "") { package = client.Player.Name; } salvage.PackageID = package; GameServer.Database.AddObject(salvage); DisplayMessage(client, string.Format("Created SalvageYield ID: {0}, Material: {1}, Count: {2}, Realm: {3}, PackageID: {4}", salvage.ID, salvage.MaterialId_nb, salvage.Count, salvage.Realm, salvage.PackageID)); } else { if (salvage == null) { DisplayMessage(client, "SalvageID not found!"); return; } if (salvage.PackageID == SalvageYield.LEGACY_SALVAGE_ID) { DisplayMessage(client, "This SalvageYield ID is used for legacy salvage support and can not be updated."); return; } salvage.MaterialId_nb = material; salvage.Count = Math.Max(1, count); salvage.Realm = realm; if (string.IsNullOrEmpty(salvage.PackageID) && package == "") { package = client.Player.Name; } if (package != "") { salvage.PackageID = package; } GameServer.Database.SaveObject(salvage); DisplayMessage(client, string.Format("Updated SalvageYield ID: {0}, Material: {1}, Count: {2}, Realm: {3}, PackageID: {4}", salvage.ID, salvage.MaterialId_nb, salvage.Count, salvage.Realm, salvage.PackageID)); } } catch { DisplaySyntax(client); } return; } #endregion Salvage GamePlayer target = null; if ((client.Player.TargetObject != null) && (client.Player.TargetObject is GamePlayer)) { target = client.Player.TargetObject as GamePlayer; } else { DisplayMessage(client, LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.Crafting.NoPlayerTarget")); return; } switch (args[1].ToLower()) { #region Add case "add": { eCraftingSkill craftingSkillID = eCraftingSkill.NoCrafting; int startLevel = 1; try { craftingSkillID = (eCraftingSkill)Convert.ToUInt16(args[2]); if (args.Length > 3) { startLevel = Convert.ToUInt16(args[3]); } AbstractCraftingSkill skill = CraftingMgr.getSkillbyEnum(craftingSkillID); if (skill == null) { DisplayMessage(client, LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.Crafting.InvalidSkill")); } else { if (target.AddCraftingSkill(craftingSkillID, startLevel)) { target.Out.SendUpdateCraftingSkills(); target.SaveIntoDatabase(); DisplayMessage(client, LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.Crafting.SkillAdded", skill.Name)); } else { DisplayMessage(client, LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.Crafting.AlreadyHaveSkill", target.Name, skill.Name)); } } } catch (Exception) { DisplaySyntax(client); } break; } #endregion Add #region Change case "change": { eCraftingSkill craftingSkillID = eCraftingSkill.NoCrafting; int amount = 1; try { craftingSkillID = (eCraftingSkill)Convert.ToUInt16(args[2]); if (args.Length > 3) { amount = Convert.ToInt32(args[3]); } AbstractCraftingSkill skill = CraftingMgr.getSkillbyEnum(craftingSkillID); if (skill == null) { DisplayMessage(client, LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.Crafting.InvalidSkill")); } else { if (target.GetCraftingSkillValue(craftingSkillID) < 0) { DisplayMessage(client, LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.Crafting.NotHaveSkillAddIt", target.Name, skill.Name)); return; } if (amount > 0) { target.GainCraftingSkill(craftingSkillID, amount); } else { target.CraftingSkills[craftingSkillID] += amount; } target.Out.SendUpdateCraftingSkills(); target.SaveIntoDatabase(); DisplayMessage(client, LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.Crafting.SkillChanged", skill.Name)); DisplayMessage(client, LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.Crafting.NowHasSkillPoints", target.Name, target.GetCraftingSkillValue(craftingSkillID), (eCraftingSkill)craftingSkillID)); } } catch (Exception) { DisplaySyntax(client); return; } break; } #endregion Change #region Default default: { DisplaySyntax(client); break; } #endregion Default } } catch { DisplaySyntax(client); } }