@ -256,16 +256,12 @@ private:
void keepTheThreeBestResistance ( const CCraftParameters & p ) ;
} ;
//------------------------------------------------------------------------
// advance declaration of classes with circular references
class CGameItem ;
class CGameItemEntry ;
//class CGameItemManager;
/**
* CGameItemVector
*
@ -278,7 +274,7 @@ class CGameItemVector
{
public :
uint32 size ( ) const ;
CGameItem & operator [ ] ( uint32 idx ) ;
CGameItem Entry & operator [ ] ( uint32 idx ) ;
void extend ( ) ;
uint32 getUniqueIndex ( const CGameItem & item ) ;
virtual ~ CGameItemVector ( ) ;
@ -289,45 +285,9 @@ private:
CGameItemVector ( ) ;
private :
std : : vector < CGameItem * > _Data ;
} ;
# ifdef GAME_PTR_DEBUG
class CGameItemPtrArray
{
public :
CGameItemPtrArray ( )
{
}
std : : vector < CGameItemEntry * > m_Data ;
CGameItemPtrArray ( const CGameItemPtrArray & )
{
// do nothing
}
CGameItemPtrArray & operator = ( const CGameItemPtrArray & )
{
// do nothing
}
# ifdef NL_CPP14
CGameItemPtrArray ( CGameItemPtrArray & & )
{
// do nothing
}
CGameItemPtrArray & operator = ( CGameItemPtrArray & & ) noexcept
{
// do nothing
}
# endif
protected :
/// keep pointers pointing this item
std : : vector < CGameItemPtr * > _Ptrs ;
} ;
# endif
/**
* CGameItem
@ -336,17 +296,18 @@ protected:
* \ author Nevrax France
* \ date 2002
*/
class CGameItem
# ifdef GAME_PTR_DEBUG
: public CGameItemPtrArray
# endif
class CGameItem
{
#if 0
NLMISC_COMMAND_FRIEND ( testParanoidItemSystem ) ;
# endif
friend class CInventoryBase ;
friend class CRefInventory ;
#if 0
NL_INSTANCE_COUNTER_DECL ( CGameItem ) ;
# endif
public :
/// returns true if the two param items are stackable
@ -752,10 +713,10 @@ protected:
/// The inventory that contains this item (NULL if none)
CInventoryPtr _Inventory ;
/// The slot inside the inventory
uint32 _InventorySlot ;
/// The inventory that reference this item (NULL if none)
CInventoryPtr _RefInventory ;
/// The slot inside the inventory
uint32 _InventorySlot ;
/// The slot inside the reference inventory
uint32 _RefInventorySlot ;
@ -773,20 +734,12 @@ private:
static CGameItemVector _Items ;
static uint32 _FirstFreeItem ;
# ifdef ITEM_DEBUG
static sint32 _NextAllocatorDataValue ;
# endif
//--------------------------------------------------------------------
// instance data for singleton's allocator algorithms
sint32 _AllocatorData ;
private :
//--------------------------------------------------------------------
// singleton interface used by the CGameItemPtr class
// make CGameItemPtr a friend to give it decent access
friend class CGameItemEntry ;
friend class CGameItemPtr ;
friend class CInventoryProxy ;
friend class COldGuildInventoryLoader ;
@ -807,32 +760,10 @@ private:
// return the CWeaponCraftParameters variable corresponding to protection type
float getMagicProtectionCraftParateters ( PROTECTION_TYPE : : TProtectionType protection ) const ;
private :
#if 0
// singleton counter
static uint32 _BugTestCounter ;
// instance debug data
uint32 _BugTestChecksum ;
uint32 _BugTestUpdate ;
# endif
public :
#if 0
// run through the items looking for bugs
static void testItemsForBugs ( ) ;
// static void testPlayerInventoryForBugs(const std::vector<CGameItemPtr>& inventory);
# endif
static std : : string showItemsStats ( ) ;
#if 0
// check a single item for bugs...
void checkItemForBugs ( ) ;
# endif
public : // I've had to make these public for now 'cos I can't work out how to make the vector class a friend :o(
//private :
private :
//--------------------------------------------------------------------
// ctors and dtors are now private for better control over allocation etc
@ -877,7 +808,7 @@ private:
/**
* pseudo Destructor
*/
void dtor ( ) ;
//void dtor();
/// Copy all the item info and parameters from model into this
// void copyItem(const CGameItemPtr &model);
@ -921,22 +852,16 @@ public:
private :
/// Item unique id
INVENTORIES : : TItemId _ItemId ;
/// Item stack size
uint32 _StackSize ;
// true if the item is on the ground
// bool _IsOnTheGround;
/// item id
// NLMISC::CEntityId _ItemId;
/// looter id of the character currently looting this item (for items on the ground only)
NLMISC : : CEntityId _Looter ;
/// sheet ref
NLMISC : : CSheetId _SheetId ;
/// Item stack size
uint32 _StackSize ;
/// carrion sheet ref
// uint32 _CarrionSheetId;
/// true if the object is destroyable
bool _Destroyable ;
/// true if the object is dropable
bool _Dropable ;
/// children
// std::vector<CGameItemPtr> _Children;
/// pointer on the parent item (NULL if no parent)
@ -954,52 +879,64 @@ private:
/// current sap load
uint32 _SapLoad ;
/// all craft parameters
NLMISC : : CDeepPtr < CItemCraftParameters > _CraftParameters ;
/// entityId of the character who has created the Item via faber (if applicable, for item not created by playres, Creator = CEntityId::Unknown)
NLMISC : : CEntityId _CreatorId ;
/// number of item locked
uint32 _LockCount ;
/// Position in the client inventory interface if item is owned by a player (sint16 juste because we need an "invalid" position (-1) for version compatibility)
// TODO : a virer
sint16 _ClientInventoryPosition ;
/// Vector of CSheetId used for craft this item
// std::vector< NLMISC::CSheetId > _RmUsedForCraft;
/// vector of sheetId of CStaticBrick define spell of enchanted item
std : : vector < NLMISC : : CSheetId > _Enchantment ;
/// pointer on the associated static form
const CStaticItem * _Form ;
/// string associated with this item
NLMISC : : CDeepPtr < std : : string > _PhraseId ;
/// skill modifiers against given ennemy types
std : : vector < CTypeSkillMod > _TypeSkillMods ;
NLMISC : : CDeepPtr < std : : string > _CustomText ;
# ifdef RYZOM_FORGE_PET_NAME
// FIXME: Reuse _PhraseId string and add a m_Literal flag
ucstring _CustomName ;
# endif
/// tick when the proc will be available again
NLMISC : : TGameCycle _LatencyEndDate ;
/// image of the item in bag / equipment
// uint16 _SlotImage;
NLMISC : : TGameCycle _TotalSaleCycle ;
/// number of item locked
uint32 _LockCount ;
// required skill
bool _UseNewSystemRequirement ;
SKILLS : : ESkills _RequiredSkill ;
uint16 _RequiredSkillLevel ;
SKILLS : : ESkills _RequiredSkill2 ;
CHARACTERISTICS : : TCharacteristics _RequiredCharac ;
uint16 _RequiredSkillLevel ;
uint16 _RequiredSkillLevel2 ;
/// min required stat level and required stat
CHARACTERISTICS : : TCharacteristics _RequiredCharac ;
uint16 _RequiredCharacLevel ;
/// whether the item has any skill requirements
bool _HasPrerequisit ;
/// skill modifiers against given ennemy types
std : : vector < CTypeSkillMod > _TypeSkillMods ;
bool _UseNewSystemRequirement ;
NLMISC : : CDeepPtr < std : : string > _CustomText ;
bool _LockedByOwner ;
bool _UnMovable ;
bool _Movable ;
uint8 _PetIndex ;
# ifdef RYZOM_FORGE_PET_NAME
ucstring _CustomName ;
# endif
/// true if the object is destroyable
bool _Destroyable ;
/// true if the object is dropable
bool _Dropable ;
// true if the item is on the ground
// bool _IsOnTheGround;
} ;
/**
@ -1029,110 +966,128 @@ private:
# define QUANTUM (1<<LOG_QUANTUM)
# define QUANTUM_MASK (QUANTUM-1)
class CGameItemEntry : public CGameItem
{
public :
CGameItemEntry ( )
{
PtrRefCount = 0 ;
}
~ CGameItemEntry ( )
{
}
uint32 AllocatorNext ;
uint32 VectorIdx ;
sint PtrRefCount ;
} ;
inline CGameItemVector : : CGameItemVector ( )
{
}
inline CGameItemVector : : ~ CGameItemVector ( )
{
for ( uint32 i = 0 ; i < _Data . size ( ) ; + + i )
delete [ ] _Data [ i ] ;
for ( uint32 i = 0 ; i < m _Data. size ( ) ; + + i )
delete [ ] m _Data[ i ] ;
}
inline uint32 CGameItemVector : : size ( ) const
{
return ( uint32 ) _Data . size ( ) < < LOG_QUANTUM ;
return ( uint32 ) m _Data. size ( ) < < LOG_QUANTUM ;
}
inline CGameItem & CGameItemVector : : operator [ ] ( uint32 idx )
inline CGameItem Entry & CGameItemVector : : operator [ ] ( uint32 idx )
{
return _Data [ idx > > LOG_QUANTUM ] [ idx & QUANTUM_MASK ] ;
return m _Data[ idx > > LOG_QUANTUM ] [ idx & QUANTUM_MASK ] ;
}
inline void CGameItemVector : : extend ( )
{
_Data . push_back ( new CGameItem [ QUANTUM ] ) ;
nlassert ( _Data . back ( ) ! = NULL ) ;
for ( uint32 i = 0 ; i < QUANTUM ; + + i )
_Data . back ( ) [ i ] . _AllocatorData = size ( ) - QUANTUM + i + 1 ;
egs_giinfo ( " Increased item vector size to %u items (%u bytes) " , size ( ) , size ( ) * sizeof ( CGameItem ) ) ;
uint32 baseIdx = size ( ) ;
CGameItemEntry * items = new CGameItemEntry [ QUANTUM ] ;
nlassert ( items ) ;
m_Data . push_back ( items ) ;
for ( uint32 i = 0 ; i < QUANTUM ; + + i )
{
items [ i ] . AllocatorNext = baseIdx + i + 1 ;
items [ i ] . VectorIdx = baseIdx + i ;
}
egs_giinfo ( " Increased item vector size to %u items (%u bytes) " , size ( ) , size ( ) * sizeof ( CGameItem ) ) ;
}
inline uint32 CGameItemVector : : getUniqueIndex ( const CGameItem & item )
{
for ( uint32 i = 0 ; i < _Data . size ( ) ; + + i )
{
uint32 lowidx = ( uint32 ) ( & item - _Data [ i ] ) ;
if ( lowidx < QUANTUM )
{
uint32 idx = lowidx + ( i < < LOG_QUANTUM ) ;
# ifdef ITEM_DEBUG
BOMB_IF ( & ( _Data [ i ] [ lowidx ] ) ! = & item , NLMISC : : toString ( " Invalid item pointer (1): %p " , & item ) , return ~ 0u ) ;
BOMB_IF ( & ( ( * this ) [ idx ] ) ! = & item , NLMISC : : toString ( " Code bug or Invalid item pointer (2): %p " , & item ) , return ~ 0u ) ;
# endif
return idx ;
}
}
STOP ( NLMISC : : toString ( " invalid item pointer (3): %p " , & item ) ) ;
return ~ 0u ;
return static_cast < const CGameItemEntry & > ( item ) . VectorIdx ;
}
# undef LOG_QUANTUM
# undef QUANTUM
# undef QUANTUM_MASK
//------------------------------------------------------------------------
// ptr class added by sadge
// inline implementations
// ctor - default
inline CGameItemPtr : : CGameItemPtr ( )
// link ptr to game item
inline void CGameItemPtr : : incRef ( )
{
reset ( ) ;
if ( ! m_Idx )
return ;
+ + CGameItem : : _Items [ m_Idx ] . PtrRefCount ;
}
inline void CGameItemPtr : : reset ( )
// unlink ptr from item
inline void CGameItemPtr : : decRef ( )
{
_idx = ~ 0u ;
// cannot unlink a pointer pointing on nothing
if ( ! m_Idx )
return ;
# ifdef ITEM_DEBUG
_debugPtr = NULL ;
_debug = 0 ;
# endif
CGameItemEntry * entry = & CGameItem : : _Items [ m_Idx ] ;
sint count = - - CGameItem : : _Items [ m_Idx ] . PtrRefCount ;
if ( ! count )
{
CGameItem : : deleteItem ( static_cast < CGameItem * > ( entry ) ) ;
}
nlassert ( count > = 0 ) ;
}
// ctor - default
inline CGameItemPtr : : CGameItemPtr ( ) : m_Idx ( 0 )
{
}
// ctor - copy
inline CGameItemPtr : : CGameItemPtr ( const CGameItemPtr & other )
inline CGameItemPtr : : CGameItemPtr ( const CGameItemPtr & other ) : m_Idx ( other . m_Idx )
{
reset ( ) ;
* this = other ;
incRef ( ) ;
}
// ctor - initialise from a CGameItem*
inline CGameItemPtr : : CGameItemPtr ( const CGameItem * item )
inline CGameItemPtr : : CGameItemPtr ( const CGameItem * item ) : m_Idx ( static_cast < const CGameItemEntry * > ( item ) - > VectorIdx )
{
reset ( ) ;
* this = item ;
incRef ( ) ;
}
// dtor
inline CGameItemPtr : : ~ CGameItemPtr ( )
{
unlinkFromItem ( ) ;
decRef ( ) ;
}
// equivalent to: new CGameItem
inline CGameItem * CGameItemPtr : : newItem ( bool destroyable , bool dropable )
{
CGameItem * item = CGameItem : : newItem ( ) ;
CGameItem * item = CGameItem : : newItem ( ) ;
item - > ctor ( ) ;
item - > _Destroyable = destroyable ;
item - > _Dropable = dropable ;
* this = item ;
#if 0
item - > _BugTestUpdate = CGameItem : : _BugTestCounter ;
# endif
return item ;
}
@ -1153,93 +1108,17 @@ inline CGameItem *CGameItemPtr::newItem( const NLMISC::CSheetId& sheetId, uint32
// item->ctor(id,sheetId,recommended,slotCount,destroyable,dropable);
item - > ctor ( sheetId , recommended , destroyable , dropable ) ;
* this = item ;
#if 0
item - > _BugTestUpdate = CGameItem : : _BugTestCounter ;
# endif
return item ;
}
// equivalent to: delete (for a CGameItem*)
//inline void CGameItemPtr::deleteItem()
//{
// CGameItem *item=**this;
//
// BOMB_IF( item == NULL, "Attempt to delete an item that is not allocated or has been freed", return );
//
// // only unlink if the pointer 'this' is not the same as the inventory ptr for the item
// // after the unlink this == NULL
// if (! ( item->_Parent!=NULL &&
// item->Loc.Slot<item->_Parent->getChildren().size() &&
// &(item->_Parent->getChildren()[item->Loc.Slot])==this ) )
// unlinkFromItem();
//
// // call dtor now to unlink all children
// item->dtor();
// // check no one else is referencing us
// nlassert(item->_Ptrs.empty());
//
// CGameItem::deleteItem(item);
// item->_BugTestUpdate=CGameItem::_BugTestCounter;
//}
// link ptr to game item
inline void CGameItemPtr : : linkToItem ( )
{
# ifdef GAME_PTR_DEBUG
if ( _idx = = ~ 0u )
return ;
CGameItem * item = * * this ;
for ( uint i = 0 ; i < item - > _Ptrs . size ( ) ; + + i )
{
nlassert ( item - > _Ptrs [ i ] ! = this ) ;
}
item - > _Ptrs . push_back ( this ) ;
# endif
}
// unlink ptr from item
inline void CGameItemPtr : : unlinkFromItem ( )
{
// cannot unlink a pointer pointing on nothing
if ( _idx = = ~ 0u )
return ;
# ifdef GAME_PTR_DEBUG
CGameItem * item = * * this ;
uint j = ~ 0u ;
for ( uint i = 0 ; i < item - > _Ptrs . size ( ) ; + + i )
{
if ( item - > _Ptrs [ i ] = = this )
{
nlassert ( j = = ~ 0u ) ;
j = i ;
}
}
nlassert ( j ! = ~ 0u ) ;
item - > _Ptrs . erase ( item - > _Ptrs . begin ( ) + j ) ;
# endif
// set the GameItemPtr to NULL
reset ( ) ;
}
// = operator - for copying another CGameItemPtr
inline const CGameItemPtr & CGameItemPtr : : operator = ( const CGameItemPtr & other )
{
unlinkFromItem ( ) ;
decRef ( ) ;
_idx = other . _idx ;
# ifdef ITEM_DEBUG
_debug = other . _debug ;
_debugPtr = other . _debugPtr ;
# endif
m_Idx = other . m_Idx ;
linkToItem ( ) ;
incRef ( ) ;
return * this ;
}
@ -1247,135 +1126,76 @@ inline const CGameItemPtr &CGameItemPtr::operator=(const CGameItemPtr &other)
// = operator - for assignment of CGameItemPtr directly to a CGameItem
inline const CGameItemPtr & CGameItemPtr : : operator = ( const CGameItem * item )
{
unlinkFromItem ( ) ;
decRef ( ) ;
if ( item = = NULL )
_idx = ~ 0u ;
else
if ( ! item )
{
_idx = CGameItem : : _Items . getUniqueIndex ( * item ) ;
// this test would only have value if the implementation of std::vector<> doesn't guarantee a
// continuous memory address space for the vector's data
// It's not in the #IFDEF DEBUG because it may only be triggered in very obscure conditions
if ( CGameItem : : getItem ( _idx ) ! = item )
{
nlwarning ( " **** BIG BAD NASTY BUG - BEGINS **** " ) ;
nlwarning ( " item: %p " , item ) ;
nlwarning ( " _idx: %i " , _idx ) ;
nlwarning ( " **** BIG BAD NASTY BUG - ENDS **** " ) ;
}
// nlassert(&CGameItem::getItem(_idx)==item);
m_Idx = 0 ;
}
else
{
m_Idx = static_cast < const CGameItemEntry * > ( item ) - > VectorIdx ;
nlassert ( CGameItem : : getItem ( m_Idx ) = = item ) ;
# ifdef ITEM_DEBUG
_debugPtr = ( CGameItem * ) item ;
if ( item = = NULL )
_debug = 0 ;
else
{
CGameItem * item = CGameItem : : getItem ( _idx ) ;
if ( item )
_debug = item - > _AllocatorData ;
}
# endif
linkToItem ( ) ;
incRef ( ) ;
}
return * this ;
}
// * operator - returning the item referenced by this pointer
inline CGameItem * CGameItemPtr : : operator * ( ) const
inline CGameItem * CGameItemPtr : : operator * ( ) const
{
if ( _idx = = ~ 0u )
return NULL ;
CGameItem * item = CGameItem : : getItem ( _idx ) ;
# ifdef ITEM_DEBUG
BOMB_IF ( CGameItem : : getItem ( _idx ) ! = _debugPtr , " CGameItemPtr do not reference the good item " , return 0 ) ;
BOMB_IF ( _idx = = ~ 0u , " Attempting to derefence a NULL pointer " , return 0 ) ;
if ( item )
BOMB_IF ( _debug ! = CGameItem : : getItem ( _idx ) - > _AllocatorData , " Attempting to access an item that has been re-allocated " , return 0 ) ;
# endif
BOMB_IF ( item = = 0 , " Attempting to access an item an item that is not allocated or has been freed " , return 0 ) ;
#if 0
item - > _BugTestUpdate = CGameItem : : _BugTestCounter ;
# endif
return item ;
CGameItemEntry * entry = static_cast < CGameItemEntry * > ( CGameItem : : getItem ( m_Idx ) ) ;
BOMB_IF ( ! entry - > VectorIdx , " Attempting to access an item an item that is not allocated or has been freed " , return 0 ) ;
return static_cast < CGameItem * > ( entry ) ;
}
// -> operator - returning the item referenced by this pointer
inline CGameItem * CGameItemPtr : : operator - > ( ) const
{
if ( _idx = = ~ 0u )
return NULL ;
CGameItem * item = CGameItem : : getItem ( _idx ) ;
# ifdef ITEM_DEBUG
BOMB_IF ( CGameItem : : getItem ( _idx ) ! = _debugPtr , " CGameItemPtr do not reference the good item " , return 0 ) ;
BOMB_IF ( _idx = = ~ 0u , " Attempting to derefence a NULL pointer " , return 0 ) ;
if ( item )
BOMB_IF ( _debug ! = CGameItem : : getItem ( _idx ) - > _AllocatorData , " Attempting to access an item that has been re-allocated " , return 0 ) ;
# endif
BOMB_IF ( item = = 0 , " Attempting to access an item an item that is not allocated or has been freed " , return 0 ) ;
#if 0
item - > _BugTestUpdate = CGameItem : : _BugTestCounter ;
# endif
return item ;
// this is crash-safe even when m_Idx is wrong, it'll return item 0
return CGameItem : : getItem ( m_Idx ) ;
}
// () operator - returning the item referenced by this pointer
inline CGameItem * CGameItemPtr : : operator ( ) ( ) const
{
return operator - > ( ) ;
CGameItemEntry * entry = static_cast < CGameItemEntry * > ( CGameItem : : getItem ( m_Idx ) ) ;
BOMB_IF ( ! entry - > VectorIdx , " Attempting to access an item an item that is not allocated or has been freed " , return 0 ) ;
return static_cast < CGameItem * > ( entry ) ;
}
// == operator - compare 2 CGameItemPtrs
inline bool CGameItemPtr : : operator = = ( const CGameItemPtr & other ) const
{
# ifdef ITEM_DEBUG
//nlassert(CGameItem::getItem(_idx)==_debugPtr);
if ( _idx = = other . _idx )
nlassert ( _debug = = other . _debug ) ;
# endif
return ( _idx = = other . _idx ) ;
return ( m_Idx = = other . m_Idx ) ;
}
// == operator - compare CGameItemPtrs to CGameItem*
inline bool CGameItemPtr : : operator = = ( const CGameItem * item ) const
{
if ( item = = NULL )
return operator* ( ) = = NULL ;
if ( ! item )
return m_Idx = = 0 ;
return * this = = CGameItemPtr ( item ) ;
return CGameItem : : getItem ( m_Idx ) = = item ;
}
// != operator - compare 2 CGameItemPtrs
inline bool CGameItemPtr : : operator ! = ( const CGameItemPtr & other ) const
{
return ! ( * this = = other ) ;
return ! ( * this = = other ) ;
}
// != operator - compare CGameItemPtrs to CGameItem*
inline bool CGameItemPtr : : operator ! = ( const CGameItem * item ) const
{
if ( item = = NULL )
return operator * ( ) ! = NULL ;
return ! ( * this = = item ) ;
return ! ( * this = = item ) ;
}
inline bool CGameItemPtr : : operator < ( const CGameItemPtr & other ) const
{
return _idx < other . _i dx;
return m_Idx < other . m_I dx;
}
# endif // GAME_ITEM_H