complete convert fixed data and decription
This commit is contained in:
@@ -137,9 +137,9 @@ fixedData.m_tmAbsFailTime = AAssit.ReadFromBinaryOf<task_tm>(fp, ref readBytes);
|
||||
|
||||
---
|
||||
|
||||
## Case 5: Pointer to Basic Type (Size Not Predefined)
|
||||
## Case 5: Pointer to Basic Type (Not Inline)
|
||||
|
||||
**Pattern**: Pointer to a basic/primitive type where the pointed-to data is not stored inline
|
||||
**Pattern**: Pointer to a basic/primitive type where only the pointer address is stored in the struct. The pointed-to content (if any) is stored elsewhere in the file and must be read later based on counts/flags.
|
||||
|
||||
**C++ Examples**:
|
||||
```cpp
|
||||
@@ -151,20 +151,13 @@ float* m_pFloatArray; // Pointer to float
|
||||
|
||||
**C# Conversion**:
|
||||
```csharp
|
||||
// Skip the size of ONE element of the basic type (not the pointer itself)
|
||||
fp.Seek(2, SeekOrigin.Current); // ushort = 2 bytes
|
||||
fp.Seek(4, SeekOrigin.Current); // int = 4 bytes
|
||||
fp.Seek(1, SeekOrigin.Current); // bool = 1 byte
|
||||
fp.Seek(4, SeekOrigin.Current); // float = 4 bytes
|
||||
// Always skip the pointer address (4 bytes in the binary layout)
|
||||
fp.Seek(4, SeekOrigin.Current);
|
||||
```
|
||||
|
||||
**Rule**: Skip `sizeof(basicType)` bytes using `fp.Seek(sizeOfType, SeekOrigin.Current)` where:
|
||||
- `ushort` → 2 bytes
|
||||
- `int`, `uint`, `float` → 4 bytes
|
||||
- `byte`, `bool`, `char` → 1 byte
|
||||
- `long`, `ulong`, `double` → 8 bytes
|
||||
**Rule**: For any pointer (to basic or user-defined types), always skip 4 bytes to account for the stored pointer address in the C++ binary. The actual data, if present, should be read later using accompanying count/flag fields.
|
||||
|
||||
**Note**: Similar to Case 3, the actual array data (if it exists) must be read separately based on count variables or other logic.
|
||||
**Note**: This assumes the source binary was written with 32-bit pointer sizes. If you ever process binaries with 64-bit pointer sizes, adjust accordingly.
|
||||
|
||||
---
|
||||
|
||||
@@ -177,7 +170,7 @@ Is it a pointer (has * in C++)?
|
||||
├── YES
|
||||
│ ├── Is it a user-defined type (struct/class)?
|
||||
│ │ ├── YES → Case 3: Skip 4 bytes (pointer address)
|
||||
│ │ └── NO (basic type) → Case 5: Skip sizeof(basic type)
|
||||
│ │ └── NO (basic type) → Case 5: Skip 4 bytes (pointer address)
|
||||
│ └── NO
|
||||
│ ├── Is it an array with predefined size?
|
||||
│ │ ├── YES → Case 2: Read array using ReadArrayFromBinary
|
||||
@@ -275,15 +268,16 @@ fixedData.m_bHasSign = AAssit.ReadFromBinaryOf<byte>(fp, ref readBytes) > 0; //
|
||||
|
||||
---
|
||||
|
||||
❌ **Wrong**: Skipping pointer size instead of basic type size for Case 5
|
||||
❌ **Wrong**: Skipping only `sizeof(basic type)` for a pointer in Case 5
|
||||
```csharp
|
||||
// C++: ushort* m_pszSignature
|
||||
fp.Seek(4, SeekOrigin.Current); // Wrong! This is Case 3, but ushort* should be Case 5
|
||||
fp.Seek(2, SeekOrigin.Current); // Wrong! Do not skip sizeof(ushort) for pointers
|
||||
```
|
||||
|
||||
✅ **Correct**:
|
||||
```csharp
|
||||
fp.Seek(2, SeekOrigin.Current); // Correct! Skip sizeof(ushort) = 2 bytes
|
||||
// Always skip the pointer address (4 bytes)
|
||||
fp.Seek(4, SeekOrigin.Current);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace PerfectWorld.Scripts.Task
|
||||
public ushort[] m_szName;
|
||||
|
||||
// 任务署名 // Task signature
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bHasSign;
|
||||
|
||||
// 署名字符串 // Signature string
|
||||
@@ -27,16 +28,20 @@ namespace PerfectWorld.Scripts.Task
|
||||
public uint m_ulTimeLimit;
|
||||
|
||||
// 下线任务失败 // Task fails when offline
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bOfflineFail;
|
||||
|
||||
// 任务失败时间 // Task failure time
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bAbsFail;
|
||||
public task_tm m_tmAbsFailTime;
|
||||
|
||||
// 任务开启物品检验不收取 // Don't take items when validating task start
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bItemNotTakeOff;
|
||||
|
||||
// 是否绝对时间 // Whether absolute time
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bAbsTime;
|
||||
|
||||
// 时间段个数 // Number of time periods
|
||||
@@ -61,42 +66,54 @@ namespace PerfectWorld.Scripts.Task
|
||||
public int m_lPeriodLimit;
|
||||
|
||||
// 选择单个子任务执行 // Execute single subtask
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bChooseOne;
|
||||
|
||||
// 随机旋转单个子任务执行 // Randomly rotate single subtask execution
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bRandOne;
|
||||
|
||||
// 子任务是否有顺序 // Whether subtasks have order
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bExeChildInOrder;
|
||||
|
||||
// 失败后是否认为父任务也失败 // Whether parent task fails when subtask fails
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bParentAlsoFail;
|
||||
|
||||
// 子任务成功后父任务成功 // Parent task succeeds when subtask succeeds
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bParentAlsoSucc;
|
||||
|
||||
// 能否放弃此任务 // Whether task can be abandoned
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bCanGiveUp;
|
||||
|
||||
// 是否可重复完成 // Whether task can be repeated
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bCanRedo;
|
||||
|
||||
// 失败后是否可重新完成 // Whether task can be redone after failure
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bCanRedoAfterFailure;
|
||||
|
||||
// 放弃清空任务 // Clear task when abandoned
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bClearAsGiveUp;
|
||||
|
||||
// 是否需要记录 // Whether recording is needed
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bNeedRecord;
|
||||
|
||||
// 玩家被杀死是否认为失败 // Whether task fails when player dies
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bFailAsPlayerDie;
|
||||
|
||||
// 接受者上限 // Maximum number of receivers
|
||||
public uint m_ulMaxReceiver;
|
||||
|
||||
// 发放区域 // Distribution area
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bDelvInZone;
|
||||
public uint m_ulDelvWorld;
|
||||
public uint m_ulDelvRegionCnt;
|
||||
@@ -105,6 +122,7 @@ namespace PerfectWorld.Scripts.Task
|
||||
public Task_Region[] m_pDelvRegion;
|
||||
|
||||
// 进入区域任务失败 // Task fails when entering region
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bEnterRegionFail;
|
||||
public uint m_ulEnterRegionWorld;
|
||||
public uint m_ulEnterRegionCnt;
|
||||
@@ -113,6 +131,7 @@ namespace PerfectWorld.Scripts.Task
|
||||
public Task_Region[] m_pEnterRegion;
|
||||
|
||||
// 离开区域任务失败 // Task fails when leaving region
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bLeaveRegionFail;
|
||||
public uint m_ulLeaveRegionWorld;
|
||||
public uint m_ulLeaveRegionCnt;
|
||||
@@ -121,40 +140,51 @@ namespace PerfectWorld.Scripts.Task
|
||||
public Task_Region[] m_pLeaveRegion;
|
||||
|
||||
// 离开阵营失败 // Fails when leaving force
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bLeaveForceFail;
|
||||
|
||||
// 传送到特定点 // Teleport to specific point
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bTransTo;
|
||||
public uint m_ulTransWldId;
|
||||
public ZONE_VERT m_TransPt;
|
||||
|
||||
// Monster controller
|
||||
public long m_lMonsCtrl;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bTrigCtrl;
|
||||
|
||||
// Auto trigger when conditions are met
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bAutoDeliver;
|
||||
|
||||
// Whether to display in exclusive UI
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bDisplayInExclusiveUI;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bReadyToNotifyServer;
|
||||
|
||||
// Whether used in token shop
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bUsedInTokenShop;
|
||||
|
||||
// Death trigger
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bDeathTrig;
|
||||
|
||||
// Whether clear all acquired items
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bClearAcquired;
|
||||
|
||||
// Recommended level
|
||||
public uint m_ulSuitableLevel;
|
||||
|
||||
// Whether to show prompt
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowPrompt;
|
||||
|
||||
// Whether it is a key task
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bKeyTask;
|
||||
|
||||
// Delivery NPC
|
||||
@@ -164,15 +194,19 @@ namespace PerfectWorld.Scripts.Task
|
||||
public uint m_ulAwardNPC;
|
||||
|
||||
// Whether it is a skill task
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bSkillTask;
|
||||
|
||||
// Whether can be searched
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bCanSeekOut;
|
||||
|
||||
// Whether show direction
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowDirection;
|
||||
|
||||
// Marriage
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bMarriage;
|
||||
|
||||
// Change global key/value
|
||||
@@ -188,27 +222,34 @@ namespace PerfectWorld.Scripts.Task
|
||||
public bool[] m_pbChangeType;
|
||||
|
||||
// Fail on scene switch
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bSwitchSceneFail;
|
||||
|
||||
// Hidden task
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bHidden;
|
||||
|
||||
// Whether deliver skill
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bDeliverySkill;
|
||||
public int m_iDeliveredSkillID;
|
||||
public int m_iDeliveredSkillLevel;
|
||||
|
||||
// Whether show task completion effect
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowGfxFinished;
|
||||
|
||||
// Whether change player ranking in PQ
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bChangePQRanking;
|
||||
|
||||
// Compare delivery items with player inventory slots
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bCompareItemAndInventory;
|
||||
public uint m_ulInventorySlotNum;
|
||||
|
||||
// PQ Task related // PQ任务相关
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
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 = 0)]
|
||||
@@ -218,7 +259,9 @@ namespace PerfectWorld.Scripts.Task
|
||||
[NonSerialized]
|
||||
public TASK_EXPRESSION[,] m_pPQExpArr; // PQ expression arrays
|
||||
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bPQSubTask; // Whether it is a PQ subtask // 是否PQ子任务
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bClearContrib; // Clear contribution when task starts // 任务开始时清空贡献度
|
||||
public uint m_ulMonsterContribCnt; // Number of monster types // 怪物种类数量
|
||||
// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0)]
|
||||
@@ -227,44 +270,61 @@ namespace PerfectWorld.Scripts.Task
|
||||
|
||||
// Account Task related // 账号任务相关
|
||||
public int m_iPremNeedRecordTasksNum; // Number of completed record tasks // 记录完成结果任务完成个数
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowByNeedRecordTasksNum; // Show by number of needed record tasks
|
||||
public int m_iPremiseFactionContrib; // Faction contribution // 帮派贡献度
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowByFactionContrib; // Show by faction contribution
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bAccountTaskLimit; // Whether account limits completion times // 是否账号限制完成次数
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bRoleTaskLimit; // Whether role limits completion times // 是否角色限制完成次数
|
||||
public uint m_ulAccountTaskLimitCnt; // Account task limit count (deprecated) // 账号限制完成次数,废弃使用了
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bLeaveFactionFail; // Fail when leaving faction
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bNotIncCntWhenFailed; // Don't increase count when failed // 是否失败时不增加完成次数
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bNotClearItemWhenFailed; // Don't clear items when failed // 任务失败时不收取任务要求的物品
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bDisplayInTitleTaskUI; // Show in title task UI // 是否显示在称号任务界面里
|
||||
|
||||
/* 开启条件 */ /* Opening conditions */
|
||||
|
||||
// 变身状态 // Transformation state
|
||||
public byte m_ucPremiseTransformedForm;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowByTransformed;
|
||||
// 等级条件 // Level conditions
|
||||
public uint m_ulPremise_Lev_Min;
|
||||
public uint m_ulPremise_Lev_Max;
|
||||
public uint m_bPremCheckMaxHistoryLevel;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowByLev;
|
||||
// 转生次数 // Reincarnation times
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bPremCheckReincarnation;
|
||||
public uint m_ulPremReincarnationMin;
|
||||
public uint m_ulPremReincarnationMax;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowByReincarnation;
|
||||
// 境界 // Realm level
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bPremCheckRealmLevel;
|
||||
public uint m_ulPremRealmLevelMin;
|
||||
public uint m_ulPremRealmLevelMax;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bPremCheckRealmExpFull;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowByRealmLevel;
|
||||
// 所需道具 // Required items
|
||||
public uint m_ulPremItems;
|
||||
// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0)]
|
||||
[NonSerialized]
|
||||
public ITEM_WANTED[] m_PremItems; //[MAX_ITEM_WANTED];
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowByItems;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bPremItemsAnyOne;
|
||||
// 发放道具 // Given items
|
||||
public uint m_ulGivenItems;
|
||||
@@ -275,50 +335,66 @@ namespace PerfectWorld.Scripts.Task
|
||||
public ITEM_WANTED[] m_GivenItems; //[MAX_ITEM_WANTED];
|
||||
// 押金 // Deposit
|
||||
public uint m_ulPremise_Deposit;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowByDeposit;
|
||||
// 声望 // Reputation
|
||||
public long m_lPremise_Reputation;
|
||||
public long m_lPremise_RepuMax;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
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;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
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;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowByPeriod;
|
||||
// 帮派 // Faction
|
||||
public uint m_ulPremise_Faction;
|
||||
public int m_iPremise_FactionRole;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowByFaction;
|
||||
|
||||
// 性别 // Gender
|
||||
public uint m_ulGender;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowByGender;
|
||||
// 职业限制 // Occupation restrictions
|
||||
public uint m_ulOccupations;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_OCCUPATIONS)]
|
||||
public uint[] m_Occupations;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowByOccup;
|
||||
// 夫妻 // Spouse
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bPremise_Spouse;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowBySpouse;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bPremiseWeddingOwner;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowByWeddingOwner;
|
||||
// GM
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bGM;
|
||||
// 完美神盾用户 // Perfect Shield user
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShieldUser;
|
||||
|
||||
// 账号累计充值金额(下限&上限) // Account accumulated recharge amount (lower & upper limit)
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowByRMB;
|
||||
public uint m_ulPremRMBMin;
|
||||
public uint m_ulPremRMBMax;
|
||||
|
||||
// 角色相关时间 // Character-related time
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bCharTime;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
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;
|
||||
@@ -341,23 +417,37 @@ namespace PerfectWorld.Scripts.Task
|
||||
public uint m_ulSpecialAward;
|
||||
|
||||
// 组队信息 // Team information
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bTeamwork; // 组队任务 // Team task
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bRcvByTeam; // 必须组队接收 // Must be in team to receive
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bSharedTask; // 新队员分享任务 // New team members share tasks
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bSharedAchieved; // 分享杀怪、物品数量 // Share kill counts and item counts
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bCheckTeammate; // 检查队友位置 // Check teammate positions
|
||||
public float m_fTeammateDist; // 队友距离平方值 // Square of teammate distance
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bAllFail; // 任意队员失败则全部失败 // Any member fails, all fail
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bCapFail; // 队长失败则全部失败 // Leader fails, all fail
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bCapSucc; // 队长成功则全队成功 // Leader succeeds, all succeed
|
||||
public float m_fSuccDist; // 成功时队员的距离 // Member distance for success
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bDismAsSelfFail; // 队员离队自身失败 // Member leaves team fails itself
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bRcvChckMem; // 接任务时检查队员位置 // Check member positions when receiving task
|
||||
public float m_fRcvMemDist; // 接任务时队员距离平方值 // Square of member distance when receiving task
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bCntByMemPos; // 队员在有效范围内杀怪有效 // Members in valid range for kill counts
|
||||
public float m_fCntMemDist; // 队员有效的范围 // Valid range for members
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bAllSucc; // 任意队员成功则全部成功 // Any member succeeds, all succeed
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bCoupleOnly; // 队长队员必须为夫妻 // Leader and member must be spouses
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bDistinguishedOcc; // 队伍中不允许有相同的职业 // No same occupations allowed in team
|
||||
|
||||
// 队伍成员需求 // Team member requirements
|
||||
@@ -365,47 +455,64 @@ namespace PerfectWorld.Scripts.Task
|
||||
// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0)]
|
||||
[NonSerialized]
|
||||
public TEAM_MEM_WANTED[] m_TeamMemsWanted;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowByTeam;
|
||||
|
||||
// 前提全局key/value // Premise global key/value
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bPremNeedComp;
|
||||
public int m_nPremExp1AndOrExp2;
|
||||
public COMPARE_KEY_VALUE m_Prem1KeyValue;
|
||||
public COMPARE_KEY_VALUE m_Prem2KeyValue;
|
||||
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bPremCheckForce;
|
||||
public int m_iPremForce;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowByForce;
|
||||
public int m_iPremForceReputation;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowByForceReputation;
|
||||
public int m_iPremForceContribution; // 扣除战功 // Deduct military merit
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowByForceContribution;
|
||||
public int m_iPremForceExp; // 经验兑换 // Experience exchange
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowByForceExp;
|
||||
public int m_iPremForceSP; // 元神兑换 // Spirit exchange
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowByForceSP;
|
||||
public int m_iPremForceActivityLevel;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowByForceActivityLevel;
|
||||
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bPremIsKing;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowByKing;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bPremNotInTeam;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowByNotInTeam;
|
||||
public uint m_iPremTitleNumTotal;
|
||||
public uint m_iPremTitleNumRequired;
|
||||
// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0)]
|
||||
[NonSerialized]
|
||||
public int[] m_PremTitles;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowByTitle;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
|
||||
public int[] m_iPremHistoryStageIndex; // 历史阶段 // Historical stage
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowByHistoryStage;
|
||||
|
||||
public uint m_ulPremGeneralCardCount; // 收集的卡牌数量 // Number of collected cards
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowByGeneralCard;
|
||||
|
||||
public int m_iPremGeneralCardRank; // 要求某品阶的卡牌数量 // Required number of cards of a certain rank
|
||||
public uint m_ulPremGeneralCardRankCount;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bShowByGeneralCardRank;
|
||||
|
||||
/* 任务完成的方式及条件 */ /* Task completion methods and conditions */
|
||||
@@ -474,6 +581,7 @@ namespace PerfectWorld.Scripts.Task
|
||||
public uint m_ulLeaveSiteId;
|
||||
|
||||
// 完成全局key/value // Complete global key/value
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bFinNeedComp;
|
||||
public int m_nFinExp1AndOrExp2;
|
||||
public COMPARE_KEY_VALUE m_Fin1KeyValue;
|
||||
@@ -509,30 +617,30 @@ namespace PerfectWorld.Scripts.Task
|
||||
public uint m_ulAwardType_F;
|
||||
|
||||
/* 普通和按每个方式 */ /* Normal and per-method rewards */
|
||||
// [NonSerialized]
|
||||
// public AWARD_DATA m_Award_S; /* 成功 */ /* Success */
|
||||
public uint m_Award_S_ptr;
|
||||
[NonSerialized]
|
||||
// public AWARD_DATA m_Award_F; /* 失败 */ /* Failure */
|
||||
public uint m_Award_F_ptr;
|
||||
public AWARD_DATA m_Award_S; /* 成功 */ /* Success */
|
||||
//public uint m_Award_S_ptr;
|
||||
[NonSerialized]
|
||||
public AWARD_DATA m_Award_F; /* 失败 */ /* Failure */
|
||||
//public uint m_Award_F_ptr;
|
||||
|
||||
|
||||
/* 时间比例方式 */ /* Time ratio method */
|
||||
//TODO: Revert
|
||||
[NonSerialized]
|
||||
// public AWARD_RATIO_SCALE m_AwByRatio_S;
|
||||
public uint m_AwByRatio_S_ptr;
|
||||
public AWARD_RATIO_SCALE m_AwByRatio_S;
|
||||
//public uint m_AwByRatio_S_ptr;
|
||||
[NonSerialized]
|
||||
// public AWARD_RATIO_SCALE m_AwByRatio_F;
|
||||
public uint m_AwByRatio_F_ptr;
|
||||
public AWARD_RATIO_SCALE m_AwByRatio_F;
|
||||
// public uint m_AwByRatio_F_ptr;
|
||||
|
||||
/* 按获得物比例方式 */ /* Item ratio method */
|
||||
//TODO: Revert
|
||||
[NonSerialized]
|
||||
// public AWARD_ITEMS_SCALE m_AwByItems_S;
|
||||
public AWARD_ITEMS_SCALE m_AwByItems_S;
|
||||
public uint m_AwByItems_S_ptr;
|
||||
[NonSerialized]
|
||||
// public AWARD_ITEMS_SCALE m_AwByItems_F;
|
||||
public AWARD_ITEMS_SCALE m_AwByItems_F;
|
||||
public uint m_AwByItems_F_ptr;
|
||||
|
||||
/* 层次结构 */ /* Hierarchy structure */
|
||||
@@ -542,8 +650,10 @@ namespace PerfectWorld.Scripts.Task
|
||||
public uint m_ulFirstChild;
|
||||
|
||||
/* 库任务相关 */ /* Library task related */
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bIsLibraryTask;
|
||||
public float m_fLibraryTasksProbability;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bIsUniqueStorageTask;
|
||||
public int m_iWorldContribution; // 世界贡献度要求 // World contribution requirement
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ namespace PerfectWorld.Scripts.Task
|
||||
// read File and prepare offset array before loading tasks
|
||||
pOffs = AAssit.ReadArrayFromBinary<uint>(fs, (int)tph.item_count, ref readBytes);
|
||||
|
||||
//Debug.Log((int)tph.item_count);
|
||||
//BMLogger.Log($" [MH] Task File Lenght: {fs.Length}");
|
||||
for (int i = 1; i < 2; i++) //TODO: tph.item_count
|
||||
{
|
||||
@@ -79,14 +80,15 @@ namespace PerfectWorld.Scripts.Task
|
||||
|
||||
ATaskTempl pTempl = new ATaskTempl();
|
||||
g_ulNewCount++;
|
||||
|
||||
|
||||
Debug.Log($"Task Index {i}: Attempting to load task template...");
|
||||
if (!pTempl.LoadFromBinFile(fs))
|
||||
{
|
||||
CECTaskInterface.WriteLog(0, (int)pTempl.m_FixedData.m_ID, 0, "Cant Load Task");
|
||||
// LOG_DELETE(pTempl);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
AddOneTaskTempl(pTempl);
|
||||
// TaskInterface::WriteLog(0, pTempl->m_ID, 2, "LoadTask");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,565 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace PerfectWorld.Scripts.Task
|
||||
{
|
||||
[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
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
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;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bTrigCtrl;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bUseLevCo;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bDivorce;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bSendMsg;
|
||||
public int m_nMsgChannel;
|
||||
public uint m_ulCandItems;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0)]
|
||||
public AWARD_ITEMS_CAND[] m_CandItems; //[MAX_AWARD_CANDIDATES];
|
||||
public uint m_CandItems_ptr;
|
||||
public uint m_ulSummonedMonsters;
|
||||
[MarshalAs(UnmanagedType.SysInt)]
|
||||
public AWARD_MONSTERS_SUMMONED m_SummonedMonsters;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bAwardDeath;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool m_bAwardDeathWithLoss;
|
||||
public uint m_ulDividend; // 鸿利值 // Dividend value
|
||||
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
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;
|
||||
[MarshalAs(UnmanagedType.SysInt)]
|
||||
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)]
|
||||
[NonSerialized]
|
||||
public int[] m_plChangeKey;
|
||||
public uint m_plChangeKey_ptr;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
|
||||
// [NonSerialized]
|
||||
public int[] m_plChangeKeyValue;
|
||||
public uint m_plChangeKeyValue_ptr;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
|
||||
// [NonSerialized]
|
||||
public bool[] m_pbChangeType;
|
||||
public uint m_pbChangeType_ptr;
|
||||
|
||||
// 修改历史进度 // Modify historical progress
|
||||
public uint m_ulHistoryChangeCnt;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
|
||||
public int[] m_plHistoryChangeKey;
|
||||
public uint m_plHistoryChangeKey_ptr;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
|
||||
public int[] m_plHistoryChangeKeyValue;
|
||||
public uint m_plHistoryChangeKeyValue_ptr;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
|
||||
public bool[] m_pbHistoryChangeType;
|
||||
public uint m_pbHistoryChangeType_ptr;
|
||||
|
||||
// 倍率 // Multiplier
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
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 = 1)]
|
||||
public int[] m_plDisplayKey;
|
||||
public uint m_plDisplayKey_ptr;
|
||||
|
||||
// 显示全局变量表达式 // Display global variable expressions
|
||||
public uint m_ulExpCnt;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
|
||||
public byte[] m_pszExp;
|
||||
public byte m_pszExp_ptr;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0)]
|
||||
public TASK_EXPRESSION[] m_pExpArr;
|
||||
public uint m_pExpArr_ptr;
|
||||
|
||||
// 显示全局变量表达式提示字符串 // Display global variable expression prompt strings
|
||||
public uint m_ulTaskCharCnt;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
|
||||
public ushort[] m_pTaskChar;
|
||||
public ushort m_pTaskChar_ptr;
|
||||
|
||||
// 势力相关 // 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;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0)]
|
||||
public TITLE_AWARD[] m_pTitleAward;
|
||||
public uint m_pTitleAward_ptr;
|
||||
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>(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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cd2f263c046d4f4299b89979d2438084
|
||||
timeCreated: 1761826313
|
||||
@@ -0,0 +1,108 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace PerfectWorld.Scripts.Task
|
||||
{
|
||||
[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;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e4085dad1f98431ab03af71a8a2cf4e8
|
||||
timeCreated: 1761826345
|
||||
@@ -0,0 +1,27 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine;
|
||||
|
||||
public class SizeTest : MonoBehaviour
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct TestStruct
|
||||
{
|
||||
public int intValue;
|
||||
public float floatValue;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool byteValue;
|
||||
|
||||
|
||||
}
|
||||
|
||||
[ContextMenu("Test Size")]
|
||||
void TestSize()
|
||||
{
|
||||
TestStruct q = new();
|
||||
|
||||
var size = Marshal.SizeOf(typeof(TestStruct));
|
||||
// byte[] data = new byte[Marshal.SizeOf(typeof(TestStruct))];
|
||||
// q = Marshal.PtrToStructure<TestStruct>();
|
||||
Debug.Log("Size of TestStruct: " + size);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: df0da79040b03460fa770600fdc054b3
|
||||
+799
-676
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user