using UnityEngine; using System.IO; using System.Runtime.InteropServices; using System; namespace PerfectWorld.Scripts.Task { public class TaskTemplConstants { public const int MAX_TASK_NAME_LEN = 30; public const int MAX_AWARD_NPC_NUM = 8; public const int MAX_PREM_TASK_COUNT = 20; public const int MAX_MUTEX_TASK_COUNT = 5; public const int MAX_OCCUPATIONS = 12; // 职业 // Occupations public const int MAX_TEAM_MEM_WANTED = MAX_OCCUPATIONS; public const int MAX_TIMETABLE_SIZE = 24; public const int MAX_AWARD_SCALES = 5; public const int MAX_AWARD_CANDIDATES = 12; public const int MAX_LIVING_SKILLS = 4; public const int MAX_CONTRIB_MONSTERS = 100; // PQ子任务贡献度最大怪物种类 // Maximum monster types for PQ subtask contribution public const int MAX_AWARD_PQ_RANKING = 32; // PQ子任务奖励最大排名数 // Maximum ranking count for PQ subtask rewards public const int MAX_TITLE_NUM = 10; public const int MAX_TASKREGION = 8; // 最大区域个数 // Maximum number of regions public const int TASK_GENDER_NONE = 0; public const int TASK_GENDER_MALE = 1; public const int TASK_GENDER_FEMALE = 2; public const int TASK_MAX_PATH = 260; public const uint INVALID_VAL = uint.MaxValue; public const int TASK_MAX_LINE_LEN = TASK_MAX_PATH; public const int TASK_MAX_VALID_COUNT = 6; public const int TASK_TREASURE_MAP_SIDE_MULTIPLE = 30; // 藏宝图边长与小区域边长的比 // Ratio of treasure map side length to small region side length public const int NUM_SPECIAL_AWARD = 2; public static readonly int[] TASK_SPECIAL_AWARD = new int[NUM_SPECIAL_AWARD] { 26969, 26970 }; public const uint TASK_PACK_MAGIC = 0x93858361; // Race-occupation mapping array public static readonly uint[] _race_occ_map = new uint[MAX_OCCUPATIONS]; } public enum DynTaskType { enumDTTNone = 0, enumDTTSpecialAward, enumDTTNormal, enumDTTGiftCard, } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct NPC_INFO { public uint id; public short x; public short y; public short z; } public class ServerNotificationConstants { // 新任务发放 // New task issued public const int TASK_SVR_NOTIFY_NEW = 1; // 任务完毕 // Task completed public const int TASK_SVR_NOTIFY_COMPLETE = 2; // 任务放弃 // Task abandoned public const int TASK_SVR_NOTIFY_GIVE_UP = 3; // 杀怪数量 // Monster kill count public const int TASK_SVR_NOTIFY_MONSTER_KILLED = 4; // 处于得到奖励状态 // In reward receiving state public const int TASK_SVR_NOTIFY_FINISHED = 5; // 错误码 // Error code public const int TASK_SVR_NOTIFY_ERROR_CODE = 6; // 遗忘生活技能 // Forget life skill public const int TASK_SVR_NOTIFY_FORGET_SKILL = 7; // 动态任务时间标记 // Dynamic task time mark public const int TASK_SVR_NOTIFY_DYN_TIME_MARK = 8; // 动态任务数据 // Dynamic task data public const int TASK_SVR_NOTIFY_DYN_DATA = 9; // 特殊奖励信息 // Special reward info public const int TASK_SVR_NOTIFY_SPECIAL_AWARD = 10; // 仓库数据 // Storage data public const int TASK_SVR_NOTIFY_STORAGE = 11; // 显示全局变量 // Display global variables public const int TASK_SVR_NOTIFY_DIS_GLOBAL_VAL = 12; // 藏宝位置 // Treasure location public const int TASK_SVR_NOTIFY_TREASURE_MAP = 13; // 设置任务列表上限 // Set task list limit public const int TASK_SVR_NOTIFY_SET_TASK_LIMIT = 14; // 杀人数量 // Player kill count public const int TASK_SVR_NOTIFY_PLAYER_KILLED = 15; } public class ClientNotificationConstants { // 检查完成 // Check completion public const int TASK_CLT_NOTIFY_CHECK_FINISH = 1; // 检查放弃 // Check abandonment public const int TASK_CLT_NOTIFY_CHECK_GIVEUP = 2; // 到达地点 // Reach location public const int TASK_CLT_NOTIFY_REACH_SITE = 3; // 自动交付 // Auto delivery public const int TASK_CLT_NOTIFY_AUTO_DELV = 4; // 手动触发 // Manual trigger public const int TASK_CLT_NOTIFY_MANUAL_TRIG = 5; // 强制放弃 // Force abandon public const int TASK_CLT_NOTIFY_FORCE_GIVEUP = 6; // 动态任务时间标记 // Dynamic task time mark public const int TASK_CLT_NOTIFY_DYN_TIMEMARK = 7; // 动态任务数据 // Dynamic task data public const int TASK_CLT_NOTIFY_DYN_DATA = 8; // 特殊奖励 // Special reward public const int TASK_CLT_NOTIFY_SPECIAL_AWARD = 9; // 离开地点 // Leave location public const int TASK_CLT_NOTIFY_LEAVE_SITE = 10; // PQ检查初始化 // PQ check initialization public const int TASK_CLT_NOTIFY_PQ_CHECK_INIT = 11; // 仓库 // Storage public const int TASK_CLT_NOTIFY_STORAGE = 12; // 请求宝藏索引 // Request treasure index public const int TASK_CLT_NOTIFY_REQUEST_TREASURE_INDEX = 14; // 15天未登录 // 15 days no login public const int TASK_CLT_NOTIFY_15DAYS_NOLOGIN = 15; // 特殊奖励掩码 // Special reward mask public const int TASK_CLT_NOTIFY_SPECIAL_AWARD_MASK = 16; // 称号任务 // Title task public const int TASK_CLT_NOTIFY_TITLE_TASK = 17; // 选择奖励 // Choose reward public const int TASK_CLT_NOTIFY_CHOOSE_AWARD = 18; // 购买代币商店物品 // Buy token shop item public const int TASK_CLT_NOTIFY_BUY_TOKENSHOP_ITEM = 20; // 通过世界贡献完成任务 // Complete task by world contribution public const int TASK_CLT_NOTIFY_FINISH_TASK_BY_WORLD_CONTRIBUTION = 21; // 移除完成任务 // Remove completed task public const int TASK_CLT_NOTIFY_RM_FINISH_TASK = 150; } public static class PlayerNotificationConstants { // Notify receiving team member task // 通知接收队员任务 public const int TASK_PLY_NOTIFY_NEW_MEM_TASK = 1; // Whole team fails // 全队失败 public const int TASK_PLY_NOTIFY_FORCE_FAIL = 2; // Whole team succeeds // 全队成功 public const int TASK_PLY_NOTIFY_FORCE_SUCC = 3; } public static class GlobalDataReasonConstants { public const int TASK_GLOBAL_CHECK_RCV_NUM = 1; public const int TASK_GLOBAL_CHECK_COTASK = 2; public const int TASK_GLOBAL_CHECK_ADD_MEM = 3; public const int TASK_GLOBAL_NPC_KILLED_TIME = 4; public const int TASK_GLOBAL_ADD_TIME_MARK = 5; public const int TASK_GLOBAL_DEL_TIME_MARK = 6; public const int TASK_GLOBAL_PROTECT_NPC = 7; } public static class CotaskConditionConstants { public const int COTASK_CORRESPOND = 0; public const int COTASK_ONCE = 1; } // 任务类型 // Task types public enum ENUM_TASK_TYPE { enumTTDaily = 100, // 每日 // Daily enumTTLevel2, // 修真 // Cultivation enumTTMajor, // 主线 // Main quest enumTTBranch, // 支线 // Branch quest enumTTEvent, // 活动 // Event enumTTQiShaList, // 七杀榜 // Seven Killers List enumTTFaction, // 帮派 // Faction enumTTFunction, // 经营 // Management enumTTLegend, // 传奇 // Legend enumTTQuestion, // 答题 // Quiz enumTTEnd, } // 完成方式 // Completion methods public enum TaskCompletionMethod { enumTMNone = 0, // 无 // None enumTMKillNumMonster, // 杀数量怪 // Kill specific number of monsters enumTMCollectNumArticle, // 获得数量道具 // Collect specific number of items enumTMTalkToNPC, // 与特定NPC对话 // Talk to specific NPC enumTMReachSite, // 到达特定地点 // Reach specific location enumTMWaitTime, // 等待特定时间 // Wait for specific time enumTMAnswerQuestion, // 选择问答 // Answer questions enumTMTinyGame, // 小游戏 // Mini game enumTMProtectNPC, // 保护特定NPC // Protect specific NPC enumTMNPCReachSite, // NPC到达特定地点 // NPC reaches specific location enumTMGlobalValOK, // 全局变量满足条件 // Global variable meets condition enumTMLeaveSite, // 离开特定地点 // Leave specific location enumTMReachTreasureZone, // 达到藏宝区域 // Reach treasure zone enumTMKillPlayer, // 杀死玩家 // Kill player enumTMTransform, // 变身状态 // Transform state enumTMReachLevel, // 检查等级:普通等级,转生次数,境界等级 // Check level: normal level, reincarnation count, realm level enumTMSimpleClientTask, // 简单任务,只做客户端验证,目前只验证表情动作 // Simple task, client-side verification only, currently only verifies emote actions enumTMSimpleClientTaskForceNavi, // 强制移动 // Force movement } // 完成条件 // Completion conditions public enum TaskFinishType { enumTFTDirect = 0, // 直接完成 // Direct completion enumTFTNPC, // NPC完成 // NPC completion enumTFTConfirm // 需要确认完成 // Need confirmation to complete } // 奖励方式 // Reward methods public enum TaskAwardType { enumTATNormal = 0, // 普通 // Normal enumTATEach, // 按杀怪数目、获得物品乘 // Multiply by monster kills, items obtained enumTATRatio, // 按时间比例 // By time ratio enumTATItemCount // 按获得物品个数分不同档次 // Different tiers based on number of items obtained } // 任务重复间隔 // Task repeat interval public enum TaskAwardFreq { enumTAFNormal = 0, // 普通 // Normal enumTAFEachDay, // 每天 // Daily enumTAFEachWeek, // 每周 // Weekly enumTAFEachMonth, // 每月 // Monthly enumTAFEachYear // 每年 // Yearly } public struct TASK_PACK_HEADER { public uint magic; public uint version; public int item_count; } public struct ZONE_VERT { public float x; public float y; public float z; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct PLAYER_WANTED { public uint m_ulTemplID; // Player Template ID public uint m_ulCount; // Count public uint m_ulLevel; // Level } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct MONSTER_WANTED { public uint m_ulMonsterTemplId; // Monster template ID public uint m_ulMonsterNum; // Number of monsters public uint m_ulDropItemId; // Drop item ID public uint m_ulDropItemCount; // Drop item count public bool m_bDropCmnItem; // Is common item drop public float m_fDropProb; // Drop probability public bool m_bKillerLev; // Killer level flag public int m_iDPH; // Damage per hit public int m_iDPS; // Damage per second public bool Equals(MONSTER_WANTED src) { return (m_ulMonsterTemplId == src.m_ulMonsterTemplId && m_ulMonsterNum == src.m_ulMonsterNum && m_ulDropItemId == src.m_ulDropItemId && m_ulDropItemCount == src.m_ulDropItemCount && m_bDropCmnItem == src.m_bDropCmnItem && m_fDropProb == src.m_fDropProb && m_bKillerLev == src.m_bKillerLev); } } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct ITEM_WANTED { public uint m_ulItemTemplId; public bool m_bCommonItem; public uint m_ulItemNum; public float m_fProb; public int m_lPeriod; public bool Equals(ITEM_WANTED src) { return (m_ulItemTemplId == src.m_ulItemTemplId && m_bCommonItem == src.m_bCommonItem && m_ulItemNum == src.m_ulItemNum && m_lPeriod == src.m_lPeriod); } } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct TITLE_AWARD { public uint m_ulTitleID; public int m_lPeriod; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct TEAM_MEM_ITEM_WANTED { public uint m_ulItemTemplId; public bool m_bCommonItem; public uint m_ulItemNum; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct MONSTERS_SUMMONED { public uint m_ulMonsterTemplId; public uint m_ulMonsterNum; public float m_fSummonProb; public int m_lPeriod; public bool Equals(MONSTERS_SUMMONED src) { return (m_ulMonsterTemplId == src.m_ulMonsterTemplId && m_ulMonsterNum == src.m_ulMonsterNum && m_fSummonProb == src.m_fSummonProb && m_lPeriod == src.m_lPeriod); } } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct MONSTERS_CONTRIB { public uint m_ulMonsterTemplId; // Monster ID // 怪物ID public int m_iWholeContrib; // Team exclusive contribution // 组队间独享贡献度 public int m_iShareContrib; // Team shared contribution // 组队间共享贡献度 public int m_iPersonalWholeContrib; // Personal exclusive contribution // 个人独享贡献度 public bool Equals(MONSTERS_CONTRIB src) { return (m_ulMonsterTemplId == src.m_ulMonsterTemplId && m_iWholeContrib == src.m_iWholeContrib && m_iShareContrib == src.m_iShareContrib && m_iPersonalWholeContrib == src.m_iPersonalWholeContrib); } } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct RANKING_AWARD { public uint m_iRankingStart; public uint m_iRankingEnd; public bool m_bCommonItem; public ulong m_ulAwardItemId; public ulong m_ulAwardItemNum; public long m_lPeriod; public bool Equals(RANKING_AWARD src) { return (m_iRankingStart == src.m_iRankingStart && m_iRankingEnd == src.m_iRankingEnd && m_bCommonItem == src.m_bCommonItem && m_ulAwardItemId == src.m_ulAwardItemId && m_ulAwardItemNum == src.m_ulAwardItemNum && m_lPeriod == src.m_lPeriod); } } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct AWARD_MONSTERS_SUMMONED { public uint m_ulMonsterNum; public bool m_bRandChoose; public uint m_ulSummonRadius; public bool m_bDeathDisappear; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.MAX_MONSTER_SUMMONED)] public MONSTERS_SUMMONED[] m_Monsters; public int MarshalBasicData(byte[] pData) { int offset = 0; pData[offset] = m_bRandChoose ? (byte)1 : (byte)0; offset++; pData[offset] = (byte)m_ulSummonRadius; offset++; pData[offset] = (byte)m_ulMonsterNum; offset++; pData[offset] = m_bDeathDisappear ? (byte)1 : (byte)0; offset++; int sz = Marshal.SizeOf(typeof(MONSTERS_SUMMONED)) * (int)m_ulMonsterNum; if (sz > 0) { // Copy MONSTERS_SUMMONED array to byte array GCHandle handle = GCHandle.Alloc(m_Monsters, GCHandleType.Pinned); try { IntPtr ptr = handle.AddrOfPinnedObject(); Marshal.Copy(ptr, pData, offset, sz); } finally { handle.Free(); } offset += sz; } return offset; } public int UnmarshalBasicData(byte[] pData) { int offset = 0; m_bRandChoose = pData[offset] != 0; offset++; m_ulSummonRadius = pData[offset]; offset++; m_ulMonsterNum = pData[offset]; offset++; m_bDeathDisappear = pData[offset] != 0; offset++; if (m_ulMonsterNum > 0) { m_Monsters = new MONSTERS_SUMMONED[m_ulMonsterNum]; int sz = Marshal.SizeOf(typeof(MONSTERS_SUMMONED)) * (int)m_ulMonsterNum; // Copy byte array to MONSTERS_SUMMONED array for (uint i = 0; i < m_ulMonsterNum; i++) { IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(MONSTERS_SUMMONED))); try { Marshal.Copy(pData, offset, ptr, Marshal.SizeOf(typeof(MONSTERS_SUMMONED))); m_Monsters[i] = (MONSTERS_SUMMONED)Marshal.PtrToStructure(ptr, typeof(MONSTERS_SUMMONED)); } finally { Marshal.FreeHGlobal(ptr); } offset += Marshal.SizeOf(typeof(MONSTERS_SUMMONED)); } } return offset; } public static bool operator ==(AWARD_MONSTERS_SUMMONED a, AWARD_MONSTERS_SUMMONED b) { if (a.m_ulMonsterNum != b.m_ulMonsterNum) { return false; } for (uint i = 0; i < a.m_ulMonsterNum; ++i) { if (!(a.m_Monsters[i].Equals(b.m_Monsters[i]))) { return false; } } return (a.m_bRandChoose == b.m_bRandChoose && a.m_ulSummonRadius == b.m_ulSummonRadius && a.m_bDeathDisappear == b.m_bDeathDisappear); } public static bool operator !=(AWARD_MONSTERS_SUMMONED a, AWARD_MONSTERS_SUMMONED b) { return !(a == b); } public override bool Equals(object obj) { if (obj is AWARD_MONSTERS_SUMMONED) return this == (AWARD_MONSTERS_SUMMONED)obj; return false; } public override int GetHashCode() { return m_ulMonsterNum.GetHashCode() ^ m_bRandChoose.GetHashCode() ^ m_ulSummonRadius.GetHashCode() ^ m_bDeathDisappear.GetHashCode(); } } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct AWARD_PQ_RANKING { public bool m_bAwardByProf; public uint m_ulRankingAwardNum; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_AWARD_PQ_RANKING)] public RANKING_AWARD[] m_RankingAward; public int MarshalBasicData(byte[] pData) { int offset = 0; pData[offset] = m_bAwardByProf ? (byte)1 : (byte)0; offset++; pData[offset] = (byte)m_ulRankingAwardNum; offset++; int sz = Marshal.SizeOf(typeof(RANKING_AWARD)) * (int)m_ulRankingAwardNum; if (sz > 0) { // Copy RANKING_AWARD array to byte array GCHandle handle = GCHandle.Alloc(m_RankingAward, GCHandleType.Pinned); try { IntPtr ptr = handle.AddrOfPinnedObject(); Marshal.Copy(ptr, pData, offset, sz); } finally { handle.Free(); } offset += sz; } return offset; } public int UnmarshalBasicData(byte[] pData) { int offset = 0; m_bAwardByProf = pData[offset] != 0; offset++; m_ulRankingAwardNum = pData[offset]; offset++; if (m_ulRankingAwardNum > 0) { m_RankingAward = new RANKING_AWARD[m_ulRankingAwardNum]; int sz = Marshal.SizeOf(typeof(RANKING_AWARD)) * (int)m_ulRankingAwardNum; // Copy byte array to RANKING_AWARD array for (uint i = 0; i < m_ulRankingAwardNum; i++) { IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(RANKING_AWARD))); try { Marshal.Copy(pData, offset, ptr, Marshal.SizeOf(typeof(RANKING_AWARD))); m_RankingAward[i] = (RANKING_AWARD)Marshal.PtrToStructure(ptr, typeof(RANKING_AWARD)); } finally { Marshal.FreeHGlobal(ptr); } offset += Marshal.SizeOf(typeof(RANKING_AWARD)); } } return offset; } public static bool operator ==(AWARD_PQ_RANKING a, AWARD_PQ_RANKING b) { if (a.m_bAwardByProf != b.m_bAwardByProf) { return false; } if (a.m_ulRankingAwardNum != b.m_ulRankingAwardNum) { return false; } for (uint i = 0; i < a.m_ulRankingAwardNum; ++i) { if (!(a.m_RankingAward[i].Equals(b.m_RankingAward[i]))) { return false; } } return true; } public static bool operator !=(AWARD_PQ_RANKING a, AWARD_PQ_RANKING b) { return !(a == b); } public override bool Equals(object obj) { if (obj is AWARD_PQ_RANKING) return this == (AWARD_PQ_RANKING)obj; return false; } public override int GetHashCode() { return m_bAwardByProf.GetHashCode() ^ m_ulRankingAwardNum.GetHashCode(); } } public class TaskTemplUtils { /// /// 必须定义operator == // Must define operator == /// /// The type of the objects to compare /// First object to compare /// Second object to compare /// True if both objects are equal or both are null public static bool CompareTwoPointer(T_NAME p1, T_NAME p2) { if (p1 == null && p2 == null) { return true; } else if (p1 != null && p2 != null) { return p1.Equals(p2); } else return false; } } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct task_tm { public int year; public int month; public int day; public int hour; public int min; public int wday; } // Define task_team_member_info struct required by TEAM_MEM_WANTED [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct task_team_member_info { public uint m_ulLevel; public uint m_ulOccupation; public int m_iForce; public bool m_bMale; } // Race-occupation mapping array public static class TaskTemplMapping { public static readonly uint[] _race_occ_map = new uint[TaskTemplConstants.MAX_OCCUPATIONS]; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct TEAM_MEM_WANTED { public uint m_ulLevelMin; public uint m_ulLevelMax; public uint m_ulRace; public uint m_ulOccupation; public uint m_ulGender; public uint m_ulMinCount; public uint m_ulMaxCount; public uint m_ulTask; public int m_iForce; // public uint m_ulTeamMemsItemWanted; // public TEAM_MEM_ITEM_WANTED[] m_TeamMemItemWanted; //[MAX_ITEM_WANTED]; // public bool m_bJustCheck; // Initialize fields with default values to avoid constructor issues public static TEAM_MEM_WANTED Create() { TEAM_MEM_WANTED result = new TEAM_MEM_WANTED(); result.Init(); return result; } public bool IsMeetBaseInfo(task_team_member_info pInfo) { if (m_ulLevelMin != 0 && pInfo.m_ulLevel < m_ulLevelMin) return false; if (m_ulLevelMax != 0 && pInfo.m_ulLevel > m_ulLevelMax) return false; if (m_ulRace != 0) { if (pInfo.m_ulOccupation >= TaskTemplConstants.MAX_OCCUPATIONS) return false; if (TaskTemplMapping._race_occ_map[pInfo.m_ulOccupation] != m_ulRace) return false; } else if (m_ulOccupation != TaskTemplConstants.INVALID_VAL && pInfo.m_ulOccupation != m_ulOccupation) return false; if (m_iForce != 0) { if (m_iForce == -1) { if (pInfo.m_iForce == 0) return false; } else if (pInfo.m_iForce != m_iForce) return false; } #if !_TASK_CLIENT if (m_ulGender == TaskTemplConstants.TASK_GENDER_MALE && !pInfo.m_bMale || m_ulGender == TaskTemplConstants.TASK_GENDER_FEMALE && pInfo.m_bMale) return false; #endif return true; } public bool IsMeetCount(uint ulCount) { if (m_ulMinCount != 0 && ulCount < m_ulMinCount) return false; if (m_ulMaxCount != 0 && ulCount > m_ulMaxCount) return false; return true; } public void Init() { m_ulLevelMin = 0; m_ulLevelMax = 0; m_ulRace = 0; m_ulOccupation = TaskTemplConstants.INVALID_VAL; m_ulGender = 0; m_ulMinCount = 0; m_ulMaxCount = 0; m_ulTask = 0; m_iForce = 0; // m_ulTeamMemsItemWanted = 0; // m_TeamMemItemWanted = null; // m_bJustCheck = false; } public bool IsValid() { return !( m_ulLevelMin == 0 && m_ulLevelMax == 0 && m_ulRace == 0 && m_ulOccupation == TaskTemplConstants.INVALID_VAL && m_ulGender == 0 && m_ulMinCount == 0 && m_ulMaxCount == 0 && m_ulTask == 0 // && // m_ulTeamMemsItemWanted == 0 && // m_TeamMemItemWanted == null && // m_bJustCheck == false ); } public static bool operator ==(TEAM_MEM_WANTED a, TEAM_MEM_WANTED b) { return ( a.m_ulLevelMin == b.m_ulLevelMin && a.m_ulLevelMax == b.m_ulLevelMax && a.m_ulRace == b.m_ulRace && a.m_ulOccupation == b.m_ulOccupation && a.m_ulGender == b.m_ulGender && a.m_ulMinCount == b.m_ulMinCount && a.m_ulMaxCount == b.m_ulMaxCount && a.m_ulTask == b.m_ulTask // && // a.m_ulTeamMemsItemWanted == b.m_ulTeamMemsItemWanted && // *a.m_TeamMemItemWanted == *(b.m_TeamMemItemWanted) && // a.m_bJustCheck == b.m_bJustCheck ); } public static bool operator !=(TEAM_MEM_WANTED a, TEAM_MEM_WANTED b) { return !(a == b); } public override bool Equals(object obj) { if (obj is TEAM_MEM_WANTED) return this == (TEAM_MEM_WANTED)obj; return false; } public override int GetHashCode() { return m_ulLevelMin.GetHashCode() ^ m_ulLevelMax.GetHashCode() ^ m_ulRace.GetHashCode() ^ m_ulOccupation.GetHashCode(); } } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct AWARD_ITEMS_CAND { public uint m_ulAwardItems; public uint m_ulAwardCmnItems; public uint m_ulAwardTskItems; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.MAX_ITEM_AWARD)] public ITEM_WANTED[] m_AwardItems; public bool m_bRandChoose; public int MarshalBasicData(byte[] pData) { int offset = 0; pData[offset] = m_bRandChoose ? (byte)1 : (byte)0; offset++; pData[offset] = (byte)m_ulAwardItems; offset++; int sz = Marshal.SizeOf(typeof(ITEM_WANTED)) * (int)m_ulAwardItems; if (sz > 0) { // Copy ITEM_WANTED array data for (int i = 0; i < m_ulAwardItems; i++) { // Would need to implement proper marshaling here // For now, just increase offset by appropriate size offset += Marshal.SizeOf(typeof(ITEM_WANTED)); } } return offset; } public int UnmarshalBasicData(byte[] pData) { int offset = 0; m_bRandChoose = pData[offset] != 0; offset++; m_ulAwardItems = pData[offset]; offset++; if (m_ulAwardItems > 0) { m_AwardItems = new ITEM_WANTED[m_ulAwardItems]; // Copy ITEM_WANTED array data for (uint i = 0; i < m_ulAwardItems; i++) { // Would need to implement proper unmarshaling here // For now, just increase offset by appropriate size offset += Marshal.SizeOf(typeof(ITEM_WANTED)); if (m_AwardItems[i].m_bCommonItem) m_ulAwardCmnItems++; else m_ulAwardTskItems++; } } return offset; } public static bool operator ==(AWARD_ITEMS_CAND a, AWARD_ITEMS_CAND b) { if (a.m_ulAwardItems != b.m_ulAwardItems) return false; for (uint i = 0; i < a.m_ulAwardItems; ++i) { if (!(a.m_AwardItems[i].Equals(b.m_AwardItems[i]))) return false; } return (a.m_ulAwardCmnItems == b.m_ulAwardCmnItems && a.m_ulAwardTskItems == b.m_ulAwardTskItems && a.m_bRandChoose == b.m_bRandChoose); } public static bool operator !=(AWARD_ITEMS_CAND a, AWARD_ITEMS_CAND b) { return !(a == b); } public override bool Equals(object obj) { if (obj is AWARD_ITEMS_CAND) return this == (AWARD_ITEMS_CAND)obj; return false; } public override int GetHashCode() { return m_ulAwardItems.GetHashCode() ^ m_ulAwardCmnItems.GetHashCode() ^ m_ulAwardTskItems.GetHashCode() ^ m_bRandChoose.GetHashCode(); } } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct AWARD_DATA { public AWARD_DATA(bool initialize = true) { m_ulGoldNum = 0; m_ulExp = 0; m_ulRealmExp = 0; m_bExpandRealmLevelMax = false; m_ulNewTask = 0; m_ulSP = 0; m_lReputation = 0; m_ulNewPeriod = 0; m_ulNewRelayStation = 0; m_ulStorehouseSize = 0; m_ulStorehouseSize2 = 0; m_ulStorehouseSize3 = 0; m_ulStorehouseSize4 = 0; m_lInventorySize = 0; m_ulPetInventorySize = 0; m_ulFuryULimit = 0; m_ulTransWldId = 0; m_TransPt = new ZONE_VERT(); m_lMonsCtrl = 0; m_bTrigCtrl = false; m_bUseLevCo = false; m_bDivorce = false; m_bSendMsg = false; m_nMsgChannel = 0; m_ulCandItems = 0; m_CandItems = null; m_ulSummonedMonsters = 0; m_SummonedMonsters = new AWARD_MONSTERS_SUMMONED(); m_bAwardDeath = false; m_bAwardDeathWithLoss = false; m_ulDividend = 0; m_bAwardSkill = false; m_iAwardSkillID = 0; m_iAwardSkillLevel = 0; m_ulSpecifyContribTaskID = 0; m_ulSpecifyContribSubTaskID = 0; m_ulSpecifyContrib = 0; m_ulContrib = 0; m_ulRandContrib = 0; m_ulLowestcontrib = 0; m_iFactionContrib = 0; m_iFactionExpContrib = 0; m_ulPQRankingAwardCnt = 0; m_PQRankingAward = new AWARD_PQ_RANKING(); m_bMulti = false; m_nNumType = 0; m_lNum = 0; m_ulChangeKeyCnt = 0; m_plChangeKey = null; m_plChangeKeyValue = null; m_pbChangeType = null; m_ulHistoryChangeCnt = 0; m_plHistoryChangeKey = null; m_plHistoryChangeKeyValue = null; m_pbHistoryChangeType = null; m_ulDisplayKeyCnt = 0; m_plDisplayKey = null; m_ulExpCnt = 0; m_pszExp = null; m_pExpArr = null; m_ulTaskCharCnt = 0; m_pTaskChar = null; m_iForceContribution = 0; m_iForceReputation = 0; m_iForceActivity = 0; m_iForceSetRepu = 0; m_iTaskLimit = 0; m_ulTitleNum = 0; m_pTitleAward = null; m_iLeaderShip = 0; m_iWorldContribution = 0; #if TASK_TEMPL_EDITOR m_CandItems = new AWARD_ITEMS_CAND[TaskTemplConstants.MAX_AWARD_CANDIDATES]; m_SummonedMonsters = new AWARD_MONSTERS_SUMMONED(); m_PQRankingAward = new AWARD_PQ_RANKING(); m_pTitleAward = new TITLE_AWARD[TaskTemplConstants.MAX_TITLE_NUM]; #endif } public uint m_ulGoldNum; public uint m_ulExp; public uint m_ulRealmExp; // 境界经验 // Realm experience public bool m_bExpandRealmLevelMax; // 境界等级10整级时提升境界等级上限 // Increase realm level upper limit when realm level is at level 10 public uint m_ulNewTask; public uint m_ulSP; public int m_lReputation; public uint m_ulNewPeriod; public uint m_ulNewRelayStation; public uint m_ulStorehouseSize; public uint m_ulStorehouseSize2; public uint m_ulStorehouseSize3; public uint m_ulStorehouseSize4; // 账号仓库 // Account warehouse public int m_lInventorySize; public uint m_ulPetInventorySize; public uint m_ulFuryULimit; public uint m_ulTransWldId; public ZONE_VERT m_TransPt; public int m_lMonsCtrl; public bool m_bTrigCtrl; public bool m_bUseLevCo; public bool m_bDivorce; public bool m_bSendMsg; public int m_nMsgChannel; public uint m_ulCandItems; public AWARD_ITEMS_CAND[] m_CandItems; //[MAX_AWARD_CANDIDATES]; public uint m_ulSummonedMonsters; public AWARD_MONSTERS_SUMMONED m_SummonedMonsters; public bool m_bAwardDeath; public bool m_bAwardDeathWithLoss; public uint m_ulDividend; // 鸿利值 // Dividend value public bool m_bAwardSkill; // 是否奖励技能 // Whether to reward skill [Yongdong, 2010-1-6] public int m_iAwardSkillID; // 技能ID // Skill ID public int m_iAwardSkillLevel;// 技能等级 // Skill level //////////////////////////////////////////////////// PQ任务奖励 start // PQ task reward start public uint m_ulSpecifyContribTaskID; // 指定任务贡献度的任务id // Task ID for specified contribution public uint m_ulSpecifyContribSubTaskID; // 指定任务贡献度的子任务ID // Subtask ID for specified contribution public uint m_ulSpecifyContrib; // 指定任务贡献度 // Specified task contribution // 仅PQ子任务专用 // Only for PQ subtasks public uint m_ulContrib; // 贡献度 // Contribution public uint m_ulRandContrib; // 随机贡献度 // Random contribution public uint m_ulLowestcontrib; // 最低贡献度 // Minimum contribution // 帮派贡献度 // Faction contribution public int m_iFactionContrib; public int m_iFactionExpContrib; public uint m_ulPQRankingAwardCnt; public AWARD_PQ_RANKING m_PQRankingAward; //////////////////////////////////////////////////// PQ任务奖励 end // PQ task reward end // 改变全局key/value // Change global key/value public uint m_ulChangeKeyCnt; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.TASK_AWARD_MAX_CHANGE_VALUE)] public int[] m_plChangeKey; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.TASK_AWARD_MAX_CHANGE_VALUE)] public int[] m_plChangeKeyValue; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.TASK_AWARD_MAX_CHANGE_VALUE)] public bool[] m_pbChangeType; // 修改历史进度 // Modify historical progress public uint m_ulHistoryChangeCnt; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.TASK_AWARD_MAX_CHANGE_VALUE)] public int[] m_plHistoryChangeKey; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.TASK_AWARD_MAX_CHANGE_VALUE)] public int[] m_plHistoryChangeKeyValue; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.TASK_AWARD_MAX_CHANGE_VALUE)] public bool[] m_pbHistoryChangeType; // 倍率 // Multiplier public bool m_bMulti; public int m_nNumType; public int m_lNum; // 显示全局key/value // Display global key/value public uint m_ulDisplayKeyCnt; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.TASK_AWARD_MAX_DISPLAY_VALUE)] public int[] m_plDisplayKey; // 显示全局变量表达式 // Display global variable expressions public uint m_ulExpCnt; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.TASK_AWARD_MAX_DISPLAY_EXP_CNT)] public string[] m_pszExp; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.TASK_AWARD_MAX_DISPLAY_EXP_CNT)] public TASK_EXPRESSION[] m_pExpArr; // 显示全局变量表达式提示字符串 // Display global variable expression prompt strings public uint m_ulTaskCharCnt; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.TASK_AWARD_MAX_DISPLAY_EXP_CNT)] public ushort[] m_pTaskChar; // 势力相关 // Force-related public int m_iForceContribution; public int m_iForceReputation; public int m_iForceActivity; public int m_iForceSetRepu; public int m_iTaskLimit; public uint m_ulTitleNum; public TITLE_AWARD[] m_pTitleAward; public int m_iLeaderShip; public int m_iWorldContribution; // 世界贡献度 // World contribution public bool HasAward() { return m_ulGoldNum != 0 || m_ulExp != 0 || m_ulNewTask != 0 || m_ulSP != 0 || m_lReputation != 0 || m_ulNewPeriod != 0 || m_ulNewRelayStation != 0 || m_ulStorehouseSize != 0 || m_ulStorehouseSize2 != 0 || m_ulStorehouseSize3 != 0 || m_ulStorehouseSize4 != 0 || m_lInventorySize != 0 || m_ulPetInventorySize != 0 || m_ulFuryULimit != 0 || m_bDivorce || m_bSendMsg || m_bAwardDeath || m_ulCandItems != 0 || m_ulSummonedMonsters != 0 || m_ulSpecifyContrib != 0 || m_ulSpecifyContribTaskID != 0 || m_ulContrib != 0 || m_ulRandContrib != 0 || m_ulDividend != 0 || m_ulPQRankingAwardCnt != 0 || m_ulSpecifyContribSubTaskID != 0 || m_bAwardSkill || m_iFactionContrib != 0 || m_iFactionExpContrib != 0 || m_iForceActivity != 0 || m_iForceContribution != 0 || m_iForceReputation != 0 || m_iForceSetRepu != 0 || m_iTaskLimit != 0 || m_ulRealmExp != 0 || m_bExpandRealmLevelMax; } public int MarshalBasicData(byte[] pData) { int offset = 0; int mask = 0; BitConverter.GetBytes(mask).CopyTo(pData, offset); offset += 4; if (m_ulGoldNum != 0) { mask |= 1; BitConverter.GetBytes((int)m_ulGoldNum).CopyTo(pData, offset); offset += sizeof(int); } if (m_ulExp != 0) { mask |= 1 << 1; BitConverter.GetBytes((int)m_ulExp).CopyTo(pData, offset); offset += sizeof(int); } if (m_ulSP != 0) { mask |= 1 << 2; BitConverter.GetBytes((int)m_ulSP).CopyTo(pData, offset); offset += sizeof(int); } if (m_lReputation != 0) { mask |= 1 << 3; BitConverter.GetBytes(m_lReputation).CopyTo(pData, offset); offset += sizeof(int); } if (m_ulCandItems != 0) { mask |= 1 << 4; pData[offset] = (byte)m_ulCandItems; offset++; for (int i = 0; i < m_ulCandItems; i++) { offset += m_CandItems[i].MarshalBasicData(pData.AsSpan(offset).ToArray()); } } if (m_ulSummonedMonsters != 0) { mask |= 1 << 5; pData[offset] = (byte)m_ulSummonedMonsters; offset++; offset += m_SummonedMonsters.MarshalBasicData(pData.AsSpan(offset).ToArray()); } if (m_ulPQRankingAwardCnt != 0) { mask |= 1 << 6; pData[offset] = (byte)m_ulPQRankingAwardCnt; offset++; offset += m_PQRankingAward.MarshalBasicData(pData.AsSpan(offset).ToArray()); } // Update the mask BitConverter.GetBytes(mask).CopyTo(pData, 0); return offset; } public int UnmarshalBasicData(byte[] pData) { int offset = 0; int mask = BitConverter.ToInt32(pData, offset); offset += sizeof(int); if ((mask & 1) != 0) { m_ulGoldNum = (uint)BitConverter.ToInt32(pData, offset); offset += 4; } if ((mask & (1 << 1)) != 0) { m_ulExp = (uint)BitConverter.ToInt32(pData, offset); offset += 4; } if ((mask & (1 << 2)) != 0) { m_ulSP = (uint)BitConverter.ToInt32(pData, offset); offset += 4; } if ((mask & (1 << 3)) != 0) { m_lReputation = BitConverter.ToInt32(pData, offset); offset += 4; } if ((mask & (1 << 4)) != 0) { m_ulCandItems = pData[offset]; offset++; if (m_ulCandItems != 0) { #if !TASK_TEMPL_EDITOR m_CandItems = new AWARD_ITEMS_CAND[m_ulCandItems]; #endif for (uint i = 0; i < m_ulCandItems; i++) { offset += m_CandItems[i].UnmarshalBasicData(pData.AsSpan(offset).ToArray()); } } } if ((mask & (1 << 5)) != 0) { m_ulSummonedMonsters = pData[offset]; offset++; if (m_ulSummonedMonsters != 0) { #if !TASK_TEMPL_EDITOR m_SummonedMonsters = new AWARD_MONSTERS_SUMMONED(); #endif offset += m_SummonedMonsters.UnmarshalBasicData(pData.AsSpan(offset).ToArray()); } } if ((mask & (1 << 6)) != 0) { m_ulPQRankingAwardCnt = pData[offset]; offset++; if (m_ulPQRankingAwardCnt != 0) { #if !TASK_TEMPL_EDITOR m_PQRankingAward = new AWARD_PQ_RANKING(); #endif offset += m_PQRankingAward.UnmarshalBasicData(pData.AsSpan(offset).ToArray()); } } return offset; } public static bool CompareTwoPointer(T p1, T p2) where T : class { if (p1 == null && p2 == null) { return true; } else if (p1 != null && p2 != null) { return p1.Equals(p2); } else return false; } public static bool operator ==(AWARD_DATA a, AWARD_DATA b) { if (a.m_ulCandItems != b.m_ulCandItems || a.m_ulSummonedMonsters != b.m_ulSummonedMonsters || a.m_ulChangeKeyCnt != b.m_ulChangeKeyCnt || a.m_ulDisplayKeyCnt != b.m_ulDisplayKeyCnt || a.m_ulExpCnt != b.m_ulExpCnt || a.m_ulTaskCharCnt != b.m_ulTaskCharCnt || a.m_ulHistoryChangeCnt != b.m_ulHistoryChangeCnt) { return false; } for (uint i = 0; i < a.m_ulCandItems; ++i) { if (!(a.m_CandItems[i] == b.m_CandItems[i])) { return false; } } if (!TaskTemplUtils.CompareTwoPointer(a.m_SummonedMonsters, b.m_SummonedMonsters)) { return false; } for (uint i = 0; i < a.m_ulChangeKeyCnt; ++i) { if (a.m_plChangeKey[i] != b.m_plChangeKey[i] || a.m_plChangeKeyValue[i] != b.m_plChangeKeyValue[i] || a.m_pbChangeType[i] != b.m_pbChangeType[i]) { return false; } } for (uint i = 0; i < a.m_ulHistoryChangeCnt; ++i) { if (a.m_plHistoryChangeKey[i] != b.m_plHistoryChangeKey[i] || a.m_plHistoryChangeKeyValue[i] != b.m_plHistoryChangeKeyValue[i] || a.m_pbHistoryChangeType[i] != b.m_pbHistoryChangeType[i]) { return false; } } for (uint i = 0; i < a.m_ulDisplayKeyCnt; ++i) { if (a.m_plDisplayKey[i] != b.m_plDisplayKey[i]) { return false; } } if (!TaskTemplUtils.CompareTwoPointer(a.m_PQRankingAward, b.m_PQRankingAward)) { return false; } return (a.m_ulGoldNum == b.m_ulGoldNum && a.m_ulExp == b.m_ulExp && a.m_ulNewTask == b.m_ulNewTask && a.m_ulSP == b.m_ulSP && a.m_lReputation == b.m_lReputation && a.m_ulNewPeriod == b.m_ulNewPeriod && a.m_ulNewRelayStation == b.m_ulNewRelayStation && a.m_ulStorehouseSize == b.m_ulStorehouseSize && a.m_ulStorehouseSize2 == b.m_ulStorehouseSize2 && a.m_ulStorehouseSize3 == b.m_ulStorehouseSize3 && a.m_ulStorehouseSize4 == b.m_ulStorehouseSize4 && a.m_lInventorySize == b.m_lInventorySize && a.m_ulPetInventorySize == b.m_ulPetInventorySize && a.m_ulFuryULimit == b.m_ulFuryULimit && a.m_ulTransWldId == b.m_ulTransWldId && a.m_TransPt.Equals(b.m_TransPt) && a.m_lMonsCtrl == b.m_lMonsCtrl && a.m_bTrigCtrl == b.m_bTrigCtrl && a.m_bUseLevCo == b.m_bUseLevCo && a.m_bDivorce == b.m_bDivorce && a.m_bSendMsg == b.m_bSendMsg && a.m_nMsgChannel == b.m_nMsgChannel && a.m_bAwardDeath == b.m_bAwardDeath && a.m_bAwardDeathWithLoss == b.m_bAwardDeathWithLoss && a.m_ulDividend == b.m_ulDividend && a.m_bAwardSkill == b.m_bAwardSkill && a.m_iAwardSkillID == b.m_iAwardSkillID && a.m_iAwardSkillLevel == b.m_iAwardSkillLevel && a.m_ulSpecifyContribTaskID == b.m_ulSpecifyContribTaskID && a.m_ulSpecifyContribSubTaskID == b.m_ulSpecifyContribSubTaskID && a.m_ulSpecifyContrib == b.m_ulSpecifyContrib && a.m_ulContrib == b.m_ulContrib && a.m_ulRandContrib == b.m_ulRandContrib && a.m_ulLowestcontrib == b.m_ulLowestcontrib && a.m_iFactionContrib == b.m_iFactionContrib && a.m_iFactionExpContrib == b.m_iFactionExpContrib && a.m_ulPQRankingAwardCnt == b.m_ulPQRankingAwardCnt && a.m_bMulti == b.m_bMulti && a.m_nNumType == b.m_nNumType && a.m_lNum == b.m_lNum ); } public static bool operator !=(AWARD_DATA a, AWARD_DATA b) { return !(a == b); } public override bool Equals(object obj) { if (obj is AWARD_DATA) { return this == (AWARD_DATA)obj; } return false; } public override int GetHashCode() { return m_ulGoldNum.GetHashCode() ^ m_ulExp.GetHashCode() ^ m_lReputation.GetHashCode() ^ m_ulSP.GetHashCode(); } } public enum task_tm_type { enumTaskTimeDate = 0, enumTaskTimeMonth, enumTaskTimeWeek, enumTaskTimeDay }; /// /// Completion Method /// public enum TaskMethod { enumTMNone = 0, // None enumTMKillNumMonster, // Kill a number of monsters enumTMCollectNumArticle, // Collect a number of items enumTMTalkToNPC, // Talk to a specific NPC enumTMReachSite, // Reach a specific location enumTMWaitTime, // Wait for a specified time enumTMAnswerQuestion, // Answer a question enumTMTinyGame, // Mini-game enumTMProtectNPC, // Protect a specific NPC enumTMNPCReachSite, // NPC reaches a specific location enumTMGlobalValOK, // Global variable condition satisfied enumTMLeaveSite, // Leave a specific location enumTMReachTreasureZone, // Reach the treasure area enumTMKillPlayer, // Kill another player enumTMTransform, // Transform state enumTMReachLevel, // Check level: normal level, rebirth count, realm level enumTMSimpleClientTask, // Simple client task (only client-side validation, currently just checks UI triggers) enumTMSimpleClientTaskForceNavi // Force navigation } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct COMPARE_KEY_VALUE { public int nLeftType; public long lLeftNum; public int nCompOper; public int nRightType; public long lRightNum; public static bool operator ==(COMPARE_KEY_VALUE a, COMPARE_KEY_VALUE b) { return (a.nLeftType == b.nLeftType && a.lLeftNum == b.lLeftNum && a.nCompOper == b.nCompOper && a.nRightType == b.nRightType && a.lRightNum == b.lRightNum); } public static bool operator !=(COMPARE_KEY_VALUE a, COMPARE_KEY_VALUE b) { return !(a == b); } public override bool Equals(object obj) { if (obj is COMPARE_KEY_VALUE) return this == (COMPARE_KEY_VALUE)obj; return false; } public override int GetHashCode() { return nLeftType.GetHashCode() ^ lLeftNum.GetHashCode() ^ nCompOper.GetHashCode() ^ nRightType.GetHashCode() ^ lRightNum.GetHashCode(); } } public struct Task_Region { public ZONE_VERT zvMin; public ZONE_VERT zvMax; public bool Equals(Task_Region src) { return (zvMin.x == src.zvMin.x && zvMin.y == src.zvMin.y && zvMin.z == src.zvMin.z && zvMax.x == src.zvMax.x && zvMax.y == src.zvMax.y && zvMax.z == src.zvMax.z); } public static bool operator ==(Task_Region a, Task_Region b) { return a.Equals(b); } public static bool operator !=(Task_Region a, Task_Region b) { return !a.Equals(b); } public override bool Equals(object obj) { if (obj is Task_Region) return Equals((Task_Region)obj); return false; } public override int GetHashCode() { return zvMin.GetHashCode() ^ zvMax.GetHashCode(); } } public struct ATaskTemplFixedData { // 任务id // Task ID public uint m_ID; // 任务名称 // Task name [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_TASK_NAME_LEN)] public char[] m_szName; // 任务署名 // Task signature public bool m_bHasSign; public string m_pszSignature; // 任务类型 // Task type public uint m_ulType; // 时间限制 // Time limit public uint m_ulTimeLimit; // 下线任务失败 // Task fails when offline public bool m_bOfflineFail; // 任务失败时间 // Task failure time public bool m_bAbsFail; public task_tm m_tmAbsFailTime; // 任务开启物品检验不收取 // Don't take items when validating task start public bool m_bItemNotTakeOff; // 是否绝对时间 // Whether absolute time public bool m_bAbsTime; // 时间段个数 // Number of time periods public uint m_ulTimetable; // 时间方式 // Time method [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_TIMETABLE_SIZE)] public char[] m_tmType; // 发放起始时间 // Distribution start time public task_tm[] m_tmStart; // 发放终止时间 // Distribution end time public task_tm[] m_tmEnd; // 发放频率 // Distribution frequency public int m_lAvailFrequency; public int m_lPeriodLimit; // 选择单个子任务执行 // Execute single subtask public bool m_bChooseOne; // 随机旋转单个子任务执行 // Randomly rotate single subtask execution public bool m_bRandOne; // 子任务是否有顺序 // Whether subtasks have order public bool m_bExeChildInOrder; // 失败后是否认为父任务也失败 // Whether parent task fails when subtask fails public bool m_bParentAlsoFail; // 子任务成功后父任务成功 // Parent task succeeds when subtask succeeds public bool m_bParentAlsoSucc; // 能否放弃此任务 // Whether task can be abandoned public bool m_bCanGiveUp; // 是否可重复完成 // Whether task can be repeated public bool m_bCanRedo; // 失败后是否可重新完成 // Whether task can be redone after failure public bool m_bCanRedoAfterFailure; // 放弃清空任务 // Clear task when abandoned public bool m_bClearAsGiveUp; // 是否需要记录 // Whether recording is needed public bool m_bNeedRecord; // 玩家被杀死是否认为失败 // Whether task fails when player dies public bool m_bFailAsPlayerDie; // 接受者上限 // Maximum number of receivers public uint m_ulMaxReceiver; // 发放区域 // Distribution area public bool m_bDelvInZone; public uint m_ulDelvWorld; public uint m_ulDelvRegionCnt; public Task_Region[] m_pDelvRegion; // 进入区域任务失败 // Task fails when entering region public bool m_bEnterRegionFail; public uint m_ulEnterRegionWorld; public uint m_ulEnterRegionCnt; public Task_Region[] m_pEnterRegion; // 离开区域任务失败 // Task fails when leaving region public bool m_bLeaveRegionFail; public uint m_ulLeaveRegionWorld; public uint m_ulLeaveRegionCnt; public Task_Region[] m_pLeaveRegion; // 离开阵营失败 // Fails when leaving force public bool m_bLeaveForceFail; // 传送到特定点 // Teleport to specific point public bool m_bTransTo; public uint m_ulTransWldId; public ZONE_VERT m_TransPt; // Monster controller public long m_lMonsCtrl; public bool m_bTrigCtrl; // Auto trigger when conditions are met public bool m_bAutoDeliver; // Whether to display in exclusive UI public bool m_bDisplayInExclusiveUI; public bool m_bReadyToNotifyServer; // Whether used in token shop public bool m_bUsedInTokenShop; // Death trigger public bool m_bDeathTrig; // Whether clear all acquired items public bool m_bClearAcquired; // Recommended level public uint m_ulSuitableLevel; // Whether to show prompt public bool m_bShowPrompt; // Whether it is a key task public bool m_bKeyTask; // Delivery NPC public uint m_ulDelvNPC; // Award NPC public uint m_ulAwardNPC; // Whether it is a skill task public bool m_bSkillTask; // Whether can be searched public bool m_bCanSeekOut; // Whether show direction public bool m_bShowDirection; // Marriage public bool m_bMarriage; // Change global key/value public uint m_ulChangeKeyCnt; public long[] m_plChangeKey; // [TASK_AWARD_MAX_CHANGE_VALUE] public long[] m_plChangeKeyValue; public bool[] m_pbChangeType; // Fail on scene switch public bool m_bSwitchSceneFail; // Hidden task public bool m_bHidden; // Whether deliver skill public bool m_bDeliverySkill; public int m_iDeliveredSkillID; public int m_iDeliveredSkillLevel; // Whether show task completion effect public bool m_bShowGfxFinished; // Whether change player ranking in PQ public bool m_bChangePQRanking; // Compare delivery items with player inventory slots public bool m_bCompareItemAndInventory; public uint m_ulInventorySlotNum; // PQ Task related // PQ任务相关 public bool m_bPQTask; // Whether it is a PQ task // 是否是PQ任务 public uint m_ulPQExpCnt; // PQ task global variable display // PQ任务全局变量显示 [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.TASK_AWARD_MAX_DISPLAY_EXP_CNT)] public string[] m_pszPQExp; // PQ expressions [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.TASK_AWARD_MAX_DISPLAY_EXP_CNT)] public TASK_EXPRESSION[] m_pPQExpArr; // PQ expression arrays public bool m_bPQSubTask; // Whether it is a PQ subtask // 是否PQ子任务 public bool m_bClearContrib; // Clear contribution when task starts // 任务开始时清空贡献度 public uint m_ulMonsterContribCnt; // Number of monster types // 怪物种类数量 [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_CONTRIB_MONSTERS)] public MONSTERS_CONTRIB[] m_MonstersContrib; // Monster contribution settings // 怪物贡献度设定 // Account Task related // 账号任务相关 public int m_iPremNeedRecordTasksNum; // Number of completed record tasks // 记录完成结果任务完成个数 public bool m_bShowByNeedRecordTasksNum; // Show by number of needed record tasks public int m_iPremiseFactionContrib; // Faction contribution // 帮派贡献度 public bool m_bShowByFactionContrib; // Show by faction contribution public bool m_bAccountTaskLimit; // Whether account limits completion times // 是否账号限制完成次数 public bool m_bRoleTaskLimit; // Whether role limits completion times // 是否角色限制完成次数 public uint m_ulAccountTaskLimitCnt; // Account task limit count (deprecated) // 账号限制完成次数,废弃使用了 public bool m_bLeaveFactionFail; // Fail when leaving faction public bool m_bNotIncCntWhenFailed; // Don't increase count when failed // 是否失败时不增加完成次数 public bool m_bNotClearItemWhenFailed; // Don't clear items when failed // 任务失败时不收取任务要求的物品 public bool m_bDisplayInTitleTaskUI; // Show in title task UI // 是否显示在称号任务界面里 /* 开启条件 */ /* Opening conditions */ // 变身状态 // Transformation state public byte m_ucPremiseTransformedForm; public bool m_bShowByTransformed; // 等级条件 // Level conditions public uint m_ulPremise_Lev_Min; public uint m_ulPremise_Lev_Max; public uint m_bPremCheckMaxHistoryLevel; public bool m_bShowByLev; // 转生次数 // Reincarnation times public bool m_bPremCheckReincarnation; public uint m_ulPremReincarnationMin; public uint m_ulPremReincarnationMax; public bool m_bShowByReincarnation; // 境界 // Realm level public bool m_bPremCheckRealmLevel; public uint m_ulPremRealmLevelMin; public uint m_ulPremRealmLevelMax; public bool m_bPremCheckRealmExpFull; public bool m_bShowByRealmLevel; // 所需道具 // Required items public uint m_ulPremItems; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.MAX_ITEM_WANTED)] public ITEM_WANTED[] m_PremItems; //[MAX_ITEM_WANTED]; public bool m_bShowByItems; public bool m_bPremItemsAnyOne; // 发放道具 // Given items public uint m_ulGivenItems; public uint m_ulGivenCmnCount; public uint m_ulGivenTskCount; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.MAX_ITEM_WANTED)] public ITEM_WANTED[] m_GivenItems; //[MAX_ITEM_WANTED]; // 押金 // Deposit public uint m_ulPremise_Deposit; public bool m_bShowByDeposit; // 声望 // Reputation public long m_lPremise_Reputation; public long m_lPremise_RepuMax; public bool m_bShowByRepu; // 完成特定任务(成功?失败?),Task ID最高位1表示条件为失败,0为成功 // Complete specific tasks (success? failure?), Task ID highest bit 1 means failure condition, 0 means success condition public uint m_ulPremise_Task_Count; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_PREM_TASK_COUNT)] public uint[] m_ulPremise_Tasks; public bool m_bShowByPreTask; public uint m_ulPremise_Task_Least_Num; // 多个前提任务需要完成若干个 // Multiple prerequisite tasks need to complete a certain number // 达到特定时期 // Reach specific period public uint m_ulPremise_Period; public bool m_bShowByPeriod; // 帮派 // Faction public uint m_ulPremise_Faction; public int m_iPremise_FactionRole; public bool m_bShowByFaction; // 性别 // Gender public uint m_ulGender; public bool m_bShowByGender; // 职业限制 // Occupation restrictions public uint m_ulOccupations; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_OCCUPATIONS)] public uint[] m_Occupations; public bool m_bShowByOccup; // 夫妻 // Spouse public bool m_bPremise_Spouse; public bool m_bShowBySpouse; public bool m_bPremiseWeddingOwner; public bool m_bShowByWeddingOwner; // GM public bool m_bGM; // 完美神盾用户 // Perfect Shield user public bool m_bShieldUser; // 账号累计充值金额(下限&上限) // Account accumulated recharge amount (lower & upper limit) public bool m_bShowByRMB; public uint m_ulPremRMBMin; public uint m_ulPremRMBMax; // 角色相关时间 // Character-related time public bool m_bCharTime; public bool m_bShowByCharTime; public int m_iCharStartTime; public int m_iCharEndTime; // 为0则为当前时间;为1则为m_tmCharEndTime指定时间; // 0 means current time; 1 means the time specified by m_tmCharEndTime; public task_tm m_tmCharEndTime; public uint m_ulCharTimeGreaterThan; // 关联任务 // Related tasks public uint m_ulPremise_Cotask; public uint m_ulCoTaskCond; // 互斥任务 // Mutually exclusive tasks public uint m_ulMutexTaskCount; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_MUTEX_TASK_COUNT)] public uint[] m_ulMutexTasks; // 生活技能级别 // Life skill levels [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_LIVING_SKILLS)] public long[] m_lSkillLev; // 动态任务类型 // Dynamic task type public char m_DynTaskType; // 特殊奖励号,用于运营的活动 // Special award number, used for operational activities public uint m_ulSpecialAward; // 组队信息 // Team information public bool m_bTeamwork; // 组队任务 // Team task public bool m_bRcvByTeam; // 必须组队接收 // Must be in team to receive public bool m_bSharedTask; // 新队员分享任务 // New team members share tasks public bool m_bSharedAchieved; // 分享杀怪、物品数量 // Share kill counts and item counts public bool m_bCheckTeammate; // 检查队友位置 // Check teammate positions public float m_fTeammateDist; // 队友距离平方值 // Square of teammate distance public bool m_bAllFail; // 任意队员失败则全部失败 // Any member fails, all fail public bool m_bCapFail; // 队长失败则全部失败 // Leader fails, all fail public bool m_bCapSucc; // 队长成功则全队成功 // Leader succeeds, all succeed public float m_fSuccDist; // 成功时队员的距离 // Member distance for success public bool m_bDismAsSelfFail; // 队员离队自身失败 // Member leaves team fails itself public bool m_bRcvChckMem; // 接任务时检查队员位置 // Check member positions when receiving task public float m_fRcvMemDist; // 接任务时队员距离平方值 // Square of member distance when receiving task public bool m_bCntByMemPos; // 队员在有效范围内杀怪有效 // Members in valid range for kill counts public float m_fCntMemDist; // 队员有效的范围 // Valid range for members public bool m_bAllSucc; // 任意队员成功则全部成功 // Any member succeeds, all succeed public bool m_bCoupleOnly; // 队长队员必须为夫妻 // Leader and member must be spouses public bool m_bDistinguishedOcc; // 队伍中不允许有相同的职业 // No same occupations allowed in team // 队伍成员需求 // Team member requirements public uint m_ulTeamMemsWanted; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_TEAM_MEM_WANTED)] public TEAM_MEM_WANTED[] m_TeamMemsWanted; public bool m_bShowByTeam; // 前提全局key/value // Premise global key/value public bool m_bPremNeedComp; public int m_nPremExp1AndOrExp2; public COMPARE_KEY_VALUE m_Prem1KeyValue; public COMPARE_KEY_VALUE m_Prem2KeyValue; public bool m_bPremCheckForce; public int m_iPremForce; public bool m_bShowByForce; public int m_iPremForceReputation; public bool m_bShowByForceReputation; public int m_iPremForceContribution; // 扣除战功 // Deduct military merit public bool m_bShowByForceContribution; public int m_iPremForceExp; // 经验兑换 // Experience exchange public bool m_bShowByForceExp; public int m_iPremForceSP; // 元神兑换 // Spirit exchange public bool m_bShowByForceSP; public int m_iPremForceActivityLevel; public bool m_bShowByForceActivityLevel; public bool m_bPremIsKing; public bool m_bShowByKing; public bool m_bPremNotInTeam; public bool m_bShowByNotInTeam; public uint m_iPremTitleNumTotal; public uint m_iPremTitleNumRequired; public int[] m_PremTitles; public bool m_bShowByTitle; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public int[] m_iPremHistoryStageIndex; // 历史阶段 // Historical stage public bool m_bShowByHistoryStage; public uint m_ulPremGeneralCardCount; // 收集的卡牌数量 // Number of collected cards public bool m_bShowByGeneralCard; public int m_iPremGeneralCardRank; // 要求某品阶的卡牌数量 // Required number of cards of a certain rank public uint m_ulPremGeneralCardRankCount; public bool m_bShowByGeneralCardRank; /* 任务完成的方式及条件 */ /* Task completion methods and conditions */ public uint m_enumMethod; public uint m_enumFinishType; /* 任务方式 */ /* Task methods */ public uint m_ulPlayerWanted; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.MAX_PLAYER_WANTED)] public PLAYER_WANTED[] m_PlayerWanted; public uint m_ulMonsterWanted; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.MAX_MONSTER_WANTED)] public MONSTER_WANTED[] m_MonsterWanted; public uint m_ulItemsWanted; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.MAX_ITEM_WANTED)] public ITEM_WANTED[] m_ItemsWanted; public uint m_ulGoldWanted; public int m_iFactionContribWanted; public int m_iFactionExpContribWanted; public uint m_ulNPCToProtect; public uint m_ulProtectTimeLen; public uint m_ulNPCMoving; public uint m_ulNPCDestSite; //public ZONE_VERT m_ReachSiteMin; //public ZONE_VERT m_ReachSiteMax; public Task_Region[] m_pReachSite; public uint m_ulReachSiteCnt; public uint m_ulReachSiteId; public uint m_ulWaitTime; //藏宝图 使用已接任务列表中的m_iUsefulData1存储 // Treasure map Use m_iUsefulData1 in the list of accepted tasks public enum TREASURE_DISTANCE_LEVEL { DISTANCE_FAR_FAR_AWAY, DISTANCE_FAR, DISTANCE_MEDIUM, DISTANCE_NEAR, DISTANCE_VERY_NEAR, DISTANCE_NUM, } // TREA section public ZONE_VERT m_TreasureStartZone; public byte m_ucZonesNumX; public byte m_ucZonesNumZ; public byte m_ucZoneSide; //public ZONE_VERT m_LeaveSiteMin; //public ZONE_VERT m_LeaveSiteMax; public Task_Region[] m_pLeaveSite; public uint m_ulLeaveSiteCnt; public uint m_ulLeaveSiteId; // 完成全局key/value // Complete global key/value public bool m_bFinNeedComp; public int m_nFinExp1AndOrExp2; public COMPARE_KEY_VALUE m_Fin1KeyValue; public COMPARE_KEY_VALUE m_Fin2KeyValue; // 需显示的全局变量表达式 // Global variable expressions to display public uint m_ulExpCnt; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.TASK_AWARD_MAX_DISPLAY_CHAR_LEN * TaskInterfaceConstants.TASK_AWARD_MAX_DISPLAY_EXP_CNT)] public char[] m_pszExp; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.TASK_AWARD_MAX_DISPLAY_CHAR_LEN * TaskInterfaceConstants.TASK_AWARD_MAX_DISPLAY_EXP_CNT)] public TASK_EXPRESSION[] m_pExpArr; // 需显示的全局变量表达式提示字符串 // Global variable expression prompt strings public uint m_ulTaskCharCnt; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.TASK_AWARD_MAX_DISPLAY_EXP_CNT * TaskInterfaceConstants.TASK_AWARD_MAX_DISPLAY_CHAR_LEN)] public ushort[] m_pTaskChar; // 变身状态 // Transformation state public byte m_ucTransformedForm; // 等级 // Level public uint m_ulReachLevel; // 转生次数 // Reincarnation count public uint m_ulReachReincarnationCount; // 境界等级 // Realm level public uint m_ulReachRealmLevel; public uint m_uiEmotion; // 表情动作 // Emotion action /* 任务结束后的奖励 */ /* Rewards after task completion */ public uint m_ulAwardType_S; public uint m_ulAwardType_F; /* 普通和按每个方式 */ /* Normal and per-method rewards */ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public AWARD_DATA[] m_Award_S; /* 成功 */ /* Success */ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public AWARD_DATA[] m_Award_F; /* 失败 */ /* Failure */ } public class ATaskTempl { public ATaskTemplFixedData m_FixedData; //Hierarchy public ATaskTempl m_pParent; public ATaskTempl m_pPrevSibling; public ATaskTempl m_pNextSibling; public ATaskTempl m_pFirstChild; const int MAX_TASK_NAME_LEN = 30; public byte m_uValidCount; public bool LoadFromBinFile(FileStream fp) { LoadBinary(fp); // CheckDepth(); return true; } private void LoadBinary(FileStream fp) { LoadFixedDataFromBinFile(fp); // LoadDescriptionBin(fp); // LoadTributeBin(fp); //# ifndef _TASK_CLIENT // CheckMask(); //#else // SyncTaskType(); //#endif // namechar code = (namechar)m_ID; // m_DelvTaskTalk.load(fp); // convert_talk_text(&m_DelvTaskTalk, code); // m_UnqualifiedTalk.load(fp); // convert_talk_text(&m_UnqualifiedTalk, code); // m_DelvItemTalk.load(fp); // convert_talk_text(&m_DelvItemTalk, code); // m_ExeTalk.load(fp); // convert_talk_text(&m_ExeTalk, code); // m_AwardTalk.load(fp); // convert_talk_text(&m_AwardTalk, code); // fread(&m_nSubCount, sizeof(m_nSubCount), 1, fp); // for (int i = 0; i < m_nSubCount; i++) // { // ATaskTempl* pSub = new ATaskTempl; // g_ulNewCount++; // AddSubTaskTempl(pSub); // pSub->LoadBinary(fp); // } // SynchID(); //return true; } private bool LoadFixedDataFromBinFile(FileStream fp) { long readBytes = 0; ATaskTemplFixedData fixedData = AAssit.ReadFromBinaryOf(fp, ref readBytes); //convert_txt(m_szName, MAX_TASK_NAME_LEN, (namechar)m_ID); // m_Award_S = new AWARD_DATA; // g_ulNewCount++; // m_Award_F = new AWARD_DATA; // g_ulNewCount++; // m_AwByRatio_S = new AWARD_RATIO_SCALE; // g_ulNewCount++; // m_AwByRatio_F = new AWARD_RATIO_SCALE; // g_ulNewCount++; // m_AwByItems_S = new AWARD_ITEMS_SCALE; // g_ulNewCount++; // m_AwByItems_F = new AWARD_ITEMS_SCALE; // g_ulNewCount++; // m_tmStart = NULL; // m_tmEnd = NULL; // m_plChangeKey = NULL; // m_plChangeKeyValue = NULL; // m_pbChangeType = NULL; // m_PremItems = NULL; // m_GivenItems = NULL; // m_TeamMemsWanted= NULL; // m_ItemsWanted = NULL; // m_PlayerWanted = NULL; // m_MonsterWanted = NULL; // m_pszSignature = NULL; // m_pszExp = NULL; // m_pExpArr = NULL; // m_pTaskChar = NULL; // m_pszPQExp = NULL; // m_pPQExpArr = NULL; // m_MonstersContrib = NULL; // m_PremTitles = NULL; // if (m_bHasSign) // { // m_pszSignature = new task_char[MAX_TASK_NAME_LEN]; // g_ulNewCount++; // fread(m_pszSignature, sizeof(task_char), MAX_TASK_NAME_LEN, fp); // convert_txt(m_pszSignature, MAX_TASK_NAME_LEN, (namechar)m_ID); // } // if (m_ulTimetable) // { // m_tmStart = new task_tm[m_ulTimetable]; // g_ulNewCount++; // m_tmEnd = new task_tm[m_ulTimetable]; // g_ulNewCount++; // } // for (i = 0; i < m_ulTimetable; i++) // { // fread(&m_tmStart[i], sizeof(task_tm), 1, fp); // fread(&m_tmEnd[i], sizeof(task_tm), 1, fp); // } // if (m_ulChangeKeyCnt) // { // m_plChangeKey = new long[m_ulChangeKeyCnt]; // m_plChangeKeyValue = new long[m_ulChangeKeyCnt]; // m_pbChangeType = new bool[m_ulChangeKeyCnt]; // } // for (i=0; i0) // { // m_pDelvRegion = new Task_Region[m_ulDelvRegionCnt]; // g_ulNewCount++; // } // else m_pDelvRegion = NULL; // for (i=0;i0) // { // m_pEnterRegion = new Task_Region[m_ulEnterRegionCnt]; // g_ulNewCount++; // } // else m_pEnterRegion = NULL; // for (i=0;i0) // { // m_pLeaveRegion = new Task_Region[m_ulLeaveRegionCnt]; // g_ulNewCount++; // } // else m_pLeaveRegion = NULL; // for (i=0;i0) // { // m_pReachSite = new Task_Region[m_ulReachSiteCnt]; // g_ulNewCount++; // } // else m_pReachSite = NULL; // for (i=0;i0) // { // m_pLeaveSite = new Task_Region[m_ulLeaveSiteCnt]; // g_ulNewCount++; // } // else m_pLeaveSite = NULL; // for (i=0;i