311 lines
9.9 KiB
C++
311 lines
9.9 KiB
C++
#pragma once
|
||
|
||
#include <Singleton.h>
|
||
#include <SolarFileReader.h>
|
||
#include <map>
|
||
#include <time.h>
|
||
#include <ScriptCode.IParser.h>
|
||
#include <ResultCode.h>
|
||
|
||
#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];
|
||
};
|
||
|
||
|
||
// <EventRewardInfo>
|
||
// 区间设置形式脚本
|
||
|
||
//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_TYPE_INFO::INDEX_T, EVENT_MINMAX_TYPE_INFO> 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<CODETYPE, EVENT_INFO> EVENTINFO_MAP;
|
||
typedef std::pair<CODETYPE, EVENT_INFO> EVENTINFO_PAIR;
|
||
typedef EVENTINFO_MAP::iterator EVENTINFO_MAP_ITER;
|
||
|
||
typedef std::vector<EVENT_INFO*> EVENT_INFO_VEC;
|
||
typedef EVENT_INFO_VEC::iterator EVENT_INFO_VEC_ITER;
|
||
|
||
// 根据事件模式绑定
|
||
typedef std::multimap<BYTE, EVENT_SUB_INFO> EVENT_SUB_INFO_MAP;
|
||
typedef std::pair<BYTE, EVENT_SUB_INFO> EVENT_SUB_INFO_PAIR;
|
||
typedef EVENT_SUB_INFO_MAP::iterator EVENT_SUB_INFO_ITER;
|
||
|
||
//-------------------------------------------------------------------------------------------------
|
||
// 事件信息解析器
|
||
//-------------------------------------------------------------------------------------------------
|
||
class SunEventInfoParser : public util::Singleton<SunEventInfoParser>, 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];
|
||
};
|