Files
Sun1602/ProgramCommon/SunEventInfoParser.h
T
2022-10-26 12:25:11 +08:00

311 lines
9.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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];
};