only get the first task for testing

This commit is contained in:
Le Duc Anh
2025-10-06 10:34:36 +07:00
parent 6de5e1dde7
commit 0d0b8c7648
2 changed files with 307 additions and 16 deletions
+2 -2
View File
@@ -67,10 +67,10 @@ namespace PerfectWorld.Scripts.Task
// fread(pOffs, sizeof(long), tph.item_count, fp);
pOffs = AAssit.ReadArrayFromBinary<uint>(fs, tph.item_count, ref readBytes);
pOffs = AAssit.ReadArrayFromBinary<uint>(fs, (int)tph.item_count, ref readBytes);
for (int i = 0; i < tph.item_count; i++)
for (int i = 0; i < 1; i++) //TODO: tph.item_count
{
fs.Seek(pOffs[i], SeekOrigin.Begin);
+305 -14
View File
@@ -2,6 +2,8 @@ using UnityEngine;
using System.IO;
using System.Runtime.InteropServices;
using System;
using BrewMonster;
using ModelRenderer.Scripts.Common;
namespace PerfectWorld.Scripts.Task
@@ -273,13 +275,15 @@ namespace PerfectWorld.Scripts.Task
enumTAFEachYear // 每年 // Yearly
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct TASK_PACK_HEADER
{
public uint magic;
public uint version;
public int item_count;
public uint item_count;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct ZONE_VERT
{
public float x;
@@ -670,6 +674,19 @@ namespace PerfectWorld.Scripts.Task
else
return false;
}
public static ushort uint_to_ushort(uint id)
{
return (ushort)(id & 0xFF);
}
public static void convert_txt(ref ushort[] str, int len, ushort code)
{
for (int i = 0; i < len; i++)
{
str[i] ^= code;
}
}
}
@@ -940,6 +957,231 @@ namespace PerfectWorld.Scripts.Task
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct AWARD_RATIO_SCALE
{
static uint g_ulNewCount; // Static counter for memory tracking
// Default constructor not available in C# 9.0, fields are initialized directly
public uint m_ulScales;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_AWARD_SCALES)]
public float[] m_Ratios;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_AWARD_SCALES)]
public AWARD_DATA[] m_Awards; //[MAX_AWARD_SCALES];
// Initialize method instead of constructor
public void Initialize()
{
m_ulScales = 0;
m_Ratios = new float[TaskTemplConstants.MAX_AWARD_SCALES];
m_Awards = null;
#if TASK_TEMPL_EDITOR
m_Awards = new AWARD_DATA[TaskTemplConstants.MAX_AWARD_SCALES];
g_ulNewCount++;
#endif
}
public static bool operator == (AWARD_RATIO_SCALE a, AWARD_RATIO_SCALE b)
{
if (a.m_ulScales != b.m_ulScales)
{
return false;
}
for (uint i = 0; i < a.m_ulScales; ++i)
{
// Add null check
if (a.m_Ratios[i] != b.m_Ratios[i] ||
(a.m_Awards != null && b.m_Awards != null && i < a.m_Awards.Length && i < b.m_Awards.Length &&
!(a.m_Awards[i] == b.m_Awards[i])))
{
return false;
}
}
return true;
}
public static bool operator != (AWARD_RATIO_SCALE a, AWARD_RATIO_SCALE b)
{
return !(a == b);
}
public override bool Equals(object obj)
{
if (obj is AWARD_RATIO_SCALE)
return this == (AWARD_RATIO_SCALE)obj;
return false;
}
public override int GetHashCode()
{
return m_ulScales.GetHashCode();
}
// Copy constructor equivalent method
public static AWARD_RATIO_SCALE CreateCopy(AWARD_RATIO_SCALE src)
{
AWARD_RATIO_SCALE result = new AWARD_RATIO_SCALE();
result.m_ulScales = src.m_ulScales;
result.m_Ratios = new float[TaskTemplConstants.MAX_AWARD_SCALES];
// Copy the ratios array
for (int i = 0; i < src.m_Ratios.Length && i < TaskTemplConstants.MAX_AWARD_SCALES; i++)
{
result.m_Ratios[i] = src.m_Ratios[i];
}
#if !TASK_TEMPL_EDITOR
if (src.m_ulScales > 0)
{
result.m_Awards = new AWARD_DATA[src.m_ulScales];
g_ulNewCount++;
}
#else
result.m_Awards = new AWARD_DATA[TaskTemplConstants.MAX_AWARD_SCALES];
g_ulNewCount++;
#endif
// Copy awards if available
if (src.m_Awards != null && result.m_Awards != null)
{
for (uint i = 0; i < src.m_ulScales && i < result.m_Awards.Length && i < src.m_Awards.Length; i++)
{
result.m_Awards[i] = src.m_Awards[i];
}
}
return result;
}
public bool HasAward()
{
if (m_Awards == null)
return false;
for (uint i = 0; i < m_ulScales && i < m_Awards.Length; i++)
if (m_Awards[i].HasAward())
return true;
return false;
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct AWARD_ITEMS_SCALE
{
static uint g_ulNewCount; // Static counter for memory tracking
// Default constructor not available in C# 9.0, fields are initialized directly
public uint m_ulScales;
public uint m_ulItemId;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_AWARD_SCALES)]
public uint[] m_Counts;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_AWARD_SCALES)]
public AWARD_DATA[] m_Awards; //[MAX_AWARD_SCALES];
// Initialize method instead of constructor
public void Initialize()
{
m_ulScales = 0;
m_ulItemId = 0;
m_Counts = new uint[TaskTemplConstants.MAX_AWARD_SCALES];
m_Awards = null;
#if TASK_TEMPL_EDITOR
m_Awards = new AWARD_DATA[TaskTemplConstants.MAX_AWARD_SCALES];
g_ulNewCount++;
#endif
}
public static bool operator == (AWARD_ITEMS_SCALE a, AWARD_ITEMS_SCALE b)
{
if (a.m_ulScales != b.m_ulScales)
{
return false;
}
for (uint i = 0; i < a.m_ulScales; ++i)
{
// Add null check
if (a.m_Counts[i] != b.m_Counts[i] ||
(a.m_Awards != null && b.m_Awards != null && i < a.m_Awards.Length && i < b.m_Awards.Length &&
!(a.m_Awards[i] == b.m_Awards[i])))
{
return false;
}
}
return a.m_ulItemId == b.m_ulItemId;
}
public static bool operator != (AWARD_ITEMS_SCALE a, AWARD_ITEMS_SCALE b)
{
return !(a == b);
}
public override bool Equals(object obj)
{
if (obj is AWARD_ITEMS_SCALE)
return this == (AWARD_ITEMS_SCALE)obj;
return false;
}
public override int GetHashCode()
{
return m_ulScales.GetHashCode() ^ m_ulItemId.GetHashCode();
}
// Copy constructor equivalent method
public static AWARD_ITEMS_SCALE CreateCopy(AWARD_ITEMS_SCALE src)
{
AWARD_ITEMS_SCALE result = new AWARD_ITEMS_SCALE();
result.m_ulScales = src.m_ulScales;
result.m_ulItemId = src.m_ulItemId;
result.m_Counts = new uint[TaskTemplConstants.MAX_AWARD_SCALES];
// Copy the counts array
for (int i = 0; i < src.m_Counts.Length && i < TaskTemplConstants.MAX_AWARD_SCALES; i++)
{
result.m_Counts[i] = src.m_Counts[i];
}
#if !TASK_TEMPL_EDITOR
if (src.m_ulScales > 0)
{
result.m_Awards = new AWARD_DATA[src.m_ulScales];
g_ulNewCount++;
}
#else
result.m_Awards = new AWARD_DATA[TaskTemplConstants.MAX_AWARD_SCALES];
g_ulNewCount++;
#endif
// Copy awards if available
if (src.m_Awards != null && result.m_Awards != null)
{
for (uint i = 0; i < src.m_ulScales && i < result.m_Awards.Length && i < src.m_Awards.Length; i++)
{
result.m_Awards[i] = src.m_Awards[i];
}
}
return result;
}
public bool HasAward()
{
if (m_Awards == null)
return false;
for (uint i = 0; i < m_ulScales && i < m_Awards.Length; i++)
if (m_Awards[i].HasAward())
return true;
return false;
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct AWARD_DATA
{
@@ -1053,6 +1295,7 @@ namespace PerfectWorld.Scripts.Task
public bool m_bSendMsg;
public int m_nMsgChannel;
public uint m_ulCandItems;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_AWARD_CANDIDATES)]
public AWARD_ITEMS_CAND[] m_CandItems; //[MAX_AWARD_CANDIDATES];
public uint m_ulSummonedMonsters;
public AWARD_MONSTERS_SUMMONED m_SummonedMonsters;
@@ -1114,9 +1357,9 @@ namespace PerfectWorld.Scripts.Task
// 显示全局变量表达式 // 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)]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.TASK_AWARD_MAX_DISPLAY_EXP_CNT * TaskInterfaceConstants.TASK_AWARD_MAX_DISPLAY_CHAR_LEN)]
public char[] m_pszExp;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.TASK_AWARD_MAX_DISPLAY_EXP_CNT * TaskInterfaceConstants.TASK_AWARD_MAX_DISPLAY_CHAR_LEN)]
public TASK_EXPRESSION[] m_pExpArr;
// 显示全局变量表达式提示字符串 // Display global variable expression prompt strings
@@ -1132,6 +1375,7 @@ namespace PerfectWorld.Scripts.Task
public int m_iTaskLimit;
public uint m_ulTitleNum;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_TITLE_NUM)]
public TITLE_AWARD[] m_pTitleAward;
public int m_iLeaderShip;
@@ -1471,6 +1715,7 @@ namespace PerfectWorld.Scripts.Task
}
public enum task_tm_type
{
@@ -1541,6 +1786,7 @@ namespace PerfectWorld.Scripts.Task
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Task_Region
{
public ZONE_VERT zvMin;
@@ -1575,6 +1821,7 @@ namespace PerfectWorld.Scripts.Task
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct ATaskTemplFixedData
{
// 任务id // Task ID
@@ -1582,11 +1829,12 @@ namespace PerfectWorld.Scripts.Task
// 任务名称 // Task name
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_TASK_NAME_LEN)]
public char[] m_szName;
public ushort[] m_szName;
// 任务署名 // Task signature
public bool m_bHasSign;
public string m_pszSignature;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_TASK_NAME_LEN)]
public ushort[] m_pszSignature;
// 任务类型 // Task type
public uint m_ulType;
@@ -1615,9 +1863,11 @@ namespace PerfectWorld.Scripts.Task
public char[] m_tmType;
// 发放起始时间 // Distribution start time
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_TIMETABLE_SIZE)]
public task_tm[] m_tmStart;
// 发放终止时间 // Distribution end time
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_TIMETABLE_SIZE)]
public task_tm[] m_tmEnd;
// 发放频率 // Distribution frequency
@@ -1664,18 +1914,21 @@ namespace PerfectWorld.Scripts.Task
public bool m_bDelvInZone;
public uint m_ulDelvWorld;
public uint m_ulDelvRegionCnt;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_TASKREGION)]
public Task_Region[] m_pDelvRegion;
// 进入区域任务失败 // Task fails when entering region
public bool m_bEnterRegionFail;
public uint m_ulEnterRegionWorld;
public uint m_ulEnterRegionCnt;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_TASKREGION)]
public Task_Region[] m_pEnterRegion;
// 离开区域任务失败 // Task fails when leaving region
public bool m_bLeaveRegionFail;
public uint m_ulLeaveRegionWorld;
public uint m_ulLeaveRegionCnt;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_TASKREGION)]
public Task_Region[] m_pLeaveRegion;
// 离开阵营失败 // Fails when leaving force
@@ -1735,8 +1988,11 @@ namespace PerfectWorld.Scripts.Task
// Change global key/value
public uint m_ulChangeKeyCnt;
public long[] m_plChangeKey; // [TASK_AWARD_MAX_CHANGE_VALUE]
public long[] m_plChangeKeyValue;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.TASK_AWARD_MAX_CHANGE_VALUE)]
public int[] m_plChangeKey; // [TASK_AWARD_MAX_CHANGE_VALUE]
[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;
// Fail on scene switch
@@ -1764,7 +2020,7 @@ namespace PerfectWorld.Scripts.Task
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
public byte[] m_pszPQExp; // PQ expressions
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.TASK_AWARD_MAX_DISPLAY_EXP_CNT)]
public TASK_EXPRESSION[] m_pPQExpArr; // PQ expression arrays
@@ -1939,6 +2195,7 @@ namespace PerfectWorld.Scripts.Task
public bool m_bShowByNotInTeam;
public uint m_iPremTitleNumTotal;
public uint m_iPremTitleNumRequired;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_TITLE_NUM)]
public int[] m_PremTitles;
public bool m_bShowByTitle;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
@@ -1982,6 +2239,7 @@ namespace PerfectWorld.Scripts.Task
//public ZONE_VERT m_ReachSiteMin;
//public ZONE_VERT m_ReachSiteMax;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_TASKREGION)]
public Task_Region[] m_pReachSite;
public uint m_ulReachSiteCnt;
public uint m_ulReachSiteId;
@@ -2005,6 +2263,7 @@ namespace PerfectWorld.Scripts.Task
//public ZONE_VERT m_LeaveSiteMin;
//public ZONE_VERT m_LeaveSiteMax;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_TASKREGION)]
public Task_Region[] m_pLeaveSite;
public uint m_ulLeaveSiteCnt;
public uint m_ulLeaveSiteId;
@@ -2043,11 +2302,29 @@ namespace PerfectWorld.Scripts.Task
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 AWARD_DATA m_Award_S; /* 成功 */ /* Success */
public AWARD_DATA m_Award_F; /* 失败 */ /* Failure */
/* 时间比例方式 */ /* Time ratio method */
public AWARD_RATIO_SCALE m_AwByRatio_S;
public AWARD_RATIO_SCALE m_AwByRatio_F;
/* 按获得物比例方式 */ /* Item ratio method */
public AWARD_ITEMS_SCALE m_AwByItems_S;
public AWARD_ITEMS_SCALE m_AwByItems_F;
/* 层次结构 */ /* Hierarchy structure */
public uint m_ulParent;
public uint m_ulPrevSibling;
public uint m_ulNextSibling;
public uint m_ulFirstChild;
/* 库任务相关 */ /* Library task related */
public bool m_bIsLibraryTask;
public float m_fLibraryTasksProbability;
public bool m_bIsUniqueStorageTask;
public int m_iWorldContribution; // 世界贡献度要求 // World contribution requirement
}
public class ATaskTempl
{
@@ -2114,7 +2391,21 @@ namespace PerfectWorld.Scripts.Task
{
long readBytes = 0;
ATaskTemplFixedData fixedData = AAssit.ReadFromBinaryOf<ATaskTemplFixedData>(fp, ref readBytes);
BMLogger.Log($"LoadFixedDataFromBinFile: {fp.Length}");
ATaskTemplFixedData fixedData;
fixedData = AAssit.ReadFromBinaryOf<ATaskTemplFixedData>(fp, ref readBytes);
// fixedData.m_ID = AAssit.ReadFromBinaryOf<uint>(fp, ref readBytes);
// fixedData.m_szName = AAssit.ReadArrayFromBinary<ushort>(fp, TaskTemplConstants.MAX_TASK_NAME_LEN, ref readBytes);
// TaskTemplUtils.convert_txt(ref fixedData.m_szName, TaskTemplConstants.MAX_TASK_NAME_LEN, TaskTemplUtils.uint_to_ushort(fixedData.m_ID));
// BMLogger.Log($"LoadFixedDataFromBinFile: ID {fixedData.m_ID} Name {ByteToStringUtils.UshortArrayToCP936String(fixedData.m_szName)}");
// fixedData.m_bHasSign = AAssit.ReadFromBinaryOf<bool>(fp, ref readBytes);
// ATaskTemplFixedData fixedData = AAssit.ReadFromBinaryOf<ATaskTemplFixedData>(fp, ref readBytes);
//convert_txt(m_szName, MAX_TASK_NAME_LEN, (namechar)m_ID);