/// <summary> /// Updates the trade window /// </summary> public void TradeUpdate() { lock (Sync) { if (m_changesCount > 0) { return; } if (m_changesCount < 0) { m_changesCount = 0; if (log.IsErrorEnabled) { log.Error("Changes count is less than 0, forgot to add m_changesCount++?\n\n" + Environment.StackTrace); } } InventoryItem itemToCombine = (InventoryItem)PartnerTradeItems[0]; // -------------------------------------------------------------- // Luhz Crafting Update: // Players may now have any, and all, "primary" crafting skills. // AbstractCraftingSkill skill = CraftingMgr.getSkillbyEnum(m_owner.CraftingPrimarySkill); AbstractCraftingSkill skill = null; lock (m_owner.TradeWindow.Sync) { foreach (InventoryItem i in (ArrayList)m_owner.TradeWindow.TradeItems.Clone()) { if (i.Object_Type == (int)eObjectType.AlchemyTincture) { if (m_owner.GetCraftingSkillValue(eCraftingSkill.Alchemy) > 0) { skill = CraftingMgr.getSkillbyEnum(eCraftingSkill.Alchemy); break; } } else if (i.Object_Type == (int)eObjectType.SpellcraftGem) { if (m_owner.GetCraftingSkillValue(eCraftingSkill.SpellCrafting) > 0) { skill = CraftingMgr.getSkillbyEnum(eCraftingSkill.SpellCrafting); break; } } } } // -------------------------------------------------------------- if (skill != null && skill is AdvancedCraftingSkill && itemToCombine != null) { if (((AdvancedCraftingSkill)skill).IsAllowedToCombine(m_owner, itemToCombine)) { if (skill is SpellCrafting) { ((SpellCrafting)skill).ShowSpellCraftingInfos(m_owner, itemToCombine); } } } m_owner.Out.SendTradeWindow(); } }
/// <summary> /// Check if the player can begin to salvage an item /// </summary> /// <param name="player"></param> /// <param name="item"></param> /// <returns></returns> public static bool IsAllowedToBeginWork(GamePlayer player, InventoryItem item) { if (player.InCombat) { player.Out.SendMessage("You can't salvage while in combat.", eChatType.CT_System, eChatLoc.CL_SystemWindow); return(false); } if (item.IsNotLosingDur || item.IsIndestructible) { player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client.Account.Language, "Salvage.BeginWork.NoSalvage", item.Name + ". This item is indestructible"), eChatType.CT_System, eChatLoc.CL_SystemWindow); return(false); } // using negative numbers to indicate item cannot be salvaged if (item.SalvageYieldID < 0) { player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client, "Salvage.BeginWork.NoSalvage", item.Name), eChatType.CT_System, eChatLoc.CL_SystemWindow); return(false); } if (item.SlotPosition < (int)eInventorySlot.FirstBackpack || item.SlotPosition > (int)eInventorySlot.LastBackpack) { player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client.Account.Language, "Salvage.IsAllowedToBeginWork.BackpackItems"), eChatType.CT_System, eChatLoc.CL_SystemWindow); return(false); } eCraftingSkill skill = CraftingMgr.GetSecondaryCraftingSkillToWorkOnItem(item); if (skill == eCraftingSkill.NoCrafting) { player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client.Account.Language, "Salvage.BeginWork.NoSalvage", item.Name + ". You do not have the required secondary skill"), eChatType.CT_System, eChatLoc.CL_SystemWindow); return(false); } if (player.IsCrafting) { player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client.Account.Language, "Salvage.IsAllowedToBeginWork.EndCurrentAction"), eChatType.CT_System, eChatLoc.CL_SystemWindow); return(false); } if (player.GetCraftingSkillValue(skill) < (0.75 * CraftingMgr.GetItemCraftLevel(item))) { player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client.Account.Language, "Salvage.IsAllowedToBeginWork.NotEnoughSkill", item.Name), eChatType.CT_System, eChatLoc.CL_SystemWindow); return(false); } return(true); }
/// <summary> /// Called each time a player push the accept button to accept the trade /// </summary> public bool AcceptTrade() { m_tradeAccept = true; lock (Sync) { // -------------------------------------------------------------- // Luhz Crafting Update: // Players may now have any, and all, "primary" crafting skills. // AbstractCraftingSkill skill = CraftingMgr.getSkillbyEnum(m_owner.CraftingPrimarySkill); AbstractCraftingSkill skill = null; lock (m_owner.TradeWindow.Sync) { foreach (InventoryItem i in (ArrayList)m_owner.TradeWindow.TradeItems.Clone()) { if (i.Object_Type == (int)eObjectType.AlchemyTincture) { if (m_owner.GetCraftingSkillValue(eCraftingSkill.Alchemy) > 0) { skill = CraftingMgr.getSkillbyEnum(eCraftingSkill.Alchemy); break; } } else if (i.Object_Type == (int)eObjectType.SpellcraftGem) { if (m_owner.GetCraftingSkillValue(eCraftingSkill.SpellCrafting) > 0) { skill = CraftingMgr.getSkillbyEnum(eCraftingSkill.SpellCrafting); break; } } } } // -------------------------------------------------------------- if (skill != null && skill is AdvancedCraftingSkill) { ((AdvancedCraftingSkill)skill).CombineItems(m_owner); } } CloseTrade(); return(true); }
/// <summary> /// Check if the player own can enchant the item /// </summary> /// <param name="player"></param> /// <param name="item"></param> /// <param name="percentNeeded">min 50 max 100</param> /// <returns></returns> public static bool IsAllowedToBeginWork(GamePlayer player, InventoryItem item, int percentNeeded) { if (item.IsNotLosingDur) { player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client.Account.Language, "Repair.IsAllowedToBeginWork.CantRepair", item.Name), eChatType.CT_System, eChatLoc.CL_SystemWindow); return(false); } if (item.SlotPosition < (int)eInventorySlot.FirstBackpack || item.SlotPosition > (int)eInventorySlot.LastBackpack) { player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client.Account.Language, "Repair.IsAllowedToBeginWork.BackpackItems"), eChatType.CT_System, eChatLoc.CL_SystemWindow); return(false); } eCraftingSkill skill = CraftingMgr.GetSecondaryCraftingSkillToWorkOnItem(item); if (skill == eCraftingSkill.NoCrafting) { player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client.Account.Language, "Repair.IsAllowedToBeginWork.CantRepair", item.Name), eChatType.CT_System, eChatLoc.CL_SystemWindow); return(false); } if (player.IsCrafting) { player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client.Account.Language, "Repair.IsAllowedToBeginWork.EndCurrentAction"), eChatType.CT_System, eChatLoc.CL_SystemWindow); return(false); } if (item.Condition >= item.MaxCondition) { player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client.Account.Language, "Repair.IsAllowedToBeginWork.FullyRepaired", item.Name), eChatType.CT_System, eChatLoc.CL_SystemWindow); return(false); } if (player.GetCraftingSkillValue(skill) < ((percentNeeded / 100) * CraftingMgr.GetItemCraftLevel(item))) { player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client.Account.Language, "Repair.IsAllowedToBeginWork.NotEnoughSkill", item.Name), eChatType.CT_System, eChatLoc.CL_SystemWindow); return(false); } return(true); }
/// <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> /// Calculate the chance of sucess /// </summary> protected static int CalculateSuccessChances(GamePlayer player, InventoryItem item) { eCraftingSkill skill = CraftingMgr.GetSecondaryCraftingSkillToWorkOnItem(item); if (skill == eCraftingSkill.NoCrafting) { return(0); } int chancePercent = (int)((90 / (CraftingMgr.GetItemCraftLevel(item) * 0.5)) * player.GetCraftingSkillValue(skill)) - 80; // 50% = 10% chance, 100% = 100% chance if (chancePercent > 100) { chancePercent = 100; } else if (chancePercent < 0) { chancePercent = 0; } return(chancePercent); }
/// <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> /// Called each time a player push the accept button to accept the trade /// </summary> public bool AcceptTrade() { lock (Sync) { m_tradeAccept = true; GamePlayer partner = m_partnerWindow.Owner; partner.Out.SendMessage(m_owner.Name + " has accepted the trade.", eChatType.CT_System, eChatLoc.CL_SystemWindow); // Check if the tradepartner has also agreed to the trade if (!m_partnerWindow.m_tradeAccept) { return(false); } bool logTrade = ServerProperties.Properties.LOG_TRADES; if (m_owner.Client.Account.PrivLevel > 1 || partner.Client.Account.PrivLevel > 1) { logTrade = true; } //Test if we and our partner have enough money bool enoughMoney = m_owner.RemoveMoney(TradeMoney); bool partnerEnoughMoney = partner.RemoveMoney(m_partnerWindow.TradeMoney); //Check the preconditions if (!enoughMoney || !partnerEnoughMoney) { if (!enoughMoney) { //Reset the money if we don't have enough TradeMoney = 0; if (partnerEnoughMoney) { partner.AddMoney(m_partnerWindow.TradeMoney); InventoryLogging.LogInventoryAction(partner, m_owner, eInventoryActionType.Trade, m_partnerWindow.TradeMoney); } m_owner.Out.SendMessage("You don't have enough money.", eChatType.CT_Merchant, eChatLoc.CL_SystemWindow); partner.Out.SendMessage(m_owner.Name + " doesn't have enough money.", eChatType.CT_Merchant, eChatLoc.CL_SystemWindow); } if (!partnerEnoughMoney) { //Reset the money if our partner doesn't have enough m_partnerWindow.TradeMoney = 0; if (enoughMoney) { m_owner.AddMoney(TradeMoney); InventoryLogging.LogInventoryAction(m_owner, partner, eInventoryActionType.Trade, TradeMoney); } partner.Out.SendMessage("You don't have enough money.", eChatType.CT_Merchant, eChatLoc.CL_SystemWindow); m_owner.Out.SendMessage(partner.Name + " doesn't have enough money.", eChatType.CT_Merchant, eChatLoc.CL_SystemWindow); } //Update our tradewindow and return TradeUpdate(); return(false); } if (m_combine == true) { GamePlayer crafter = (m_recipiant == true ? m_owner : partner); // -------------------------------------------------------------- // Luhz Crafting Update: // Players may now have any, and all, "primary" crafting skills. // AbstractCraftingSkill skill = CraftingMgr.getSkillbyEnum(crafter.CraftingPrimarySkill); AbstractCraftingSkill skill = null; lock (crafter.TradeWindow.Sync) { foreach (InventoryItem i in (ArrayList)crafter.TradeWindow.TradeItems.Clone()) { if (i.Object_Type == (int)eObjectType.AlchemyTincture) { if (m_owner.GetCraftingSkillValue(eCraftingSkill.Alchemy) > 0) { skill = CraftingMgr.getSkillbyEnum(eCraftingSkill.Alchemy); break; } } else if (i.Object_Type == (int)eObjectType.SpellcraftGem) { if (crafter.GetCraftingSkillValue(eCraftingSkill.SpellCrafting) > 0) { skill = CraftingMgr.getSkillbyEnum(eCraftingSkill.SpellCrafting); break; } } } } // -------------------------------------------------------------- if (skill != null && skill is AdvancedCraftingSkill) { ((AdvancedCraftingSkill)skill).CombineItems(crafter); } } else if (m_repair == true) { GamePlayer crafter = (m_recipiant == true ? m_owner : partner); InventoryItem itemToRepair = (InventoryItem)(m_recipiant == true ? m_partnerWindow.TradeItems[0] : TradeItems[0]); if (itemToRepair != null) { crafter.RepairItem(itemToRepair); } } else { //Calculate the count of items int myTradeItemsCount = m_tradeItems.Count; int partnerTradeItemsCount = m_partnerWindow.TradeItems.Count; //Test if we and our partner have enough space in inventory int mySpaceNeeded = Math.Max(0, partnerTradeItemsCount - myTradeItemsCount); int partnerSpaceNeeded = Math.Max(0, myTradeItemsCount - partnerTradeItemsCount); bool enoughSpace = m_owner.Inventory.IsSlotsFree(mySpaceNeeded, eInventorySlot.FirstBackpack, eInventorySlot.LastBackpack); bool partnerEnoughSpace = partner.Inventory.IsSlotsFree(partnerSpaceNeeded, eInventorySlot.FirstBackpack, eInventorySlot.LastBackpack); //Check the preconditions if (!enoughSpace || !partnerEnoughSpace) { if (!enoughSpace) { m_owner.Out.SendMessage("You don't have enough space in your inventory.", eChatType.CT_Merchant, eChatLoc.CL_SystemWindow); partner.Out.SendMessage(m_owner.Name + " doesn't have enough space in his inventory.", eChatType.CT_Merchant, eChatLoc.CL_SystemWindow); } if (!partnerEnoughSpace) { partner.Out.SendMessage("You don't have enough space in your inventory.", eChatType.CT_Merchant, eChatLoc.CL_SystemWindow); m_owner.Out.SendMessage(partner.Name + " doesn't have enough space in his inventory.", eChatType.CT_Merchant, eChatLoc.CL_SystemWindow); } //Update our tradewindow and return TradeUpdate(); //This was already removed above, needs to be returned to the players on trade failure. m_owner.AddMoney(TradeMoney); partner.AddMoney(m_partnerWindow.TradeMoney); return(false); } //Now transfer everything m_owner.Inventory.BeginChanges(); partner.Inventory.BeginChanges(); m_changesCount++; m_partnerWindow.m_changesCount++; // must be cloned because Inventory.RemoveItem removes it from trade window ArrayList ownerTradeItems = (ArrayList)TradeItems.Clone(); ArrayList partnerTradeItems = (ArrayList)m_partnerWindow.TradeItems.Clone(); // remove all items first to make sure there is enough space // if inventory is full but removed items count >= received count foreach (InventoryItem item in ownerTradeItems) { lock (m_owner.Inventory) { if (!m_owner.Inventory.RemoveTradeItem(item)) { if (logTrade) { GameServer.Instance.LogGMAction(" NOTItem: " + m_owner.Name + "(" + m_owner.Client.Account.Name + ") -> " + partner.Name + "(" + partner.Client.Account.Name + ") : " + item.Name + "(" + item.Id_nb + ")"); } //BOT.Ban(m_owner, "Trade Hack"); //BOT.Ban(partner, "Trade Hack"); return(false); } } } foreach (InventoryItem item in partnerTradeItems) { lock (partner.Inventory) { if (!partner.Inventory.RemoveTradeItem(item)) { if (logTrade) { GameServer.Instance.LogGMAction(" NOTItem: " + m_owner.Name + "(" + m_owner.Client.Account.Name + ") -> " + partner.Name + "(" + partner.Client.Account.Name + ") : " + item.Name + "(" + item.Id_nb + ")"); } //BOT.Ban(m_owner, "Trade Hack"); //BOT.Ban(partner, "Trade Hack"); return(false); } } } foreach (InventoryItem item in ownerTradeItems) { if (m_owner.Guild != partner.Guild) { item.Emblem = 0; } bool tradeSuccess = false; if (item.IsDeleted) { tradeSuccess = partner.Inventory.AddItem(eInventorySlot.FirstEmptyBackpack, item); } else { tradeSuccess = partner.Inventory.AddTradeItem(eInventorySlot.FirstEmptyBackpack, item); } if (!tradeSuccess) { log.Error("Trade item was not added to Partner first free slot. Owner = " + m_owner.Name + ", Partner = " + partner.Name + "; Item = " + item.Id_nb); } else { InventoryLogging.LogInventoryAction(m_owner, partner, eInventoryActionType.Trade, item.Template, item.Count); if (logTrade) { GameServer.Instance.LogGMAction(" Item: " + m_owner.Name + "(" + m_owner.Client.Account.Name + ") -> " + partner.Name + "(" + partner.Client.Account.Name + ") : " + item.Name + "(" + item.Id_nb + ")"); } } } foreach (InventoryItem item in partnerTradeItems) { if (m_owner.Guild != partner.Guild) { item.Emblem = 0; } bool tradeSuccess = false; if (item.IsDeleted) { tradeSuccess = m_owner.Inventory.AddItem(eInventorySlot.FirstEmptyBackpack, item); } else { tradeSuccess = m_owner.Inventory.AddTradeItem(eInventorySlot.FirstEmptyBackpack, item); } if (!tradeSuccess) { log.Error("Trade item was not added to Owner first free slot. Owner = " + m_owner.Name + ", Partner = " + partner.Name + "; Item = " + item.Id_nb); } else { InventoryLogging.LogInventoryAction(partner, m_owner, eInventoryActionType.Trade, item.Template, item.Count); if (logTrade) { GameServer.Instance.LogGMAction(" Item: " + partner.Name + "(" + partner.Client.Account.Name + ") -> " + m_owner.Name + "(" + m_owner.Client.Account.Name + ") : " + item.Name + "(" + item.Id_nb + ")"); } } } m_owner.Inventory.CommitChanges(); partner.Inventory.CommitChanges(); m_changesCount--; m_partnerWindow.m_changesCount--; m_owner.Out.SendMessage("Trade Completed. " + myTradeItemsCount + " items for " + partnerTradeItemsCount + " items.", eChatType.CT_System, eChatLoc.CL_SystemWindow); partner.Out.SendMessage("Trade Completed. " + partnerTradeItemsCount + " items for " + myTradeItemsCount + " items.", eChatType.CT_System, eChatLoc.CL_SystemWindow); m_owner.Inventory.SaveIntoDatabase(m_owner.InternalID); partner.Inventory.SaveIntoDatabase(partner.InternalID); } if (logTrade) { if (m_partnerWindow.TradeMoney > 0) { GameServer.Instance.LogGMAction(" Money: " + partner.Name + "(" + partner.Client.Account.Name + ") -> " + m_owner.Name + "(" + m_owner.Client.Account.Name + ") : " + m_partnerWindow.TradeMoney + "coppers"); } if (TradeMoney > 0) { GameServer.Instance.LogGMAction(" Money: " + m_owner.Name + "(" + m_owner.Client.Account.Name + ") -> " + partner.Name + "(" + partner.Client.Account.Name + ") : " + TradeMoney + "coppers"); } } if (TradeMoney > 0 || m_partnerWindow.TradeMoney > 0) { //Now add the money m_owner.AddMoney(m_partnerWindow.TradeMoney, "You get {0}."); partner.AddMoney(TradeMoney, "You get {0}."); InventoryLogging.LogInventoryAction(m_owner, partner, eInventoryActionType.Trade, TradeMoney); InventoryLogging.LogInventoryAction(partner, m_owner, eInventoryActionType.Trade, m_partnerWindow.TradeMoney); m_owner.SaveIntoDatabase(); partner.SaveIntoDatabase(); } CloseTrade(); // Close the Trade Window return(true); } }