#pragma once #include #include #include #include #include #include #ifdef _NA_007919_20141211_ADD_GMCOMMAND_EVENT #include "GameOptionParser.h" #endif //_NA_007919_20141211_ADD_GMCOMMAND_EVENT // 事件类型 enum eEVENT_MODE { eEVENT_CREATECHAR, // 创建角色时提供特定道具 eEVENT_REGWEBITEM, // 在网上注册物品时赠送赠品 eEVENT_REGITEM_GETITEM, // 登录道具后提供特定道具 eEVENT_REGITEM_RANDREWARD, // 登录道具后随机发放奖励 eEVENT_CRAFTITEM, // 道具制造活动 eEVENT_ENCHANTITEM, // 物品交易活动 eEVENT_DECOMPITEM, // 物品分解活动 eEVENT_PEAKTIME, // 高峰时间事件 eEVENT_COUPON, // 游戏内优惠券活动 eEVENT_PCBANG_PEAKTIME, // 网吧高峰时间活动 eEVENT_DONATION_HEIM, // 注册事件 eEVENT_ITEM_SELECT, // 物品选择活动(未登录只需选择npc即可进行的活动) eEVENT_BUFF_GRANT, // Buff赋予活动(没有活动ID邀请,只需选择NPC即可进行的活动) #ifdef _NA_20081121_ABUMAN_NIJOT_EVENT eEVENT_GUILD_MISSION_EVENT = 13, // 任务完成时任务进行全部为公会成员提供更多经验的活动. #endif //_KR_0_20091021_FIRENDINVITATION_EXTEND eEVENT_FRIENDINVATION_EVENT = 14, // 邀请朋友后,在同一个队伍上玩游戏的话,会有额外经验的活动 #ifdef _NA_007992_20150127_EVENT_MONSTER_INVASION eEVENT_MONSTER_INVASION = 15, // 怪物入侵事件 #endif //_NA_007992_20150127_EVENT_MONSTER_INVASION #ifdef _NA_008404_20150712_MINIGAME_SYSTEM eEVENT_MINIGAME_BINGO = 16, // 宾果活动 #endif // _NA_008404_20150712_MINIGAME_SYSTEM // eEVENT_MAX, // 活动ID最大值 // __NA001094_080904_TASK_SSQ_REWARD_PROCESS__ // T_EventUser DB Table 多功能预约代码 // ref type) eEVENT_MODE_MULTIUSE // range) eEVENT_MULTIUSE_START(10000) ~ 10002 }; enum eEVENT_DAY_FLAG { eEVENT_DAY_FLAG_ALLDAY = (0), //< 0 eEVENT_DAY_FLAG_SUNDAY = (1<<0), //< 1 eEVENT_DAY_FLAG_MONDAY = (1<<1), //< 2 eEVENT_DAY_FLAG_TUESDAY = (1<<2), //< 4 eEVENT_DAY_FLAG_WEDNESDAY = (1<<3), //< 8 eEVENT_DAY_FLAG_THURSDAY = (1<<4), //< 16 eEVENT_DAY_FLAG_FRYDAY = (1<<5), //< 32 eEVENT_DAY_FLAG_SATURDAY = (1<<6), //< 64 }; //#define _WHATTHEHELL_SUNEVENT_20060727 // 正在修改从SUN事件脚本中删除的事件 // 用于保存每个事件信息 struct EVENT_INFO { CODETYPE m_dwEventID; //在不使用npc信息的怪物入侵(mode==15)中,将npc代码用作mapcode CODETYPE m_NpcCode; BYTE m_byEventMode; __time64_t m_start_time; __time64_t m_end_time; WORD m_wEventDayFlag; BYTE m_byCountMax; enum eAPPLY_LEVEL { LEVEL_MIN = 0, LEVEL_MAX, LEVEL_RANGE, }; WORD m_byApplyToLvRng[LEVEL_RANGE]; CODETYPE m_dwRegisterItemIndex[_MAX_EVENT_REGITEM]; WORD m_wRegisterItemNum[_MAX_EVENT_REGITEM]; WORD m_wPeakTimeStart; WORD m_wPeakTimeEnd; CODETYPE m_dwItemCraftIndex; CODETYPE m_dwItemEnchantIndex; CODETYPE m_dwItemDecompoIndex; float m_fRewardExpRate; // 峰值时间经验增加率 float m_fRewardExpRate2; // 神圭角色经验值增加率 float m_fRewardHimeRate; float m_fRewardItemDropRate; CODETYPE m_dwRewardInfo[_MAX_EVENT_REWARD]; // 重命名,(现有)奖励代码->(变更)奖励信息奖励代码+其他(根据活动模式区分) CODETYPE m_dwPCRoomRewardInfo[_MAX_EVENT_REWARD]; CODETYPE m_EventRewardCode; BYTE m_IsDeleteFlagForRewardedItem; enum { _MAX_DELETE_ITEM_CODES = 5, }; SLOTCODE m_DeleteRewaredItemCode[_MAX_DELETE_ITEM_CODES]; enum { _MAX_EXPRATE_NUM = 3 }; float m_fPlayTimeExpRate[_MAX_EXPRATE_NUM]; // (071120) 当前不使用. #ifdef _NA_007919_20141211_ADD_GMCOMMAND_EVENT bool is_gm_event_; // 在脚本中读到的活动是false/GM制作的活动 bool is_pre_notify_; // 活动开始“5分钟前通知”是否运行(false:尚未通知) // 设置GM活动信息. // 单独设置Event ID. BOOL SetGMEventWithoutID(eEVENT_MODE event_mode, int start_date, WORD start_time, int end_date, WORD end_time, int reward_ratio); #endif //_NA_007919_20141211_ADD_GMCOMMAND_EVENT eEVENT_DAY_FLAG GetDayFlag(int tm_wday); BOOL CheckEvent(time_t curtime); BOOL CheckEvent(); BOOL CheckLevel(const LEVELTYPE playerLevel); }; inline eEVENT_DAY_FLAG EVENT_INFO::GetDayFlag(int tm_wday) { switch(tm_wday) { case 0: return eEVENT_DAY_FLAG_SUNDAY; case 1: return eEVENT_DAY_FLAG_MONDAY; case 2: return eEVENT_DAY_FLAG_TUESDAY; case 3: return eEVENT_DAY_FLAG_WEDNESDAY; case 4: return eEVENT_DAY_FLAG_THURSDAY; case 5: return eEVENT_DAY_FLAG_FRYDAY; case 6: return eEVENT_DAY_FLAG_SATURDAY; } return eEVENT_DAY_FLAG_SUNDAY; } inline BOOL EVENT_INFO::CheckEvent() { time_t cur_time; util::TimeSync::time(&cur_time); return CheckEvent(cur_time); } inline BOOL EVENT_INFO::CheckLevel(const LEVELTYPE playerLevel) { return (m_byApplyToLvRng[LEVEL_MIN] <= playerLevel) && (playerLevel <= m_byApplyToLvRng[LEVEL_MAX]); } //================================================================================================== struct EVENT_SUB_INFO { CODETYPE m_dwEventID; BYTE m_byEventMode; BYTE m_byCountMax; CODETYPE m_dwRegisterItemIndex[5]; WORD m_wRegisterItemNum[5]; }; // // 区间设置形式脚本 //struct EVENT_MINMAX_TYPE_INFO //{ // enum { _MAX_GROUPNODE_COUNT = 15, }; // typedef DWORD INDEX_T; // typedef DWORD ROUND_T; // typedef DWORD HEIM_BOUND_T; // typedef HEIM_BOUND_T MinMaxArray[_MAX_GROUPNODE_COUNT]; // typedef MinMaxArray DropCodeArray; // typedef MinMaxArray CountLimitArray; // // INDEX_T m_Index; // ROUND_T m_MaxGroupRound; // 整个集团的行政最多可以进行几次? // MinMaxArray m_MinBoundaries; // 每组的最小边界 // MinMaxArray m_MaxBoundaries; // 每组的最大边界 // CountLimitArray m_LimitCounts; // DropCodeArray m_DropCodes; //}; struct EVENT_MINMAX_TYPE_INFO { enum { _MAX_GROUPNODE_COUNT = 15, _MAX_GAPNODE_COUNT = _MAX_GROUPNODE_COUNT+1 }; enum { _TOTAL_ROUND_UNLIMITED = 255, }; // 允许无限制的完整组管理。 typedef DWORD INDEX_T; typedef DWORD ROUND_T; typedef DWORD HEIM_BOUND_T; INDEX_T m_Index; ROUND_T m_MaxGroupRound; // 全组管理可以进行多少次?? HEIM_BOUND_T m_LimitHeimPerDonation; // 最低捐款金额 #ifdef _NA_20100307_BETAKEY_SYSTEM INT32 m_BeytaKey; #endif struct NODE { HEIM_BOUND_T Min; // 每组的最小边界 HEIM_BOUND_T Max; // 每组的最大边界 } m_Nodes[_MAX_GROUPNODE_COUNT]; // 每个组的 MinMax ROUND_T m_Limits[_MAX_GROUPNODE_COUNT]; // 每组可奖励多少次 DWORD m_DropCodes[_MAX_GROUPNODE_COUNT]; // DropCode 从每组获得随机奖励 struct GAP // 每组之间有一个未补偿的空间。结构来计算它。 { HEIM_BOUND_T Min; HEIM_BOUND_T Max; } m_Gaps[_MAX_GAPNODE_COUNT]; }; typedef std::map EVENT_MINMAX_MAP; typedef EVENT_MINMAX_MAP::iterator EVENT_MINMAX_MAP_IT; struct sEVENT_MINMAX_RESULT { enum eCONTROL { CNTL_FAIL = 0, // 无法补偿. CNTL_UPDATE , // 没有补偿,只有信息更新. CNTL_SUCCESS , // 得到奖励 (不分群落专心丢码) }; eCONTROL m_Result; RC::eEVENT_RESULT m_ResultCode; // <- FAIL 情况下的详细错误 DWORD m_DropCode; // 奖励掉落代码 DWORD m_RewaredCount; // 该组的奖励数量 DWORD m_CalcedDonatedMoney; // 内部计算捐款总额,可能会出现以下情况( calced != donated + add ) DWORD m_TotalRounds; // 总组笔画数 inline VOID SetInfo( eCONTROL IN ctrl, DWORD IN dropCode, DWORD IN rewardedCnt, DWORD IN calcedMoney, DWORD IN totalRounts ) { m_Result = ctrl; m_ResultCode=(RC::eEVENT_RESULT)0; m_DropCode = dropCode ; m_RewaredCount = rewardedCnt; m_CalcedDonatedMoney = calcedMoney; m_TotalRounds = totalRounts; } }; struct sEVENT_MINMAX_QUERY { const DWORD linkedID; const MONEY donatedMoney; // const MONEY addinMoney; // const EVENT_INFO* pEventInfo; const DWORD curRewardedCount; const DWORD curTotalRounds; // (县)团体行政总人数 const BOOL bSkipCheckHeims; // 检查最小贡献 heim 约束(顶部为 FALSE) sEVENT_MINMAX_QUERY( const DWORD _linkedID, const MONEY _donatedMoney, const MONEY _addinMoney, const EVENT_INFO* _pEventInfo, const DWORD _curRewardedCount, const DWORD _curTotalRounds, const BOOL _bSkipCheckHeims = FALSE ) : bSkipCheckHeims(_bSkipCheckHeims), linkedID(_linkedID), donatedMoney(_donatedMoney), addinMoney(_addinMoney), pEventInfo(_pEventInfo), curRewardedCount(_curRewardedCount), curTotalRounds(_curTotalRounds) { } // __DISABLE_COPY(sEVENT_MINMAX_QUERY); }; // 按事件 ID 排序 typedef std::map EVENTINFO_MAP; typedef std::pair EVENTINFO_PAIR; typedef EVENTINFO_MAP::iterator EVENTINFO_MAP_ITER; typedef std::vector EVENT_INFO_VEC; typedef EVENT_INFO_VEC::iterator EVENT_INFO_VEC_ITER; // 根据事件模式绑定 typedef std::multimap EVENT_SUB_INFO_MAP; typedef std::pair EVENT_SUB_INFO_PAIR; typedef EVENT_SUB_INFO_MAP::iterator EVENT_SUB_INFO_ITER; //------------------------------------------------------------------------------------------------- // 事件信息解析器 //------------------------------------------------------------------------------------------------- class SunEventInfoParser : public util::Singleton, public IParser { public: SunEventInfoParser(); ~SunEventInfoParser(); VOID Init( char * pszPackFileName ); VOID Release(); VOID Reload(); EVENT_INFO* FindEventInfo( CODETYPE dwEventID ); EVENT_INFO* FindEventInfoFromMode( eEVENT_MODE eMode ); //返回每个模式的第一个事件信息。 EVENT_INFO_VEC* FindEventInfoFromNpcType( CODETYPE dwNpcType ); EVENTINFO_MAP* GetEventInfoMap() { return &m_mapEventInfo; } EVENT_SUB_INFO_MAP* GetEventSubInfoMap() { return &m_mapEventSubInfo; } #if defined(_SERVER) public: VOID FindMinMaxInfoByBoundary( sEVENT_MINMAX_QUERY& IN rARG, sEVENT_MINMAX_RESULT& OUT rResult ); BOOL _LoadEventReward( BOOL bReload ); #endif public: BOOL LoadScript( eSCRIPT_CODE ScriptCode, BOOL bReload ); private: BOOL _Load( BOOL bReload ); VOID Unload(); private: EVENTINFO_MAP m_mapEventInfo; EVENT_SUB_INFO_MAP m_mapEventSubInfo; EVENT_INFO_VEC m_vecFindedEventInfo; #if defined(_SERVER) EVENT_MINMAX_MAP m_MinMaxMap; #endif CHAR m_pszEventFileName[MAX_PATH]; };