#pragma once #include #include #include "StructBase.h" #include "GameType.h" #include "ItemInstance.h" #include "StructGold.h" #include "GameDBManager.h" #include #include struct StructItem : GameObject { struct ITEM_PICKUP_ORDER { AR_HANDLE hPlayer[ 3 ]; int nPartyID[ 3 ]; }; // PreviousUID에 따른 정렬을 쉽게 하기 위해 필요한 구조체 struct INDEX_FINDER { StructItem * pItem; INDEX_FINDER( StructItem * _pItem ) : pItem( _pItem ){} bool operator ==( ItemUID uid ) { return uid == pItem->GetPreviousUID(); } }; enum _TARGET_TYPE { TARGET_TYPE_PLAYER = 0, TARGET_TYPE_SUMMON = 1, TARGET_TYPE_MONSTER = 2, TARGET_TYPE_NPC = 3, TARGET_TYPE_UNKNOWN = 4 }; static StructItem* AllocItem( ItemUID uid, ItemBase::ItemCode code, const __int64 & cnt = 1, ItemInstance::GenerateCode info = ItemInstance::BY_UNKNOWN, int level = -1, int enhance = -1, int flag = -1, ItemBase::ItemCode socket_0 = 0, ItemBase::ItemCode socket_1 = 0, ItemBase::ItemCode socket_2 = 0, ItemBase::ItemCode socket_3 = 0, int awaken_sid = 0, int identified_sid = 0, int remain_time = -1, const unsigned char & elemental_effect_type = 0, const time_t & elemental_effect_expire_time = 0, const int elemental_effect_attack_point = 0, const int elemental_effect_magic_point = 0, const ItemBase::ItemCode appearance_code = 0, int summon_code = 0, int extra_item_effect = 0); // Fraun Sky Accessories 7/12/2025 static StructItem* FindItem( AR_HANDLE handle ); static StructItem* AllocGold( const StructGold & gold, ItemInstance::GenerateCode gcode = ItemInstance::BY_UNKNOWN ); static void InitItemSystem(); static void DeInitItemSystem(); #define PendFreeItem( p ) PendFreeItem_( p, __FILE__, __LINE__ ) static void PendFreeItem_( StructItem* p, const char* function, const int line ); // 지워 달라고 요청. (모았다 주기적으로 한꺼번에 delete 한다) friend struct StructPlayer; virtual bool IsDeleteable(); static bool RegisterItemBase( const ItemBaseServer & base ); static ItemBase::ItemCode GetItemCode( const char *szItemName ); static bool IsValidItemCode( ItemBase::ItemCode code ); static bool RegisterConvertingInfo( ItemBase::ItemCode _key, ItemBase::ItemCode _value ); AR_HANDLE GetHandle() const { return m_hHandle; } virtual bool IsItem() const { return true; } inline bool IsBow() const { return ( GetItemBase().nClass == ItemBase::CLASS_LIGHT_BOW || GetItemBase().nClass == ItemBase::CLASS_HEAVY_BOW ); } inline bool IsCrossBow() const { return GetItemBase().nClass == ItemBase::CLASS_CROSSBOW; } // Bullet 류는 화살 뿐만 아니라 화살통을 포함한다. inline bool IsBullet() const { return GetItemBase().nGroup == ItemBase::GROUP_BULLET; } inline bool IsBelt() const { return GetItemBase().nGroup == ItemBase::GROUP_BELT; } inline bool IsEquipment() const { return GetItemBase().nType == ItemBase::TYPE_ARMOR; } inline bool IsCard() const { return GetItemBase().nType == ItemBase::TYPE_CARD; } inline bool IsChaosStone() const { return GetItemBase().nCode == 804000; } inline bool IsCharm() const { return GetItemBase().nType == ItemBase::TYPE_CHARM; } inline bool IsCollection() const { return GetItemBase().nType == ItemBase::TYPE_COLLECTION; } inline bool IsWeapon() const { return GetItemGroup() == ItemBase::GROUP_WEAPON; } inline bool IsAccessory() const { return GetItemGroup() == ItemBase::GROUP_ACCESSORY; } inline bool IsItemCard() const { return GetItemGroup() == ItemBase::GROUP_ITEMCARD; } inline bool IsWarpItem() const { return GetItemBase().Flag.IsOn( ItemBase::FLAG_WARP ); } inline bool IsSummonCard() const { return GetItemGroup() == ItemBase::GROUP_SUMMONCARD; } inline bool IsPetCage() const { return GetItemGroup() == ItemBase::GROUP_PET_CAGE; } inline bool IsSkillCard() const { return GetItemGroup() == ItemBase::GROUP_SKILLCARD; } inline bool IsSpellCard() const { return GetItemGroup() == ItemBase::GROUP_SPELLCARD; } inline bool IsCube() const { return GetItemBase().nType == ItemBase::TYPE_CUBE; } inline bool IsSupplyItem() const { return GetItemBase().nType == ItemBase::TYPE_SUPPLY; } inline bool IsUsingItem() const { return GetItemBase().nType == ItemBase::TYPE_USE || GetItemBase().nType == ItemBase::TYPE_USE_CARD; } inline bool IsArmor() const { return GetItemBase().nGroup == ItemBase::GROUP_ARMOR ; } inline bool IsStrikeCube() const { return GetItemGroup() == ItemBase::GROUP_STRIKE_CUBE; } inline bool IsDefenceCube() const { return GetItemGroup() == ItemBase::GROUP_DEFENCE_CUBE; } inline bool IsSkillCube() const { return GetItemGroup() == ItemBase::GROUP_SKILL_CUBE; } inline bool IsArtifact() const { return GetItemGroup() == ItemBase::GROUP_ARTIFACT; } //AziaMafia SkinPet inline bool IsSkin1() const { return GetItemGroup() == ItemBase::GROUP_SKIN1; } inline bool IsSkin2() const { return GetItemGroup() == ItemBase::GROUP_SKIN2; } inline bool IsSkin3() const { return GetItemGroup() == ItemBase::GROUP_SKIN3; } //AziaMafia PetSlot armure Set inline bool IsHelmet() const { return GetItemGroup() == ItemBase::GROUP_HELM; } inline bool IsGloves() const { return GetItemGroup() == ItemBase::GROUP_GLOVE; } inline bool IsBoots() const { return GetItemGroup() == ItemBase::GROUP_BOOTS; } //accesoire inline bool IsEarRing() const { return GetItemClass() == ItemBase::CLASS_EARRING; } inline bool IsRing() const { return GetItemClass() == ItemBase::CLASS_RING; } inline bool IsAmulet() const { return GetItemClass() == ItemBase::CLASS_ARMULET; } inline bool IsEquipmentOnBelt() const { return GetItemGroup() == ItemBase::GROUP_EQUIPMENT_ON_BELT; } inline bool IsFarmPass() const { return GetItemBase().nClass == ItemBase::CLASS_FARM_PASS; } inline bool IsRefreshStone() const { return GetItemCode() == 800000; } // 하드코드 -_- inline bool IsEtherealStone() const { return GetItemBase().nClass == ItemBase::CLASS_ETHEREAL_STONE;} inline bool IsShield() const { return GetItemBase().nClass == ItemBase::CLASS_SHIELD; } inline bool IsTwoHandItem() const { return GetItemBase().WearType == ItemBase::WEAR_TWOHAND; } inline bool IsDonatable() const { return !GetBaseFlag().IsOn( ItemBase::FLAG_CANT_DONATE ); } inline bool IsNeedTarget() const { return GetBaseFlag().IsOn( ItemBase::FLAG_TARGET_USE ); } inline bool IsCashItem() const { return GetBaseFlag().IsOn( ItemBase::FLAG_CASHITEM ); } inline bool IsTradable() const { return !GetBaseFlag().IsOn( ItemBase::FLAG_CANT_TRADE ); } // 뭐가 좀;; inline bool IsDropable() const { return !GetBaseFlag().IsOn( ItemBase::FLAG_CANT_DROP ); } // 역시 좀;; inline bool IsUsableMoving() const { return !GetBaseFlag().IsOn( ItemBase::FLAG_CANT_USE_MOVING ); } // 으음;; inline bool IsUsableSit() const { return !GetBaseFlag().IsOn( ItemBase::FLAG_CANT_USE_SIT ); } // 으음;; inline bool IsUsableInSiegeOrRaid() const { return !GetBaseFlag().IsOn( ItemBase::FLAG_CANT_USE_IN_RAID_SIEGE ); } // 아... 막 가는거다;; inline bool IsUsableInSecroute() const { return !GetBaseFlag().IsOn( ItemBase::FLAG_CANT_USE_IN_SECROUTE ); } // 젠장 왜 사용 불가 플래그냐고... inline bool IsUsableInEventmap() const { return !GetBaseFlag().IsOn( ItemBase::FLAG_CANT_USE_IN_EVENTMAP ); } // 역시 긍정 문으로 바꾸는 것이...;; inline bool IsUsableInHuntaholic() const { return !GetBaseFlag().IsOn( ItemBase::FLAG_CANT_USE_IN_HUNTAHOLIC ); } // ... inline bool IsUsableInOnlyHuntaholic() const { return GetBaseFlag().IsOn( ItemBase::FLAG_USABLE_IN_ONLY_HUNTAHOLIC ); } inline bool IsUsableInDeathmatch() const { return !GetBaseFlag().IsOn( ItemBase::FLAG_CANT_USE_IN_DEATHMATCH ); } inline bool IsUsableInOnlyDeathmatch() const { return GetBaseFlag().IsOn( ItemBase::FLAG_USABLE_IN_ONLY_DEATHMATCH ); } inline bool IsErasable() const { return !GetBaseFlag().IsOn( ItemBase::FLAG_NOT_ERASABLE ); } inline bool IsUsableOnOnlySit() const { return GetBaseFlag().IsOn( ItemBase::FLAG_USABLE_ON_ONLY_SIT ); } inline bool IsUsableInSecretDungeon() const { return !GetBaseFlag().IsOn( ItemBase::FLAG_CANT_USE_IN_SECRET_DUNGEON ); } inline bool IsUsableInBattleArena() const { return !GetBaseFlag().IsOn( ItemBase::FLAG_CANT_USE_IN_BATTLE_ARENA ); } inline bool IsRandomizable() const { return GetBaseFlag().IsOn( ItemBase::FLAG_RANDOMIZABLE ); } // 중첩기준: 중첩 가능한 플래그, 소환수가 들어 있지 않고, 스킬카드면 장비되있지 않아야 함. bool IsJoinable() const { return GetBaseFlag().IsOn( ItemBase::FLAG_JOIN ) && !GetInstanceFlag().IsOn( ItemInstance::ITEM_FLAG_SUMMON ) && !( IsSkillCard() && ( GetBindedPlayerSID() || GetBindedSummonSID() ) ); } void CopyFrom( StructItem* pFrom ); const bool IsReplaceable( const ItemBase::ItemCode code, const bool reset_remain_time ); const char* GetName() const; std::string GetNameInGame(); // 게임상 이름 반환 (게임에서 못 보는 이름인 '< >' 태그 삭제된 이름으로 반환) inline void SetPickupOrder( const ITEM_PICKUP_ORDER& ItemPickupOrder ) { s_memcpy( &m_ItemPickupOrder, sizeof( m_ItemPickupOrder ), &ItemPickupOrder, sizeof( m_ItemPickupOrder ) ); } inline const ITEM_PICKUP_ORDER& GetPickupOrder() const { return m_ItemPickupOrder; } // ItemUID 는 DB 에 저장할 필요가 있을때 발급된다. // 이는 플레이어의 인벤토리에 포함될때를 의미하며 해서 StructPlayer 에서 할당해준다. bool SetItemUID( ItemUID uid ); ItemUID GetItemUID() const { return m_Instance.UID; } bool ChangeItemCode( const ItemBase::ItemCode code ); bool ChangeAdditionalItemEffect( const ItemBase::ItemCode code, const int nItemEffectID ); // Fraun Sky Accessories 7/12/2025 // PreviuosUID는 아이템이 StructInventory 구조체 하에서 관리될 때 벡터형태의 메모리 구조의 단점을 어느정도 커버하기위해 사용된다. // 구체적으로는 발급은 StructInventory::push 로직내에서 처리되고, 데이터의 관리는 StructInventory내의 각 함수들에 의해 이루어진다. inline void SetPreviousUID( ItemUID uid ) { m_Instance.PreviousUID = uid; } inline ItemUID GetPreviousUID() { return m_Instance.PreviousUID; } inline AR_HANDLE GetOwnerHandle() const { return m_Instance.OwnerHandle; } inline void SetOwnerInfo( AR_HANDLE handle, int UID, int nAccountID ) { m_Instance.OwnerHandle = handle; m_Instance.nOwnerUID = UID; m_nAccountID = nAccountID; memset( &m_ItemPickupOrder, 0, sizeof( m_ItemPickupOrder ) ); } inline int GetOwnerUID() const { return m_Instance.nOwnerUID; } inline int GetAccountID() const { return m_nAccountID; } inline int GetAuctionID() const { return m_Instance.nAuctionID; } inline void SetAuctionID( int nAuctionID ) { m_Instance.nAuctionID = nAuctionID; } inline int GetItemKeepingID() const { return m_Instance.nItemKeepingID; } inline void SetItemKeepingID( int nItemKeepingID ) { m_Instance.nItemKeepingID = nItemKeepingID; } inline void SetIdx( int nIdx ) { m_Instance.nIdx = nIdx; } inline int GetIdx() const { return m_Instance.nIdx; } inline bool IsVirtualItem() const { return m_bIsVirtualItem; } inline void SetVirtualItem() { m_bIsVirtualItem = true; } inline void SetOwnSummonInfo( AR_HANDLE handle, int UID ) { m_Instance.OwnSummonHandle = handle; m_Instance.nOwnSummonUID = UID; } inline int GetOwnSummonUID() const { return m_Instance.nOwnSummonUID; } inline AR_HANDLE GetOwnSummonHandle() const { return m_Instance.OwnSummonHandle; } inline int GetItemAdditionalEffect() const { return m_Instance.nAdditionalItemEffect; } // Fraun Sky Accessories 7/12/2025 inline bool IsInStorage() const { return ( GetAccountID() && !GetOwnerUID() && GetItemCode() != 0 ); } // gold 아이템은 안친다.-_- inline bool IsInInventory() const { return ( !GetAccountID() && GetOwnerUID() ); } inline void SetWearInfo( ItemBase::ItemWearType wear_info, const bool bSkipDBUpdate = false ) { m_Instance.nWearInfo = wear_info; if( !bSkipDBUpdate ) TurnOnUpdateFlag(); } inline ItemBase::ItemWearType GetWearInfo() const { return m_Instance.nWearInfo; } // 1000 이상일경우 소환수에 장착된것임. void SetBindedCreatureHandle( AR_HANDLE target ) { m_hBindedTarget = target; } AR_HANDLE GetBindedCreatureHandle() const { return m_hBindedTarget; } ItemBase::ItemCode GetItemCode() const { return m_Instance.Code; } const ItemBaseServer & GetItemBase() const { return *m_pItemBase; } float GetWeight( const __int64 & cnt ) const { return cnt * GetItemBase().fWeight; } float GetWeight() const { return GetCount() * GetItemBase().fWeight; } ItemBase::ITEM_TYPE GetItemType() const { return static_cast< ItemBase::ITEM_TYPE >( GetItemBase().nType ); } ItemBase::ItemClass GetItemClass() const { return GetItemBase().nClass; } bool IsWearable() const; ItemBase::ItemWearType GetWearType() const { return GetItemBase().WearType; } int GetMaxSocketCount() const; int GetUsingSocketCount() const; ItemBase::ItemCode GetSocketCode( unsigned idx ) const { return m_Instance.Socket[idx]; } void SetSocketCode( unsigned idx, ItemBase::ItemCode code ) { m_Instance.Socket[idx] = code; } void SetSummonCode( int _nSummonCode ) { m_Instance.nSummonCode = _nSummonCode; } int GetSummonCode() const; int GetStateCode() const { return m_pItemBase->nStateCode; } int GetStateLevel() const { return m_pItemBase->nStateLevel; } AR_TIME GetStateTime() const { return m_pItemBase->nStateTime; } AR_TIME GetCoolTime() const { return m_pItemBase->nCoolTime * 100; } int GetCoolTimeGroup() const { return m_pItemBase->nCoolTimeGroup; } // 소환수 카드 전용 void SetSummonSID( int sid, const bool bSkipDBUpdate = false ) { if( !bSkipDBUpdate ) TurnOnUpdateFlag(); m_Instance.Socket[0] = sid; } int GetSummonSID() const { return static_cast< int >( m_Instance.Socket[0] ); } void SetSummonStruct( struct StructSummon* pSummon ) { m_pSummon = pSummon; } struct StructSummon* GetSummonStruct() const { return m_pSummon; } // 펫 우리 전용 void SetPetSID( const int sid ) { m_Instance.Socket[0] = sid; TurnOnUpdateFlag(); } const int GetPetSID() const { return static_cast< int >( m_Instance.Socket[0] ); } void SetPetCode( const int code ) { m_Instance.Socket[1] = code; TurnOnUpdateFlag(); } const int GetPetCode() const { return static_cast< int >( m_Instance.Socket[1] ); } void SetPetStruct( struct StructPet * pPet ) { m_pPet = pPet; } struct StructPet * GetPetStruct() const { return m_pPet; } void SetEventDropFlag( bool bFlag ) { m_bIsEventDrop = bFlag; } bool GetEventDropFlag() const { return m_bIsEventDrop; } // (스킬카드일경우) 누구에게 바인딩 되었는지? int GetSkillId() const { return m_pItemBase->nSkillID; } // TODO : 스킬카드일경우 스킬 번호 알려줘야함 bool IsBinded() const { return !!m_hBindedTarget; } void SetBindTarget( struct StructCreature *pTarget, const bool bSkipDBUpdate = false ); int GetBindedPlayerSID() const { return static_cast< int >( m_Instance.Socket[0] ); } int GetBindedSummonSID() const { return static_cast< int >( m_Instance.Socket[1] ); } bool IsGold() const { return !GetItemCode(); } void SetCount( const __int64 & c ) { m_Instance.nCount = c; TurnOnUpdateFlag(); } const __int64 GetCount() const { return m_Instance.nCount; } unsigned char GetItemGrade() const { return GetItemBase().nGrade; } int GetItemRank() const { return GetItemBase().nRank; } int GetItemLevel( bool toDB = false ) const { return toDB ? m_Instance.nLevel : m_Instance.nLevel % 100; } void SetItemLevel( int level ) { m_Instance.nLevel = GetItemEnhanceChance() * 100 + level; TurnOnUpdateFlag(); } int GetItemEnhance() const { return m_Instance.nEnhance; } void SetItemEnhance( int enhance ); short GetItemEnhanceChance() const { return ( ( m_Instance.nLevel - GetItemLevel() ) / 100 ); } void SetItemEnhanceChance(float chance) { m_Instance.nLevel = GetItemLevel() + chance * 100; TurnOnUpdateFlag(); } // 에테리얼 내구도 관련 const int ProcEtherealDurabilityConsumption( const int nBaseConsumption, const c_fixed10 & fConsumeRate, const c_fixed10 & fEnvironmentalConsumeRate ); const int GetCurrentEtherealDurability() const { return m_Instance.nCurrentEtherealDurability; } void SetCurrentEtherealDurability( const int nDurability ) { m_Instance.nCurrentEtherealDurability = std::min( std::max( nDurability, 0 ), GetMaxEtherealDurability() ); TurnOnUpdateFlag(); } void AddCurrentEtherealDurability( const int nAdd ) { // 오버 플로우 체크 __int64 nNewEtherealDurability = GetCurrentEtherealDurability(); nNewEtherealDurability += nAdd; if( nNewEtherealDurability > INT_MAX ) { assert( 0 ); nNewEtherealDurability = INT_MAX; } SetCurrentEtherealDurability( int( nNewEtherealDurability ) ); } const int GetMaxEtherealDurability() const; int GetCurrentEndurance() const { return m_Instance.nCurrentEndurance; } void SetCurrentEndurance( int n ); int GetMaxEndurance() const; // 레벨제한 int GetLevelLimit() const; // 권장레벨 int GetRecommendLevel() const; AR_UNIT GetItemAttackRange() const { return AR_UNIT( GetItemBase().nRange ); } int GetItemGroup() const { return GetItemBase().nGroup; } ItemBase::BaseFlag GetBaseFlag() const { return GetItemBase().Flag; } inline ItemInstance::InstanceFlag & GetInstanceFlag() { return m_Instance.Flag; } inline const ItemInstance::InstanceFlag & GetInstanceFlag() const { return m_Instance.Flag; } void SetInstanceFlagOn( int idx ); void SetInstanceFlagOff( int idx ); bool IsQuestItem() { return GetBaseFlag().IsOn( ItemBase::FLAG_QUEST ); } bool IsQuestDistributeItem() { return GetBaseFlag().IsOn( ItemBase::FLAG_QUEST_DISTRIBUTE ); } inline ItemInstance::GenerateCode GetGenerateCode() const { return m_Instance.GenerateInfo; } // 기간제 아이템 관련 bool IsExpireItem() const; time_t GetExpireTime() const { return m_Instance.tExpire; } // 단위 : 초 void SetRemainTime( time_t t ) { m_Instance.tExpire = t; } // 기간제 속성 이펙트 관련 const unsigned short SetElementalEffect( const unsigned char & cType, const time_t & tExpire ); const unsigned short SetElementalEffectAttackPoint( const int nAttackPoint ); const unsigned short SetElementalEffectMagicPoint( const int nMagicPoint ); void ClearElementalEffect(); // tElementalEffectExpire가 0일 경우는 무제한 inline const unsigned char GetElementalEffectType() const { return ( ( !m_Instance.tElementalEffectExpire || m_Instance.tElementalEffectExpire >= time( NULL ) ) ? m_Instance.cElementalEffectType : 0 ); } const time_t & GetElementalEffectExpireTime() const { return m_Instance.tElementalEffectExpire; } const int GetElementalEffectAttackPoint() const { return m_Instance.nElementalEffectAttackPoint; } const int GetElementalEffectMagicPoint() const { return m_Instance.nElementalEffectMagicPoint; } // 형상 변환 관련 const ItemBase::ItemCode GetAppearanceCode() const { return m_Instance.nAppearanceCode; } const bool SetAppearanceCode( const ItemBase::ItemCode nAppearanceCode ) { m_Instance.nAppearanceCode = nAppearanceCode; return true; } // 이하는 구현을 위해 존재하는 인터페이스임. void DBQuery( GameDBManager::DBProc *pWork ); void onEndQuery(); volatile size_t GetDBQueryCount() { return m_lQueryList.size(); } inline bool IsNeedUpdateToDB() { return ( m_nDBUpdateFlag != 0 ); } inline void TurnOffDbUpdateFlag() { InterlockedExchange( &m_nDBUpdateFlag, 0 ); } inline void TurnOnUpdateFlag() { InterlockedIncrement( &m_nDBUpdateFlag ); } inline void SetDropTime( AR_TIME t ) { m_nDropTime = t; } inline AR_TIME GetDropTime() { return m_nDropTime; } static ItemBaseServer & GetItemBase( ItemBase::ItemCode c ); // 세트 아이템 전용 int GetSetItemID() { return m_pItemBase->nSetID; } int GetSetItemPartFlag() { return m_pItemBase->nSetPartFlag; } // 아이템 랜덤 옵션 관련 함수들 (각성, 아이템옵션랜덤화) inline int GetRandomOptionType( ItemInstance::RANDOM_TYPE eType, int nIndex ) const { return m_Instance.RandomOption[ eType ].OptionInfo[ nIndex ].nType; } inline c_fixed10 GetRandomOptionValue1( ItemInstance::RANDOM_TYPE eType, int nIndex ) const { return m_Instance.RandomOption[ eType ].OptionInfo[ nIndex ].fValue1; } inline c_fixed10 GetRandomOptionValue2( ItemInstance::RANDOM_TYPE eType, int nIndex ) const { return m_Instance.RandomOption[ eType ].OptionInfo[ nIndex ].fValue2; } inline int GetRandomSID( ItemInstance::RANDOM_TYPE eType ) const { return m_Instance.RandomOption[ eType ].nSID; } inline void SetRandomSID( ItemInstance::RANDOM_TYPE eType, int nSID ) { m_Instance.RandomOption[ eType ].nSID = nSID; } inline bool IsRandomOptionItem( ItemInstance::RANDOM_TYPE eType ) const { return !!m_Instance.RandomOption[ eType ].nSID; } bool SetRandomOption( ItemInstance::RANDOM_TYPE eType, ItemInstance::RANDOM_OPTION & RandomOption ); ItemInstance::RANDOM_OPTION* GetRandomOption( ItemInstance::RANDOM_TYPE eType ); inline int GetAwakenOptionType( int nIndex ) const { return GetRandomOptionType( ItemInstance::AWAKEN, nIndex ); } inline c_fixed10 GetAwakenOptionValue1( int nIndex ) const { return GetRandomOptionValue1( ItemInstance::AWAKEN, nIndex ); } inline c_fixed10 GetAwakenOptionValue2( int nIndex ) const { return GetRandomOptionValue2( ItemInstance::AWAKEN, nIndex ); } inline int GetAwakenSID() const { return GetRandomSID( ItemInstance::AWAKEN ); } inline void SetAwakenSID( int nSID ) { return SetRandomSID( ItemInstance::AWAKEN, nSID ); } inline bool IsAwaken() const { return IsRandomOptionItem( ItemInstance::AWAKEN ); } inline bool SetAwakenOption( ItemInstance::RANDOM_OPTION & AwakenOption ) { return SetRandomOption( ItemInstance::AWAKEN, AwakenOption ); } inline int GetIdentifiedOptionType( int nIndex ) const { return GetRandomOptionType( ItemInstance::IDENTIFIED, nIndex ); } inline c_fixed10 GetIdentifiedOptionValue1( int nIndex ) const { return GetRandomOptionValue1( ItemInstance::IDENTIFIED, nIndex ); } inline c_fixed10 GetIdentifiedOptionValue2( int nIndex ) const { return GetRandomOptionValue2( ItemInstance::IDENTIFIED, nIndex ); } inline int GetIdentifiedSID() const { return GetRandomSID( ItemInstance::IDENTIFIED ); } inline void SetIdentifiedSID( int nSID ) { return SetRandomSID( ItemInstance::IDENTIFIED, nSID ); } inline bool IsIdentified() const { return IsRandomOptionItem( ItemInstance::IDENTIFIED ); } inline bool SetIdentifiedOption( ItemInstance::RANDOM_OPTION & IdentifiedOption ) { return SetRandomOption( ItemInstance::IDENTIFIED, IdentifiedOption ); } protected: static void deletePendingItem(); static void freeItem( StructItem* p ); // ArScheduler 에서 StructItem 을 지우기 위해 존재함. // alloc/free 메커니즘에 관한 확실한 이해 전에는 수정 말것! virtual bool ProcDelete(); AR_HANDLE m_hHandle; ItemInstance m_Instance; int m_nAccountID; unsigned m_unInventoryIndex; // 리스트에서의 위치 bool m_bIsEventDrop; bool m_bIsVirtualItem; volatile long m_nDBUpdateFlag; ItemBaseServer* m_pItemBase; struct StructSummon * m_pSummon; struct StructPet * m_pPet; AR_HANDLE m_hBindedTarget; // 스킬카드일경우 AR_TIME m_nDropTime; ITEM_PICKUP_ORDER m_ItemPickupOrder; // 아이템 집는 순서. XCriticalSection m_bQueryLock; std::list< GameDBManager::DBProc* > m_lQueryList; const char* m_deleteFunction; int m_deleteLine; StructItem( AR_HANDLE handle ); virtual ~StructItem(); };