/// <summary> /// Get all the items in the specified range /// </summary> /// <param name="minSlot">Slot Position where begin the search</param> /// <param name="maxSlot">Slot Position where stop the search</param> /// <returns>all items found</returns> public virtual ICollection <InventoryItem> GetItemRange(eInventorySlot minSlot, eInventorySlot maxSlot) { minSlot = GetValidInventorySlot(minSlot); maxSlot = GetValidInventorySlot(maxSlot); if (minSlot == eInventorySlot.Invalid || maxSlot == eInventorySlot.Invalid) { return(null); } // If lower slot is greater than upper slot, flip the values. if (minSlot > maxSlot) { eInventorySlot tmp = minSlot; minSlot = maxSlot; maxSlot = tmp; } var items = new List <InventoryItem>(); lock (m_items) { InventoryItem item; for (eInventorySlot i = minSlot; i <= maxSlot; i++) { if (m_items.TryGetValue(i, out item)) { items.Add(item); } } } return(items); }
/// <summary> /// Checks if specified count of slots is free /// </summary> /// <param name="count"></param> /// <param name="minSlot"></param> /// <param name="maxSlot"></param> /// <returns></returns> public bool IsSlotsFree(int count, eInventorySlot minSlot, eInventorySlot maxSlot) { if (count < 1) { return(true); } // If lower slot is greater than upper slot, flip the values. if (minSlot > maxSlot) { eInventorySlot tmp = minSlot; minSlot = maxSlot; maxSlot = tmp; } lock (m_items) // Mannen 10:56 PM 10/30/2006 - Fixing every lock(this) { for (eInventorySlot i = minSlot; i <= maxSlot; i++) { if (m_items.ContainsKey(i)) { continue; } count--; if (count <= 0) { return(true); } } return(false); } }
/// <summary> /// Check if the slot is valid in the inventory /// </summary> /// <param name="slot">SlotPosition to check</param> /// <returns>the slot if it's valid or eInventorySlot.Invalid if not</returns> protected override eInventorySlot GetValidInventorySlot(eInventorySlot slot) { foreach (eInventorySlot visibleSlot in VISIBLE_SLOTS) if (visibleSlot == slot) return slot; return eInventorySlot.Invalid; }
/// <summary> /// Count items of some type /// </summary> /// <param name="itemtemplateID">template to count</param> /// <param name="minSlot">first slot</param> /// <param name="maxSlot">last slot</param> /// <returns>number of matched items found</returns> public int CountItemTemplate(string itemtemplateID, eInventorySlot minSlot, eInventorySlot maxSlot) { lock (m_items) // Mannen 10:56 PM 10/30/2006 - Fixing every lock(this) { int count = 0; // If lower slot is greater than upper slot, flip the values. if (minSlot > maxSlot) { eInventorySlot tmp = minSlot; minSlot = maxSlot; maxSlot = tmp; } InventoryItem item; for (eInventorySlot i = minSlot; i <= maxSlot; i++) { if (m_items.TryGetValue(i, out item) && item.Id_nb == itemtemplateID) { count += item.Count; } } return(count++); } }
/// <summary> /// Removes item from slot if template is not closed. /// </summary> /// <param name="slot">The slot to remove</param> /// <returns>true if removed</returns> public bool RemoveNPCEquipment(eInventorySlot slot) { lock (m_items) { slot = GetValidInventorySlot(slot); if (slot == eInventorySlot.Invalid) { return(false); } if (m_isClosed) { return(false); } if (!m_items.ContainsKey(slot)) { return(false); } m_items.Remove(slot); return(true); } }
/// <summary> /// Searches for the first occurrence of an item with given /// name between specified slots /// </summary> /// <param name="name">name</param> /// <param name="minSlot">fist slot for search</param> /// <param name="maxSlot">last slot for search</param> /// <returns>found item or null</returns> public InventoryItem GetFirstItemByName(string name, eInventorySlot minSlot, eInventorySlot maxSlot) { minSlot = GetValidInventorySlot(minSlot); maxSlot = GetValidInventorySlot(maxSlot); if (minSlot == eInventorySlot.Invalid || maxSlot == eInventorySlot.Invalid) { return(null); } // If lower slot is greater than upper slot, flip the values. if (minSlot > maxSlot) { eInventorySlot tmp = minSlot; minSlot = maxSlot; maxSlot = tmp; } lock (m_items) { InventoryItem item; for (eInventorySlot i = minSlot; i <= maxSlot; i++) { if (m_items.TryGetValue(i, out item)) { if (item.Name == name) { return(item); } } } } return(null); }
/// <summary> /// Counts used/free slots between min and max /// </summary> /// <param name="countUsed"></param> /// <param name="minSlot"></param> /// <param name="maxSlot"></param> /// <returns></returns> public int CountSlots(bool countUsed, eInventorySlot minSlot, eInventorySlot maxSlot) { // If lower slot is greater than upper slot, flip the values. if (minSlot > maxSlot) { eInventorySlot tmp = minSlot; minSlot = maxSlot; maxSlot = tmp; } int result = 0; lock (m_items) // Mannen 10:56 PM 10/30/2006 - Fixing every lock(this) { for (eInventorySlot i = minSlot; i <= maxSlot; i++) { if (m_items.ContainsKey(i)) { if (countUsed) { result++; } } else { if (!countUsed) { result++; } } } return(result); } }
/// <summary> /// Adds item to template reusing iventory item instances from other templates. /// </summary> /// <param name="slot">The equipment slot</param> /// <param name="model">The equipment model</param> /// <param name="color">The equipment color</param> /// <param name="effect">The equipment effect</param> /// <param name="extension">The equipment extension</param> /// <returns>true if added</returns> public bool AddNPCEquipment(eInventorySlot slot, int model, int color, int effect, int extension, int emblem = 0) { lock (m_items) { lock (m_usedInventoryItems.SyncRoot) { if (m_isClosed) { return(false); } slot = GetValidInventorySlot(slot); if (slot == eInventorySlot.Invalid) { return(false); } // Changed to support randomization of slots - if we try to load a weapon in the same spot with a different model, // let's make it random 50% chance to either overwrite the item or leave it be if (m_items.ContainsKey(slot)) { // 50% chance to keep the item we have if (Util.Chance(50)) { return(false); } // Let's remove the old item! m_items.Remove(slot); } string itemID = string.Format("{0}:{1},{2},{3}", slot, model, color, effect, extension); InventoryItem item = null; if (!m_usedInventoryItems.ContainsKey(itemID)) { item = new GameInventoryItem(); item.Template = new ItemTemplate(); item.Template.Id_nb = itemID; item.Model = model; item.Color = color; item.Effect = effect; item.Extension = (byte)extension; item.Emblem = emblem; item.SlotPosition = (int)slot; } else { return(false); } m_items.Add(slot, item); } } return(true); }
/// <summary> /// Check if the slot is valid in the inventory /// </summary> /// <param name="slot">SlotPosition to check</param> /// <returns>the slot if it's valid or eInventorySlot.Invalid if not</returns> protected override eInventorySlot GetValidInventorySlot(eInventorySlot slot) { foreach (eInventorySlot visibleSlot in VISIBLE_SLOTS) { if (visibleSlot == slot) { return(slot); } } return(eInventorySlot.Invalid); }
/// <summary> /// Check if the slot is valid in the inventory /// </summary> /// <param name="slot">SlotPosition to check</param> /// <returns>the slot if it's valid or eInventorySlot.Invalid if not</returns> protected virtual eInventorySlot GetValidInventorySlot(eInventorySlot slot) { if ((slot >= eInventorySlot.RightHandWeapon && slot <= eInventorySlot.FourthQuiver) || (slot >= eInventorySlot.HeadArmor && slot <= eInventorySlot.Neck) || (slot >= eInventorySlot.HorseArmor && slot <= eInventorySlot.Horse) || (slot >= eInventorySlot.Waist && slot <= eInventorySlot.Mythical) || (slot == eInventorySlot.Ground) // INVENTAIRE DES CHEVAUX || (slot >= eInventorySlot.FirstBagHorse && slot <= eInventorySlot.LastBagHorse)) { return(slot); } return(eInventorySlot.Invalid); }
public static void MoveItem(GamePlayer player, eInventorySlot fromSlot, eInventorySlot toSlot) { //backpack to CM if ((int)fromSlot >= (int)eInventorySlot.FirstBackpack && (int)fromSlot <= (int)eInventorySlot.LastBackpack && (int)toSlot >= (int)eInventorySlot.HousingInventory_First && (int)toSlot <= (int)eInventorySlot.HousingInventory_Last) { InventoryItem fromItem = player.Inventory.GetItem(fromSlot); player.TempProperties.setProperty(Storm.Market.MarketNPC.TEMP_ITEM_PRICE_KEY, fromItem); toSlot = (eInventorySlot)(toSlot - (int)eInventorySlot.HousingInventory_First + (int)eInventorySlot.Consignment_First); player.Inventory.MoveItem(fromSlot, toSlot, fromItem.Count); DisplayOwnItems(player); } else if ((int)fromSlot >= (int)eInventorySlot.HousingInventory_First && (int)fromSlot <= (int)eInventorySlot.HousingInventory_Last && (int)toSlot >= (int)eInventorySlot.FirstBackpack && (int)toSlot <= (int)eInventorySlot.LastBackpack) { } }
/// <summary> /// Adds an item to the inventory and DB /// </summary> /// <param name="slot"></param> /// <param name="item"></param> /// <returns>The eInventorySlot where the item has been added</returns> public virtual bool AddItem(eInventorySlot slot, InventoryItem item) { if (item == null) { return(false); } lock (m_items) // Mannen 10:56 PM 10/30/2006 - Fixing every lock(this) { slot = GetValidInventorySlot(slot); if (slot == eInventorySlot.Invalid) { return(false); } if (m_items.ContainsKey(slot)) { if (Log.IsErrorEnabled) { Log.Error("Inventory.AddItem -> Destination slot is not empty (" + (int)slot + ")\n\n" + Environment.StackTrace); } return(false); } m_items.Add(slot, item); item.SlotPosition = (int)slot; if (item.OwnerID != null) { item.OwnerID = null; // owner ID for NPC } if (!m_changedSlots.Contains(slot)) { m_changedSlots.Add(slot); } if (m_changesCounter <= 0) { UpdateChangedSlots(); } return(true); } }
/// <summary> /// Get the item to the inventory in the specified slot /// </summary> /// <param name="slot">SlotPosition</param> /// <returns>the item in the specified slot if the slot is valid and null if not</returns> public virtual InventoryItem GetItem(eInventorySlot slot) { slot = GetValidInventorySlot(slot); if (slot == eInventorySlot.Invalid) { return(null); } lock (m_items) // Mannen 10:56 PM 10/30/2006 - Fixing every lock(this) { InventoryItem item; m_items.TryGetValue(slot, out item); return(item); //else // return null; } }
/// <summary> /// The Player is buying an Item from the merchant /// </summary> /// <param name="player"></param> /// <param name="playerInventory"></param> /// <param name="fromClientSlot"></param> /// <param name="toClientSlot"></param> public virtual void OnPlayerBuy(GamePlayer player, eInventorySlot fromClientSlot, eInventorySlot toClientSlot, bool usingMarketExplorer = false) { IDictionary <int, InventoryItem> clientInventory = GetClientInventory(player); InventoryItem fromItem = null; if (clientInventory.ContainsKey((int)fromClientSlot)) { fromItem = clientInventory[(int)fromClientSlot]; } if (fromItem == null) { ChatUtil.SendErrorMessage(player, "I can't find the item you want to purchase!"); log.ErrorFormat("CM: {0}:{1} can't find item to buy in slot {2} on consignment merchant on lot {3}.", player.Name, player.Client.Account, (int)fromClientSlot, HouseNumber); return; } string buyText = "Do you want to buy this Item?"; // If the player has a marketExplorer activated they will be charged a commission if (player.TargetObject is MarketExplorer) { player.TempProperties.setProperty(CONSIGNMENT_BUY_ITEM, fromClientSlot); if (ServerProperties.Properties.MARKET_FEE_PERCENT > 0) { player.Out.SendCustomDialog("Buying directly from the Market Explorer costs an additional " + ServerProperties.Properties.MARKET_FEE_PERCENT + "% fee. Do you want to buy this Item?", new CustomDialogResponse(BuyMarketResponse)); } else { player.Out.SendCustomDialog(buyText, new CustomDialogResponse(BuyResponse)); } } else if (player.TargetObject == this) { player.TempProperties.setProperty(CONSIGNMENT_BUY_ITEM, fromClientSlot); player.Out.SendCustomDialog(buyText, new CustomDialogResponse(BuyResponse)); } else { ChatUtil.SendErrorMessage(player, "I'm sorry, you need to be talking to a market explorer or consignment merchant in order to make a purchase."); log.ErrorFormat("CM: {0}:{1} did not have a CM or ME targeted when attempting to purchase {2} on consignment merchant on lot {3}.", player.Name, player.Client.Account, fromItem.Name, HouseNumber); } }
public void OnCommand(GameClient client, string[] args) { if (args.Length < 2) { DisplaySyntax(client); return; } eInventorySlot ToSlot = eInventorySlot.FirstBackpack; switch (args[1]) { case "1h": ToSlot = eInventorySlot.RightHandWeapon; break; case "2h": ToSlot = eInventorySlot.TwoHandWeapon; break; case "offhand": ToSlot = eInventorySlot.LeftHandWeapon; break; case "range": ToSlot = eInventorySlot.DistanceWeapon; break; } // The first backpack. int FromSlot = 40; if (int.TryParse(args[2], out FromSlot)) { FromSlot = int.Parse(args[2]); SwitchItem(client.Player, ToSlot, (eInventorySlot)FromSlot + 39); } else { DisplayMessage(client, "There seems to have been a problem. Please try again."); DisplaySyntax(client); return; } }
/// <summary> /// Searches between two slots for the first or last full or empty slot /// </summary> /// <param name="first"></param> /// <param name="last"></param> /// <param name="searchFirst"></param> /// <param name="searchNull"></param> /// <returns></returns> protected virtual eInventorySlot FindSlot(eInventorySlot first, eInventorySlot last, bool searchFirst, bool searchNull) { lock (m_items) // Mannen 10:56 PM 10/30/2006 - Fixing every lock(this) { first = GetValidInventorySlot(first); last = GetValidInventorySlot(last); if (first == eInventorySlot.Invalid || last == eInventorySlot.Invalid) { return(eInventorySlot.Invalid); } // If first/last slots are identical, check to see if the slot is full/empty and return based on // whether we instructed to find an empty or a full slot. if (first == last) { // If slot is empty, and we wanted an empty slot, or if slot is full, and we wanted // a full slot, return the given slot, otherwise return invalid. return(!m_items.ContainsKey(first) == searchNull ? first : eInventorySlot.Invalid); } // If lower slot is greater than upper slot, flip the values. if (first > last) { eInventorySlot tmp = first; first = last; last = tmp; } for (int i = 0; i <= last - first; i++) { var testSlot = (int)(searchFirst ? (first + i) : (last - i)); if (!m_items.ContainsKey((eInventorySlot)testSlot) == searchNull) { return((eInventorySlot)testSlot); } } return(eInventorySlot.Invalid); } }
public void SwitchItem(GamePlayer player, eInventorySlot ToSlot, eInventorySlot FromSlot) { if (player.Inventory.GetItem(FromSlot) != null) { InventoryItem item = player.Inventory.GetItem(FromSlot); if (!GlobalConstants.IsWeapon(item.Object_Type)) { DisplayMessage(player.Client, "That is not a weapon!"); DisplaySyntax(player.Client); return; } if (!player.Inventory.MoveItem(FromSlot, ToSlot, 1)) { DisplayMessage(player.Client, "There seems to have been a problem. Please try again."); DisplaySyntax(player.Client); return; } } }
/// <summary> /// Exchange one item position with another one /// </summary> /// <param name="fromSlot">First SlotPosition</param> /// <param name="toSlot">Second SlotPosition</param> /// <returns>true if items exchanged successfully</returns> protected virtual bool ExchangeItems(eInventorySlot fromSlot, eInventorySlot toSlot) { InventoryItem newFromItem; InventoryItem newToItem; m_items.TryGetValue(fromSlot, out newToItem); m_items.TryGetValue(toSlot, out newFromItem); // Make sure one of the slots has an item, otherwise there is nothing to exchange. if (newFromItem == null && newToItem == null) { return(false); } // Swap the items. m_items[fromSlot] = newFromItem; m_items[toSlot] = newToItem; // If 'toSlot' wasn't empty, adjust the slot position for the item now in 'fromSlot', otherwise clear the new slot. if (newFromItem != null) { newFromItem.SlotPosition = (int)fromSlot; } else { m_items.Remove(fromSlot); } // If 'fromSlot' wasn't empty, adjust the slot position for the item now in 'toSlot', otherwise clear the new slot. if (newToItem != null) { newToItem.SlotPosition = (int)toSlot; } else { m_items.Remove(toSlot); } return(true); }
/// <summary> /// Changes the commander's weapon to the specified type /// </summary> /// <param name="slot"></param> /// <param name="aSlot"></param> /// <param name="weaponType"></param> protected void CommanderSwitchWeapon(eInventorySlot slot, eActiveWeaponSlot aSlot, string weaponType) { if (Inventory == null) { return; } string itemId = string.Format("BD_Commander_{0}_{1}", slot.ToString(), weaponType); // all weapons removed before InventoryItem item = Inventory.GetItem(eInventorySlot.RightHandWeapon); if (item != null) { Inventory.RemoveItem(item); } item = Inventory.GetItem(eInventorySlot.TwoHandWeapon); if (item != null) { Inventory.RemoveItem(item); } ItemTemplate temp = GameServer.Database.FindObjectByKey <ItemTemplate>(itemId); if (temp == null) { if (log.IsErrorEnabled) { log.Error(string.Format("Unable to find Bonedancer item: {0}", itemId)); } return; } Inventory.AddItem(slot, GameInventoryItem.Create(temp)); SwitchWeapon(aSlot); AddStatsToWeapon(); BroadcastLivingEquipmentUpdate(); }
/// <summary> /// Exchange two Items in form specified slot /// </summary> /// <param name="fromSlot">Source slot</param> /// <param name="toSlot">Destination slot</param> /// <param name="itemCount"></param> /// <returns>true if successfull false if not</returns> public virtual bool MoveItem(eInventorySlot fromSlot, eInventorySlot toSlot, int itemCount) { lock (m_items) // Mannen 10:56 PM 10/30/2006 - Fixing every lock(this) { fromSlot = GetValidInventorySlot(fromSlot); toSlot = GetValidInventorySlot(toSlot); if (fromSlot == eInventorySlot.Invalid || toSlot == eInventorySlot.Invalid) { return(false); } InventoryItem fromItem; InventoryItem toItem; m_items.TryGetValue(fromSlot, out fromItem); m_items.TryGetValue(toSlot, out toItem); if (!CombineItems(fromItem, toItem) && !StackItems(fromSlot, toSlot, itemCount)) { ExchangeItems(fromSlot, toSlot); } if (!m_changedSlots.Contains(fromSlot)) { m_changedSlots.Add(fromSlot); } if (!m_changedSlots.Contains(toSlot)) { m_changedSlots.Add(toSlot); } if (m_changesCounter <= 0) { UpdateChangedSlots(); } return(true); } }
/// <summary> /// Find the last full slot in the inventory /// </summary> /// <param name="first">SlotPosition to start the search</param> /// <param name="last">SlotPosition to stop the search</param> /// <returns>the empty inventory slot or eInventorySlot.Invalid</returns> public virtual eInventorySlot FindLastFullSlot(eInventorySlot first, eInventorySlot last) { return FindSlot(first, last, false, false); }
/// <summary> /// Checks if specified count of slots is free /// </summary> /// <param name="count"></param> /// <param name="minSlot"></param> /// <param name="maxSlot"></param> /// <returns></returns> public bool IsSlotsFree(int count, eInventorySlot minSlot, eInventorySlot maxSlot) { if (count < 1) return true; // If lower slot is greater than upper slot, flip the values. if (minSlot > maxSlot) { eInventorySlot tmp = minSlot; minSlot = maxSlot; maxSlot = tmp; } lock (m_items) // Mannen 10:56 PM 10/30/2006 - Fixing every lock(this) { for (eInventorySlot i = minSlot; i <= maxSlot; i++) { if (m_items.ContainsKey(i)) continue; count--; if (count <= 0) return true; } return false; } }
/// <summary> /// Counts used/free slots between min and max /// </summary> /// <param name="countUsed"></param> /// <param name="minSlot"></param> /// <param name="maxSlot"></param> /// <returns></returns> public int CountSlots(bool countUsed, eInventorySlot minSlot, eInventorySlot maxSlot) { // If lower slot is greater than upper slot, flip the values. if (minSlot > maxSlot) { eInventorySlot tmp = minSlot; minSlot = maxSlot; maxSlot = tmp; } int result = 0; lock (m_items) // Mannen 10:56 PM 10/30/2006 - Fixing every lock(this) { for (eInventorySlot i = minSlot; i <= maxSlot; i++) { if (m_items.ContainsKey(i)) { if (countUsed) result++; } else { if (!countUsed) result++; } } return result; } }
/// <summary> /// Stack an item with another one /// </summary> /// <param name="fromSlot">First SlotPosition</param> /// <param name="toSlot">Second SlotPosition</param> /// <param name="itemCount">How many items to move</param> /// <returns>true if items stacked successfully</returns> protected virtual bool StackItems(eInventorySlot fromSlot, eInventorySlot toSlot, int itemCount) { return false; }
/// <summary> /// Add starter equipment to the character /// </summary> /// <param name="c">The character</param> public static void AddEquipment(DOLCharacters c) { Hashtable usedSlots = new Hashtable(); // 0 = for all classes, then quickcheck if it contains the classid var items = GameServer.Database.SelectObjects <StarterEquipment>("`Class` = '0' OR `Class` LIKE '%" + c.Class + "%'"); foreach (StarterEquipment item in items) { if (item.Template == null) { GameServer.Instance.Logger.Error("StartupEquipment.cs error adding starter equipment for class " + c.Class + " cannot find itemtemplate for " + item.TemplateID); continue; } // deeper check if item is suitable to classid if (!Util.IsEmpty(item.Class, true)) { int charClass; bool isFind = false; foreach (string currentItem in item.Class.SplitCSV(true)) { int.TryParse(currentItem, out charClass); if (charClass == c.Class) { isFind = true; break; } } if (!isFind) { continue; } } InventoryItem inventoryItem = GameInventoryItem.Create <ItemTemplate>(item.Template); inventoryItem.OwnerID = c.ObjectId; inventoryItem.Realm = c.Realm; //if equipable item, equip foreach (eInventorySlot slot in GameLivingInventory.EQUIP_SLOTS) { if (slot == (eInventorySlot)inventoryItem.Item_Type) { eInventorySlot chosenSlot = eInventorySlot.FirstEmptyBackpack; if (slot == eInventorySlot.LeftHandWeapon && (eObjectType)inventoryItem.Object_Type != eObjectType.Shield && usedSlots.ContainsKey(eInventorySlot.RightHandWeapon) == false) { chosenSlot = eInventorySlot.RightHandWeapon; } else { chosenSlot = slot; } if (usedSlots.ContainsKey(chosenSlot)) { GameServer.Instance.Logger.Error("Cannot add item " + item.TemplateID + " to class " + item.Class + " already an item for that slot assigned!"); continue; } inventoryItem.SlotPosition = (int)chosenSlot; usedSlots[chosenSlot] = true; if (c.ActiveWeaponSlot == 0) { switch (inventoryItem.SlotPosition) { case Slot.RIGHTHAND: c.ActiveWeaponSlot = (byte)GamePlayer.eActiveWeaponSlot.Standard; break; case Slot.TWOHAND: c.ActiveWeaponSlot = (byte)GamePlayer.eActiveWeaponSlot.TwoHanded; break; case Slot.RANGED: c.ActiveWeaponSlot = (byte)GamePlayer.eActiveWeaponSlot.Distance; break; } } } } if (inventoryItem.SlotPosition == 0) { //otherwise stick the item in the backpack for (int i = (int)eInventorySlot.FirstBackpack; i < (int)eInventorySlot.LastBackpack; i++) { if (usedSlots[i] == null) { inventoryItem.SlotPosition = i; usedSlots[i] = true; break; } } } GameServer.Database.AddObject(inventoryItem); } }
/// <summary> /// Move an item from a player's backpack to this inventory object (uses client slots) /// </summary> public static IDictionary<int, InventoryItem> MoveItemToObject(this IGameInventoryObject thisObject, GamePlayer player, eInventorySlot fromClientSlot, eInventorySlot toClientSlot) { // We will only allow moving from the backpack. if (fromClientSlot < eInventorySlot.FirstBackpack || fromClientSlot > eInventorySlot.LastBackpack) return null; InventoryItem fromItem = player.Inventory.GetItem(fromClientSlot); if (fromItem == null) return null; lock (thisObject.LockObject()) { Dictionary<int, InventoryItem> inventory = thisObject.GetClientInventory(player); player.Inventory.RemoveTradeItem(fromItem); // if there is an item in the objects target slot then move it to the players inventory if (inventory.ContainsKey((int)toClientSlot)) { InventoryItem toItem = inventory[(int)toClientSlot]; thisObject.OnRemoveItem(player, toItem); player.Inventory.AddTradeItem(fromClientSlot, toItem); } fromItem.OwnerID = thisObject.GetOwner(player); fromItem.SlotPosition = (int)(toClientSlot) - (int)(thisObject.FirstClientSlot) + thisObject.FirstDBSlot; thisObject.OnAddItem(player, fromItem); GameServer.Database.SaveObject(fromItem); var updateItems = new Dictionary<int, InventoryItem>(1); updateItems.Add((int)toClientSlot, fromItem); // for objects that support doing something when added (setting a price, for example) player.TempProperties.setProperty(ITEM_BEING_ADDED, fromItem); return updateItems; } }
public virtual bool AddTradeItem(eInventorySlot slot, InventoryItem item) { return false; }
/// <summary> /// Overridden. Inventory template cannot be modified. /// </summary> /// <param name="fromSlot">First SlotPosition</param> /// <param name="toSlot">Second SlotPosition</param> /// <param name="itemCount">How many items to move</param> /// <returns>false</returns> protected override bool StackItems(eInventorySlot fromSlot, eInventorySlot toSlot, int itemCount) { return false; }
/// <summary> /// Overridden. Inventory template cannot be modified. /// </summary> /// <param name="fromSlot">First SlotPosition</param> /// <param name="toSlot">Second SlotPosition</param> /// <returns>false</returns> protected override bool ExchangeItems(eInventorySlot fromSlot, eInventorySlot toSlot) { return false; }
/// <summary> /// Overridden. Inventory template cannot be modified. /// </summary> /// <param name="template">The ItemTemplate</param> /// <param name="count">The count of items to add</param> /// <param name="minSlot">The first slot</param> /// <param name="maxSlot">The last slot</param> /// <returns>false</returns> public override bool AddTemplate(InventoryItem template, int count, eInventorySlot minSlot, eInventorySlot maxSlot) { return false; }
/// <summary> /// Overridden. Inventory template cannot be modified. /// </summary> /// <param name="templateID">The ItemTemplate ID</param> /// <param name="count">The count of items to add</param> /// <param name="minSlot">The first slot</param> /// <param name="maxSlot">The last slot</param> /// <returns>false</returns> public override bool RemoveTemplate(string templateID, int count, eInventorySlot minSlot, eInventorySlot maxSlot) { return false; }
/// <summary> /// Find the last full slot in the inventory /// </summary> /// <param name="first">SlotPosition to start the search</param> /// <param name="last">SlotPosition to stop the search</param> /// <returns>the empty inventory slot or eInventorySlot.Invalid</returns> public virtual eInventorySlot FindLastFullSlot(eInventorySlot first, eInventorySlot last) { return(FindSlot(first, last, false, false)); }
/// <summary> /// Find the last empty slot in the inventory /// </summary> /// <param name="first">SlotPosition to start the search</param> /// <param name="last">SlotPosition to stop the search</param> /// <returns>the empty inventory slot or eInventorySlot.Invalid</returns> public virtual eInventorySlot FindLastEmptySlot(eInventorySlot first, eInventorySlot last) { return(FindSlot(first, last, false, true)); }
/// <summary> /// Adds item to template reusing inventory item instances from other templates. /// </summary> /// <param name="slot">The equipment slot</param> /// <param name="model">The equipment model</param> /// <returns>true if added</returns> public bool AddNPCEquipment(eInventorySlot slot, int model) { return AddNPCEquipment(slot, model, 0, 0, 0); }
/// <summary> /// Searches between two slots for the first or last full or empty slot /// </summary> /// <param name="first"></param> /// <param name="last"></param> /// <param name="searchFirst"></param> /// <param name="searchNull"></param> /// <returns></returns> protected virtual eInventorySlot FindSlot(eInventorySlot first, eInventorySlot last, bool searchFirst, bool searchNull) { lock (m_items) // Mannen 10:56 PM 10/30/2006 - Fixing every lock(this) { first = GetValidInventorySlot(first); last = GetValidInventorySlot(last); if (first == eInventorySlot.Invalid || last == eInventorySlot.Invalid) return eInventorySlot.Invalid; // If first/last slots are identical, check to see if the slot is full/empty and return based on // whether we instructed to find an empty or a full slot. if (first == last) { // If slot is empty, and we wanted an empty slot, or if slot is full, and we wanted // a full slot, return the given slot, otherwise return invalid. return !m_items.ContainsKey(first) == searchNull ? first : eInventorySlot.Invalid; } // If lower slot is greater than upper slot, flip the values. if (first > last) { eInventorySlot tmp = first; first = last; last = tmp; } for (int i = 0; i <= last - first; i++) { var testSlot = (int) (searchFirst ? (first + i) : (last - i)); if (!m_items.ContainsKey((eInventorySlot) testSlot) == searchNull) return (eInventorySlot) testSlot; } return eInventorySlot.Invalid; } }
/// <summary> /// Searches for the first occurrence of an item with given /// name between specified slots /// </summary> /// <param name="name">name</param> /// <param name="minSlot">fist slot for search</param> /// <param name="maxSlot">last slot for search</param> /// <returns>found item or null</returns> public InventoryItem GetFirstItemByName(string name, eInventorySlot minSlot, eInventorySlot maxSlot) { minSlot = GetValidInventorySlot(minSlot); maxSlot = GetValidInventorySlot(maxSlot); if (minSlot == eInventorySlot.Invalid || maxSlot == eInventorySlot.Invalid) return null; // If lower slot is greater than upper slot, flip the values. if (minSlot > maxSlot) { eInventorySlot tmp = minSlot; minSlot = maxSlot; maxSlot = tmp; } lock (m_items) { InventoryItem item; for (eInventorySlot i = minSlot; i <= maxSlot; i++) { if (m_items.TryGetValue(i, out item)) { if (item.Name == name) return item; } } } return null; }
/// <summary> /// Exchange two Items in form specified slot /// </summary> /// <param name="fromSlot">Source slot</param> /// <param name="toSlot">Destination slot</param> /// <param name="itemCount"></param> /// <returns>true if successfull false if not</returns> public virtual bool MoveItem(eInventorySlot fromSlot, eInventorySlot toSlot, int itemCount) { lock (m_items) // Mannen 10:56 PM 10/30/2006 - Fixing every lock(this) { fromSlot = GetValidInventorySlot(fromSlot); toSlot = GetValidInventorySlot(toSlot); if (fromSlot == eInventorySlot.Invalid || toSlot == eInventorySlot.Invalid) return false; InventoryItem fromItem; InventoryItem toItem; m_items.TryGetValue(fromSlot, out fromItem); m_items.TryGetValue(toSlot, out toItem); if (!CombineItems(fromItem, toItem) && !StackItems(fromSlot, toSlot, itemCount)) { ExchangeItems(fromSlot, toSlot); } if (!m_changedSlots.Contains(fromSlot)) m_changedSlots.Add(fromSlot); if (!m_changedSlots.Contains(toSlot)) m_changedSlots.Add(toSlot); if (m_changesCounter <= 0) UpdateChangedSlots(); return true; } }
/// <summary> /// Removes needed amount of items from inventory if /// enough amount of items are in inventory /// </summary> /// <param name="templateID">The ItemTemplate ID</param> /// <param name="count">The count of items to add</param> /// <param name="minSlot">The first slot</param> /// <param name="maxSlot">The last slot</param> /// <returns>True if all items were added</returns> public virtual bool RemoveTemplate(string templateID, int count, eInventorySlot minSlot, eInventorySlot maxSlot) { if (templateID == null) { return(false); } if (count <= 0) { return(false); } if (minSlot > maxSlot) { eInventorySlot tmp = minSlot; minSlot = maxSlot; maxSlot = tmp; } if (minSlot < eInventorySlot.Min_Inv) { return(false); } if (maxSlot > eInventorySlot.Max_Inv) { return(false); } lock (m_items) // Mannen 10:56 PM 10/30/2006 - Fixing every lock(this) { var changedSlots = new Dictionary <InventoryItem, int>(); // value: null = remove item completely; >0 = remove count from stack bool remove = false; for (eInventorySlot slot = minSlot; slot <= maxSlot; slot++) { InventoryItem item; if (!m_items.TryGetValue(slot, out item)) { continue; } if (item.Id_nb != templateID) { continue; } if (count >= item.Count) { count -= item.Count; changedSlots.Add(item, -1); // remove completely } else { changedSlots.Add(item, count); // remove count count = 0; } if (count == 0) { remove = true; break; } else if (count < 0) { throw new Exception("Count less than zero while removing template."); } } if (!remove) { return(false); } BeginChanges(); try { foreach (var de in changedSlots) { InventoryItem item = de.Key; if (de.Value == -1) { if (!RemoveItem(item)) { CommitChanges(); throw new Exception("Error removing item."); } } else if (!RemoveCountFromStack(item, de.Value)) { CommitChanges(); throw new Exception("Error removing count from stack."); } } } finally { CommitChanges(); } return(true); } }
/// <summary> /// Overridden. Inventory template cannot be modified. /// </summary> /// <param name="fromSlot"></param> /// <param name="toSlot"></param> /// <param name="itemCount"></param> /// <returns></returns> public override bool MoveItem(eInventorySlot fromSlot, eInventorySlot toSlot, int itemCount) { return false; }
/// <summary> /// Move an item around inside this object (uses client slots) /// </summary> public static IDictionary<int, InventoryItem> MoveItemInsideObject(this IGameInventoryObject thisObject, GamePlayer player, eInventorySlot fromSlot, eInventorySlot toSlot) { lock (thisObject.LockObject()) { IDictionary<int, InventoryItem> inventory = thisObject.GetClientInventory(player); if (!inventory.ContainsKey((int)fromSlot)) return null; var updateItems = new Dictionary<int, InventoryItem>(2); InventoryItem fromItem = null, toItem = null; fromItem = inventory[(int)fromSlot]; if (inventory.ContainsKey((int)toSlot)) { toItem = inventory[(int)toSlot]; toItem.SlotPosition = fromItem.SlotPosition; GameServer.Database.SaveObject(toItem); } fromItem.SlotPosition = (int)toSlot - (int)(thisObject.FirstClientSlot) + thisObject.FirstDBSlot; GameServer.Database.SaveObject(fromItem); updateItems.Add((int)fromSlot, toItem); updateItems.Add((int)toSlot, fromItem); return updateItems; } }
/// <summary> /// Constructs a new ItemEquippedArgs /// </summary> /// <param name="item">The unequipped item</param> /// <param name="previousSlotPos">The slot position item had before it was equipped</param> public ItemUnequippedArgs(InventoryItem item, int previousSlotPos) { m_item = item; m_previousSlotPos = (eInventorySlot)previousSlotPos; }
/// <summary> /// Removes needed amount of items from inventory if /// enough amount of items are in inventory /// </summary> /// <param name="templateID">The ItemTemplate ID</param> /// <param name="count">The count of items to add</param> /// <param name="minSlot">The first slot</param> /// <param name="maxSlot">The last slot</param> /// <returns>True if all items were added</returns> public virtual bool RemoveTemplate(string templateID, int count, eInventorySlot minSlot, eInventorySlot maxSlot) { if (templateID == null) return false; if (count <= 0) return false; if (minSlot > maxSlot) { eInventorySlot tmp = minSlot; minSlot = maxSlot; maxSlot = tmp; } if (minSlot < eInventorySlot.Min_Inv) return false; if (maxSlot > eInventorySlot.Max_Inv) return false; lock (m_items) // Mannen 10:56 PM 10/30/2006 - Fixing every lock(this) { var changedSlots = new Dictionary<InventoryItem, int>(); // value: null = remove item completely; >0 = remove count from stack bool remove = false; for (eInventorySlot slot = minSlot; slot <= maxSlot; slot++) { InventoryItem item; if (!m_items.TryGetValue(slot, out item)) continue; if (item.Id_nb != templateID) continue; if (count >= item.Count) { count -= item.Count; changedSlots.Add(item, -1); // remove completely } else { changedSlots.Add(item, count); // remove count count = 0; } if (count == 0) { remove = true; break; } else if (count < 0) { throw new Exception("Count less than zero while removing template."); } } if (!remove) return false; BeginChanges(); try { foreach (var de in changedSlots) { InventoryItem item = de.Key; if (de.Value == -1) { if (!RemoveItem(item)) { CommitChanges(); throw new Exception("Error removing item."); } } else if (!RemoveCountFromStack(item, de.Value)) { CommitChanges(); throw new Exception("Error removing count from stack."); } } } finally { CommitChanges(); } return true; } }
/// <summary> /// Adds needed amount of items to inventory if there /// is enough space else nothing is done /// </summary> /// <param name="sourceItem">The source inventory item</param> /// <param name="count">The count of items to add</param> /// <param name="minSlot">The first slot</param> /// <param name="maxSlot">The last slot</param> /// <returns>True if all items were added</returns> public virtual bool AddTemplate(InventoryItem sourceItem, int count, eInventorySlot minSlot, eInventorySlot maxSlot) { // Make sure template isn't null. if (sourceItem == null) { return(false); } // Make sure we have a positive item count. if (count <= 0) { return(false); } // If lower slot is greater than upper slot, flip the values. if (minSlot > maxSlot) { eInventorySlot tmp = minSlot; minSlot = maxSlot; maxSlot = tmp; } // Make sure lower slot is within inventory bounds. if (minSlot < eInventorySlot.Min_Inv) { return(false); } // Make sure upper slot is within inventory bounds. if (maxSlot > eInventorySlot.Max_Inv) { return(false); } lock (m_items) // Mannen 10:56 PM 10/30/2006 - Fixing every lock(this) { var changedSlots = new Dictionary <eInventorySlot, int>(); // value: <0 = new item count; >0 = add to old bool fits = false; int itemcount = count; eInventorySlot i = minSlot; // Find open slots/existing stacks to fit in these items. do { // Get the current slot, make sure it's valid. eInventorySlot curSlot = GetValidInventorySlot(i); if (curSlot == eInventorySlot.Invalid) { continue; } InventoryItem curItem; // Make sure slot isn't empty. if (!m_items.TryGetValue(curSlot, out curItem)) { continue; } // If slot isn't of the same type as our template, we can't stack, so skip. if (curItem.Id_nb != sourceItem.Id_nb) { continue; } // Can't add to an already maxed-out stack. if (curItem.Count >= curItem.MaxCount) { continue; } // Get the number of free spaces left in the given stack. int countFree = curItem.MaxCount - curItem.Count; // See if we can fit all our items in the given stack. If not, fit what we can. int countAdd = count; if (countAdd > countFree) { countAdd = countFree; } // Set the number of items to add to the stack at the given slot. (positive value indicates we're adding to a stack, not to an empty slot.) changedSlots[curSlot] = countAdd; // Reduce the overall count of items we need to fit. count -= countAdd; // If we've fit everything in existing stacks, we're done trying to find matches. if (count == 0) { fits = true; break; } // Exceptional error, count should never be negative. if (count < 0) { throw new Exception("Count is less than zero while filling gaps, should never happen!"); } } while (++i <= maxSlot); if (!fits) { // We couldn't manage to find existing stacks, or enough existing stacks, to add our items to. // We now need to find totally open slots to put our items in. for (i = minSlot; i <= maxSlot; i++) { // Get the current slot, make sure it's valid. eInventorySlot curSlot = GetValidInventorySlot(i); if (curSlot == eInventorySlot.Invalid) { continue; } // Skip any slots we already found as being occupied. if (changedSlots.ContainsKey(curSlot)) { continue; } // Skip any slots that are already in use. if (m_items.ContainsKey(curSlot)) { continue; } // If the max stack count is less than remaining items to add, we can only add the max // stack count and must find remaining slots to allocate the rest of the items to. int countAdd = count; if (countAdd > sourceItem.MaxCount) { countAdd = sourceItem.MaxCount; } // Set the number of items to add to the given slot. (negative amount indicates we're adding a new item, not stacking) changedSlots[curSlot] = -countAdd; // Reduce the overall count of items we need to fit. count -= countAdd; // If we've fit everything in existing stacks and open slots, we're done trying to find matches. if (count == 0) { fits = true; break; } // Exceptional error, count should never be negative. if (count < 0) { throw new Exception("Count is less than zero while adding new items, should never happen!"); } } } // If we still weren't able to fit all the items, then this is a failed add. if (!fits) { return(false); } // Add new items BeginChanges(); try { foreach (var slot in changedSlots) { InventoryItem item; eInventorySlot itemSlot = slot.Key; int itemCount = slot.Value; if (itemCount > 0) // existing item should be changed { if (m_items.TryGetValue(itemSlot, out item)) { AddCountToStack(item, itemCount); } } else if (itemCount < 0) // new item should be added { if (sourceItem.Template is ItemUnique) { item = GameInventoryItem.Create(sourceItem); } else { item = GameInventoryItem.Create(sourceItem.Template); } item.Count = -itemCount; AddItem(itemSlot, item); } } } finally { CommitChanges(); } return(true); } }
/// <summary> /// Exchange one item position with another one /// </summary> /// <param name="fromSlot">First SlotPosition</param> /// <param name="toSlot">Second SlotPosition</param> /// <returns>true if items exchanged successfully</returns> protected virtual bool ExchangeItems(eInventorySlot fromSlot, eInventorySlot toSlot) { InventoryItem newFromItem; InventoryItem newToItem; m_items.TryGetValue(fromSlot, out newToItem); m_items.TryGetValue(toSlot, out newFromItem); // Make sure one of the slots has an item, otherwise there is nothing to exchange. if (newFromItem == null && newToItem == null) return false; // Swap the items. m_items[fromSlot] = newFromItem; m_items[toSlot] = newToItem; // If 'toSlot' wasn't empty, adjust the slot position for the item now in 'fromSlot', otherwise clear the new slot. if (newFromItem != null) { newFromItem.SlotPosition = (int) fromSlot; } else { m_items.Remove(fromSlot); } // If 'fromSlot' wasn't empty, adjust the slot position for the item now in 'toSlot', otherwise clear the new slot. if (newToItem != null) { newToItem.SlotPosition = (int) toSlot; } else { m_items.Remove(toSlot); } return true; }
/// <summary> /// The Player is buying an Item from the merchant /// </summary> /// <param name="player"></param> /// <param name="playerInventory"></param> /// <param name="fromClientSlot"></param> /// <param name="toClientSlot"></param> public virtual void OnPlayerBuy(GamePlayer player, eInventorySlot fromClientSlot, eInventorySlot toClientSlot, bool usingMarketExplorer = false) { IDictionary<int, InventoryItem> clientInventory = GetClientInventory(player); InventoryItem fromItem = null; if (clientInventory.ContainsKey((int)fromClientSlot)) { fromItem = clientInventory[(int)fromClientSlot]; } if (fromItem == null) { ChatUtil.SendErrorMessage(player, "I can't find the item you want to purchase!"); log.ErrorFormat("CM: {0}:{1} can't find item to buy in slot {2} on consignment merchant on lot {3}.", player.Name, player.Client.Account, (int)fromClientSlot, HouseNumber); return; } string buyText = "Do you want to buy this Item?"; // If the player has a marketExplorer activated they will be charged a commission if (player.TargetObject is MarketExplorer) { player.TempProperties.setProperty(CONSIGNMENT_BUY_ITEM, fromClientSlot); if (ServerProperties.Properties.MARKET_FEE_PERCENT > 0) { player.Out.SendCustomDialog("Buying directly from the Market Explorer costs an additional " + ServerProperties.Properties.MARKET_FEE_PERCENT + "% fee. Do you want to buy this Item?", new CustomDialogResponse(BuyMarketResponse)); } else { player.Out.SendCustomDialog(buyText, new CustomDialogResponse(BuyResponse)); } } else if (player.TargetObject == this) { player.TempProperties.setProperty(CONSIGNMENT_BUY_ITEM, fromClientSlot); player.Out.SendCustomDialog(buyText, new CustomDialogResponse(BuyResponse)); } else { ChatUtil.SendErrorMessage(player, "I'm sorry, you need to be talking to a market explorer or consignment merchant in order to make a purchase."); log.ErrorFormat("CM: {0}:{1} did not have a CM or ME targeted when attempting to purchase {2} on consignment merchant on lot {3}.", player.Name, player.Client.Account, fromItem.Name, HouseNumber); } }
/// <summary> /// Count items of some type /// </summary> /// <param name="itemtemplateID">template to count</param> /// <param name="minSlot">first slot</param> /// <param name="maxSlot">last slot</param> /// <returns>number of matched items found</returns> public int CountItemTemplate(string itemtemplateID, eInventorySlot minSlot, eInventorySlot maxSlot) { lock (m_items) // Mannen 10:56 PM 10/30/2006 - Fixing every lock(this) { int count = 0; // If lower slot is greater than upper slot, flip the values. if (minSlot > maxSlot) { eInventorySlot tmp = minSlot; minSlot = maxSlot; maxSlot = tmp; } InventoryItem item; for (eInventorySlot i = minSlot; i <= maxSlot; i++) { if (m_items.TryGetValue(i, out item) && item.Id_nb == itemtemplateID) { count += item.Count; } } return count++; } }
/// <summary> /// Changes the commander's weapon to the specified type /// </summary> /// <param name="slot"></param> /// <param name="aSlot"></param> /// <param name="weaponType"></param> protected void CommanderSwitchWeapon(eInventorySlot slot, eActiveWeaponSlot aSlot, string weaponType) { if (Inventory == null) return; string itemId = string.Format("BD_Commander_{0}_{1}", slot.ToString(), weaponType); //all weapons removed before InventoryItem item = Inventory.GetItem(eInventorySlot.RightHandWeapon); if (item != null) Inventory.RemoveItem(item); item = Inventory.GetItem(eInventorySlot.TwoHandWeapon); if (item != null) Inventory.RemoveItem(item); ItemTemplate temp = GameServer.Database.FindObjectByKey<ItemTemplate>(itemId); if (temp == null) { if (log.IsErrorEnabled) log.Error(string.Format("Unable to find Bonedancer item: {0}", itemId)); return; } Inventory.AddItem(slot, GameInventoryItem.Create<ItemTemplate>(temp)); SwitchWeapon(aSlot); AddStatsToWeapon(); BroadcastLivingEquipmentUpdate(); }
/// <summary> /// Find the last empty slot in the inventory /// </summary> /// <param name="first">SlotPosition to start the search</param> /// <param name="last">SlotPosition to stop the search</param> /// <returns>the empty inventory slot or eInventorySlot.Invalid</returns> public virtual eInventorySlot FindLastEmptySlot(eInventorySlot first, eInventorySlot last) { return FindSlot(first, last, false, true); }
/// <summary> /// Make the crafted item and add it to player's inventory /// </summary> /// <param name="player"></param> /// <param name="recipe"></param> /// <returns></returns> protected virtual void BuildCraftedItem(GamePlayer player, DBCraftedItem recipe, ItemTemplate itemToCraft) { Dictionary <int, int> changedSlots = new Dictionary <int, int>(5); // key : > 0 inventory ; < 0 ground || value: < 0 = new item count; > 0 = add to old lock (player.Inventory) { int count = itemToCraft.PackSize < 1 ? 1 : itemToCraft.PackSize; foreach (InventoryItem item in player.Inventory.GetItemRange(eInventorySlot.FirstBackpack, eInventorySlot.LastBackpack)) { if (item == null) { continue; } if (item.Id_nb.Equals(itemToCraft.Id_nb) == false) { continue; } if (item.Count >= itemToCraft.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); if (firstEmptySlot == eInventorySlot.Invalid) { changedSlots.Add(-1, -count); // Create the item on the ground } else { changedSlots.Add((int)firstEmptySlot, -count); // Create the item in the free slot } count = 0; } InventoryItem newItem = null; player.Inventory.BeginChanges(); Dictionary <int, int> .Enumerator enumerator = changedSlots.GetEnumerator(); while (enumerator.MoveNext()) { KeyValuePair <int, int> slot = enumerator.Current; int countToAdd = slot.Value; if (countToAdd > 0) // Add to exiting item { newItem = player.Inventory.GetItem((eInventorySlot)slot.Key); if (newItem != null && player.Inventory.AddCountToStack(newItem, countToAdd)) { InventoryLogging.LogInventoryAction("(craft)", player, eInventoryActionType.Other, newItem.Template, countToAdd); // count incremented, continue with next change continue; } } if (recipe.MakeTemplated) { string adjItem = itemToCraft.Id_nb + (GetQuality(player, recipe).ToString()); ItemTemplate adjItemToCraft = GameServer.Database.FindObjectByKey <ItemTemplate>(adjItem); if (adjItemToCraft != null) { newItem = GameInventoryItem.Create <ItemTemplate>(adjItemToCraft); } else { newItem = GameInventoryItem.Create <ItemTemplate>(itemToCraft); } } else { ItemUnique unique = new ItemUnique(itemToCraft); GameServer.Database.AddObject(unique); newItem = GameInventoryItem.Create <ItemUnique>(unique); newItem.Quality = GetQuality(player, recipe); } newItem.IsCrafted = true; newItem.Creator = player.Name; newItem.Count = -countToAdd; if (slot.Key > 0) // Create new item in the backpack { player.Inventory.AddItem((eInventorySlot)slot.Key, newItem); InventoryLogging.LogInventoryAction("(craft)", player, eInventoryActionType.Craft, newItem.Template, newItem.Count); } else // Create new item on the ground { player.CreateItemOnTheGround(newItem); player.Out.SendDialogBox(eDialogCode.SimpleWarning, 0, 0, 0, 0, eDialogType.Ok, true, LanguageMgr.GetTranslation(player.Client.Account.Language, "AbstractCraftingSkill.BuildCraftedItem.BackpackFull", itemToCraft.Name)); } } player.Inventory.CommitChanges(); player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client.Account.Language, "AbstractCraftingSkill.BuildCraftedItem.Successfully", itemToCraft.Name, newItem.Quality), eChatType.CT_Missed, eChatLoc.CL_SystemWindow); if (recipe.MakeTemplated == false && newItem.Quality == 100) { player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client.Account.Language, "AbstractCraftingSkill.BuildCraftedItem.Masterpiece"), eChatType.CT_Important, eChatLoc.CL_SystemWindow); player.Out.SendPlaySound(eSoundType.Craft, 0x04); } else { player.Out.SendPlaySound(eSoundType.Craft, 0x03); } } }
/// <summary> /// Check if the slot is valid in the inventory /// </summary> /// <param name="slot">SlotPosition to check</param> /// <returns>the slot if it's valid or eInventorySlot.Invalid if not</returns> protected virtual eInventorySlot GetValidInventorySlot(eInventorySlot slot) { if ((slot >= eInventorySlot.RightHandWeapon && slot <= eInventorySlot.FourthQuiver) || (slot >= eInventorySlot.HeadArmor && slot <= eInventorySlot.Neck) || (slot >= eInventorySlot.HorseArmor && slot <= eInventorySlot.Horse) || (slot >= eInventorySlot.Waist && slot <= eInventorySlot.Mythical) || (slot == eInventorySlot.Ground) // INVENTAIRE DES CHEVAUX || (slot >= eInventorySlot.FirstBagHorse && slot <= eInventorySlot.LastBagHorse)) return slot; return eInventorySlot.Invalid; }
protected virtual void BuyItem(GamePlayer player, bool usingMarketExplorer = false) { eInventorySlot fromClientSlot = player.TempProperties.getProperty <eInventorySlot>(CONSIGNMENT_BUY_ITEM, eInventorySlot.Invalid); player.TempProperties.removeProperty(CONSIGNMENT_BUY_ITEM); InventoryItem item = null; lock (LockObject()) { if (fromClientSlot != eInventorySlot.Invalid) { IDictionary <int, InventoryItem> clientInventory = GetClientInventory(player); if (clientInventory.ContainsKey((int)fromClientSlot)) { item = clientInventory[(int)fromClientSlot]; } } if (item == null) { ChatUtil.SendErrorMessage(player, "I can't find the item you want to purchase!"); log.ErrorFormat("{0}:{1} tried to purchase an item from slot {2} for consignment merchant on lot {3} and the item does not exist.", player.Name, player.Client.Account, (int)fromClientSlot, HouseNumber); return; } int sellPrice = item.SellPrice; int purchasePrice = sellPrice; if (usingMarketExplorer && ServerProperties.Properties.MARKET_FEE_PERCENT > 0) { purchasePrice += ((purchasePrice * ServerProperties.Properties.MARKET_FEE_PERCENT) / 100); } lock (player.Inventory) { if (purchasePrice <= 0) { ChatUtil.SendErrorMessage(player, "This item can't be purchased!"); log.ErrorFormat("{0}:{1} tried to purchase {2} for consignment merchant on lot {3} and purchasePrice was {4}.", player.Name, player.Client.Account, item.Name, HouseNumber, purchasePrice); return; } if (ServerProperties.Properties.CONSIGNMENT_USE_BP) { if (player.BountyPoints < purchasePrice) { ChatUtil.SendSystemMessage(player, "GameMerchant.OnPlayerBuy.YouNeedBP", purchasePrice); return; } } else { if (player.GetCurrentMoney() < purchasePrice) { ChatUtil.SendSystemMessage(player, "GameMerchant.OnPlayerBuy.YouNeed", Money.GetString(purchasePrice)); return; } } eInventorySlot toClientSlot = player.Inventory.FindFirstEmptySlot(eInventorySlot.FirstBackpack, eInventorySlot.LastBackpack); if (toClientSlot == eInventorySlot.Invalid) { ChatUtil.SendSystemMessage(player, "GameMerchant.OnPlayerBuy.NotInventorySpace", null); return; } if (ServerProperties.Properties.CONSIGNMENT_USE_BP) { ChatUtil.SendMerchantMessage(player, "GameMerchant.OnPlayerBuy.BoughtBP", item.GetName(1, false), purchasePrice); player.BountyPoints -= purchasePrice; player.Out.SendUpdatePoints(); } else { if (player.RemoveMoney(purchasePrice)) { InventoryLogging.LogInventoryAction(player, this, eInventoryActionType.Merchant, purchasePrice); ChatUtil.SendMerchantMessage(player, "GameMerchant.OnPlayerBuy.Bought", item.GetName(1, false), Money.GetString(purchasePrice)); } else { return; } } TotalMoney += sellPrice; if (ServerProperties.Properties.MARKET_ENABLE_LOG) { log.DebugFormat("CM: {0}:{1} purchased '{2}' for {3} from consignment merchant on lot {4}.", player.Name, player.Client.Account.Name, item.Name, purchasePrice, HouseNumber); } NotifyObservers(player, this.MoveItemFromObject(player, fromClientSlot, toClientSlot)); } } }
/// <summary> /// Get all the items in the specified range /// </summary> /// <param name="minSlot">Slot Position where begin the search</param> /// <param name="maxSlot">Slot Position where stop the search</param> /// <returns>all items found</returns> public virtual ICollection<InventoryItem> GetItemRange(eInventorySlot minSlot, eInventorySlot maxSlot) { minSlot = GetValidInventorySlot(minSlot); maxSlot = GetValidInventorySlot(maxSlot); if (minSlot == eInventorySlot.Invalid || maxSlot == eInventorySlot.Invalid) return null; // If lower slot is greater than upper slot, flip the values. if (minSlot > maxSlot) { eInventorySlot tmp = minSlot; minSlot = maxSlot; maxSlot = tmp; } var items = new List<InventoryItem>(); lock (m_items) { InventoryItem item; for (eInventorySlot i = minSlot; i <= maxSlot; i++) { if (m_items.TryGetValue(i, out item)) { items.Add(item); } } } return items; }
/// <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); }
/// <summary> /// Adds an item to the inventory and DB /// </summary> /// <param name="slot"></param> /// <param name="item"></param> /// <returns>The eInventorySlot where the item has been added</returns> public virtual bool AddItem(eInventorySlot slot, InventoryItem item) { if (item == null) return false; lock (m_items) // Mannen 10:56 PM 10/30/2006 - Fixing every lock(this) { slot = GetValidInventorySlot(slot); if (slot == eInventorySlot.Invalid) return false; if (m_items.ContainsKey(slot)) { if (Log.IsErrorEnabled) Log.Error("Inventory.AddItem -> Destination slot is not empty (" + (int) slot + ")\n\n" + Environment.StackTrace); return false; } m_items.Add(slot, item); item.SlotPosition = (int)slot; if (item.OwnerID != null) { item.OwnerID = null; // owner ID for NPC } if (!m_changedSlots.Contains(slot)) m_changedSlots.Add(slot); if (m_changesCounter <= 0) UpdateChangedSlots(); return true; } }
/// <summary> /// Move an item from the inventory object to a player's backpack (uses client slots) /// </summary> public static IDictionary<int, InventoryItem> MoveItemFromObject(this IGameInventoryObject thisObject, GamePlayer player, eInventorySlot fromClientSlot, eInventorySlot toClientSlot) { // We will only allow moving to the backpack. if (toClientSlot < eInventorySlot.FirstBackpack || toClientSlot > eInventorySlot.LastBackpack) return null; lock (thisObject.LockObject()) { Dictionary<int, InventoryItem> inventory = thisObject.GetClientInventory(player); if (inventory.ContainsKey((int)fromClientSlot) == false) { ChatUtil.SendErrorMessage(player, "Item not found in slot " + (int)fromClientSlot); return null; } InventoryItem fromItem = inventory[(int)fromClientSlot]; InventoryItem toItem = player.Inventory.GetItem(toClientSlot); // if there is an item in the players target inventory slot then move it to the object if (toItem != null) { player.Inventory.RemoveTradeItem(toItem); toItem.SlotPosition = fromItem.SlotPosition; toItem.OwnerID = thisObject.GetOwner(player); thisObject.OnAddItem(player, toItem); GameServer.Database.SaveObject(toItem); } thisObject.OnRemoveItem(player, fromItem); // Create the GameInventoryItem from this InventoryItem. This simply wraps the InventoryItem, // which is still updated when this item is moved around InventoryItem objectItem = GameInventoryItem.Create<InventoryItem>(fromItem); player.Inventory.AddTradeItem(toClientSlot, objectItem); var updateItems = new Dictionary<int, InventoryItem>(1); updateItems.Add((int)fromClientSlot, toItem); return updateItems; } }
/// <summary> /// Get the item to the inventory in the specified slot /// </summary> /// <param name="slot">SlotPosition</param> /// <returns>the item in the specified slot if the slot is valid and null if not</returns> public virtual InventoryItem GetItem(eInventorySlot slot) { slot = GetValidInventorySlot(slot); if (slot == eInventorySlot.Invalid) return null; lock (m_items) // Mannen 10:56 PM 10/30/2006 - Fixing every lock(this) { InventoryItem item; m_items.TryGetValue(slot, out item); return item; //else // return null; } }
/// <summary> /// Stack an item with another one /// </summary> /// <param name="fromSlot">First SlotPosition</param> /// <param name="toSlot">Second SlotPosition</param> /// <param name="itemCount">How many items to move</param> /// <returns>true if items stacked successfully</returns> protected virtual bool StackItems(eInventorySlot fromSlot, eInventorySlot toSlot, int itemCount) { return(false); }
/// <summary> /// Adds needed amount of items to inventory if there /// is enough space else nothing is done /// </summary> /// <param name="sourceItem">The source inventory item</param> /// <param name="count">The count of items to add</param> /// <param name="minSlot">The first slot</param> /// <param name="maxSlot">The last slot</param> /// <returns>True if all items were added</returns> public virtual bool AddTemplate(InventoryItem sourceItem, int count, eInventorySlot minSlot, eInventorySlot maxSlot) { // Make sure template isn't null. if (sourceItem == null) return false; // Make sure we have a positive item count. if (count <= 0) return false; // If lower slot is greater than upper slot, flip the values. if (minSlot > maxSlot) { eInventorySlot tmp = minSlot; minSlot = maxSlot; maxSlot = tmp; } // Make sure lower slot is within inventory bounds. if (minSlot < eInventorySlot.Min_Inv) return false; // Make sure upper slot is within inventory bounds. if (maxSlot > eInventorySlot.Max_Inv) return false; lock (m_items) // Mannen 10:56 PM 10/30/2006 - Fixing every lock(this) { var changedSlots = new Dictionary<eInventorySlot, int>(); // value: <0 = new item count; >0 = add to old bool fits = false; int itemcount = count; eInventorySlot i = minSlot; // Find open slots/existing stacks to fit in these items. do { // Get the current slot, make sure it's valid. eInventorySlot curSlot = GetValidInventorySlot(i); if (curSlot == eInventorySlot.Invalid) continue; InventoryItem curItem; // Make sure slot isn't empty. if (!m_items.TryGetValue(curSlot, out curItem)) continue; // If slot isn't of the same type as our template, we can't stack, so skip. if (curItem.Id_nb != sourceItem.Id_nb) continue; // Can't add to an already maxed-out stack. if (curItem.Count >= curItem.MaxCount) continue; // Get the number of free spaces left in the given stack. int countFree = curItem.MaxCount - curItem.Count; // See if we can fit all our items in the given stack. If not, fit what we can. int countAdd = count; if (countAdd > countFree) countAdd = countFree; // Set the number of items to add to the stack at the given slot. (positive value indicates we're adding to a stack, not to an empty slot.) changedSlots[curSlot] = countAdd; // Reduce the overall count of items we need to fit. count -= countAdd; // If we've fit everything in existing stacks, we're done trying to find matches. if (count == 0) { fits = true; break; } // Exceptional error, count should never be negative. if (count < 0) { throw new Exception("Count is less than zero while filling gaps, should never happen!"); } } while (++i <= maxSlot); if (!fits) { // We couldn't manage to find existing stacks, or enough existing stacks, to add our items to. // We now need to find totally open slots to put our items in. for (i = minSlot; i <= maxSlot; i++) { // Get the current slot, make sure it's valid. eInventorySlot curSlot = GetValidInventorySlot(i); if (curSlot == eInventorySlot.Invalid) continue; // Skip any slots we already found as being occupied. if (changedSlots.ContainsKey(curSlot)) continue; // Skip any slots that are already in use. if (m_items.ContainsKey(curSlot)) continue; // If the max stack count is less than remaining items to add, we can only add the max // stack count and must find remaining slots to allocate the rest of the items to. int countAdd = count; if (countAdd > sourceItem.MaxCount) countAdd = sourceItem.MaxCount; // Set the number of items to add to the given slot. (negative amount indicates we're adding a new item, not stacking) changedSlots[curSlot] = -countAdd; // Reduce the overall count of items we need to fit. count -= countAdd; // If we've fit everything in existing stacks and open slots, we're done trying to find matches. if (count == 0) { fits = true; break; } // Exceptional error, count should never be negative. if (count < 0) { throw new Exception("Count is less than zero while adding new items, should never happen!"); } } } // If we still weren't able to fit all the items, then this is a failed add. if (!fits) return false; // Add new items BeginChanges(); try { foreach (var slot in changedSlots) { InventoryItem item; eInventorySlot itemSlot = slot.Key; int itemCount = slot.Value; if (itemCount > 0) // existing item should be changed { if (m_items.TryGetValue(itemSlot, out item)) { AddCountToStack(item, itemCount); } } else if (itemCount < 0) // new item should be added { if (sourceItem.Template is ItemUnique) { item = GameInventoryItem.Create<InventoryItem>(sourceItem); } else { item = GameInventoryItem.Create<ItemTemplate>(sourceItem.Template); } item.Count = -itemCount; AddItem(itemSlot, item); } } } finally { CommitChanges(); } return true; } }
public virtual bool AddTradeItem(eInventorySlot slot, InventoryItem item) { return(false); }