using System; using System.Data; using System.Collections.Generic; using MySql.Data.MySqlClient; using Woodpecker.Storage; using Woodpecker.Sessions; using Woodpecker.Specialized.Text; namespace Woodpecker.Game.Items { /// /// Provides management and methods for items that a user has in his/her inventory. Also provides methods for trading items with other sessions. /// public class itemStripHandler { #region Fields #region General /// /// The database ID of the user this item strip belongs to. /// private int userID; #endregion #region Hand (item inventory) /// /// The page ID the hand is currently on. /// private byte handStripPageIndex; /// /// A List of the type Woodpecker.Game.Items.stripItem holding all the stripItem instances that a user currently has in his/her Hand. (item inventory) /// private List handItems; /// /// The total amount of items in the hand as an integer. /// public int handItemCount { get { return this.handItems.Count; } } #endregion #region Item trading /// /// The session ID of the session where this user is currently trading with. /// public uint tradePartnerSessionID; /// /// Holds the current 'user accepts trade' state. /// public bool tradeAccept; /// /// A List of the type integer holding all the IDs of the items from this user's hand collection that are currently being offered in a trade. /// private List tradeOfferItemIDs; /// /// True if this user's hand strip is currently in trade with another user. /// public bool isTrading { get { return this.tradePartnerSessionID > 0; } } /// /// The total amount of items that this user is currently offering in a trade with another user. /// public int tradeOfferItemCount { get { if (this.tradeOfferItemIDs == null) return 0; else return this.tradeOfferItemIDs.Count; } } #endregion #endregion #region Constructors /// /// Constructs a item strip handler for a given user and loads the hand items. /// /// The database ID of the user to load this item strip handler for. public itemStripHandler(int userID) { this.userID = userID; this.handItems = new List(); this.loadHandItems(); } #endregion #region Methods #region Hand /// /// Loads all the items this user currently has in her/hand and stores them in the item collection. /// public void loadHandItems() { this.handItems.Clear(); Database dbClient = new Database(false, true); dbClient.addParameterWithValue("userid", this.userID); dbClient.Open(); if (dbClient.Ready) { foreach (DataRow dItem in dbClient.getTable("SELECT id,definitionid,customdata,teleporterid FROM items WHERE ownerid = @userid AND roomid = '0' ORDER BY id ASC").Rows) { stripItem pItem = new stripItem(); pItem.ID = (int)dItem["id"]; pItem.ownerID = this.userID; pItem.Definition = Engine.Game.Items.getItemDefinition((int)dItem["definitionid"]); if (dItem["customdata"] != DBNull.Value) pItem.customData = (string)dItem["customdata"]; else pItem.customData = null; if (pItem.Definition.Behaviour.isTeleporter) pItem.teleporterID = (int)dItem["teleporterid"]; this.handItems.Add(pItem); } } } /// /// Saves all the items in the hand that have been marked for update. (items that are new in the hand etc) /// public void saveHandItems() { Database dbClient = null; MySqlParameter vchrCustomData = null; foreach (stripItem lItem in this.handItems) { if (lItem.requiresUpdate) { #region Create database connection if (dbClient == null) // No database connection yet { dbClient = new Database(false, true); dbClient.addParameterWithValue("userid", this.userID); vchrCustomData = new MySqlParameter("customdata", MySqlDbType.VarChar); dbClient.addRawParameter(vchrCustomData); dbClient.Open(); if (!dbClient.Ready) // Can't use this database connection for some reason return; } #endregion if (lItem.customData == null) vchrCustomData.Value = DBNull.Value; else vchrCustomData.Value = lItem.customData; dbClient.runQuery("UPDATE items SET ownerid = @userid,roomid = '0',customdata = @customdata WHERE id = '" + lItem.ID + "' LIMIT 1"); } } if (dbClient != null) dbClient.Close(); } /// /// Clears all hand items objects from the hand item collection. /// public void Clear() { this.handItems.Clear(); } /// /// Modifies the internal hand page ID, by checking a given string. /// /// The action to perform on the index. public void changeHandStripPage(string szTo) { switch (szTo) { case "new": this.handStripPageIndex = 0; break; case "next": this.handStripPageIndex++; break; case "prev": if (this.handStripPageIndex > 0) this.handStripPageIndex--; break; case "last": this.handStripPageIndex = 255; break; // Other = 'update' } } /// /// Returns the item list of all the items in the hand ordered by ID. /// public string getHandItemCasts() { fuseStringBuilder Items = new fuseStringBuilder(); int startID = 0; int endID = this.handItems.Count; if(this.handStripPageIndex == 255) this.handStripPageIndex = (byte)((endID - 1) / 9); calculateStripOffset: if (endID > 0) { startID = this.handStripPageIndex * 9; if(endID > (startID + 9)) endID = startID + 9; if(startID >= endID) { this.handStripPageIndex--; goto calculateStripOffset; } for (int stripSlotID = startID; stripSlotID < endID; stripSlotID++) { Items.Append(this.handItems[stripSlotID].ToStripString(stripSlotID)); } } return Items.ToString(); } /// /// Adds a given strip item to the hand item collection. /// /// The strip item to add. public void addHandItem(stripItem Item) { this.handItems.Add(Item); } public void addHandItems(List Items) { this.handItems.AddRange(Items); } /// /// Removes an item from the hand item collection and optionally deletes it from the database. /// /// The database ID of the item to remove from the hand. /// public void removeHandItem(int ID, bool deleteItem) { for(int i = 0; i < this.handItems.Count; i++) { if(this.handItems[i].ID == ID) { this.handItems.RemoveAt(i); if (deleteItem) Engine.Game.Items.deleteItemInstance(ID); break; } } } /// /// Returns true if the hand item collection currently contains a strip item with a given ID. /// /// The database ID of the item to check. public bool containsHandItem(int ID) { foreach (stripItem lItem in this.handItems) { if (lItem.ID == ID) return true; } return false; } /// /// Tries to find a hand item with a given ID in the hand item collection and return it. If the item isn't found, null is returned. /// /// The database ID of the item to retrieve. public stripItem getHandItem(int ID) { foreach (stripItem lItem in this.handItems) { if (lItem.ID == ID) return lItem; } return null; } #endregion #region Trading /// /// Prepares the inner collection etc of the item strip manager for an item trade with the user of a different session. /// /// The session ID of the session of the user that will be the trade partner. public void initTrade(uint partnerSessionID) { if (this.isTrading) return; this.tradePartnerSessionID = partnerSessionID; this.tradeOfferItemIDs = new List(); } /// /// Disposes and resets all trading related fields in the item strip handler. /// public void stopTrade() { if (this.isTrading) { this.tradeOfferItemIDs.Clear(); this.tradeOfferItemIDs = null; this.tradeAccept = false; this.tradePartnerSessionID = 0; } } /// /// Adds an item to the trade offer item ID collection and sets the 'accept trade' state to false. The item is only added if the item is indeed in the hand item collection. /// /// The database ID of the item to add to the trade offer. public void addItemToTradeOffer(int ID) { if (this.isTrading && this.containsHandItem(ID)) { this.tradeOfferItemIDs.Add(ID); this.tradeAccept = false; } } /// /// Removes an item from the trade offer item ID collection and sets the 'accept trade' state to false. /// /// public void removeItemFromTradeOffer(int ID) { if (this.isTrading) { this.tradeOfferItemIDs.Remove(ID); this.tradeAccept = false; } } /// /// Returns true if an item with a given item ID is currently being offered in a trade with another user. /// /// The database ID of the item to check. public bool itemIsInTradeOffer(int ID) { if (this.isTrading) { foreach (int lID in this.tradeOfferItemIDs) { if (lID == ID) return true; } } return false; } /// /// Returns a string with all the offered trade items represented as a string. /// public string getTradeOfferItems() { fuseStringBuilder FSB = new fuseStringBuilder(); if (this.isTrading) { for (int slotID = 0; slotID < this.tradeOfferItemIDs.Count; slotID++) { stripItem pItem = this.getHandItem(this.tradeOfferItemIDs[slotID]); if (pItem != null) FSB.Append(pItem.ToStripString(slotID)); } } return FSB.ToString(); } /// /// Generates the trade box for a given session and returns it as as string. /// /// The Woodpecker.Sessions.Session object to generate the trade box string for. public string generateTradeBox(Session Session) { fuseStringBuilder Box = new fuseStringBuilder(); if (Session.itemStripHandler.isTrading) { Box.appendTabbedValue(Session.User.Username); Box.appendTabbedValue(Session.itemStripHandler.tradeAccept.ToString().ToLower()); Box.Append(Session.itemStripHandler.getTradeOfferItems()); Box.appendChar(13); } return Box.ToString(); } /// /// Swaps the trade offer items of two trade partners and updates the database, hand item collection etc. The swap is aborted if the trade is invalid. /// /// The itemStripHandler object of the trade partner session. public void swapTradeOffers(itemStripHandler partnerItemStrip) { if (this.isTrading && partnerItemStrip.isTrading && (this.tradeOfferItemCount > 0 || partnerItemStrip.tradeOfferItemCount > 0)) // Can swap items { Database dbClient = new Database(true, false); if (!dbClient.Ready) return; foreach (int myTradeOfferItemID in this.tradeOfferItemIDs) { stripItem lItem = this.getHandItem(myTradeOfferItemID); if (lItem == null) return; // Trade invalid this.removeHandItem(myTradeOfferItemID, false); // Remove from this item strip partnerItemStrip.addHandItem(lItem); // Add to partner item strip dbClient.runQuery("UPDATE items SET ownerid = '" + partnerItemStrip.userID + "' WHERE id = '" + lItem.ID + "' LIMIT 1"); // Update database } foreach (int partnerTradeOfferItemID in partnerItemStrip.tradeOfferItemIDs) { stripItem lItem = partnerItemStrip.getHandItem(partnerTradeOfferItemID); if (lItem == null) return; // Trade invalid partnerItemStrip.removeHandItem(partnerTradeOfferItemID, false); // Remove from partner item strip this.addHandItem(lItem); // Add to this item strip dbClient.runQuery("UPDATE items SET ownerid = '" + this.userID + "' WHERE id = '" + lItem.ID + "' LIMIT 1"); // Update database } dbClient.Close(); // Close database connection } } #endregion #endregion } }