#ifndef _SOLAR_SLOT_SCITEMSTREAMSERIALIZER_H #define _SOLAR_SLOT_SCITEMSTREAMSERIALIZER_H #include "./ItemOptionHeader.h" #include "./SCSlotHeader.h" #include "./SCSlotStruct_Version.h" //================================================================================================== // @history: // - 100523|waverix|move a stream parts section from SCSlotStruct.h #pragma pack(push) #pragma pack() class SCItemSlot; struct BASE_ITEMINFO; //================================================================================================== // begin of stream parts // #pragma pack(push, 1) //-------------------------------------------------------------------------------------------------- struct RENDER_ITEMPART { // DWORD dwSerial; //< ÆÐŶ¿ë WORD wCode; DURATYPE byDura; inline bool IsValid() const { return (wCode != 0); } }; //-------------------------------------------------------------------------------------------------- struct OPT_ITEMPART { WORD wCode; inline bool IsValid() const { return (wCode != 0); } }; //-------------------------------------------------------------------------------------------------- struct RENDER_OPTIONPART { BYTE Enchant :6; BYTE Set :2; BYTE bEquipDevice :1; //__NA_000968_ETHER_EMISSION_DEVICE BYTE byBulletIndex :4; BYTE Awakening :6; }; //================================================================================================== // // ¾ÆÀÌÅÛÆÄÃ÷ÀÇ ÁýÇÕ ½ºÆ®¸² //-------------------------------------------------------------------------------------------------- /* (CHANGES) (f100520.1L) remove an unused section // ±âº» ¾ÆÀÌÅÛ Á¤º¸ // Buy, Pick, Obtain, ÆÄƼ¿¡¼­ ºÐ¹è typedef union { ITEMPART Part; BYTE pStream[sizeof(ITEMPART)]; } ITEMSTREAM ; //ÆÐŶ¿ë ¾ÆÀÌÅÛ ½ºÆ®¸² ±¸Á¶Ã¼ typedef union { RENDER_ITEMPART Part; BYTE pStream[sizeof(RENDER_ITEMPART)]; } RENDER_ITEMSTREAM ; */ typedef union { struct { RENDER_ITEMPART Part; OPTIONPART OptionPart; }; BYTE pStream[sizeof(RENDER_ITEMPART) + sizeof(OPTIONPART)]; } RENDER_ITEMSTREAMEX ; //ÃÖÀûÈ­ ±âº»Á¤º¸ ÆÐŶ¿ë ±¸Á¶Ã¼ typedef union { struct { OPT_ITEMPART Part; RENDER_OPTIONPART OptionPart; }; BYTE pStream[sizeof(OPT_ITEMPART) + sizeof(RENDER_OPTIONPART)]; } OPT_ITEMSTREAMEX; //-------------------------------------------------------------------------------------------------- // ½ºÅ³ÆÄÃ÷ÀÇ ÃÖ¼Ò ´ÜÀ§ // ½ºÅ³ Á¤º¸ Ç¥½Ã ±âº» ´ÜÀ§ //-------------------------------------------------------------------------------------------------- struct SKILLPART { WORD wCode; inline bool IsValid() const { return (wCode != 0); } }; //-------------------------------------------------------------------------------------------------- // ½ºÅ³ÆÄÃ÷ÀÇ ÁýÇÕ ½ºÆ®¸² //-------------------------------------------------------------------------------------------------- typedef union { SKILLPART Part; BYTE pStream[sizeof(SKILLPART)]; } SKILLSTREAM ; //-------------------------------------------------------------------------------------------------- // ÄüÆÄÃ÷ÀÇ ÃÖ¼Ò ´ÜÀ§ // Äü Á¤º¸ Ç¥½Ã ±âº» ´ÜÀ§ //-------------------------------------------------------------------------------------------------- struct QUICKPART { SLOTIDX SlotIdx; SLOTCODE Code; BYTE Pos; inline bool IsValid() const { return (SlotIdx != 0); } }; //-------------------------------------------------------------------------------------------------- // ÄüÆÄÃ÷ÀÇ ÁýÇÕ ½ºÆ®¸² //-------------------------------------------------------------------------------------------------- typedef union { QUICKPART Part; BYTE pStream[sizeof(QUICKPART)]; } QUICKSTREAM ; //-------------------------------------------------------------------------------------------------- // ½ºÅ¸ÀÏÆÄÃ÷ÀÇ ÃÖ¼Ò ´ÜÀ§ // ½ºÅ¸ÀÏ Á¤º¸ Ç¥½Ã ±âº» ´ÜÀ§ //-------------------------------------------------------------------------------------------------- struct STYLEPART { SLOTCODE Code; inline bool IsValid() const { return (Code != 0); } }; //-------------------------------------------------------------------------------------------------- // ½ºÅ¸ÀÏÆÄÃ÷ÀÇ ÁýÇÕ ½ºÆ®¸² //-------------------------------------------------------------------------------------------------- typedef union { STYLEPART Part; BYTE pStream[sizeof(STYLEPART)]; } STYLESTREAM ; #pragma pack(pop) //-------------------------------------------------------------------------------------------------- // (NOTE) declared by _NA002217_100728_EP2_PERK_SYSTEM_ // current state : pack=8 struct PerkID { PerkID() : uid_(0) {} PerkID(ulong uid) : uid_(uid) {} PerkID(SLOTCODE group, LEVELTYPE level) : group_(group), level_(level) {} union { ulong uid_; struct { SLOTCODE group_; // perk group LEVELTYPE level_; // perk level }; }; }; struct PerkCommand { enum eCmd { eCmd_None = 0, eCmd_Insert, eCmd_Delete, eCmd_Register, // change to active eCmd_Unregister, // change to inactive // eCmd_Counts }; enum eResult { eResult_Success = 0, eResult_Fail, // default fail eResult_CantInsert, eResult_CantDelete, // eResult_Counts }; typedef uint8_t cmd_t; typedef uint16_t result_t; // cmd_t cmd_; result_t result_value_; // void InitCommand(cmd_t cmd) { ZeroMemory(this, sizeof(*this)); cmd_ = cmd; }; }; // current state : pack=8 // loaded by PerkInfoParser struct PerkInfo { static const uint16_t kMaxPerkLevel = 5; static const int kNumberOfBenefitOptions = 4; static const int kNumberOfPenaltyOptions = 2; struct OptionNode { uint16_t option_; // ref: eATTR uint8_t item_option_;// ref: item option in script, 'option_ = g_ITEM_OPTION[item_option_]' uint8_t value_type_; // ref: eVALUE_TYPE uint8_t attr_kind_; // ref: eATTR_KIND // (WARNING) this is a double converted value // based on the converted result of for a skill process of a result of a item caculator // after loading the perk script data int32_t value_; }; // (NOTE) the unique identification of a perk is presented by composition of a group and a level PerkID perk_id_; uint8_t order_; // sorted value based on a group code, runtime calculating data = { 0, ... } bool max_level_; // whether max level perk in same group SLOTCODE item_code_; // whether this perk is a base perk or an registerable perk using an item DWORD name_code_; // the perk name DWORD icon_code_; DWORD option_description_code_; DWORD penalty_description_code_; const PerkInfo* next_perk_; const PerkInfo* prev_perk_; EXPTYPE exp_value_; // a player needs exp_value_ to acquire this perk by level EXPTYPE next_level_exp_; // support value, a perk can level up on reached this value // OptionNode benefit_option_[kNumberOfBenefitOptions]; OptionNode penalty_2x_option_[kNumberOfPenaltyOptions]; OptionNode penalty_3x_option_[kNumberOfPenaltyOptions]; OptionNode penalty_4x_option_[kNumberOfPenaltyOptions]; }; // struct PerkData { PerkID perk_id_; SLOTCODE link_code_; // NOTE: a normal perk differs from a cash perk in below repect // a normal perk use the experience but a cash perk use the expiration date. DWORD64 exp_; }; // //-------------------------------------------------------------------------------------------------- // (NOTE) this data container is a data presentation for the perk slot container. // the perk slot container have 'active link slot' and 'registered slot' // the active link slot has unique group code // that has link point related to a registered slot using 'slot_index_' field. // the registered slot has an information to use when a player change to active // (specification) // Active Link Slot // GroupCode = { 65001, 65002, 65003, 65004 } ; // Unique Active Slot (1~4) // = { 65010, } ; // Unique Active Slot for cash event(1) // SlotIndex = slot index link for active slots of register slots // struct PerkDataList { static const int kNumberOfDefaultSlots = 15; static const int kNumberOfCashSlots = 3; static const int kNumberOfActiveSlots = 5; static const int kMaxNumberOfFixedSlots = 40; // reference : SCPerkSlotContainer.h static const int kMaxNumberOfNodes = kNumberOfDefaultSlots + kNumberOfCashSlots + kNumberOfActiveSlots; enum eGroupCodeActiveSlot { eActiveGroup01 = 65001, eActiveGroup02 = 65002, eActiveGroup03 = 65003, eActiveGroup04 = 65004, eActiveGroup10 = 65010, // cash slot linker }; // int number_of_nodes_; int reference_; PerkData perk_data_[kMaxNumberOfNodes]; // static const eGroupCodeActiveSlot kGroupCodeActiveSlots[kNumberOfActiveSlots]; static const POSTYPE kDefaultSlotPositions[kNumberOfDefaultSlots]; static const POSTYPE kCashSlotPositions[kNumberOfCashSlots]; static const POSTYPE kActiveSlotPositions[kNumberOfActiveSlots]; // static SLOTCODE GetActiveGroupCodeByIndex(int index); static int GetIndexByActiveGroupCode(int active_group_code); static bool CanRegisterToActiveSlot(const PerkInfo* perk_info, int active_group_code_index); // uint16_t GetSize() const { const int kMinSize = sizeof(*this) - sizeof(perk_data_); return static_cast(kMinSize + (sizeof(perk_data_[0]) * number_of_nodes_)); } }; inline SLOTCODE PerkDataList::GetActiveGroupCodeByIndex(int index) { if (!FlowControl::FCAssert(index >= 0 && index < _countof(kGroupCodeActiveSlots))) { return 0; } return static_cast(kGroupCodeActiveSlots[index]); } inline int PerkDataList::GetIndexByActiveGroupCode(int active_group_code) { const PerkDataList::eGroupCodeActiveSlot* it = kGroupCodeActiveSlots, * end = &kGroupCodeActiveSlots[_countof(kGroupCodeActiveSlots)]; for ( ; it != end; ++it) { if (*it == active_group_code) { return static_cast(it - kGroupCodeActiveSlots); } } assert(!"index out of range"); return _countof(kGroupCodeActiveSlots); } inline bool PerkDataList::CanRegisterToActiveSlot(const PerkInfo* perk_info, int active_group_code_index) { if (active_group_code_index < 0 || active_group_code_index >= _countof(kGroupCodeActiveSlots)) { return false; } const int kCashActiveSlotIndex = (_countof(kGroupCodeActiveSlots) - 1); const bool cash_perk = (perk_info->item_code_ != 0); if (cash_perk) { return active_group_code_index == kCashActiveSlotIndex; } // non-cash return active_group_code_index < kCashActiveSlotIndex; } // // end of stream parts //================================================================================================== struct SlotDeleter { template void operator()(T *& p) const { delete p; p = NULL; } }; //================================================================================================== namespace nsSlot { ; //-------------------------------------------------------------------------------------------------- // (CHANGES) (f100802.4L) moved from code file to support type version control struct Binder; // NOTE, f100826.3L, add an interface which is needed between two binders // when an version upgrade is processing struct IBinderPerVersion { virtual bool ModifySerializeBlock(const Binder* binder, const BASE_ITEMINFO* item_info) const = 0; }; // //-------------------------------------------------------------------------------------------------- // ulong used_bits #define SLOT_BITBOUND_CHECK(_from_, _bit_count_) \ ( ((_from_) & util::bit_range_mask_<(_bit_count_)>::value) == (_from_) ) #define SLOT_BITBOUND_CHECK_ASSERT(_from_, _bit_count_) \ { assert(SLOT_BITBOUND_CHECK(_from_, _bit_count_)); } // ulong(i/o) used_bits #define SLOT_BITBOUND_SET(_from_to_, _bit_count_) { \ SLOT_BITBOUND_CHECK_ASSERT(_from_to_, _bit_count_); \ (_from_to_) &= util::bit_range_mask_<(_bit_count_)>::value; } // byte used_bits #define SLOT_BITBOUND_CHECK_1B(_from_, _bit_count_) \ ( ((_from_) & (BYTE)util::bit_range_mask_<(_bit_count_)>::value) == (_from_) ) #define SLOT_BITBOUND_CHECK_ASSERT_1B(_from_, _bit_count_) \ { assert(SLOT_BITBOUND_CHECK_1B(_from_, _bit_count_)); } // byte(i/o) used_bits #define SLOT_BITBOUND_SET_1B(_from_to_, _bit_count_) { \ SLOT_BITBOUND_CHECK_ASSERT_1B(_from_to_, _bit_count_); \ (_from_to_) &= (BYTE)util::bit_range_mask_<(_bit_count_)>::value; } #define SP_CONST const //================================================================================================== // struct SerializeItemOption { //---------------------------------------------------------------------------------------------- // Shared Block & normal item (no equipment) struct sDefault { ulong ParseType; //8 // eParse_CantParse(Old)ÀÏ °æ¿ì, Block¿¡¼­ºÎÅÍ ¿¬¼Ó CopyStreamÀ¸·Î ó¸® ulong Block; //1 ulong UserBlock; //1 // the item purchase history to support distinction of a C cash or a PP cash (use 1bit) ulong Tag; //2 - renaming of a 'History' }; //---------------------------------------------------------------------------------------------- struct sTime : sDefault { ulong IsExpired; //1 ½Ã°£ ¸¸·á ¿©ºÎ ulong IsProgressTime; //1 ulong IsExpiredWaitTime; //1 UINT64 DateTime; //45 }; //---------------------------------------------------------------------------------------------- // _NA_0_20100727_SOCKET_SYSTEM_CONVERT struct sExtendData : sDefault { ulong data; //16 }; struct sBackupStream { ulong ParseType; BYTE stream[sizeof(OPTIONPART) - 1]; // Version5 | 6 - can't convert | can't find item_code }; //---------------------------------------------------------------------------------------------- #ifdef _NA_003740_20210624_ADDITEMRANDOM_ITEM6 struct RandomSetting { enum { kMaxOptionSize = 6 }; enum { kOptionBitSize = 16 }; }; #else struct RandomSetting { enum { kMaxOptionSize = 5 }; enum { kOptionBitSize = 16 }; }; #endif //---------------------------------------------------------------------------------------------- struct sEquip : sDefault { ulong IsIdentifyPossession; //1 ulong IsDestroyed; //1 ulong NOption; //3 ulong Rank; //4 ulong RankOption[RANK_MAX]; //7 x 10 ulong EnchantGrade; //4 ulong IsDivine; //1 old 'Set' // ulong SocketIdentifyType; //2 - _NA_0_20100727_SOCKET_SYSTEM_CONVERT ulong NumberOfSockets; //3 ulong SocketOption[SOCKET_MAX]; //10 x 5 // // ulong IsEquipEtherDevice; //1 ulong EtherBulletIndex; //4 // // the specification to support item customizing contents ulong History; //2 ulong ImageCode; //16 _NA000109_100427_ITEM_CUSTOMIZING_CONTENTS_ // _NA_003740_20111122_RANDOM_ITEM ulong RandomOptions[RandomSetting::kMaxOptionSize]; ulong AwakeningGrade; //4 // _NA_008124_20150313_AWAKENING_SYSTEM }; //---------------------------------------------------------------------------------------------- struct sEquipEtc : sDefault { ulong IsIdentifyPossession; //1 ulong IsDestroyed; //1 ulong NOption; //3 ulong EnchantGrade; //4 - restored by _NA002823_WINGS_EQUIPMENTS_EXTENTION ulong IsDivine; //1 ulong Rank; //4 ulong RankOption[RANK_MAX]; //7 x 10 ulong SocketIdentifyType; //2 - //xiaomi fix accessory SocketOption ulong NumberOfSockets; //3 ulong SocketOption[SOCKET_MAX]; //10 x 5 // // _NA_003740_20111122_RANDOM_ITEM ulong RandomOptions[RandomSetting::kMaxOptionSize]; }; //---------------------------------------------------------------------------------------------- struct sEquipTime : sDefault { ulong IsIdentifyPossession; //1 ulong IsDestroyed; //1 ulong NOption; //3 ulong Rank; //4 ulong RankOption[RANK_MAX]; //7 x 10 ulong EnchantGrade; //4 // ulong IsDivine; //1 old 'Set' // ulong SocketIdentifyType; //2 - _NA_0_20100727_SOCKET_SYSTEM_CONVERT // ulong NumberOfSockets; //3 ulong SocketOption[SOCKET_MAX]; //10 x 5 // ulong IsExpired; //1 ½Ã°£ ¸¸·á ¿©ºÎ ulong IsProgressTime; //1 ulong IsExpiredWaitTime; //1 UINT64 DateTime; //45 // ulong IsEquipEtherDevice; //1 ulong EtherBulletIndex; //4 // _NA_003740_20111122_RANDOM_ITEM ulong RandomOptions[RandomSetting::kMaxOptionSize]; ulong AwakeningGrade; //4 // _NA_008124_20150313_AWAKENING_SYSTEM }; //---------------------------------------------------------------------------------------------- struct sEquipEtcTime : sDefault { ulong IsIdentifyPossession; //1 ulong IsDestroyed; //1 ulong NOption; //3 ulong EnchantGrade; //4 - restored by _NA002823_WINGS_EQUIPMENTS_EXTENTION ulong IsDivine; //1 ulong Rank; //4 ulong RankOption[RANK_MAX]; //7 x 10 // ulong IsExpired; //1 ½Ã°£ ¸¸·á ¿©ºÎ ulong IsProgressTime; //1 ulong IsExpiredWaitTime; //1 UINT64 DateTime; //45 ulong SocketIdentifyType; //2 - //xiaomi fix accessory SocketOption ulong NumberOfSockets; //3 ulong SocketOption[SOCKET_MAX]; //10 x 5 // // _NA_003740_20111122_RANDOM_ITEM ulong RandomOptions[RandomSetting::kMaxOptionSize]; }; //---------------------------------------------------------------------------------------------- struct sLimited : sDefault { // Limited (no-divine(?) + armors) ulong IsIdentifyPossession; //1 ulong IsDestroyed; //1 ulong NOption; //3 ulong EnchantGrade; //4 // ulong IsDivine; //1 old 'Set' // ulong SocketIdentifyType; //2 - _NA_0_20100727_SOCKET_SYSTEM_CONVERT // ulong NumberOfSockets; //3 ulong SocketOption[SOCKET_MAX];//10 x 5 // ulong Index; //16 ulong DurationForRestore; //9 ÃÖ°í ³»±¸µµ(ȸº¹¿ë) ulong Duration; //9 ÃÖ°í ³»±¸µµ ulong NumberOfRepairs; //4 ¼ö¸® ȸ¼ö ulong DefenceRatio; //9 °ø°Ý·Â ºñÀ²(¹æ¾î±¸´Â ¹æ¾î·Â) ulong LimitValueRatio; //9 Á¦ÇÑ ¼öÄ¡ ºñÀ² /* // (CHANGES) (UNUSED SECTION) (WAVERIX) - ±âȹ È®ÀÎ struct sOption { ulong Option; //7 ulong Value; //6 } LimitedOption[LIMITED_MAX]; */ // the specification to support item customizing contents ulong History; //2 ulong ImageCode; //16 _NA000109_100427_ITEM_CUSTOMIZING_CONTENTS_ // _NA_003740_20111122_RANDOM_ITEM ulong RandomOptions[RandomSetting::kMaxOptionSize]; }; //---------------------------------------------------------------------------------------------- struct sFate : sDefault { // Fate (Lucky item) ulong IsIdentifyPossession; //1 ulong IsDestroyed; //1 ulong NOption; //3 ulong EnchantGrade; //4 // ulong SocketIdentifyType; //2 - _NA_0_20100727_SOCKET_SYSTEM_CONVERT // ulong NumberOfSockets; //3 ulong SocketOption[SOCKET_MAX]; //10 x 5 ulong Index; //16 ulong AtkDefRatio; //9 ulong Duration; //9 ÃÖ´ë ³»±¸µµ ulong IsIdentify; //1 ulong IsEquipEtherDevice; //1 -- f101105.3L, unused ulong EtherBulletIndex; //4 -- f101105.3L, unused UINT64 DateTime; //45 ulong IsExpired; //1 ½Ã°£ ¸¸·á ¿©ºÎ (not used) ulong IsExpiredWaitTime; //1 ulong Period; //14 // the specification to support item customizing contents ulong History; //2 ulong ImageCode; //16 _NA000109_100427_ITEM_CUSTOMIZING_CONTENTS_ // _NA_003740_20111122_RANDOM_ITEM ulong RandomOptions[RandomSetting::kMaxOptionSize]; }; //---------------------------------------------------------------------------------------------- struct sLottery : sDefault { // Lottery ulong Index; //16 LotteryScript Index ulong Identity; //8 Identity State ulong Count; //8 Item Count struct sSlot { ulong Random; //1 Is Random? ulong Exist; //1 Is Exist? ulong Position; // if(Exist) Part Index [1, 8] } Slots[MAX_PANDORA_SLOT_NUM]; }; //---------------------------------------------------------------------------------------------- struct sCoord : sDefault { ulong MapCode; //16 ÁÂÇ¥ ulong X; //16 ulong Y; //16 ulong Z; //16 }; //---------------------------------------------------------------------------------------------- struct sWayPoint : sDefault { // WayPoint // ÁÂÇ¥¸®½ºÆ® ¸µÅ©µÈ ¾ÆÀÌÅÛ ±â´ÉµéÀÇ È°¼º, ºñȰ¼º ±Ù°Å¸¦ °¡Áø´Ù. ulong IsExpired; //1 ½Ã°£ ¸¸·á ¿©ºÎ : ¾ÆÀÌÅÛ ÀÚü (lucky itemó·³ »ç¿ë ºÒ°¡ »óÅÂ?) ulong IsProgress; //1 UINT64 DateTime; //45 ulong WayPointDeleteEnabled;//1 ¿þÀÌÆ÷ÀÎÆ® ¸ñ·Ï¿¡¼­ ƯÁ¤ Ç׸ñ »èÁ¦ µÚ ºí·Ï »óÅ ¿©ºÎ UINT64 WayPointDeleteDateTime;//45 ¿þÀÌÆ÷ÀÎÆ® ¸ñ·Ï¿¡¼­ ƯÁ¤ Ç׸ñ »èÁ¦ µÚ ´ÙÀ½ »èÁ¦ °¡´É±îÁö ´ë±â½Ã°£ }; //---------------------------------------------------------------------------------------------- struct sPet : sDefault { ulong Fullness; //8 Æ÷¸¸°¨ ulong Intimacy; //8 Ä£¹Ðµµ ulong IsExpired; //1 UINT64 DateTime; //45 ulong IsSetPetName; //4 Æê³×ÀÓ ¼³Á¤ (Ver5¿¡¼­ Enchant¿µ¿ª »ç¿ë) char Name[MAX_PET_NAME_LENGTH]; //8 x 10 // the specification to support item customizing contents ulong History; //2 ulong ImageCode; //16 _NA000109_100427_ITEM_CUSTOMIZING_CONTENTS_ }; //---------------------------------------------------------------------------------------------- struct sRider : sDefault { //ulong IsIdentifyPossession; //1 //ulong IsDestroyed; //1 ulong IsUnlimitedPeriod; //1 ±âÇÑ ¼³Á¤ ¾øÀ½. ulong IsExpiredWaitTime; //1 ±âÇÑ ¸¸·á ÈÄ ´ë±â »óÅ UINT64 DateTime; //45 struct sPart { // migration from sRiderParts ulong ItemCode; //16 ¶óÀÌ´õ ÆÄÃ÷ ¾ÆÀÌÅÛ ÄÚµå ulong EnchantGrade; //3 (<- 4), (CHANGES) (f100803.2L) ulong Tag; //1 ulong IsUnlimitedPeriod;//1 ±âÇÑ ¼³Á¤ ¾øÀ½. ulong IsProgress; //1 ÀåÂø ½ÃÁ¡ºÎÅÍ ½Ã°£ °è»ê ulong IsExpiredWaitTime;//1 ±âÇÑ ¸¸·á ÈÄ ´ë±â »óÅ ulong DateOffset; //16 + 1 (±â°£ ¿¬Àå °í·Á +/- 30ÀÏ)(ºÐ ´ÜÀ§:60x12x30 x sign) } Parts[eRIGER_PARTS_SLOT_IDX_COUNT]; // // DateOffset Description - used(16) ÃÖÀå (+/-)45ÀÏ ±îÁö´Â °¡´ÉÇÏÁö¸¸ undocumented optionÀ¸·Î.... // (0/1) = +/- // 1010 1000 1100 0000 = 30ÀÏ // (090916) (CURRENT) // Rider : used( 49) = 49 // RiderParts : used(120) = 40 * 3 // Total : used(169) = Rider + RiderParts }; //---------------------------------------------------------------------------------------------- // (NOTE) Enchant´Â ÀÌÆåÆ® Åø¿¡¼­ ¼³Á¤ÇÏ´Â ´Ü°è = {0, 1, 2, 3, 4}·Î ¼³Á¤µÈ´Ù. ÇÏÁö¸¸ È¥¶õ ¹æÁö ¸ñÀû // À¸·Î ÀÔÃâ·ÂÀº ´Ù¸¥ °Í°ú °°Àº [0, 12] + 1(ÀϺ» ÃÖ°­ ÀÌÆåÆ®)¿Í °°ÀÌ ¼³Á¤ÇÑ´Ù. struct sRiderParts : sDefault { // ulong EnchantGrade; //4 ¿Î½º¿¡ ÀÇÇÑ ÀÎæÃ÷, ÇØ´ç °ªÀÇ Àç ¼³Á¤ ÇÊ¿äÇÏ´Ù. ulong IsUnlimitedPeriod; //1 ±âÇÑ ¼³Á¤ ¾øÀ½. ulong IsProgress; //1 ÀåÂø ¿©ºÎ ulong IsExpiredWaitTime; //1 ±âÇÑ ¸¸·á ÈÄ ´ë±â »óÅ UINT64 DateTime; //45 µ¶¸³ ¾ÆÀÌÅÛÀ¸·Î Á¸Àç½Ã¿¡´Â ÀϹÝÀûÀÎ SolarDateTime ulong Period; //14 }; //---------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------- union { //------------------------------------------------------------------------------------------ sDefault Default; sTime Time; sExtendData ExtendData; //_NA_0_20100727_SOCKET_SYSTEM_CONVERT sEquip Equip; sEquipEtc EquipEtc; sEquipTime EquipTime; sEquipEtcTime EquipEtcTime; sCoord Coord; sLimited Limited; sFate Fate; sLottery Lottery; sWayPoint WayPoint; sPet Pet; sRider Rider; sRiderParts RiderParts; sBackupStream BackupStream; }; //end of union SerializeItemOption() {} SerializeItemOption(const SerializeItemOption& r) { CopyMemory(this, &r, sizeof(*this)); } SerializeItemOption& operator=(const SerializeItemOption& r) { CopyMemory(this, &r, sizeof(*this)); return *this; } void Clear() { ZeroMemory(this, sizeof(*this)); } // (CHANGES) (f100802.4L) add an interface to acquire multiple list based on type and version static bool GetBinder( const ItemParseType::ValueType parse_type, const int version, const Binder** result_binder, const IBinderPerVersion** modifier ); }; //================================================================================================== // ÇØ´ç ½½·Ô¿¡ ÀûÀçµÈ ¾ÆÀÌÅÛ Á¤º¸¿¡ µû¸¥ ±â´É Á¦ÇÑ. struct ItemFuncAttr { enum Function { eEnable_None = 0, eEnable_Divine = 1 << 1, eEnable_NOption = 1 << 2, eEnable_Rank = 1 << 3, eEnable_Enchant = 1 << 4, eEnable_Socket = 1 << 5, eEnable_Possession = 1 << 6, //ÀåÂø °è¿­ eEnable_Timer = 1 << 7, //ŸÀÌ¸Ó ¼³Á¤ °¡´É ¾ÆÀÌÅÛ eEnable_Coord = 1 << 8, eEnable_Etherealize = 1 << 9, // the means of Konglish. can extract option to the etheria item eEnable_AddData = 1 << 10, // ex) Zard item with identification information eEnable_Randomize = 1 << 11, // ´É·ÂÄ¡ ·£´ýÈ­ °¡´É eEnable_Awakening = 1 << 12, // °¢¼º °¡´É // _NA_008124_20150313_AWAKENING_SYSTEM }; enum ItemFunctionSet { kNoneItem = 0, kDefaultItem = eEnable_None, kExtendDataItem = eEnable_AddData, kEquipItem = eEnable_NOption|eEnable_Enchant|eEnable_Rank|eEnable_Socket|eEnable_Divine| eEnable_Randomize #ifdef _NA_008124_20150313_AWAKENING_SYSTEM | eEnable_Awakening #endif // _NA_008124_20150313_AWAKENING_SYSTEM , kEquipEtcsItem = eEnable_NOption|eEnable_Rank|eEnable_Randomize|eEnable_Socket, //xiaomi add accessory enchant socket kFateItem = eEnable_NOption|eEnable_Enchant|eEnable_Socket|eEnable_Timer|eEnable_Randomize, kLimitedItem = eEnable_NOption|eEnable_Enchant|eEnable_Socket|eEnable_Divine|eEnable_Randomize, kLotteryItem = eEnable_None, kPetItem = eEnable_None, // apply timer by ItemInfoParser rule kCordItem = eEnable_Coord, kWaypointItem = eEnable_Timer, kRiderItem = eEnable_None, kRiderPartsItem = eEnable_Enchant, }; ItemFuncAttr() : value(0) { } bool IsEnable(const Function func) const { return !!(value & func); } uint16_t value; }; //================================================================================================== // ÀÚÁÖ »ç¿ëµÇ´Â ¾ÆÀÌÅÛ ºÐ·ù µ¥ÀÌÅÍ // @history // - 09.09.23|waverix|created and preparation for the item stream version 7| // - 09.10.03|waverix|updates all sections to support the item stream version 7| // - 10.05.06|waverix|add an edit rule to support the etheria item control| // // (Item Rule) // // eParse_CantParse - ½ºÅ©¸³Æ®¿¡ ÀÇÇÑ °Íµµ ÀÖ°í, Á¤º¸ º¸Á¸ Â÷¿ø¿¡¼­¶óµµ À¯ÁöÇÒ ÇÊ¿ä ÀÖ´Ù. // // eParse_Limited // { NOption(O), Divine(O), Rankup(X), Enchant(O), Socket(O), Possession(O), DateTime(X) } // eParse_Pet // { Pet(O), PetName(O) } // eParse_Lottery // { MiniSlot(O) } // // #else base on ChargeSubType // ChargeSubType(eCHARGE_SUB_GENERAL) // eCHARGE_SUB_GENERAL // eCHARGE_PC_ROOM PC¹æ ¾ÆÀÌÅÛÀº ÇÊ¿ä ¾ø´Ù. // { NOption(O), Divine(O), Rankup(O), Enchant(O), Socket(O), Possession(O), DateTime(X) } // eParse_EquipWeapon // eParse_EquipArmor // eParse_EquipEtcs // // eCHARGE_SUB_FIXED_AMOUNT: // eCHARGE_SUB_FIXED_AMOUNT_EX: // eCHARGE_SUB_FIXED_QUANTITY: // eCHARGE_SUB_FIXED_AMOUNT_WAIT: // { NOption(O), Divine(O), Rankup(X), Enchant(O), Socket(O), DateTime(O) } // // eCHARGE_SUB_COORDINATE // { Coordinate(O) } // // eCHARGE_SUB_FATE // { NOption(X), Divine(X), Rankup(X), Enchant(O), Socket(O), DateTime(O) } // // eCHARGE_SUB_COORDINATE_EX // { DateTime(O) } struct ItemRuleInfo { ItemParseType::ValueType parse_type; uint8 charge_sub_type; ItemFuncAttr func_attr; // ÇØ´ç ½½·Ô¿¡ ÀûÀçµÈ ¾ÆÀÌÅÛ Á¤º¸¿¡ µû¸¥ ±â´É Á¦ÇÑ. struct { bool is_valid_item; bool is_can_overlap; bool is_use_shared; bool is_editable; bool is_etheria; bool is_shell; bool is_normal; bool is_limited; bool is_fate; bool is_armor; bool is_weapon; bool is_accessory; bool is_accessory_special; bool is_accessory_wings; bool is_lottery; bool is_pet; bool is_waypoint; bool is_coord; bool is_rider; bool is_rider_parts; bool is_extend_data; bool is_costume; //_NA_008610_20160104_ADD_DECORATECOSTUME bool is_deco_costume; bool is_toggle_item; }; ItemRuleInfo() : parse_type(0), charge_sub_type(0), is_valid_item(false), is_can_overlap(false), is_use_shared(false), is_editable(false), is_etheria(false), is_shell(false), is_normal(false), is_limited(false), is_fate(false), is_armor(false), is_weapon(false), is_accessory(false), is_accessory_special(false), is_accessory_wings(false), is_lottery(false), is_pet(false), is_waypoint(false), is_coord(false), is_rider(false), is_rider_parts(false), is_extend_data(false), is_costume(false), #ifdef _NA_008610_20160104_ADD_DECORATECOSTUME is_deco_costume(false), #endif //_NA_008610_20160104_ADD_DECORATECOSTUME is_toggle_item(false) { } // true: pass constraints // false: violation item constraints static bool GetRuleInfo(ItemRuleInfo* OUT result, const BASE_ITEMINFO* base_item_info, bool is_limited_set); // limited ¼³Á¤Àº ¿ÜºÎ Á¦¾î´Ù. // true: pass constraints // false: violation item constraints // limited ¼³Á¤Àº ¿ÜºÎ Á¦¾î´Ù. static bool GetRuleInfo( ItemRuleInfo* OUT result, const SCItemSlot& ref_item_slot, bool is_limited_set, const ItemParseType::ValueType* const parent_parse_type ); // (CHANGES) (f100523.2L) prefetch the rule for a item information static bool PrefetchRuleInfo(ItemRuleInfo* OUT result, const BASE_ITEMINFO* item_info); // (NOTE) ¿ÜºÎ easiable access interface // SCItemSlot ³»ºÎ¿¡¼­´Â ¹Ù·Î Á¢±ÙÇØ¼­ »ç¿ë Áß¿¡ ÀÖ´Ù. bool IsEnableDivine() const { return !!(func_attr.value & func_attr.eEnable_Divine); } bool IsEnableExtraOption() const { return !!(func_attr.value & func_attr.eEnable_NOption); } bool IsEnableRank() const { return !!(func_attr.value & func_attr.eEnable_Rank); } bool IsEnableEnchant() const { return !!(func_attr.value & func_attr.eEnable_Enchant); } bool IsEnableSocket() const { return !!(func_attr.value & func_attr.eEnable_Socket); } bool IsEnablePossession() const { return !!(func_attr.value & func_attr.eEnable_Possession); } bool IsEnableTimer() const { return !!(func_attr.value & func_attr.eEnable_Timer); } bool IsEnableCoord() const { return !!(func_attr.value & func_attr.eEnable_Coord); } // _NA000109_100427_ITEM_CUSTOMIZING_CONTENTS_ bool IsEnableEtherealize() const { return (func_attr.value & func_attr.eEnable_Etherealize) != 0; } bool IsEnableRandomize() const { return (!!is_editable && func_attr.IsEnable(ItemFuncAttr::eEnable_Randomize)); } #ifdef _NA_008124_20150313_AWAKENING_SYSTEM bool IsEnableAwakening() const { return (!!func_attr.value & func_attr.IsEnable(ItemFuncAttr::eEnable_Awakening)); } #endif // _NA_008124_20150313_AWAKENING_SYSTEM }; // //================================================================================================== // °øÀ¯ Á¤º¸¸¦ »ç¿ëÇϰí ÀÖ´Â ¾ÆÀÌÅÛÀÏ °æ¿ì ¼³Á¤µÇ´Â Á¤º¸ // SCItemSlot::shared_ //---------------------------------------------------------------------------------------------- // // Sharing Part - address union block // union { // SCLimitedInfo limited_info_; // SCFateInfo fate_info_; // SCPetInfo pet_info_; // SCWayPointInfo waypoint_info_; // SCLottoInfo lotto_info_; // nsSlot::SCCoordinateInfo coordinate_info_; // SCRiderInfo rider_info_; // SCRiderPartsInfo rider_parts_info_; // } shared_; struct SCSharedInfoCheck { BOOLEAN value; // true : used | false : unused }; }; //end of namespace 'nsSlot' // //================================================================================================== //================================================================================================== namespace nsSlot { ; // for internal operation // (Specification) // [0] [1] [2] [3] [4] [5] [6] [7] // add_rider sub_rider add_p0 add_p1 add_p2 sub_p0 sub_p1 sub_p2 struct RiderUpdateBits { // 0 - add apply rider option // 1 - sub apply rider option // 2~4 - add apply parts option // 5~7 - sub apply parts option union { struct { BYTE value; }; struct { BYTE add_rider : 1; BYTE sub_rider : 1; BYTE add_parts0 : 1; BYTE add_parts1 : 1; BYTE add_parts2 : 1; BYTE sub_parts0 : 1; BYTE sub_parts1 : 1; BYTE sub_parts2 : 1; }; }; static const BYTE NoOperation = 0; static const BYTE AllAddParts = (1 << 2) | (1 << 3) | (1 << 4); static const BYTE AllSubParts = (1 << 5) | (1 << 6) | (1 << 7); static const BYTE AllAddOptions = (1 << 0) | AllAddParts; static const BYTE AllSubOptions = (1 << 1) | AllSubParts; }; }; //end of namespace #pragma pack(pop) #endif //_SOLAR_SLOT_SCITEMSTREAMSERIALIZER_H