Planeshift
|
00001 /* 00002 * pscharinventory.h by Keith Fulton <[email protected]> 00003 * 00004 * Copyright (C) 2007 Atomic Blue ([email protected], http://www.atomicblue.org) 00005 * 00006 * 00007 * This program is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU General Public License 00009 * as published by the Free Software Foundation (version 2 of the License) 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software 00016 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 * 00018 */ 00019 00020 #ifndef __PSCHARINV_H__ 00021 #define __PSCHARINV_H__ 00022 00023 //============================================================================= 00024 // Crystal Space Includes 00025 //============================================================================= 00026 #include <csutil/sysfunc.h> 00027 #include <csutil/weakref.h> 00028 00029 //============================================================================= 00030 // Project Includes 00031 //============================================================================= 00032 #include "util/poolallocator.h" 00033 #include "util/psconst.h" 00034 00035 #include "../icachedobject.h" 00036 00037 //============================================================================= 00038 // Local Includes 00039 //============================================================================= 00040 #include "psitemstats.h" 00041 #include "psstdint.h" 00042 #include "psitem.h" 00043 #include "psinventorycachesvr.h" 00044 #include "psspell.h" 00045 00046 struct iDocumentNode; 00047 00048 class MsgEntry; 00049 class psItemStats; 00050 class psItem; 00051 class gemContainer; 00052 struct psRaceInfo; 00053 class gemActor; 00054 00059 00060 #define PSCHARACTER_EQUIPMENTFLAG_AUTOATTACK 0x00000001 00061 00062 #define PSCHARACTER_EQUIPMENTFLAG_SINGLEATTACK 0x00000002 00063 00064 #define PSCHARACTER_EQUIPMENTFLAG_ATTACKIFEMPTY 0x00000004 00065 00066 00067 //----------------------------------------------------------------------------- 00068 00070 struct glyphSlotInfo 00071 { 00072 psItemStats* glyphType; 00073 int purifyStatus; 00074 }; 00075 00076 00077 //----------------------------------------------------------------------------- 00078 00081 class psCharacterInventory 00082 { 00083 public: 00085 psCharacter* owner; 00086 00087 class psCharacterInventoryItem 00088 { 00089 friend class psCharacterInventory; 00090 psItem* item; 00091 public: 00092 psCharacterInventoryItem(psItem* it) 00093 { 00094 item = it; 00095 exchangeOfferSlot = -1; 00096 exchangeStackCount = 0; 00097 } 00098 int exchangeOfferSlot; 00099 int exchangeStackCount; 00100 psItem* GetItem() 00101 { 00102 return item; 00103 } 00104 }; 00105 00106 protected: 00107 00109 csArray<psCharacterInventoryItem> inventory; 00110 00112 csArray<psItem*> storageInventory; 00113 00114 struct psEquipInfo 00115 { 00116 unsigned int EquipmentFlags; 00117 int eventId; 00118 size_t itemIndexEquipped; 00119 psItem* default_if_empty; 00120 }; 00121 00123 psEquipInfo equipment[PSCHARACTER_SLOT_BULK1]; // bulk1 is the first slot above equipment 00124 00126 bool doRestrictions; 00127 00129 bool loaded; 00130 00132 float maxWeight; 00133 00135 float maxSize; 00136 00138 bool inExchangeMode; 00139 00141 uint32 version; 00142 00143 public: 00144 00145 psCharacterInventory(psCharacter* owner); 00146 ~psCharacterInventory(); 00147 00149 bool Load(); 00150 00160 bool Load(PID id); 00161 00165 bool QuickLoad(PID id); 00166 00173 bool HasEnoughUnusedSpace(float desiredSpace); 00174 int GetCurrentTotalSpace(); 00175 int GetCurrentMaxSpace(); 00176 00183 void AddStorageItem(psItem* &item); 00184 00191 bool HasEnoughUnusedWeight(float requiredWeight); 00192 float GetCurrentTotalWeight(); 00193 00200 size_t HowManyCanFit(psItem* item); 00201 00204 00208 float MaxWeight() 00209 { 00210 return maxWeight; 00211 } 00212 00215 00217 // float Weight() { return 0; } 00218 00222 float GetTotalSizeOfItemsInContainer(psItem* container=NULL); 00223 00227 uint32 GetInventoryVersion() const 00228 { 00229 return version; 00230 } 00231 00235 void IncreaseInventoryVersion() 00236 { 00237 version++; 00238 } 00239 00255 bool Add(psItem* &item, bool test = false, bool stack = true, 00256 INVENTORY_SLOT_NUMBER slot = PSCHARACTER_SLOT_NONE, gemContainer* container = NULL, bool precise = true, bool skip_requirements = false); 00257 00265 psItem* AddStacked(psItem* &item, int &added); 00266 00270 bool AddOrDrop(psItem* &item, bool stack = true); 00271 00279 psItem* GetItem(psItem* container, INVENTORY_SLOT_NUMBER slot); 00280 00293 bool hasItemsWithName(csString &itemname, bool includeEquipment, bool includeBulk, int amountMin = 1, int amountMax = -1, float qualityMin = 0, float qualityMax = 0); 00294 00301 psItem* GetInventoryItem(INVENTORY_SLOT_NUMBER slot); 00302 00308 void RestoreAllInventoryQuality(); 00309 00313 psItem* GetItemHeld(); 00314 00315 psCharacterInventoryItem* GetCharInventoryItem(INVENTORY_SLOT_NUMBER slot); 00316 00323 INVENTORY_SLOT_NUMBER FindSlotHoldingItem(psItem* item); 00324 00328 size_t FindItemStatIndex(psItemStats* itemstats,size_t startAt=1); 00329 00338 psItem* RemoveItem(psItem* container, INVENTORY_SLOT_NUMBER bulkslot, int count = -1); 00339 00348 psItem* RemoveItemID(uint32 itemID,int count = -1, bool storage = false); 00349 00357 psItem* RemoveInventoryItem(INVENTORY_SLOT_NUMBER slot, int count = -1); 00358 00359 00366 unsigned int TotalStackOfItem(psItemStats* item); 00367 00375 psItem* FindItemID(uint32 itemID, bool storage = false); 00376 00377 void SetExchangeOfferSlot(psItem* Container,INVENTORY_SLOT_NUMBER slot,int toSlot,int stackCount); 00378 int GetOfferedStackCount(psItem* item); 00379 psCharacterInventoryItem* FindExchangeSlotOffered(int slotID); 00380 void PurgeOffered(); 00381 00388 bool HaveKeyForLock(uint32 lock); 00389 00396 bool CanItemAttack(INVENTORY_SLOT_NUMBER slot); 00397 00404 bool IsItemAutoAttack(INVENTORY_SLOT_NUMBER slot); 00405 00413 psEquipInfo &GetEquipmentObject(INVENTORY_SLOT_NUMBER idx); 00414 00424 psItem* GetEffectiveWeaponInSlot(INVENTORY_SLOT_NUMBER slot, bool includeShield = false); 00425 00432 psItem* GetEffectiveArmorInSlot(INVENTORY_SLOT_NUMBER slot); 00433 00443 bool hasItemCategory(psItemCategory* category, bool includeEquipment, bool includeBulk, bool includeStorage = false); 00444 00458 bool hasItemCategory(csString &categoryname, bool includeEquipment, bool includeBulk, bool includeStorage = false, int amountMin = 1, int amountMax = -1 , float qualityMin = 0, float qualityMax = 0); 00459 00468 csArray<psItem*> GetItemsInCategory(psItemCategory* category, bool storage = false); 00469 00478 psItem* StackNumberItems(const csString &itemname, int count, bool container); 00479 00480 00481 size_t GetContainedItemCount(psItem* container); 00482 float GetContainedWeight(psItem* container); 00483 float GetContainedSize(psItem* container); 00484 00486 void CalculateLimits(); 00487 00489 void RunEquipScripts(); 00490 00492 csString lastError; 00493 00495 void SetDoRestrictions(bool v); 00496 00498 bool GetDoRestrictions() 00499 { 00500 return doRestrictions; 00501 } 00502 00504 psInventoryCacheServer* GetInventoryCacheServer(void) 00505 { 00506 return &inventoryCacheServer; 00507 } 00508 00510 bool HasPurifiedGlyphs(const glyphList_t glyphsToCheck); 00511 00513 void CreateGlyphList(csArray <glyphSlotInfo> &slots); 00514 00523 bool AddLoadedItem(uint32 parentID, INVENTORY_SLOT_NUMBER slot, psItem* item); 00524 00525 void Equip(psItem* item); 00526 void Unequip(psItem* item); 00527 bool CheckSlotRequirements(psItem* item, INVENTORY_SLOT_NUMBER proposedSlot, unsigned short stackCount = 0); 00528 00536 bool EquipItem(psItem* newItem, INVENTORY_SLOT_NUMBER slotID); 00537 00541 INVENTORY_SLOT_NUMBER FindFreeEquipSlot(psItem* itemToPlace); 00542 00548 size_t GetInventoryIndexCount() 00549 { 00550 return inventory.GetSize(); 00551 } 00552 00558 psItem* GetInventoryIndexItem(size_t which) 00559 { 00560 return inventory[which].item; 00561 } 00562 00564 psCharacterInventoryItem* GetIndexCharInventoryItem(size_t index) 00565 { 00566 return &inventory[index]; 00567 } 00568 00570 void WriteAllInventory(iDocumentNode* npcRoot); 00571 00581 psItem* RemoveItemIndex(size_t index,int count=-1, bool storage = false); 00582 00584 bool BeginExchange(); 00585 00587 void CommitExchange(); 00588 00590 void RollbackExchange(); 00591 00593 void UpdateEncumbrance(); 00594 00601 void SetBasicArmor(psRaceInfo* race = NULL); 00602 00609 void SetBasicWeapon(psRaceInfo* race = NULL); 00610 00614 static psItem* GetItemFactory(psItemStats* stats); 00615 00616 private: 00617 void WriteItem(csRef<iDocumentNode> equipmentNode, psItem* item, int bulk, INVENTORY_SLOT_NUMBER slot); 00618 00619 size_t GetItemIndex(psItem* item); 00620 00625 size_t FindSlotIndex(psItem* container,INVENTORY_SLOT_NUMBER slot); 00626 00630 int FindFirstOpenSlot(psItem* container); 00631 00636 size_t FindCompatibleStackedItem(psItem* item, bool checkStackCount = true); 00637 00647 csArray<size_t> FindCompatibleStackedItems(psItem* item, bool checkStackCount = true, bool precise = true); 00648 00649 psInventoryCacheServer inventoryCacheServer; 00650 00651 }; 00652 00653 class InventoryTransaction 00654 { 00655 public: 00656 InventoryTransaction(psCharacterInventory* what) 00657 { 00658 myInv = what; 00659 committed = false; 00660 myInv->BeginExchange(); 00661 } 00662 ~InventoryTransaction() 00663 { 00664 if(!committed && myInv) 00665 myInv->RollbackExchange(); 00666 } 00667 void Commit() 00668 { 00669 myInv->CommitExchange(); 00670 committed = true; 00671 } 00672 void Cancel() 00673 { 00674 myInv = NULL; // character deleted or somesuch 00675 } 00676 00677 protected: 00678 psCharacterInventory* myInv; 00679 bool committed; 00680 }; 00681 00684 #endif 00685