#pragma once #include #include #include "../AreaTileLoadHelper.h" //¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬ // // // - Ÿ¶ôÇÑ »ç¿ø SSQ(Survival Soloing Quest) // // - SSQInfo // - SSQPattern // //¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡ // const DWORD SSQ_MAX_CHARACTERS = 100; const DWORD SSQ_MAX_PLAYERS = 70; const DWORD SSQ_NAME_LEN = 31; typedef util::cSTRING_BUFFER SSQ_NAME; //¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬ // // struct SSQInfo { //¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡ // //#pragma pack(push, 1) typedef WORD INDEX_T; typedef MAPCODE SSQCODE; enum eLEVEL { LV_MIN, LV_MAX, LV_RANGE }; typedef LEVELTYPE LEVEL_RANGE[LV_RANGE]; enum eMAX_INFO { MI_ENTER_TIME_SECTION_MAX = 4, MI_EARTHQUAKE_SECTION_MAX = 4, MI_SUMMONED_NPC_SECTION_MAX = 16, MI_SUCCESS_POINT_BY_GRADE = 3, MI_REWARD_DROP_INFO_SECTION_MAX = 5, MI_REWARD_WINNER_INFO_SECTION_MAX = 3, MI_RESTRICT_SKILL_SECTION_MAX = 20, MI_RESTRICT_ITEM_SECTION_MAX = 15, }; typedef WORD WzTmFmt; // 17:27 --> { 17*100 + 27 } struct TimeRange { WzTmFmt Start, End; inline bool OnTime( const WzTmFmt& tm ) const { return Start && Start <= tm && tm <= End; } }; typedef TimeRange TIME_RANGE[MI_ENTER_TIME_SECTION_MAX]; typedef BYTE MINUTE_T; typedef BYTE SECOND_T; static const WzTmFmt TIME_NOTICE_START = 5; // ½ºÅ©¸³Æ®»ó ½ÃÀÛ ½Ã°£ Á¤º¸¿¡¼­ 5ºÐ Àü static const SECOND_T TIME_BATTLE_START_COUNTDOWN = 10; // 10ÃÊ Àü typedef WORD COUNT_T; enum ePLAYER_COUNT_LIMIT { PCL_MIN, PCL_MAX, PCL_RANGE, }; typedef COUNT_T PLAYER_COUNT_LIMIT[PCL_RANGE]; typedef BYTE RATIO_T; typedef WORD RATIO_SUM_T; typedef BYTE PAD_DUMMY_T; // ÇöÀç °·ºí °ü·Ã Á¤º¸´Â Çϳª... struct GAMBLE_INFO { RATIO_T m_ChargeRatio; }; struct EARTHQUAKE_NODE { MINUTE_T m_ElapsedTime; // Áö¿¬ ½Ã°£ COUNT_T m_RemainPlayers;// ³²Àº Àοø inline bool OnSatisfiedCondition( const EARTHQUAKE_NODE& rQuery ) const { return (rQuery.m_RemainPlayers // INDEX_T m_Index; // À妽º SSQCODE m_MapCode; // ÀÔÀå ¸ÊÄÚµå LEVEL_RANGE m_LevelRange; // ·¹º§ (ÃÖ¼Ò, ÃÖ´ë) MONEY m_Cost; // ÀÔÀå·á TIME_RANGE m_TimeRange; // ÀÔÀå½Ã°£ 1,2,... MINUTE_T m_WatingTime; // ÀüÅõ´ë±â½Ã°£ MINUTE_T m_QuestPlayTime; // ÀüüÇ÷¹À̽ð£ PLAYER_COUNT_LIMIT m_PlayerCountInfo; // ÀÔÀåÀοø Á¦ÇѰª GAMBLE_INFO m_GamebleInfo; // °·ºí Á¤º¸ EARTHQUAKE_INFO m_EarthquakeInfo; // ÁöÁøÁ¶°Ç 1,2,... THUNDERBOLT_NODE m_ThunderboltInfo; // ³«·Ú Á¤º¸ CLOSED_SPACE_NODE m_ClosedSpaceInfo; // °á°è Á¤º¸ SUMMONDED_NPC_INFO m_SummonedNpcInfo; // Ç÷¹À̾ÇÒ ¼öÇàÇÏ´Â ¸ó½ºÅÍ Á¤º¸ PLAYER_HUNTING_INFO m_PlayerHuntingInfo; // Player vs. Playerº° »ç³É Æ÷ÀÎÆ® »ó¼ö°ª NPC_HUNTING_INFO m_NpcHuntingInfo; // Player vs. Monsterº° »ç³É Æ÷ÀÎÆ® »ó¼ö°ª EXP_RATIO_INFO m_ExpRatioInfo; // ij¸¯Åͺ° »ç³É Æ÷ÀÎÆ® ¹èÀ² SUCCESS_POINT_INFO m_SuccessPointInfo; // Äù½ºÆ® ¼º°ø Æ÷ÀÎÆ® (1µî, 2µî, 3µî...) REWARD_NODE m_DefaultRewardInfo; // Âü°¡ÀÚ ±âº» º¸»ó Á¤º¸ REWARD_DROP_INFO m_RewardDropInfo; // º¸»ó ÀÏ¹Ý Á¤º¸ REWARD_WINNER_CHAR_INFO m_RewardWinnerInfo; // ÃÖÁ¾ ½Â¸®ÀÚ º¸»ó Á¤º¸ //REWARD_WINNER_INFO m_RewardWinnerInfo; // ÃÖÁ¾ ½Â¸®ÀÚ º¸»ó Á¤º¸ RESTRICT_SKILL_GROUP_INFO m_RestrictSkillGroupInfo; // »ç¿ëÀÌ Á¦ÇѵǴ ½ºÅ³ ±×·ì RESTRICT_ITEM_TYPE_INFO m_RestrictItemTypeInfo; // »ç¿ëÀÌ Á¦ÇѵǴ ¾ÆÀÌÅÛ Å¸ÀÔ //¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡ // ½Ã°£ °è»ê ÆíÀǸ¦ À§ÇÑ Çʵås <- ½ºÅ©¸³Æ®¿¡´Â Á¤ÀǵÇÁö ¾ÊÀ½. TIME_RANGE m_CTimeNotice; // °øÁö ½ÃÀÛ ½Ã°£ : 1ºÐ ´ÜÀ§ TIME_RANGE m_CTimeWaiting; // ÀüÅõ ´ë±â ½Ã°£ TIME_RANGE m_CTimeBattle; // ÀüÅõ ½Ã°£ SSQ_NAME m_SSQName; // ÀÔÀå À̸§, ExtraInfo (for Debug) //¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡ // public: inline bool IsAcceptLevel( const LEVELTYPE level ) const { return (m_LevelRange[LV_MIN]<=level) && (level<=m_LevelRange[LV_MAX]); } public: bool IsSSQOpenTime( const SYSTEMTIME* IN pSysTime=NULL, DWORD* OUT pIndex=NULL ) const; bool IsNoticeTime( const SYSTEMTIME* IN pSysTime=NULL, DWORD* OUT pIndex=NULL ) const; bool IsWaitingTime( const SYSTEMTIME* IN pSysTime=NULL, DWORD* OUT pIndex=NULL ) const; bool IsBattleTime( const SYSTEMTIME* IN pSysTime=NULL, DWORD* OUT pIndex=NULL ) const; public: inline bool IsValidCountForEnter( const COUNT_T curplayercnt ) const // for SERVER { return (curplayercnt<=m_PlayerCountInfo[PCL_MAX]); } inline bool IsValidCountForStart( const COUNT_T curplayercnt ) const // for SERVER { return (m_PlayerCountInfo[PCL_MIN]<=curplayercnt) && (curplayercnt<=m_PlayerCountInfo[PCL_MAX]); } inline COUNT_T GetSummonMobCount( const COUNT_T curplayercnt ) const // for SERVER { return SSQ_MAX_CHARACTERS-curplayercnt ; } public: bool IsSatisfiedEarthquakeCondition( const MINUTE_T elapsedTm, const COUNT_T curplayercnt ) const; //for SERVER MONSTERCODE GetRandomRegenMonster() const; private: inline const TimeRange* const _FindMatchTimeRange( const TimeRange* const pBegin , const TimeRange* const pEnd , const WzTmFmt calcTime , DWORD* OUT pIndex ) const; }; // end SSQInfo //¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬ inline BOOLEAN SSQInfo::RESTRICT_SKILL_GROUP_INFO::IsPassed( const SSQInfo::SKILL_GROUPCODE skill_group ) const { const SKILL_GROUPCODE* pIt = &SkillGroupCodes[0]; const SKILL_GROUPCODE* const pItEnd = &SkillGroupCodes[Count]; for( ; pIt!=pItEnd ; ++pIt ) if( *pIt == skill_group ) return FALSE; return TRUE; } inline BOOLEAN SSQInfo::RESTRICT_ITEM_TYPE_INFO::IsPassed( const WORD item_type ) const { const WORD* pIt = &ItemTypes[0]; const WORD* const pItEnd = &ItemTypes[Count]; for( ; pIt!=pItEnd ; ++pIt ) if( *pIt == item_type ) return FALSE; return TRUE; } //¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬ // // struct SSQPattern { //¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡ // //#pragma pack(push, 1) typedef WORD INDEX_T; typedef WORD STEP_T; typedef INT OBJECT_ID_T; enum eMAX_INFO { MI_OBJECT_COUNT_MAX = 25, MI_STEP_MAX = 4, }; struct sSINGLE_STEP { STEP_T m_Step; WORD m_ListSize; OBJECT_ID_T m_List[MI_OBJECT_COUNT_MAX]; }; typedef sSINGLE_STEP STEP_GROUP[MI_STEP_MAX]; //#pragma pack(pop) //¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡ // // INDEX_T m_Index; // ÇØ´ç ÆÐÅÏ À妽º STEP_T m_BanLiftStep; // °á°è Á¦°Å ´Ü°è (´Ü°è ¼ö) STEP_GROUP m_StepGroup; // °³º° ´Ü°è + ¿ÀºêÁ§Æ® Á¤º¸ // À̸§Àº... ÇÊ¿ä ¾øÀ» µí... ÀÖÀ¸¸é ±×¶§ Ãß°¡Çϱâ·Î ÇÑ´Ù. }; // end SSQPattern //¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬ namespace nsSSQ { class SSQTicketTimeInfo : public SSQTicketInfo { private: DWORD check_start_tick; SYSTEMTIME systemTime; // Ŭ¶ó Ä«¿îÆ®´Ù¿î Á¤º¸ ¾ò±â public: SSQTicketTimeInfo() { Init(); } VOID Init(); // ¼­¹ö·ÎÀÇ Á¤º¸ ¿äû ÇÊ¿äÇÑÁö ¿©ºÎ (eTM_NoneÀÏ °æ¿ì¸¸) inline eTM GetStatus() const { return (eTM)tmMode; } // ¼­¹ö·ÎÀÇ Á¤º¸ ¿äû ÁßÀ¸·Î ¼³Á¤. inline VOID SetStatus_Queried() { tmMode = eTM_Transaction; } // condition ] GetStatus() = { eTM_EnterableTimeout, eTM_CloseTimeout } // action ] const SYSTEMTIME& countdown = GetTicketTimeInfo(); // - used field = { countdown.wHour, countdown.wMinute, countdown.wSecond } const SYSTEMTIME& GetTicketTimeInfo(); // ¼­¹ö·ÎºÎÅÍ ¹ÞÀº Á¤º¸ ¼³Á¤. VOID QueryResult( const SSQTicketInfo& rTicketInfo ); #ifdef _SERVER BOOLEAN Update( const SYSTEMTIME* const pCurSysTime ); // for Server inline const SSQTicketInfo& GetTicketInfo() const { return *this; } #endif private: inline VOID _CalculationTime(); }; }; // end namespace nsSSQ //¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬ namespace nsSSQ { namespace Observer { struct Info { enum eRequest { eRequest_None = 0, eRequest_Observer , // not Observer eRequest_Leave , // always eRequest_ChangeCoord , // in ObserverMode eRequest_Max }; enum eKeyCmd { eKeyCmd_Q = 0, eKeyCmd_W = 1, eKeyCmd_E = 2, eKeyCmd_Max = 3, }; enum eCoordinates { eCoord_0 = 0, eCoord_1 = 1, eCoord_2 = 2, eCoord_3 = 3, eCoord_Slots = 4, }; enum eInfo { eInfo_Delay_NextKeyCmd = 3, // 3sec eInfo_Delay_QuestLeave = 5, }; }; struct Controller { // // true : { x | x // true : ÇØ´ç index¿¡ ¿¬°áµÈ ÁÂÇ¥ // false: NULL static const WzVector* GetPosByIndex( const Info::eCoordinates inputed_idx ); // for Client // C->G Packet Structure }; }}; // end namespace nsSSQ::Observer namespace nsSSQ { namespace Rules { typedef Observer::Info Info; enum eC2G_ReqRule { eC2G_ReqRule_None = 0, eC2G_ReqRule_BlockRequest = 1<< 0, eC2G_ReqRule_CondInSSQField = 1<< 2, eC2G_ReqRule_CondInFieldServer = 1<< 3, eC2G_ReqRule_CondObserverModeOn = 1<< 5, eC2G_ReqRule_CondObserverModeOff = 1<< 6, eC2G_ReqRule_CondDeadState = 1<< 7, }; struct C2G_RequestRule { Info::eRequest ReqType; eC2G_ReqRule RuleSet; }; const eC2G_ReqRule GetC2G_RequestRule( const Info::eRequest request ); }}; //end namespace nsSSQ::Rules //¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬ namespace nsSSQ { inline VOID _ConvertWzTmFmt2AcmTime( SSQInfo::TimeRange& INOUT rValue ) { const WORD bound =100; const WORD hour = 60; SSQInfo::WzTmFmt x; // = (x / B) * H + (x % B) x = rValue.Start; x = (SSQInfo::WzTmFmt) ( ((x / bound) * hour) + (x % bound) ); rValue.Start = x; x = rValue.End; x = (SSQInfo::WzTmFmt) ( ((x / bound) * hour) + (x % bound) ); rValue.End = x; } inline VOID _ConvertAcmTime2WzTmFmt( SSQInfo::TimeRange& INOUT rValue ) { const WORD bound =100; const WORD hour = 60; SSQInfo::WzTmFmt x; // = ( (x / H) * B ) + ( x % H ) x = rValue.Start; x = (SSQInfo::WzTmFmt) ( ( (x / hour) * bound ) + ( x % hour ) ); rValue.Start = x; x = rValue.End; x = (SSQInfo::WzTmFmt) ( ( (x / hour) * bound ) + ( x % hour ) ); rValue.End = x; } }; //¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬ // #include "SSQInfoStruct.hxx"