complete convert fixed data and decription

This commit is contained in:
MinhHai
2025-11-01 19:21:48 +07:00
parent c26cdcdc36
commit b904c00762
10 changed files with 1643 additions and 706 deletions
+11 -17
View File
@@ -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);
```
---
+121 -11
View File
@@ -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
}
+4 -2
View File
@@ -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");
}
+565
View File
@@ -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();
}
}
}
+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: cd2f263c046d4f4299b89979d2438084
timeCreated: 1761826313
+108
View File
@@ -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
+27
View File
@@ -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);
}
}
+2
View File
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: df0da79040b03460fa770600fdc054b3
File diff suppressed because it is too large Load Diff