Merge branch 'feature/convert-task-templ' into develop

This commit is contained in:
MinhHai
2025-11-03 18:34:36 +07:00
50 changed files with 6499 additions and 834 deletions
+309
View File
@@ -0,0 +1,309 @@
---
description: Binary data conversion rules when reading C++ binary files in C#
---
# Binary Data Conversion Rules (C++ to C#)
When reading binary data from C++ files using `FileStream`, follow these conversion patterns based on the variable type in the original C++ struct.
## Important Type Mappings
- `unsigned long` in C++ → `uint` in C#
- `bool` in C++ → 1 byte (read as `byte` in C#, then convert with `> 0`)
- `wchar_t` on Windows → 2 bytes
- `task_char` → `ushort`
- Pointer size in C++ binary → typically 4 bytes (32-bit)
**Critical**: When reading binary data, match the original C++ memory layout exactly, accounting for struct packing and alignment.
## Case 1: Normal Value Type Variables (Primitives)
**Pattern**: Directly stored scalar values (no arrays, no pointers, no user-defined structs)
**C++ Examples**:
```cpp
unsigned long m_ID;
bool m_bHasSign;
int m_lAvailFrequency;
float m_fLibraryTasksProbability;
```
**C# Conversion**:
```csharp
// Read value and assign to the field
fixedData.m_ID = AAssit.ReadFromBinaryOf<uint>(fp, ref readBytes);
// Special case for bool: read as byte and compare with > 0
fixedData.m_bHasSign = AAssit.ReadFromBinaryOf<byte>(fp, ref readBytes) > 0;
fixedData.m_bChooseOne = AAssit.ReadFromBinaryOf<byte>(fp, ref readBytes) > 0;
// Other primitive types
fixedData.m_lAvailFrequency = AAssit.ReadFromBinaryOf<int>(fp, ref readBytes);
fixedData.m_fLibraryTasksProbability = AAssit.ReadFromBinaryOf<float>(fp, ref readBytes);
```
**Rule**: Use `AAssit.ReadFromBinaryOf<T>(fp, ref readBytes)` where T is the C# equivalent type.
**Important for bool**: C++ bool is stored as 1 byte in binary files. Always read as `byte` and convert to C# bool using `> 0`:
```csharp
// Correct pattern for bool
fixedData.m_boolField = AAssit.ReadFromBinaryOf<byte>(fp, ref readBytes) > 0;
```
---
## Case 2: Fixed-Size Arrays (Inline Memory)
**Pattern**: Arrays with a known constant size defined by a macro or constant
**C++ Examples**:
```cpp
task_char m_szName[MAX_TASK_NAME_LEN]; // MAX_TASK_NAME_LEN = 30
char m_tmType[MAX_TIMETABLE_SIZE]; // MAX_TIMETABLE_SIZE = 32
task_tm m_tmStart[MAX_TIMETABLE_SIZE];
task_tm m_tmEnd[MAX_TIMETABLE_SIZE];
```
**C# Conversion**:
```csharp
// Read array from binary and assign to the field
fixedData.m_szName = AAssit.ReadArrayFromBinary<ushort>(fp, TaskTemplConstants.MAX_TASK_NAME_LEN, ref readBytes);
fixedData.m_tmType = AAssit.ReadArrayFromBinary<byte>(fp, TaskTemplConstants.MAX_TIMETABLE_SIZE, ref readBytes);
fixedData.m_tmStart = AAssit.ReadArrayFromBinary<task_tm>(fp, TaskTemplConstants.MAX_TIMETABLE_SIZE, ref readBytes);
fixedData.m_tmEnd = AAssit.ReadArrayFromBinary<task_tm>(fp, TaskTemplConstants.MAX_TIMETABLE_SIZE, ref readBytes);
```
**Rule**: Use `AAssit.ReadArrayFromBinary<T>(fp, arraySize, ref readBytes)` where:
- `T` is the C# equivalent element type
- `arraySize` is the predefined constant size
---
## Case 3: Pointer to User-Defined Type or String
**Pattern**: Fields that store only the pointer address, not the actual object/data
**C++ Examples**:
```cpp
task_char* m_pszSignature;
AWARD_DATA* m_Award_S;
Task_Region* m_pDelvRegion;
ITEM_WANTED* m_PremItems;
```
**C# Conversion**:
```csharp
// Skip pointer size (4 bytes for 32-bit pointers)
// The content is not inlined in the struct
fp.Seek(4, SeekOrigin.Current);
```
**Rule**: Skip 4 bytes using `fp.Seek(4, SeekOrigin.Current)` because only the pointer address is stored in the binary file, not the actual data.
**Note**: If the pointed-to data exists separately in the file, it must be read later based on additional logic (e.g., checking a count variable or flag).
---
## Case 4: User-Defined Struct (Inline, Not Pointer)
**Pattern**: A complete user-defined struct embedded directly in the parent struct
**C++ Examples**:
```cpp
task_tm m_tmAbsFailTime; // Inline struct
AWARD_DATA m_Award_S; // Inline struct (if not a pointer)
```
**C# Conversion**:
```csharp
// Skip the full size of the struct in bytes
// Check the struct's internal members and padding to calculate correct size
fp.Seek(24, SeekOrigin.Current); // Example: sizeof(task_tm) = 24 bytes on Windows/MSVC
```
**Rule**:
1. Calculate the exact size of the struct including padding
2. Skip that many bytes using `fp.Seek(structSize, SeekOrigin.Current)`
**Important**: Do not rely on hardcoded numbers. Calculate the actual struct size considering:
- Size of each member
- Struct packing (`Pack = 1`, `Pack = 4`, etc.)
- Platform-specific alignment rules
**Alternative**: If you need the data, read the struct directly:
```csharp
fixedData.m_tmAbsFailTime = AAssit.ReadFromBinaryOf<task_tm>(fp, ref readBytes);
```
---
## Case 5: Pointer to Basic Type (Not 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
ushort* m_pszSignature; // Pointer to ushort
int* m_plChangeKey; // Pointer to int
bool* m_pbChangeType; // Pointer to bool
float* m_pFloatArray; // Pointer to float
```
**C# Conversion**:
```csharp
// Always skip the pointer address (4 bytes in the binary layout)
fp.Seek(4, SeekOrigin.Current);
```
**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**: This assumes the source binary was written with 32-bit pointer sizes. If you ever process binaries with 64-bit pointer sizes, adjust accordingly.
---
## Decision Tree
Use this flowchart to determine which case applies:
```
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 4 bytes (pointer address)
│ └── NO
│ ├── Is it an array with predefined size?
│ │ ├── YES → Case 2: Read array using ReadArrayFromBinary
│ │ └── NO
│ │ ├── Is it a user-defined struct (inline)?
│ │ │ ├── YES → Case 4: Skip sizeof(struct) or read struct
│ │ │ └── NO → Case 1: Read value using ReadFromBinaryOf
```
---
## Common Patterns and Examples
### Pattern: Conditional Data Reading
When a field has associated data only if a flag/count is set:
**C++ Example**:
```cpp
bool m_bHasSign;
task_char* m_pszSignature; // Only has data if m_bHasSign is true
unsigned long m_ulTimetable;
task_tm* m_tmStart; // Only has data if m_ulTimetable > 0
```
**C# Conversion**:
```csharp
// First read the flag/count (read bool as byte and convert with > 0)
fixedData.m_bHasSign = AAssit.ReadFromBinaryOf<byte>(fp, ref readBytes) > 0;
// Skip the pointer (Case 3)
fp.Seek(4, SeekOrigin.Current);
// Later, conditionally read the actual data
if (fixedData.m_bHasSign)
{
fixedData.m_pszSignature = AAssit.ReadArrayFromBinary<ushort>(fp, MAX_TASK_NAME_LEN, ref readBytes);
}
```
### Pattern: String Conversion
For `task_char` arrays (which are `ushort` arrays in C#):
```csharp
// Read the array
fixedData.m_szName = AAssit.ReadArrayFromBinary<ushort>(fp, MAX_TASK_NAME_LEN, ref readBytes);
// Convert to readable string
TaskTemplUtils.convert_txt(ref fixedData.m_szName, MAX_TASK_NAME_LEN, TaskTemplUtils.uint_to_ushort(fixedData.m_ID));
string taskName = ByteToStringUtils.UshortArrayToCP936String(fixedData.m_szName);
```
---
## Reference: AAssit Helper Methods
From [AAssit.cs](mdc:Assets/PerfectWorld/Scripts/Common/DataProcess/AAssit.cs):
```csharp
// Read a single value
public static T ReadFromBinaryOf<T>(FileStream fp, ref long readBytes) where T : struct
// Read an array of values
public static T[] ReadArrayFromBinary<T>(FileStream fp, int count, ref long readBytes) where T : struct
```
---
## Best Practices
1. **Always track readBytes**: Pass `ref readBytes` to track how many bytes have been read for debugging
2. **Match C++ layout exactly**: Ensure struct packing in C# matches C++ (`Pack = 1` is common)
3. **Document your assumptions**: Add comments explaining the byte sizes you're skipping
4. **Verify with logs**: Log read values to verify correctness
5. **Check file position**: Use `fp.Position` to verify you're reading from the expected location
6. **Handle platform differences**: Be aware of 32-bit vs 64-bit pointer sizes (though binary files usually use fixed sizes)
---
## Common Mistakes to Avoid
❌ **Wrong**: Reading bool directly as bool type
```csharp
// C++: bool m_bHasSign
fixedData.m_bHasSign = AAssit.ReadFromBinaryOf<bool>(fp, ref readBytes); // Wrong!
```
✅ **Correct**:
```csharp
// Read as byte and compare with > 0
fixedData.m_bHasSign = AAssit.ReadFromBinaryOf<byte>(fp, ref readBytes) > 0; // Correct!
```
---
❌ **Wrong**: Skipping only `sizeof(basic type)` for a pointer in Case 5
```csharp
// C++: ushort* m_pszSignature
fp.Seek(2, SeekOrigin.Current); // Wrong! Do not skip sizeof(ushort) for pointers
```
✅ **Correct**:
```csharp
// Always skip the pointer address (4 bytes)
fp.Seek(4, SeekOrigin.Current);
```
---
❌ **Wrong**: Reading inline array as a single value
```csharp
// C++: char m_tmType[MAX_TIMETABLE_SIZE]
byte value = AAssit.ReadFromBinaryOf<byte>(fp, ref readBytes); // Wrong!
```
✅ **Correct**:
```csharp
byte[] values = AAssit.ReadArrayFromBinary<byte>(fp, MAX_TIMETABLE_SIZE, ref readBytes);
```
---
❌ **Wrong**: Not accounting for struct padding
```csharp
// C++: struct with padding
fp.Seek(20, SeekOrigin.Current); // Might be wrong due to padding!
```
✅ **Correct**:
```csharp
// Calculate actual size with padding
// Or read the struct directly if needed
fixedData.m_structField = AAssit.ReadFromBinaryOf<MyStruct>(fp, ref readBytes);
```
+13
View File
@@ -0,0 +1,13 @@
---
alwaysApply: true
---
When convert cpp to c#
- unsigned long convert to uint
- unsigned char to byte
- task_char to ushort
- Keeps all the naming
- keeps all the original chinese comments. But add a translated English version side by side
- struct has to be public
- struct has to be use [StructLayout(LayoutKind.Sequential, Pack = 1)]
- all field in struct has to be public
- array has to be use [MarshalAs(UnmanagedType.ByValArray, SizeConst = )] to fix the array size
+2
View File
@@ -12,6 +12,8 @@
/[Uu]ser[Ss]ettings/
*.log
.DS_Store
# By default unity supports Blender asset imports, *.blend1 blender files do not need to be commited to version control.
*.blend1
*.blend1.meta
+170
View File
@@ -0,0 +1,170 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 10
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 13
m_BakeOnSceneLoad: 0
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 0
m_LightmapEditorSettings:
serializedVersion: 12
m_Resolution: 2
m_BakeResolution: 40
m_AtlasSize: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1
m_CompAOExponentDirect: 0
m_ExtractAmbientOcclusion: 0
m_Padding: 2
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_ReflectionCompression: 2
m_MixedBakeMode: 2
m_BakeBackend: 1
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 512
m_PVRBounces: 2
m_PVREnvironmentSampleCount: 256
m_PVREnvironmentReferencePointCount: 2048
m_PVRFilteringMode: 1
m_PVRDenoiserTypeDirect: 1
m_PVRDenoiserTypeIndirect: 1
m_PVRDenoiserTypeAO: 1
m_PVRFilterTypeDirect: 0
m_PVRFilterTypeIndirect: 0
m_PVRFilterTypeAO: 0
m_PVREnvironmentMIS: 1
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 1
m_PVRFilteringGaussRadiusAO: 1
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
m_ExportTrainingData: 0
m_TrainingDataDestination: TrainingData
m_LightProbeSampleCountMultiplier: 4
m_LightingDataAsset: {fileID: 20201, guid: 0000000000000000f000000000000000, type: 0}
m_LightingSettings: {fileID: 0}
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 3
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.4
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
buildHeightMesh: 0
maxJobWorkers: 0
preserveTilesOutsideBounds: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &1956623781
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1956623783}
- component: {fileID: 1956623782}
m_Layer: 0
m_Name: TaskTest
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1956623782
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1956623781}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 561ff33122f704147a67d91c42fde5a4, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!4 &1956623783
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1956623781}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1660057539 &9223372036854775807
SceneRoots:
m_ObjectHideFlags: 0
m_Roots:
- {fileID: 1956623783}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 768ce4fda26964eca987fc64bf5bab70
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -15,6 +15,8 @@ public class AAssit
}
int size = Marshal.SizeOf(typeof(T));
if (typeof(T) == typeof(bool)) size = 1; // bool is stored as 1 byte
byte[] buffer = new byte[size];
// Read `size` bytes into `buffer[0..size]`
@@ -51,7 +53,21 @@ public class AAssit
return array;
}
public static T[] ReadArrayFromBinary<T>(FileStream stream, ref long readBytes, long fileOffset = -1)
/// <summary>
/// Reads an array from a binary stream where the data layout is:
/// [int32 count] followed by <c>count</c> serialized elements of <typeparamref name="T"/>.
/// If <paramref name="fileOffset"/> >= 0, seeks to that absolute position before
/// reading the count and re-seeks before reading each element. Updates
/// <paramref name="readBytes"/> with the total number of bytes consumed. Returns
/// null when the read <c>count</c> is less than or equal to zero.
/// </summary>
/// <param name="stream">Open readable <see cref="FileStream"/> to read from.</param>
/// <param name="readBytes">Reference accumulator updated with bytes consumed by this method.</param>
/// <param name="fileOffset">Optional absolute file position to seek prior to reads; if >= 0 the stream is
/// re-seeked before reading the count and each element.</param>
/// <typeparam name="T">Element type to deserialize. Must be blittable/marshallable via <see cref="Marshal.PtrToStructure(System.IntPtr,System.Type)"/>.</typeparam>
/// <returns>The populated array when <c>count</c> > 0; otherwise null.</returns>
public static T[] ReadArrayPointerFromBinary<T>(FileStream stream, ref long readBytes, long fileOffset = -1)
{
// seek to the fileOffset if it's >= 0
if (fileOffset >= 0)
@@ -312,88 +312,88 @@ namespace ModelRenderer.Scripts.GameData
long t = AAssit.GetIntFromFileStream(file, ref dwRead);
// if(equipment_addon_array.load(file) != 0) return -1;
equipment_addon_array = AAssit.ReadArrayFromBinary<EQUIPMENT_ADDON>(file, ref dwRead);
equipment_addon_array = AAssit.ReadArrayPointerFromBinary<EQUIPMENT_ADDON>(file, ref dwRead);
// if(weapon_major_type_array.load(file) != 0) return -1;
weapon_major_type_array = AAssit.ReadArrayFromBinary<WEAPON_MAJOR_TYPE>(file, ref dwRead);
weapon_major_type_array = AAssit.ReadArrayPointerFromBinary<WEAPON_MAJOR_TYPE>(file, ref dwRead);
// if(weapon_sub_type_array.load(file) != 0) return -1;
weapon_sub_type_array = AAssit.ReadArrayFromBinary<WEAPON_SUB_TYPE>(file, ref dwRead);
weapon_sub_type_array = AAssit.ReadArrayPointerFromBinary<WEAPON_SUB_TYPE>(file, ref dwRead);
// if(weapon_essence_array.load(file) != 0) return -1;
weapon_essence_array = AAssit.ReadArrayFromBinary<WEAPON_ESSENCE>(file, ref dwRead);
weapon_essence_array = AAssit.ReadArrayPointerFromBinary<WEAPON_ESSENCE>(file, ref dwRead);
// if(armor_major_type_array.load(file) != 0) return -1;
armor_major_type_array = AAssit.ReadArrayFromBinary<ARMOR_MAJOR_TYPE>(file, ref dwRead);
armor_major_type_array = AAssit.ReadArrayPointerFromBinary<ARMOR_MAJOR_TYPE>(file, ref dwRead);
// if(armor_sub_type_array.load(file) != 0) return -1;
armor_sub_type_array = AAssit.ReadArrayFromBinary<ARMOR_SUB_TYPE>(file, ref dwRead);
armor_sub_type_array = AAssit.ReadArrayPointerFromBinary<ARMOR_SUB_TYPE>(file, ref dwRead);
// if(armor_essence_array.load(file) != 0) return -1;
armor_essence_array = AAssit.ReadArrayFromBinary<ARMOR_ESSENCE>(file, ref dwRead);
armor_essence_array = AAssit.ReadArrayPointerFromBinary<ARMOR_ESSENCE>(file, ref dwRead);
// if(decoration_major_type_array.load(file) != 0) return -1;
decoration_major_type_array = AAssit.ReadArrayFromBinary<DECORATION_MAJOR_TYPE>(file, ref dwRead);
decoration_major_type_array = AAssit.ReadArrayPointerFromBinary<DECORATION_MAJOR_TYPE>(file, ref dwRead);
// if(decoration_sub_type_array.load(file) != 0) return -1;
decoration_sub_type_array = AAssit.ReadArrayFromBinary<DECORATION_SUB_TYPE>(file, ref dwRead);
decoration_sub_type_array = AAssit.ReadArrayPointerFromBinary<DECORATION_SUB_TYPE>(file, ref dwRead);
// if(decoration_essence_array.load(file) != 0) return -1;
decoration_essence_array = AAssit.ReadArrayFromBinary<DECORATION_ESSENCE>(file, ref dwRead);
decoration_essence_array = AAssit.ReadArrayPointerFromBinary<DECORATION_ESSENCE>(file, ref dwRead);
medicine_major_type_array = AAssit.ReadArrayFromBinary<MEDICINE_MAJOR_TYPE>(file, ref dwRead);
medicine_sub_type_array = AAssit.ReadArrayFromBinary<MEDICINE_SUB_TYPE>(file, ref dwRead);
medicine_essence_array = AAssit.ReadArrayFromBinary<MEDICINE_ESSENCE>(file, ref dwRead);
material_major_type_array = AAssit.ReadArrayFromBinary<MATERIAL_MAJOR_TYPE>(file, ref dwRead);
material_sub_type_array = AAssit.ReadArrayFromBinary<MATERIAL_SUB_TYPE>(file, ref dwRead);
medicine_major_type_array = AAssit.ReadArrayPointerFromBinary<MEDICINE_MAJOR_TYPE>(file, ref dwRead);
medicine_sub_type_array = AAssit.ReadArrayPointerFromBinary<MEDICINE_SUB_TYPE>(file, ref dwRead);
medicine_essence_array = AAssit.ReadArrayPointerFromBinary<MEDICINE_ESSENCE>(file, ref dwRead);
material_major_type_array = AAssit.ReadArrayPointerFromBinary<MATERIAL_MAJOR_TYPE>(file, ref dwRead);
material_sub_type_array = AAssit.ReadArrayPointerFromBinary<MATERIAL_SUB_TYPE>(file, ref dwRead);
material_essence_array = AAssit.ReadArrayFromBinary<MATERIAL_ESSENCE>(file, ref dwRead);
damagerune_sub_type_array = AAssit.ReadArrayFromBinary<DAMAGERUNE_SUB_TYPE>(file, ref dwRead);
damagerune_essence_array = AAssit.ReadArrayFromBinary<DAMAGERUNE_ESSENCE>(file, ref dwRead);
armorrune_sub_type_array = AAssit.ReadArrayFromBinary<ARMORRUNE_SUB_TYPE>(file, ref dwRead);
armorrune_essence_array = AAssit.ReadArrayFromBinary<ARMORRUNE_ESSENCE>(file, ref dwRead);
material_essence_array = AAssit.ReadArrayPointerFromBinary<MATERIAL_ESSENCE>(file, ref dwRead);
damagerune_sub_type_array = AAssit.ReadArrayPointerFromBinary<DAMAGERUNE_SUB_TYPE>(file, ref dwRead);
damagerune_essence_array = AAssit.ReadArrayPointerFromBinary<DAMAGERUNE_ESSENCE>(file, ref dwRead);
armorrune_sub_type_array = AAssit.ReadArrayPointerFromBinary<ARMORRUNE_SUB_TYPE>(file, ref dwRead);
armorrune_essence_array = AAssit.ReadArrayPointerFromBinary<ARMORRUNE_ESSENCE>(file, ref dwRead);
// skip the computer's name of the exporter
int tag = AAssit.GetIntFromFileStream(file, ref dwRead);
AAssit.ReadString(file, ref dwRead, out var result);
t = AAssit.GetIntFromFileStream(file, ref dwRead);
skilltome_sub_type_array = AAssit.ReadArrayFromBinary<SKILLTOME_SUB_TYPE>(file, ref dwRead);
skilltome_essence_array = AAssit.ReadArrayFromBinary<SKILLTOME_ESSENCE>(file, ref dwRead);
flysword_essence_array = AAssit.ReadArrayFromBinary<FLYSWORD_ESSENCE>(file, ref dwRead);
wingmanwing_essence_array = AAssit.ReadArrayFromBinary<WINGMANWING_ESSENCE>(file, ref dwRead);
townscroll_essence_array = AAssit.ReadArrayFromBinary<TOWNSCROLL_ESSENCE>(file, ref dwRead);
skilltome_sub_type_array = AAssit.ReadArrayPointerFromBinary<SKILLTOME_SUB_TYPE>(file, ref dwRead);
skilltome_essence_array = AAssit.ReadArrayPointerFromBinary<SKILLTOME_ESSENCE>(file, ref dwRead);
flysword_essence_array = AAssit.ReadArrayPointerFromBinary<FLYSWORD_ESSENCE>(file, ref dwRead);
wingmanwing_essence_array = AAssit.ReadArrayPointerFromBinary<WINGMANWING_ESSENCE>(file, ref dwRead);
townscroll_essence_array = AAssit.ReadArrayPointerFromBinary<TOWNSCROLL_ESSENCE>(file, ref dwRead);
unionscroll_essence_array = AAssit.ReadArrayFromBinary<UNIONSCROLL_ESSENCE>(file, ref dwRead);
revivescroll_essence_array = AAssit.ReadArrayFromBinary<REVIVESCROLL_ESSENCE>(file, ref dwRead);
element_essence_array = AAssit.ReadArrayFromBinary<ELEMENT_ESSENCE>(file, ref dwRead);
taskmatter_essence_array = AAssit.ReadArrayFromBinary<TASKMATTER_ESSENCE>(file, ref dwRead);
tossmatter_essence_array = AAssit.ReadArrayFromBinary<TOSSMATTER_ESSENCE>(file, ref dwRead);
unionscroll_essence_array = AAssit.ReadArrayPointerFromBinary<UNIONSCROLL_ESSENCE>(file, ref dwRead);
revivescroll_essence_array = AAssit.ReadArrayPointerFromBinary<REVIVESCROLL_ESSENCE>(file, ref dwRead);
element_essence_array = AAssit.ReadArrayPointerFromBinary<ELEMENT_ESSENCE>(file, ref dwRead);
taskmatter_essence_array = AAssit.ReadArrayPointerFromBinary<TASKMATTER_ESSENCE>(file, ref dwRead);
tossmatter_essence_array = AAssit.ReadArrayPointerFromBinary<TOSSMATTER_ESSENCE>(file, ref dwRead);
projectile_type_array = AAssit.ReadArrayFromBinary<PROJECTILE_TYPE>(file, ref dwRead);
projectile_essence_array = AAssit.ReadArrayFromBinary<PROJECTILE_ESSENCE>(file, ref dwRead);
quiver_sub_type_array = AAssit.ReadArrayFromBinary<QUIVER_SUB_TYPE>(file, ref dwRead);
quiver_essence_array = AAssit.ReadArrayFromBinary<QUIVER_ESSENCE>(file, ref dwRead);
stone_sub_type_array = AAssit.ReadArrayFromBinary<STONE_SUB_TYPE>(file, ref dwRead);
projectile_type_array = AAssit.ReadArrayPointerFromBinary<PROJECTILE_TYPE>(file, ref dwRead);
projectile_essence_array = AAssit.ReadArrayPointerFromBinary<PROJECTILE_ESSENCE>(file, ref dwRead);
quiver_sub_type_array = AAssit.ReadArrayPointerFromBinary<QUIVER_SUB_TYPE>(file, ref dwRead);
quiver_essence_array = AAssit.ReadArrayPointerFromBinary<QUIVER_ESSENCE>(file, ref dwRead);
stone_sub_type_array = AAssit.ReadArrayPointerFromBinary<STONE_SUB_TYPE>(file, ref dwRead);
stone_essence_array = AAssit.ReadArrayFromBinary<STONE_ESSENCE>(file, ref dwRead);
monster_addon_array = AAssit.ReadArrayFromBinary<MONSTER_ADDON>(file, ref dwRead);
monster_type_array = AAssit.ReadArrayFromBinary<MONSTER_TYPE>(file, ref dwRead);
monster_essence_array = AAssit.ReadArrayFromBinary<MONSTER_ESSENCE>(file, ref dwRead);
stone_essence_array = AAssit.ReadArrayPointerFromBinary<STONE_ESSENCE>(file, ref dwRead);
monster_addon_array = AAssit.ReadArrayPointerFromBinary<MONSTER_ADDON>(file, ref dwRead);
monster_type_array = AAssit.ReadArrayPointerFromBinary<MONSTER_TYPE>(file, ref dwRead);
monster_essence_array = AAssit.ReadArrayPointerFromBinary<MONSTER_ESSENCE>(file, ref dwRead);
npc_talk_service_array = AAssit.ReadArrayFromBinary<NPC_TALK_SERVICE>(file, ref dwRead);
npc_sell_service_array = AAssit.ReadArrayFromBinary<NPC_SELL_SERVICE>(file, ref dwRead);
npc_buy_service_array = AAssit.ReadArrayFromBinary<NPC_BUY_SERVICE>(file, ref dwRead);
npc_repair_service_array = AAssit.ReadArrayFromBinary<NPC_REPAIR_SERVICE>(file, ref dwRead);
npc_install_service_array = AAssit.ReadArrayFromBinary<NPC_INSTALL_SERVICE>(file, ref dwRead);
npc_uninstall_service_array = AAssit.ReadArrayFromBinary<NPC_UNINSTALL_SERVICE>(file, ref dwRead);
npc_task_in_service_array = AAssit.ReadArrayFromBinary<NPC_TASK_IN_SERVICE>(file, ref dwRead);
npc_task_out_service_array = AAssit.ReadArrayFromBinary<NPC_TASK_OUT_SERVICE>(file, ref dwRead);
npc_task_matter_service_array = AAssit.ReadArrayFromBinary<NPC_TASK_MATTER_SERVICE>(file, ref dwRead);
npc_skill_service_array = AAssit.ReadArrayFromBinary<NPC_SKILL_SERVICE>(file, ref dwRead);
npc_heal_service_array = AAssit.ReadArrayFromBinary<NPC_HEAL_SERVICE>(file, ref dwRead);
npc_transmit_service_array = AAssit.ReadArrayFromBinary<NPC_TRANSMIT_SERVICE>(file, ref dwRead);
npc_talk_service_array = AAssit.ReadArrayPointerFromBinary<NPC_TALK_SERVICE>(file, ref dwRead);
npc_sell_service_array = AAssit.ReadArrayPointerFromBinary<NPC_SELL_SERVICE>(file, ref dwRead);
npc_buy_service_array = AAssit.ReadArrayPointerFromBinary<NPC_BUY_SERVICE>(file, ref dwRead);
npc_repair_service_array = AAssit.ReadArrayPointerFromBinary<NPC_REPAIR_SERVICE>(file, ref dwRead);
npc_install_service_array = AAssit.ReadArrayPointerFromBinary<NPC_INSTALL_SERVICE>(file, ref dwRead);
npc_uninstall_service_array = AAssit.ReadArrayPointerFromBinary<NPC_UNINSTALL_SERVICE>(file, ref dwRead);
npc_task_in_service_array = AAssit.ReadArrayPointerFromBinary<NPC_TASK_IN_SERVICE>(file, ref dwRead);
npc_task_out_service_array = AAssit.ReadArrayPointerFromBinary<NPC_TASK_OUT_SERVICE>(file, ref dwRead);
npc_task_matter_service_array = AAssit.ReadArrayPointerFromBinary<NPC_TASK_MATTER_SERVICE>(file, ref dwRead);
npc_skill_service_array = AAssit.ReadArrayPointerFromBinary<NPC_SKILL_SERVICE>(file, ref dwRead);
npc_heal_service_array = AAssit.ReadArrayPointerFromBinary<NPC_HEAL_SERVICE>(file, ref dwRead);
npc_transmit_service_array = AAssit.ReadArrayPointerFromBinary<NPC_TRANSMIT_SERVICE>(file, ref dwRead);
npc_transport_service_array = AAssit.ReadArrayFromBinary<NPC_TRANSPORT_SERVICE>(file, ref dwRead);
npc_proxy_service_array = AAssit.ReadArrayFromBinary<NPC_PROXY_SERVICE>(file, ref dwRead);
npc_storage_service_array = AAssit.ReadArrayFromBinary<NPC_STORAGE_SERVICE>(file, ref dwRead);
npc_make_service_array = AAssit.ReadArrayFromBinary<NPC_MAKE_SERVICE>(file, ref dwRead);
npc_decompose_service_array = AAssit.ReadArrayFromBinary<NPC_DECOMPOSE_SERVICE>(file, ref dwRead);
npc_transport_service_array = AAssit.ReadArrayPointerFromBinary<NPC_TRANSPORT_SERVICE>(file, ref dwRead);
npc_proxy_service_array = AAssit.ReadArrayPointerFromBinary<NPC_PROXY_SERVICE>(file, ref dwRead);
npc_storage_service_array = AAssit.ReadArrayPointerFromBinary<NPC_STORAGE_SERVICE>(file, ref dwRead);
npc_make_service_array = AAssit.ReadArrayPointerFromBinary<NPC_MAKE_SERVICE>(file, ref dwRead);
npc_decompose_service_array = AAssit.ReadArrayPointerFromBinary<NPC_DECOMPOSE_SERVICE>(file, ref dwRead);
npc_type_array = AAssit.ReadArrayFromBinary<NPC_TYPE>(file, ref dwRead);
npc_essence_array = AAssit.ReadArrayFromBinary<NPC_ESSENCE>(file, ref dwRead);
npc_type_array = AAssit.ReadArrayPointerFromBinary<NPC_TYPE>(file, ref dwRead);
npc_essence_array = AAssit.ReadArrayPointerFromBinary<NPC_ESSENCE>(file, ref dwRead);
uint sz = AAssit.GetUIntFromFileStream(file, ref dwRead);
if (sz <= 0) return -1;
@@ -405,87 +405,87 @@ namespace ModelRenderer.Scripts.GameData
talk_proc_array[i] = tp;
}
face_texture_essence_array = AAssit.ReadArrayFromBinary<FACE_TEXTURE_ESSENCE>(file, ref dwRead);
face_shape_essence_array = AAssit.ReadArrayFromBinary<FACE_SHAPE_ESSENCE>(file, ref dwRead);
face_emotion_type_array = AAssit.ReadArrayFromBinary<FACE_EMOTION_TYPE>(file, ref dwRead);
face_expression_essence_array = AAssit.ReadArrayFromBinary<FACE_EXPRESSION_ESSENCE>(file, ref dwRead);
face_hair_essence_array = AAssit.ReadArrayFromBinary<FACE_HAIR_ESSENCE>(file, ref dwRead);
face_moustache_essence_array = AAssit.ReadArrayFromBinary<FACE_MOUSTACHE_ESSENCE>(file, ref dwRead);
colorpicker_essence_array = AAssit.ReadArrayFromBinary<COLORPICKER_ESSENCE>(file, ref dwRead);
customizedata_essence_array = AAssit.ReadArrayFromBinary<CUSTOMIZEDATA_ESSENCE>(file, ref dwRead);
face_texture_essence_array = AAssit.ReadArrayPointerFromBinary<FACE_TEXTURE_ESSENCE>(file, ref dwRead);
face_shape_essence_array = AAssit.ReadArrayPointerFromBinary<FACE_SHAPE_ESSENCE>(file, ref dwRead);
face_emotion_type_array = AAssit.ReadArrayPointerFromBinary<FACE_EMOTION_TYPE>(file, ref dwRead);
face_expression_essence_array = AAssit.ReadArrayPointerFromBinary<FACE_EXPRESSION_ESSENCE>(file, ref dwRead);
face_hair_essence_array = AAssit.ReadArrayPointerFromBinary<FACE_HAIR_ESSENCE>(file, ref dwRead);
face_moustache_essence_array = AAssit.ReadArrayPointerFromBinary<FACE_MOUSTACHE_ESSENCE>(file, ref dwRead);
colorpicker_essence_array = AAssit.ReadArrayPointerFromBinary<COLORPICKER_ESSENCE>(file, ref dwRead);
customizedata_essence_array = AAssit.ReadArrayPointerFromBinary<CUSTOMIZEDATA_ESSENCE>(file, ref dwRead);
recipe_major_type_array = AAssit.ReadArrayFromBinary<RECIPE_MAJOR_TYPE>(file, ref dwRead);
recipe_sub_type_array = AAssit.ReadArrayFromBinary<RECIPE_SUB_TYPE>(file, ref dwRead);
recipe_essence_array = AAssit.ReadArrayFromBinary<RECIPE_ESSENCE>(file, ref dwRead);
recipe_major_type_array = AAssit.ReadArrayPointerFromBinary<RECIPE_MAJOR_TYPE>(file, ref dwRead);
recipe_sub_type_array = AAssit.ReadArrayPointerFromBinary<RECIPE_SUB_TYPE>(file, ref dwRead);
recipe_essence_array = AAssit.ReadArrayPointerFromBinary<RECIPE_ESSENCE>(file, ref dwRead);
enemy_faction_config_array = AAssit.ReadArrayFromBinary<ENEMY_FACTION_CONFIG>(file, ref dwRead);
character_class_config_array = AAssit.ReadArrayFromBinary<CHARACTER_CLASS_CONFIG>(file, ref dwRead);
param_adjust_config_array = AAssit.ReadArrayFromBinary<PARAM_ADJUST_CONFIG>(file, ref dwRead);
player_action_info_config_array = AAssit.ReadArrayFromBinary<PLAYER_ACTION_INFO_CONFIG>(file, ref dwRead);
taskdice_essence_array = AAssit.ReadArrayFromBinary<TASKDICE_ESSENCE>(file, ref dwRead);
enemy_faction_config_array = AAssit.ReadArrayPointerFromBinary<ENEMY_FACTION_CONFIG>(file, ref dwRead);
character_class_config_array = AAssit.ReadArrayPointerFromBinary<CHARACTER_CLASS_CONFIG>(file, ref dwRead);
param_adjust_config_array = AAssit.ReadArrayPointerFromBinary<PARAM_ADJUST_CONFIG>(file, ref dwRead);
player_action_info_config_array = AAssit.ReadArrayPointerFromBinary<PLAYER_ACTION_INFO_CONFIG>(file, ref dwRead);
taskdice_essence_array = AAssit.ReadArrayPointerFromBinary<TASKDICE_ESSENCE>(file, ref dwRead);
tasknormalmatter_essence_array = AAssit.ReadArrayFromBinary<TASKNORMALMATTER_ESSENCE>(file, ref dwRead);
face_faling_essence_array = AAssit.ReadArrayFromBinary<FACE_FALING_ESSENCE>(file, ref dwRead);
player_levelexp_config_array = AAssit.ReadArrayFromBinary<PLAYER_LEVELEXP_CONFIG>(file, ref dwRead);
mine_type_array = AAssit.ReadArrayFromBinary<MINE_TYPE>(file, ref dwRead);
mine_essence_array = AAssit.ReadArrayFromBinary<MINE_ESSENCE>(file, ref dwRead);
tasknormalmatter_essence_array = AAssit.ReadArrayPointerFromBinary<TASKNORMALMATTER_ESSENCE>(file, ref dwRead);
face_faling_essence_array = AAssit.ReadArrayPointerFromBinary<FACE_FALING_ESSENCE>(file, ref dwRead);
player_levelexp_config_array = AAssit.ReadArrayPointerFromBinary<PLAYER_LEVELEXP_CONFIG>(file, ref dwRead);
mine_type_array = AAssit.ReadArrayPointerFromBinary<MINE_TYPE>(file, ref dwRead);
mine_essence_array = AAssit.ReadArrayPointerFromBinary<MINE_ESSENCE>(file, ref dwRead);
npc_identify_service_array = AAssit.ReadArrayFromBinary<NPC_IDENTIFY_SERVICE>(file, ref dwRead);
fashion_major_type_array = AAssit.ReadArrayFromBinary<FASHION_MAJOR_TYPE>(file, ref dwRead);
fashion_sub_type_array = AAssit.ReadArrayFromBinary<FASHION_SUB_TYPE>(file, ref dwRead);
fashion_essence_array = AAssit.ReadArrayFromBinary<FASHION_ESSENCE>(file, ref dwRead);
npc_identify_service_array = AAssit.ReadArrayPointerFromBinary<NPC_IDENTIFY_SERVICE>(file, ref dwRead);
fashion_major_type_array = AAssit.ReadArrayPointerFromBinary<FASHION_MAJOR_TYPE>(file, ref dwRead);
fashion_sub_type_array = AAssit.ReadArrayPointerFromBinary<FASHION_SUB_TYPE>(file, ref dwRead);
fashion_essence_array = AAssit.ReadArrayPointerFromBinary<FASHION_ESSENCE>(file, ref dwRead);
faceticket_major_type_array = AAssit.ReadArrayFromBinary<FACETICKET_MAJOR_TYPE>(file, ref dwRead);
faceticket_sub_type_array = AAssit.ReadArrayFromBinary<FACETICKET_SUB_TYPE>(file, ref dwRead);
faceticket_essence_array = AAssit.ReadArrayFromBinary<FACETICKET_ESSENCE>(file, ref dwRead);
facepill_major_type_array = AAssit.ReadArrayFromBinary<FACEPILL_MAJOR_TYPE>(file, ref dwRead);
facepill_sub_type_array = AAssit.ReadArrayFromBinary<FACEPILL_SUB_TYPE>(file, ref dwRead);
faceticket_major_type_array = AAssit.ReadArrayPointerFromBinary<FACETICKET_MAJOR_TYPE>(file, ref dwRead);
faceticket_sub_type_array = AAssit.ReadArrayPointerFromBinary<FACETICKET_SUB_TYPE>(file, ref dwRead);
faceticket_essence_array = AAssit.ReadArrayPointerFromBinary<FACETICKET_ESSENCE>(file, ref dwRead);
facepill_major_type_array = AAssit.ReadArrayPointerFromBinary<FACEPILL_MAJOR_TYPE>(file, ref dwRead);
facepill_sub_type_array = AAssit.ReadArrayPointerFromBinary<FACEPILL_SUB_TYPE>(file, ref dwRead);
facepill_essence_array = AAssit.ReadArrayFromBinary<FACEPILL_ESSENCE>(file, ref dwRead);
suite_essence_array = AAssit.ReadArrayFromBinary<SUITE_ESSENCE>(file, ref dwRead);
gm_generator_type_array = AAssit.ReadArrayFromBinary<GM_GENERATOR_TYPE>(file, ref dwRead);
gm_generator_essence_array = AAssit.ReadArrayFromBinary<GM_GENERATOR_ESSENCE>(file, ref dwRead);
pet_type_array = AAssit.ReadArrayFromBinary<PET_TYPE>(file, ref dwRead);
facepill_essence_array = AAssit.ReadArrayPointerFromBinary<FACEPILL_ESSENCE>(file, ref dwRead);
suite_essence_array = AAssit.ReadArrayPointerFromBinary<SUITE_ESSENCE>(file, ref dwRead);
gm_generator_type_array = AAssit.ReadArrayPointerFromBinary<GM_GENERATOR_TYPE>(file, ref dwRead);
gm_generator_essence_array = AAssit.ReadArrayPointerFromBinary<GM_GENERATOR_ESSENCE>(file, ref dwRead);
pet_type_array = AAssit.ReadArrayPointerFromBinary<PET_TYPE>(file, ref dwRead);
pet_essence_array = AAssit.ReadArrayFromBinary<PET_ESSENCE>(file, ref dwRead);
pet_egg_essence_array = AAssit.ReadArrayFromBinary<PET_EGG_ESSENCE>(file, ref dwRead);
pet_food_essence_array = AAssit.ReadArrayFromBinary<PET_FOOD_ESSENCE>(file, ref dwRead);
pet_faceticket_essence_array = AAssit.ReadArrayFromBinary<PET_FACETICKET_ESSENCE>(file, ref dwRead);
fireworks_essence_array = AAssit.ReadArrayFromBinary<FIREWORKS_ESSENCE>(file, ref dwRead);
pet_essence_array = AAssit.ReadArrayPointerFromBinary<PET_ESSENCE>(file, ref dwRead);
pet_egg_essence_array = AAssit.ReadArrayPointerFromBinary<PET_EGG_ESSENCE>(file, ref dwRead);
pet_food_essence_array = AAssit.ReadArrayPointerFromBinary<PET_FOOD_ESSENCE>(file, ref dwRead);
pet_faceticket_essence_array = AAssit.ReadArrayPointerFromBinary<PET_FACETICKET_ESSENCE>(file, ref dwRead);
fireworks_essence_array = AAssit.ReadArrayPointerFromBinary<FIREWORKS_ESSENCE>(file, ref dwRead);
war_tankcallin_essence_array = AAssit.ReadArrayFromBinary<WAR_TANKCALLIN_ESSENCE>(file, ref dwRead);
war_tankcallin_essence_array = AAssit.ReadArrayPointerFromBinary<WAR_TANKCALLIN_ESSENCE>(file, ref dwRead);
tag = AAssit.GetIntFromFileStream(file, ref dwRead);
AAssit.ReadString(file, ref dwRead, out result);
npc_war_towerbuild_service_array = AAssit.ReadArrayFromBinary<NPC_WAR_TOWERBUILD_SERVICE>(file, ref dwRead);
player_secondlevel_config_array = AAssit.ReadArrayFromBinary<PLAYER_SECONDLEVEL_CONFIG>(file, ref dwRead);
npc_resetprop_service_array = AAssit.ReadArrayFromBinary<NPC_RESETPROP_SERVICE>(file, ref dwRead);
npc_petname_service_array = AAssit.ReadArrayFromBinary<NPC_PETNAME_SERVICE>(file, ref dwRead);
npc_war_towerbuild_service_array = AAssit.ReadArrayPointerFromBinary<NPC_WAR_TOWERBUILD_SERVICE>(file, ref dwRead);
player_secondlevel_config_array = AAssit.ReadArrayPointerFromBinary<PLAYER_SECONDLEVEL_CONFIG>(file, ref dwRead);
npc_resetprop_service_array = AAssit.ReadArrayPointerFromBinary<NPC_RESETPROP_SERVICE>(file, ref dwRead);
npc_petname_service_array = AAssit.ReadArrayPointerFromBinary<NPC_PETNAME_SERVICE>(file, ref dwRead);
npc_petlearnskill_service_array = AAssit.ReadArrayFromBinary<NPC_PETLEARNSKILL_SERVICE>(file, ref dwRead);
npc_petforgetskill_service_array = AAssit.ReadArrayFromBinary<NPC_PETFORGETSKILL_SERVICE>(file, ref dwRead);
skillmatter_essence_array = AAssit.ReadArrayFromBinary<SKILLMATTER_ESSENCE>(file, ref dwRead);
refine_ticket_essence_array = AAssit.ReadArrayFromBinary<REFINE_TICKET_ESSENCE>(file, ref dwRead);
destroying_essence_array = AAssit.ReadArrayFromBinary<DESTROYING_ESSENCE>(file, ref dwRead);
npc_petlearnskill_service_array = AAssit.ReadArrayPointerFromBinary<NPC_PETLEARNSKILL_SERVICE>(file, ref dwRead);
npc_petforgetskill_service_array = AAssit.ReadArrayPointerFromBinary<NPC_PETFORGETSKILL_SERVICE>(file, ref dwRead);
skillmatter_essence_array = AAssit.ReadArrayPointerFromBinary<SKILLMATTER_ESSENCE>(file, ref dwRead);
refine_ticket_essence_array = AAssit.ReadArrayPointerFromBinary<REFINE_TICKET_ESSENCE>(file, ref dwRead);
destroying_essence_array = AAssit.ReadArrayPointerFromBinary<DESTROYING_ESSENCE>(file, ref dwRead);
npc_equipbind_service_array = AAssit.ReadArrayFromBinary<NPC_EQUIPBIND_SERVICE>(file, ref dwRead);
npc_equipdestroy_service_array = AAssit.ReadArrayFromBinary<NPC_EQUIPDESTROY_SERVICE>(file, ref dwRead);
npc_equipundestroy_service_array = AAssit.ReadArrayFromBinary<NPC_EQUIPUNDESTROY_SERVICE>(file, ref dwRead);
bible_essence_array = AAssit.ReadArrayFromBinary<BIBLE_ESSENCE>(file, ref dwRead);
speaker_essence_array = AAssit.ReadArrayFromBinary<SPEAKER_ESSENCE>(file, ref dwRead);
npc_equipbind_service_array = AAssit.ReadArrayPointerFromBinary<NPC_EQUIPBIND_SERVICE>(file, ref dwRead);
npc_equipdestroy_service_array = AAssit.ReadArrayPointerFromBinary<NPC_EQUIPDESTROY_SERVICE>(file, ref dwRead);
npc_equipundestroy_service_array = AAssit.ReadArrayPointerFromBinary<NPC_EQUIPUNDESTROY_SERVICE>(file, ref dwRead);
bible_essence_array = AAssit.ReadArrayPointerFromBinary<BIBLE_ESSENCE>(file, ref dwRead);
speaker_essence_array = AAssit.ReadArrayPointerFromBinary<SPEAKER_ESSENCE>(file, ref dwRead);
autohp_essence_array = AAssit.ReadArrayFromBinary<AUTOHP_ESSENCE>(file, ref dwRead);
automp_essence_array = AAssit.ReadArrayFromBinary<AUTOMP_ESSENCE>(file, ref dwRead);
double_exp_essence_array = AAssit.ReadArrayFromBinary<DOUBLE_EXP_ESSENCE>(file, ref dwRead);
transmitscroll_essence_array = AAssit.ReadArrayFromBinary<TRANSMITSCROLL_ESSENCE>(file, ref dwRead);
dye_ticket_essence_array = AAssit.ReadArrayFromBinary<DYE_TICKET_ESSENCE>(file, ref dwRead);
autohp_essence_array = AAssit.ReadArrayPointerFromBinary<AUTOHP_ESSENCE>(file, ref dwRead);
automp_essence_array = AAssit.ReadArrayPointerFromBinary<AUTOMP_ESSENCE>(file, ref dwRead);
double_exp_essence_array = AAssit.ReadArrayPointerFromBinary<DOUBLE_EXP_ESSENCE>(file, ref dwRead);
transmitscroll_essence_array = AAssit.ReadArrayPointerFromBinary<TRANSMITSCROLL_ESSENCE>(file, ref dwRead);
dye_ticket_essence_array = AAssit.ReadArrayPointerFromBinary<DYE_TICKET_ESSENCE>(file, ref dwRead);
goblin_essence_array = AAssit.ReadArrayFromBinary<GOBLIN_ESSENCE>(file, ref dwRead);
goblin_equip_type_array = AAssit.ReadArrayFromBinary<GOBLIN_EQUIP_TYPE>(file, ref dwRead);
goblin_equip_essence_array = AAssit.ReadArrayFromBinary<GOBLIN_EQUIP_ESSENCE>(file, ref dwRead);
goblin_exppill_essence_array = AAssit.ReadArrayFromBinary<GOBLIN_EXPPILL_ESSENCE>(file, ref dwRead);
sell_certificate_essence_array = AAssit.ReadArrayFromBinary<SELL_CERTIFICATE_ESSENCE>(file, ref dwRead);
goblin_essence_array = AAssit.ReadArrayPointerFromBinary<GOBLIN_ESSENCE>(file, ref dwRead);
goblin_equip_type_array = AAssit.ReadArrayPointerFromBinary<GOBLIN_EQUIP_TYPE>(file, ref dwRead);
goblin_equip_essence_array = AAssit.ReadArrayPointerFromBinary<GOBLIN_EQUIP_ESSENCE>(file, ref dwRead);
goblin_exppill_essence_array = AAssit.ReadArrayPointerFromBinary<GOBLIN_EXPPILL_ESSENCE>(file, ref dwRead);
sell_certificate_essence_array = AAssit.ReadArrayPointerFromBinary<SELL_CERTIFICATE_ESSENCE>(file, ref dwRead);
// target_item_essence_array = AAssit.ReadArrayFromBinary<TARGET_ITEM_ESSENCE>(file, ref dwRead);
// look_info_essence_array = AAssit.ReadArrayFromBinary<LOOK_INFO_ESSENCE>(file, ref dwRead);
@@ -0,0 +1,661 @@
using System;
using System.Runtime.InteropServices;
using BrewMonster.Scripts.Task;
namespace PerfectWorld.Scripts.Task
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct ATaskTemplFixedData
{
// 任务id // Task ID
public uint m_ID;
// 任务名称 // Task name
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_TASK_NAME_LEN)]
public ushort[] m_szName;
// 任务署名 // Task signature
[MarshalAs(UnmanagedType.U1)]
public bool m_bHasSign;
// 署名字符串 // Signature string
// skip 4 bytes
public ushort[] m_pszSignature;
// 任务类型 // Task type
public uint m_ulType;
// 时间限制 // Time limit
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
public uint m_ulTimetable;
// 时间方式 // Time method
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_TIMETABLE_SIZE)]
public byte[] m_tmType;
// 发放起始时间 // Distribution start time
// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0)]
[NonSerialized]
public task_tm[] m_tmStart;
// 发放终止时间 // Distribution end time
// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0)]
[NonSerialized]
public task_tm[] m_tmEnd;
// 发放频率 // Distribution frequency
public int m_lAvailFrequency;
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;
// [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_TASKREGION)]
[NonSerialized]
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;
// [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_TASKREGION)]
[NonSerialized]
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;
// [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_TASKREGION)]
[NonSerialized]
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
public uint m_ulDelvNPC;
// Award NPC
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
public uint m_ulChangeKeyCnt;
// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0)]
[NonSerialized]
public int[] m_plChangeKey; // [TASK_AWARD_MAX_CHANGE_VALUE]
// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0)]
[NonSerialized]
public int[] m_plChangeKeyValue;
// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0)]
[NonSerialized]
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)]
[NonSerialized]
public byte[,] m_pszPQExp; // PQ expressions
// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0)]
[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)]
[NonSerialized]
public MONSTERS_CONTRIB[] m_MonstersContrib; // Monster contribution settings // 怪物贡献度设定
// 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;
public uint m_ulGivenCmnCount;
public uint m_ulGivenTskCount;
// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0)]
[NonSerialized]
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;
public task_tm m_tmCharEndTime;
public uint m_ulCharTimeGreaterThan;
// 关联任务 // Related tasks
public uint m_ulPremise_Cotask;
public uint m_ulCoTaskCond;
// 互斥任务 // Mutually exclusive tasks
public uint m_ulMutexTaskCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_MUTEX_TASK_COUNT)]
public uint[] m_ulMutexTasks;
// 生活技能级别 // Life skill levels
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_LIVING_SKILLS)]
public long[] m_lSkillLev;
// 动态任务类型 // Dynamic task type
public byte m_DynTaskType;
// 特殊奖励号,用于运营的活动 // Special award number, used for operational activities
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
public uint m_ulTeamMemsWanted;
// [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 */
public uint m_enumMethod;
public uint m_enumFinishType;
/* 任务方式 */ /* Task methods */
public uint m_ulPlayerWanted;
// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0)]
[NonSerialized]
public PLAYER_WANTED[] m_PlayerWanted;
public uint m_ulMonsterWanted;
// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0)]
[NonSerialized]
public MONSTER_WANTED[] m_MonsterWanted;
public uint m_ulItemsWanted;
// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0)]
[NonSerialized]
public ITEM_WANTED[] m_ItemsWanted;
public uint m_ulGoldWanted;
public int m_iFactionContribWanted;
public int m_iFactionExpContribWanted;
public uint m_ulNPCToProtect;
public uint m_ulProtectTimeLen;
public uint m_ulNPCMoving;
public uint m_ulNPCDestSite;
//public ZONE_VERT m_ReachSiteMin;
//public ZONE_VERT m_ReachSiteMax;
// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0)]
[NonSerialized]
public Task_Region[] m_pReachSite;
public uint m_ulReachSiteCnt;
public uint m_ulReachSiteId;
public uint m_ulWaitTime;
//藏宝图 使用已接任务列表中的m_iUsefulData1存储 // Treasure map Use m_iUsefulData1 in the list of accepted tasks
public enum TREASURE_DISTANCE_LEVEL
{
DISTANCE_FAR_FAR_AWAY,
DISTANCE_FAR,
DISTANCE_MEDIUM,
DISTANCE_NEAR,
DISTANCE_VERY_NEAR,
DISTANCE_NUM,
}
// TREA section
public ZONE_VERT m_TreasureStartZone;
public byte m_ucZonesNumX;
public byte m_ucZonesNumZ;
public byte m_ucZoneSide;
//public ZONE_VERT m_LeaveSiteMin;
//public ZONE_VERT m_LeaveSiteMax;
// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0)]
[NonSerialized]
public Task_Region[] m_pLeaveSite;
public uint m_ulLeaveSiteCnt;
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;
public COMPARE_KEY_VALUE m_Fin2KeyValue;
// 需显示的全局变量表达式 // Global variable expressions to display
public uint m_ulExpCnt;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public byte[,] m_pszExp;
// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
[NonSerialized]
public TASK_EXPRESSION[,] m_pExpArr;
// 需显示的全局变量表达式提示字符串 // Global variable expression prompt strings
public uint m_ulTaskCharCnt;
// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
[NonSerialized]
public ushort[,] m_pTaskChar;
// 变身状态 // Transformation state
public byte m_ucTransformedForm;
// 等级 // Level
public uint m_ulReachLevel;
// 转生次数 // Reincarnation count
public uint m_ulReachReincarnationCount;
// 境界等级 // Realm level
public uint m_ulReachRealmLevel;
public uint m_uiEmotion; // 表情动作 // Emotion action
/* 任务结束后的奖励 */ /* Rewards after task completion */
public uint m_ulAwardType_S;
public uint m_ulAwardType_F;
/* 普通和按每个方式 */ /* Normal and per-method rewards */
[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;
/* 时间比例方式 */ /* Time ratio method */
//TODO: Revert
[NonSerialized]
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;
/* 按获得物比例方式 */ /* Item ratio method */
//TODO: Revert
[NonSerialized]
public AWARD_ITEMS_SCALE m_AwByItems_S;
public uint m_AwByItems_S_ptr;
[NonSerialized]
public AWARD_ITEMS_SCALE m_AwByItems_F;
public uint m_AwByItems_F_ptr;
/* 层次结构 */ /* Hierarchy structure */
public uint m_ulParent;
public uint m_ulPrevSibling;
public uint m_ulNextSibling;
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
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 98da1f5a890d42488e2ef0b4bce1acef
timeCreated: 1761707323
@@ -67,16 +67,21 @@ namespace BrewMonster.Scripts.Task
// fread(pOffs, sizeof(long), tph.item_count, fp);
pOffs = AAssit.ReadArrayFromBinary<uint>(fs, tph.item_count, ref readBytes);
// read File and prepare offset array before loading tasks
pOffs = AAssit.ReadArrayFromBinary<uint>(fs, (int)tph.item_count, ref readBytes);
for (int i = 0; i < tph.item_count; i++)
//Debug.Log((int)tph.item_count);
//BMLogger.Log($" [MH] Task File Lenght: {fs.Length}");
for (int i = 874; i < 875; i++) //TODO: tph.item_count
{
// mvoe file pointer to task offset
fs.Seek(pOffs[i], SeekOrigin.Begin);
BMLogger.Log(" [MH] Loading Task Templ at offset: " + pOffs[i]);
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");
@@ -153,7 +158,7 @@ namespace BrewMonster.Scripts.Task
if (pTask.m_FixedData.m_bSkillTask) m_SkillTaskLst.Add(pTask);
//todo: recheck m_DynTaskType type
if (!string.IsNullOrEmpty(pTask.m_FixedData.m_DynTaskType))
if (pTask.m_FixedData.m_DynTaskType != '\0')
{
if (m_DynTaskMap.TryGetValue(pTask.m_FixedData.m_ID, out ATaskTempl task))
{
@@ -0,0 +1,566 @@
using System;
using System.Runtime.InteropServices;
using BrewMonster.Scripts.Task;
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,109 @@
using System.Runtime.InteropServices;
using BrewMonster.Scripts.Task;
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
@@ -1,10 +1,164 @@
using BrewMonster.Network;
using BrewMonster.Scripts.Player;
using System.Collections.Generic;
using PerfectWorld.Scripts.Task;
using UnityEngine;
namespace BrewMonster.Scripts.Task
{
public class TaskInterfaceConstants
{
// Task Prerequisite Error Code
public const int TASK_PREREQU_FAIL_INDETERMINATE = 1;
public const int TASK_PREREQU_FAIL_NOT_ROOT = 2;
public const int TASK_PREREQU_FAIL_SAME_TASK = 3;
public const int TASK_PREREQU_FAIL_NO_SPACE = 4;
public const int TASK_PREREQU_FAIL_FULL = 5;
public const int TASK_PREREQU_FAIL_CANT_REDO = 6;
public const int TASK_PREREQU_FAIL_BELOW_LEVEL = 7;
public const int TASK_PREREQU_FAIL_ABOVE_LEVEL = 8;
public const int TASK_PREREQU_FAIL_NO_ITEM = 9;
public const int TASK_PREREQU_FAIL_BELOW_REPU = 10;
public const int TASK_PREREQU_FAIL_CLAN = 11;
public const int TASK_PREREQU_FAIL_WRONG_GENDER = 12;
public const int TASK_PREREQU_FAIL_NOT_IN_OCCU = 13;
public const int TASK_PREREQU_FAIL_WRONG_PERIOD = 14;
public const int TASK_PREREQU_FAIL_PREV_TASK = 15;
public const int TASK_PREREQU_FAIL_MAX_RCV = 16;
public const int TASK_PREREQU_FAIL_NO_DEPOSIT = 17;
public const int TASK_PREREQU_FAIL_NO_TASK = 18;
public const int TASK_PREREQU_FAIL_NOT_CAPTAIN = 19;
public const int TASK_PREREQU_FAIL_ILLEGAL_MEM = 20;
public const int TASK_PREREQU_FAIL_WRONG_TIME = 21;
public const int TASK_PREREQU_FAIL_NO_SUCH_SUB = 22;
public const int TASK_PREREQU_FAIL_MUTEX_TASK = 23;
public const int TASK_PREREQU_FAIL_NOT_IN_ZONE = 24;
public const int TASK_PREREQU_FAIL_WRONG_SUB = 25;
public const int TASK_PREREQU_FAIL_OUTOF_DIST = 26;
public const int TASK_PREREQU_FAIL_GIVEN_ITEM = 27;
public const int TASK_PREREQU_FAIL_LIVING_SKILL = 28;
public const int TASK_PREREQU_FAIL_SPECIAL_AWARD = 29;
public const int TASK_PREREQU_FAIL_GM = 30;
public const int TASK_PREREQU_FAIL_GLOBAL_KEYVAL = 31;
public const int TASK_PREREQU_FAIL_SHIELD_USER = 32;
public const int TASK_PREREQU_FAIL_ALREADY_HAS_PQ = 33;
public const int TASK_PREREQU_FAIL_MAX_ACC_CNT = 34;
public const int TASK_PREREQU_FAIL_RMB_NOT_ENOUGH = 35;
public const int TASK_PREREQU_FAIL_NOT_COUPLE = 36;
public const int TASK_PREREQU_FAIL_ERR_CHAR_TIME = 37;
public const int TASK_PREREQU_FAIL_NOT_IVTRSLOTNUM = 38; // version 81
public const int TASK_PREREQU_FAIL_BELOW_FACTION_CONTRIB = 39; // version 87
public const int TASK_PREREQU_FAIL_BELOW_RECORD_TASKS_NUM = 40; // version 91
public const int TASK_PREREQU_FAIL_OVER_RECEIVE_PER_DAY = 41;
public const int TASK_PREREQU_FAIL_TRANSFORM_MASK = 42;
public const int TASK_PREREQU_FAIL_FORCE = 43;
public const int TASK_PREREQU_FAIL_FORCE_REPUTATION = 44;
public const int TASK_PREREQU_FAIL_FORCE_CONTRIBUTION = 45;
public const int TASK_PREREQU_FAIL_EXP = 46;
public const int TASK_PREREQU_FAIL_SP = 47;
public const int TASK_PREREQU_FAIL_FORCE_AL = 48;
public const int TASK_PREREQU_FAIL_WEDDING_OWNER = 49;
public const int TASK_PREREQU_FAIL_CROSSSERVER_NO_ACOUNT_LIMIT = 50;
public const int TASK_PREREQU_FAIL_CROSSSERVER_NO_MARRIAGE = 51;
public const int TASK_PREREQU_FAIL_CROSSSERVER_NO_FORCE = 52;
public const int TASK_PREREQU_FAIL_KING = 53;
public const int TASK_PREREQU_FAIL_IN_TEAM = 54;
public const int TASK_PREREQU_FAIL_TITLE = 55;
public const int TASK_PREREQU_FAIL_HISTORYSTAGE = 56;
public const int TASK_PREREQU_FAIL_NO_GIFTCARD_TASK = 57;
public const int TASK_PREREQU_FAIL_BELOW_REINCARNATION = 57;
public const int TASK_PREREQU_FAIL_ABOVE_REINCARNATION = 58;
public const int TASK_PREREQU_FAIL_BELOW_REALMLEVEL = 59;
public const int TASK_PREREQU_FAIL_ABOVE_REALMLEVEL = 60;
public const int TASK_PREREQU_FAIL_REALM_EXP_FULL = 61;
public const int TASK_PREREQU_FAIL_CARD_COUNT_COLLECTION = 62;
public const int TASK_PREREQU_FAIL_MAX_ROLE_CNT = 63;
public const int TASK_PREREQU_FAIL_CARD_COUNT_RANK = 64;
public const int TASK_PREREQU_FAIL_TASK_FORBID = 65;
public const int TASK_PREREQU_FAIL_NO_NAVIGATE_INSHPAED = 66;
public const int TASK_AWARD_FAIL_GIVEN_ITEM = 150;
public const int TASK_AWARD_FAIL_NEW_TASK = 151;
public const int TASK_AWARD_FAIL_REPUTATION = 152;
public const int TASK_AWARD_FAIL_GLOBAL_KEYVAL = 153;
public const int TASK_AWARD_FAIL_CROSSSERVER_NO_ACOUNT_LIMIT = 154;
public const int TASK_AWARD_FAIL_CROSSSERVER_NO_ACOUNT_STORAGE = 155;
public const int TASK_AWARD_FAIL_CROSSSERVER_NO_DIVORCE = 156;
public const int TASK_AWARD_FAIL_CROSSSERVER_NO_FACTION_RALATED = 157;
public const int TASK_AWARD_FAIL_CROSSSERVER_NO_FORCE_RALATED = 158;
public const int TASK_AWARD_FAIL_CROSSSERVER_NO_DIVIEND = 159;
public const int TASK_AWARD_FAIL_LEVEL_CHECK = 160;
// Task messages
public const int TASK_MSG_NEW = 1;
public const int TASK_MSG_SUCCESS = 2;
public const int TASK_MSG_FAIL = 3;
public const int TASK_ACTIVE_LIST_HEADER_LEN = 8;
public const int TASK_ACTIVE_LIST_MAX_LEN = 175;
public const int TASK_FINISHED_LIST_MAX_LEN = 2040;
public const int TASK_DATA_BUF_MAX_LEN = 32;
public const int TASK_FINISH_TIME_MAX_LEN = 1700;
public const int TASK_FINISH_COUNT_MAX_LEN = 730;
// 库任务 // Library tasks
public const int TASK_MAX_DELIVER_COUNT = 5;
public const int TASK_STORAGE_COUNT = 32;
public const int TASK_STORAGE_LEN = 10;
public const int TASK_STORAGE_WHELL_SCALE = 10000; // 10000.f originally
// 当前激活的任务列表缓冲区大小 // Current active task list buffer size
public const int TASK_ACTIVE_LIST_BUF_SIZE = (TASK_ACTIVE_LIST_MAX_LEN * TASK_DATA_BUF_MAX_LEN + TASK_ACTIVE_LIST_HEADER_LEN);
// 已完成的任务列表缓冲区大小 // Completed task list buffer size
public const int TASK_FINISHED_LIST_BUF_SIZE = 8192;
public const int TASK_FINISHED_LIST_BUF_SIZE_OLD = 4096;
// 任务全局数据大小 // Task global data size
public const int TASK_GLOBAL_DATA_SIZE = 256;
// 任务完成时间 // Task completion time
public const int TASK_FINISH_TIME_LIST_BUF_SIZE = 10240;
//任务完成次数 // Task completion count
public const int TASK_FINISH_COUNT_LIST_BUF_SIZE = 10240;
// 库任务 // Library tasks
public const int TASK_STORAGE_LIST_BUF_SIZE = 1024;
// Masks
public const int TASK_MASK_KILL_MONSTER = 0x00000001;
public const int TASK_MASK_COLLECT_ITEM = 0x00000002;
public const int TASK_MASK_TALK_TO_NPC = 0x00000004;
public const int TASK_MASK_REACH_SITE = 0x00000008;
public const int TASK_MASK_ANSWER_QUESTION = 0x00000010;
public const int TASK_MASK_TINY_GAME = 0x00000020;
public const int TASK_MASK_KILL_PQ_MONSTER = 0x00000040;
public const int TASK_MASK_KILL_PLAYER = 0x00000080;
public const int MAX_MONSTER_WANTED = 3; // 受ActiveTaskEntry大小限制,最大3 // Limited by ActiveTaskEntry size, max 3
public const int MAX_PLAYER_WANTED = MAX_MONSTER_WANTED;
public const int MAX_ITEM_WANTED = 10;
public const int MAX_ITEM_AWARD = 64;
public const int MAX_MONSTER_SUMMONED = 32; // 最大召唤出的怪物数量 // Maximum number of summoned monsters
public const int MAX_OCCUPATIONS = 12; // 职业 // Occupations
public const int TASK_MSG_CHANNEL_LOCAL = 0;
public const int TASK_MSG_CHANNEL_WORLD = 1;
public const int TASK_MSG_CHANNEL_BROADCAST = 9;
public const int TASK_TEAM_RELATION_MARRIAGE = 1;
public const int TASK_AWARD_MAX_CHANGE_VALUE = 255;
public const int TASK_AWARD_MAX_DISPLAY_VALUE = 64;
public const int TASK_AWARD_MAX_DISPLAY_EXP_CNT = 32; // 表达式的个数 // Number of expressions
public const int TASK_AWARD_MAX_DISPLAY_CHAR_LEN = 64; // 表达式的长度 // Length of expression
public const int TASK_WORLD_CONTRIBUTION_SPEND_PER_DAY = 30; // 免费玩家每日消费贡献度上限 // Daily contribution spend cap for free players
}
public class CECTaskInterface : TaskInterface
{
public const int TASK_MAX_DELIVER_COUNT = 5;
@@ -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
@@ -1,5 +1,8 @@
namespace BrewMonster.Scripts.Task
using System.Runtime.InteropServices;
namespace PerfectWorld.Scripts.Task
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct TASK_EXPRESSION
{
public int type;
@@ -9,5 +12,24 @@
{
return (type == src.type && value == src.value);
}
public override bool Equals(object obj)
{
if (obj is TASK_EXPRESSION other)
{
return Equals(other);
}
return false;
}
public static bool operator ==(TASK_EXPRESSION lhs, TASK_EXPRESSION rhs)
{
return lhs.Equals(rhs);
}
public static bool operator !=(TASK_EXPRESSION lhs, TASK_EXPRESSION rhs)
{
return !lhs.Equals(rhs);
}
}
}
@@ -0,0 +1,290 @@
if(m_ID == 33519UL){
// Log all non-pointer properties of ATaskTemplFixedData, one per line
a_LogOutput(1, "[MH] m_ID=%lu", m_ID);
// m_szName skipped as complex char array; name already converted above
a_LogOutput(1, "[MH] m_bHasSign=%d", (int)m_bHasSign);
a_LogOutput(1, "[MH] m_ulType=%lu", m_ulType);
a_LogOutput(1, "[MH] m_ulTimeLimit=%lu", m_ulTimeLimit);
a_LogOutput(1, "[MH] m_bOfflineFail=%d", (int)m_bOfflineFail);
a_LogOutput(1, "[MH] m_bAbsFail=%d", (int)m_bAbsFail);
a_LogOutput(1, "[MH] m_tmAbsFailTime={year=%ld,month=%ld,day=%ld,hour=%ld,min=%ld,wday=%ld}",
(long)m_tmAbsFailTime.year,(long)m_tmAbsFailTime.month,(long)m_tmAbsFailTime.day,(long)m_tmAbsFailTime.hour,(long)m_tmAbsFailTime.min,(long)m_tmAbsFailTime.wday);
a_LogOutput(1, "[MH] m_bItemNotTakeOff=%d", (int)m_bItemNotTakeOff);
a_LogOutput(1, "[MH] m_bAbsTime=%d", (int)m_bAbsTime);
a_LogOutput(1, "[MH] m_ulTimetable=%lu", m_ulTimetable);
{
char buf[1024];
int off = 0;
off += snprintf(buf + off, (size_t)(sizeof(buf) - off), "[");
for (unsigned long i = 0; i < (unsigned long)MAX_TIMETABLE_SIZE; ++i){
off += snprintf(buf + off, (size_t)(sizeof(buf) - off), "%s%d", (i?",":""), (int)m_tmType[i]);
if (off < 0 || off >= (int)sizeof(buf)) break;
}
snprintf(buf + (off<0?0:off), (size_t)((off<0?0:sizeof(buf)-off)), "]");
a_LogOutput(1, "[MH] m_tmType=%s", buf);
}
a_LogOutput(1, "[MH] m_lAvailFrequency=%ld", m_lAvailFrequency);
a_LogOutput(1, "[MH] m_lPeriodLimit=%ld", m_lPeriodLimit);
a_LogOutput(1, "[MH] m_bChooseOne=%d", (int)m_bChooseOne);
a_LogOutput(1, "[MH] m_bRandOne=%d", (int)m_bRandOne);
a_LogOutput(1, "[MH] m_bExeChildInOrder=%d", (int)m_bExeChildInOrder);
a_LogOutput(1, "[MH] m_bParentAlsoFail=%d", (int)m_bParentAlsoFail);
a_LogOutput(1, "[MH] m_bParentAlsoSucc=%d", (int)m_bParentAlsoSucc);
a_LogOutput(1, "[MH] m_bCanGiveUp=%d", (int)m_bCanGiveUp);
a_LogOutput(1, "[MH] m_bCanRedo=%d", (int)m_bCanRedo);
a_LogOutput(1, "[MH] m_bCanRedoAfterFailure=%d", (int)m_bCanRedoAfterFailure);
a_LogOutput(1, "[MH] m_bClearAsGiveUp=%d", (int)m_bClearAsGiveUp);
a_LogOutput(1, "[MH] m_bNeedRecord=%d", (int)m_bNeedRecord);
a_LogOutput(1, "[MH] m_bFailAsPlayerDie=%d", (int)m_bFailAsPlayerDie);
a_LogOutput(1, "[MH] m_ulMaxReceiver=%lu", m_ulMaxReceiver);
a_LogOutput(1, "[MH] m_bDelvInZone=%d", (int)m_bDelvInZone);
a_LogOutput(1, "[MH] m_ulDelvWorld=%lu", m_ulDelvWorld);
a_LogOutput(1, "[MH] m_ulDelvRegionCnt=%lu", m_ulDelvRegionCnt);
a_LogOutput(1, "[MH] m_bEnterRegionFail=%d", (int)m_bEnterRegionFail);
a_LogOutput(1, "[MH] m_ulEnterRegionWorld=%lu", m_ulEnterRegionWorld);
a_LogOutput(1, "[MH] m_ulEnterRegionCnt=%lu", m_ulEnterRegionCnt);
a_LogOutput(1, "[MH] m_bLeaveRegionFail=%d", (int)m_bLeaveRegionFail);
a_LogOutput(1, "[MH] m_ulLeaveRegionWorld=%lu", m_ulLeaveRegionWorld);
a_LogOutput(1, "[MH] m_ulLeaveRegionCnt=%lu", m_ulLeaveRegionCnt);
a_LogOutput(1, "[MH] m_bLeaveForceFail=%d", (int)m_bLeaveForceFail);
a_LogOutput(1, "[MH] m_bTransTo=%d", (int)m_bTransTo);
a_LogOutput(1, "[MH] m_ulTransWldId=%lu", m_ulTransWldId);
a_LogOutput(1, "[MH] m_TransPt={x=%f,y=%f,z=%f}", m_TransPt.x, m_TransPt.y, m_TransPt.z);
a_LogOutput(1, "[MH] m_lMonsCtrl=%ld", m_lMonsCtrl);
a_LogOutput(1, "[MH] m_bTrigCtrl=%d", (int)m_bTrigCtrl);
a_LogOutput(1, "[MH] m_bAutoDeliver=%d", (int)m_bAutoDeliver);
a_LogOutput(1, "[MH] m_bDisplayInExclusiveUI=%d", (int)m_bDisplayInExclusiveUI);
a_LogOutput(1, "[MH] m_bReadyToNotifyServer=%d", (int)m_bReadyToNotifyServer);
a_LogOutput(1, "[MH] m_bUsedInTokenShop=%d", (int)m_bUsedInTokenShop);
a_LogOutput(1, "[MH] m_bDeathTrig=%d", (int)m_bDeathTrig);
a_LogOutput(1, "[MH] m_bClearAcquired=%d", (int)m_bClearAcquired);
a_LogOutput(1, "[MH] m_ulSuitableLevel=%lu", m_ulSuitableLevel);
a_LogOutput(1, "[MH] m_bShowPrompt=%d", (int)m_bShowPrompt);
a_LogOutput(1, "[MH] m_bKeyTask=%d", (int)m_bKeyTask);
a_LogOutput(1, "[MH] m_ulDelvNPC=%lu", m_ulDelvNPC);
a_LogOutput(1, "[MH] m_ulAwardNPC=%lu", m_ulAwardNPC);
a_LogOutput(1, "[MH] m_bSkillTask=%d", (int)m_bSkillTask);
a_LogOutput(1, "[MH] m_bCanSeekOut=%d", (int)m_bCanSeekOut);
a_LogOutput(1, "[MH] m_bShowDirection=%d", (int)m_bShowDirection);
a_LogOutput(1, "[MH] m_bMarriage=%d", (int)m_bMarriage);
a_LogOutput(1, "[MH] m_ulChangeKeyCnt=%lu", m_ulChangeKeyCnt);
a_LogOutput(1, "[MH] m_bSwitchSceneFail=%d", (int)m_bSwitchSceneFail);
a_LogOutput(1, "[MH] m_bHidden=%d", (int)m_bHidden);
a_LogOutput(1, "[MH] m_bDeliverySkill=%d", (int)m_bDeliverySkill);
a_LogOutput(1, "[MH] m_iDeliveredSkillID=%d", m_iDeliveredSkillID);
a_LogOutput(1, "[MH] m_iDeliveredSkillLevel=%d", m_iDeliveredSkillLevel);
a_LogOutput(1, "[MH] m_bShowGfxFinished=%d", (int)m_bShowGfxFinished);
a_LogOutput(1, "[MH] m_bChangePQRanking=%d", (int)m_bChangePQRanking);
a_LogOutput(1, "[MH] m_bCompareItemAndInventory=%d", (int)m_bCompareItemAndInventory);
a_LogOutput(1, "[MH] m_ulInventorySlotNum=%lu", m_ulInventorySlotNum);
a_LogOutput(1, "[MH] m_bPQTask=%d", (int)m_bPQTask);
a_LogOutput(1, "[MH] m_ulPQExpCnt=%lu", m_ulPQExpCnt);
a_LogOutput(1, "[MH] m_bPQSubTask=%d", (int)m_bPQSubTask);
a_LogOutput(1, "[MH] m_bClearContrib=%d", (int)m_bClearContrib);
a_LogOutput(1, "[MH] m_ulMonsterContribCnt=%lu", m_ulMonsterContribCnt);
a_LogOutput(1, "[MH] m_iPremNeedRecordTasksNum=%d", m_iPremNeedRecordTasksNum);
a_LogOutput(1, "[MH] m_bShowByNeedRecordTasksNum=%d", (int)m_bShowByNeedRecordTasksNum);
a_LogOutput(1, "[MH] m_iPremiseFactionContrib=%d", m_iPremiseFactionContrib);
a_LogOutput(1, "[MH] m_bShowByFactionContrib=%d", (int)m_bShowByFactionContrib);
a_LogOutput(1, "[MH] m_bAccountTaskLimit=%d", (int)m_bAccountTaskLimit);
a_LogOutput(1, "[MH] m_bRoleTaskLimit=%d", (int)m_bRoleTaskLimit);
a_LogOutput(1, "[MH] m_ulAccountTaskLimitCnt=%lu", m_ulAccountTaskLimitCnt);
a_LogOutput(1, "[MH] m_bLeaveFactionFail=%d", (int)m_bLeaveFactionFail);
a_LogOutput(1, "[MH] m_bNotIncCntWhenFailed=%d", (int)m_bNotIncCntWhenFailed);
a_LogOutput(1, "[MH] m_bNotClearItemWhenFailed=%d", (int)m_bNotClearItemWhenFailed);
a_LogOutput(1, "[MH] m_bDisplayInTitleTaskUI=%d", (int)m_bDisplayInTitleTaskUI);
a_LogOutput(1, "[MH] m_ucPremiseTransformedForm=%u", (unsigned int)m_ucPremiseTransformedForm);
a_LogOutput(1, "[MH] m_bShowByTransformed=%d", (int)m_bShowByTransformed);
a_LogOutput(1, "[MH] m_ulPremise_Lev_Min=%lu", m_ulPremise_Lev_Min);
a_LogOutput(1, "[MH] m_ulPremise_Lev_Max=%lu", m_ulPremise_Lev_Max);
a_LogOutput(1, "[MH] m_bPremCheckMaxHistoryLevel=%lu", m_bPremCheckMaxHistoryLevel);
a_LogOutput(1, "[MH] m_bShowByLev=%d", (int)m_bShowByLev);
a_LogOutput(1, "[MH] m_bPremCheckReincarnation=%d", (int)m_bPremCheckReincarnation);
a_LogOutput(1, "[MH] m_ulPremReincarnationMin=%lu", m_ulPremReincarnationMin);
a_LogOutput(1, "[MH] m_ulPremReincarnationMax=%lu", m_ulPremReincarnationMax);
a_LogOutput(1, "[MH] m_bShowByReincarnation=%d", (int)m_bShowByReincarnation);
a_LogOutput(1, "[MH] m_bPremCheckRealmLevel=%d", (int)m_bPremCheckRealmLevel);
a_LogOutput(1, "[MH] m_ulPremRealmLevelMin=%lu", m_ulPremRealmLevelMin);
a_LogOutput(1, "[MH] m_ulPremRealmLevelMax=%lu", m_ulPremRealmLevelMax);
a_LogOutput(1, "[MH] m_bPremCheckRealmExpFull=%d", (int)m_bPremCheckRealmExpFull);
a_LogOutput(1, "[MH] m_bShowByRealmLevel=%d", (int)m_bShowByRealmLevel);
a_LogOutput(1, "[MH] m_ulPremItems=%lu", m_ulPremItems);
a_LogOutput(1, "[MH] m_bShowByItems=%d", (int)m_bShowByItems);
a_LogOutput(1, "[MH] m_bPremItemsAnyOne=%d", (int)m_bPremItemsAnyOne);
a_LogOutput(1, "[MH] m_ulGivenItems=%lu", m_ulGivenItems);
a_LogOutput(1, "[MH] m_ulGivenCmnCount=%lu", m_ulGivenCmnCount);
a_LogOutput(1, "[MH] m_ulGivenTskCount=%lu", m_ulGivenTskCount);
a_LogOutput(1, "[MH] m_ulPremise_Deposit=%lu", m_ulPremise_Deposit);
a_LogOutput(1, "[MH] m_bShowByDeposit=%d", (int)m_bShowByDeposit);
a_LogOutput(1, "[MH] m_lPremise_Reputation=%ld", m_lPremise_Reputation);
a_LogOutput(1, "[MH] m_lPremise_RepuMax=%ld", m_lPremise_RepuMax);
a_LogOutput(1, "[MH] m_bShowByRepu=%d", (int)m_bShowByRepu);
a_LogOutput(1, "[MH] m_ulPremise_Task_Count=%lu", m_ulPremise_Task_Count);
{
char buf[1024];
int off = 0;
off += snprintf(buf + off, (size_t)(sizeof(buf) - off), "[");
for (unsigned long i = 0; i < m_ulPremise_Task_Count && i < (unsigned long)MAX_PREM_TASK_COUNT; ++i){
off += snprintf(buf + off, (size_t)(sizeof(buf) - off), "%s%lu", (i?",":""), m_ulPremise_Tasks[i]);
if (off < 0 || off >= (int)sizeof(buf)) break;
}
snprintf(buf + (off<0?0:off), (size_t)((off<0?0:sizeof(buf)-off)), "]");
a_LogOutput(1, "[MH] m_ulPremise_Tasks=%s", buf);
}
a_LogOutput(1, "[MH] m_bShowByPreTask=%d", (int)m_bShowByPreTask);
a_LogOutput(1, "[MH] m_ulPremise_Task_Least_Num=%lu", m_ulPremise_Task_Least_Num);
a_LogOutput(1, "[MH] m_ulPremise_Period=%lu", m_ulPremise_Period);
a_LogOutput(1, "[MH] m_bShowByPeriod=%d", (int)m_bShowByPeriod);
a_LogOutput(1, "[MH] m_ulPremise_Faction=%lu", m_ulPremise_Faction);
a_LogOutput(1, "[MH] m_iPremise_FactionRole=%d", m_iPremise_FactionRole);
a_LogOutput(1, "[MH] m_bShowByFaction=%d", (int)m_bShowByFaction);
a_LogOutput(1, "[MH] m_ulGender=%lu", m_ulGender);
a_LogOutput(1, "[MH] m_bShowByGender=%d", (int)m_bShowByGender);
a_LogOutput(1, "[MH] m_ulOccupations=%lu", m_ulOccupations);
{
char buf[1024];
int off = 0;
off += snprintf(buf + off, (size_t)(sizeof(buf) - off), "[");
for (unsigned long i = 0; i < m_ulOccupations && i < (unsigned long)MAX_OCCUPATIONS; ++i){
off += snprintf(buf + off, (size_t)(sizeof(buf) - off), "%s%lu", (i?",":""), m_Occupations[i]);
if (off < 0 || off >= (int)sizeof(buf)) break;
}
snprintf(buf + (off<0?0:off), (size_t)((off<0?0:sizeof(buf)-off)), "]");
a_LogOutput(1, "[MH] m_Occupations=%s", buf);
}
a_LogOutput(1, "[MH] m_bShowByOccup=%d", (int)m_bShowByOccup);
a_LogOutput(1, "[MH] m_bPremise_Spouse=%d", (int)m_bPremise_Spouse);
a_LogOutput(1, "[MH] m_bShowBySpouse=%d", (int)m_bShowBySpouse);
a_LogOutput(1, "[MH] m_bPremiseWeddingOwner=%d", (int)m_bPremiseWeddingOwner);
a_LogOutput(1, "[MH] m_bShowByWeddingOwner=%d", (int)m_bShowByWeddingOwner);
a_LogOutput(1, "[MH] m_bGM=%d", (int)m_bGM);
a_LogOutput(1, "[MH] m_bShieldUser=%d", (int)m_bShieldUser);
a_LogOutput(1, "[MH] m_bShowByRMB=%d", (int)m_bShowByRMB);
a_LogOutput(1, "[MH] m_ulPremRMBMin=%lu", m_ulPremRMBMin);
a_LogOutput(1, "[MH] m_ulPremRMBMax=%lu", m_ulPremRMBMax);
a_LogOutput(1, "[MH] m_bCharTime=%d", (int)m_bCharTime);
a_LogOutput(1, "[MH] m_bShowByCharTime=%d", (int)m_bShowByCharTime);
a_LogOutput(1, "[MH] m_iCharStartTime=%d", m_iCharStartTime);
a_LogOutput(1, "[MH] m_iCharEndTime=%d", m_iCharEndTime);
a_LogOutput(1, "[MH] m_tmCharEndTime={year=%ld,month=%ld,day=%ld,hour=%ld,min=%ld,wday=%ld}",
(long)m_tmCharEndTime.year,(long)m_tmCharEndTime.month,(long)m_tmCharEndTime.day,(long)m_tmCharEndTime.hour,(long)m_tmCharEndTime.min,(long)m_tmCharEndTime.wday);
a_LogOutput(1, "[MH] m_ulCharTimeGreaterThan=%lu", m_ulCharTimeGreaterThan);
a_LogOutput(1, "[MH] m_ulPremise_Cotask=%lu", m_ulPremise_Cotask);
a_LogOutput(1, "[MH] m_ulCoTaskCond=%lu", m_ulCoTaskCond);
a_LogOutput(1, "[MH] m_ulMutexTaskCount=%lu", m_ulMutexTaskCount);
{
char buf[512];
int off = 0;
off += snprintf(buf + off, (size_t)(sizeof(buf) - off), "[");
for (unsigned long i = 0; i < m_ulMutexTaskCount && i < (unsigned long)MAX_MUTEX_TASK_COUNT; ++i){
off += snprintf(buf + off, (size_t)(sizeof(buf) - off), "%s%lu", (i?",":""), m_ulMutexTasks[i]);
if (off < 0 || off >= (int)sizeof(buf)) break;
}
snprintf(buf + (off<0?0:off), (size_t)((off<0?0:sizeof(buf)-off)), "]");
a_LogOutput(1, "[MH] m_ulMutexTasks=%s", buf);
}
{
char buf[256];
snprintf(buf, sizeof(buf), "[%ld,%ld,%ld,%ld]", (long)m_lSkillLev[0], (long)m_lSkillLev[1], (long)m_lSkillLev[2], (long)m_lSkillLev[3]);
a_LogOutput(1, "[MH] m_lSkillLev=%s", buf);
}
a_LogOutput(1, "[MH] m_DynTaskType=%d", (int)m_DynTaskType);
a_LogOutput(1, "[MH] m_ulSpecialAward=%lu", m_ulSpecialAward);
a_LogOutput(1, "[MH] m_bTeamwork=%d", (int)m_bTeamwork);
a_LogOutput(1, "[MH] m_bRcvByTeam=%d", (int)m_bRcvByTeam);
a_LogOutput(1, "[MH] m_bSharedTask=%d", (int)m_bSharedTask);
a_LogOutput(1, "[MH] m_bSharedAchieved=%d", (int)m_bSharedAchieved);
a_LogOutput(1, "[MH] m_bCheckTeammate=%d", (int)m_bCheckTeammate);
a_LogOutput(1, "[MH] m_fTeammateDist=%f", m_fTeammateDist);
a_LogOutput(1, "[MH] m_bAllFail=%d", (int)m_bAllFail);
a_LogOutput(1, "[MH] m_bCapFail=%d", (int)m_bCapFail);
a_LogOutput(1, "[MH] m_bCapSucc=%d", (int)m_bCapSucc);
a_LogOutput(1, "[MH] m_fSuccDist=%f", m_fSuccDist);
a_LogOutput(1, "[MH] m_bDismAsSelfFail=%d", (int)m_bDismAsSelfFail);
a_LogOutput(1, "[MH] m_bRcvChckMem=%d", (int)m_bRcvChckMem);
a_LogOutput(1, "[MH] m_fRcvMemDist=%f", m_fRcvMemDist);
a_LogOutput(1, "[MH] m_bCntByMemPos=%d", (int)m_bCntByMemPos);
a_LogOutput(1, "[MH] m_fCntMemDist=%f", m_fCntMemDist);
a_LogOutput(1, "[MH] m_bAllSucc=%d", (int)m_bAllSucc);
a_LogOutput(1, "[MH] m_bCoupleOnly=%d", (int)m_bCoupleOnly);
a_LogOutput(1, "[MH] m_bDistinguishedOcc=%d", (int)m_bDistinguishedOcc);
a_LogOutput(1, "[MH] m_ulTeamMemsWanted=%lu", m_ulTeamMemsWanted);
a_LogOutput(1, "[MH] m_bShowByTeam=%d", (int)m_bShowByTeam);
a_LogOutput(1, "[MH] m_bPremNeedComp=%d", (int)m_bPremNeedComp);
a_LogOutput(1, "[MH] m_nPremExp1AndOrExp2=%d", m_nPremExp1AndOrExp2);
a_LogOutput(1, "[MH] m_Prem1KeyValue={lType=%d,lNum=%ld,op=%d,rType=%d,rNum=%ld}", m_Prem1KeyValue.nLeftType, (long)m_Prem1KeyValue.lLeftNum, m_Prem1KeyValue.nCompOper, m_Prem1KeyValue.nRightType, (long)m_Prem1KeyValue.lRightNum);
a_LogOutput(1, "[MH] m_Prem2KeyValue={lType=%d,lNum=%ld,op=%d,rType=%d,rNum=%ld}", m_Prem2KeyValue.nLeftType, (long)m_Prem2KeyValue.lLeftNum, m_Prem2KeyValue.nCompOper, m_Prem2KeyValue.nRightType, (long)m_Prem2KeyValue.lRightNum);
a_LogOutput(1, "[MH] m_bPremCheckForce=%d", (int)m_bPremCheckForce);
a_LogOutput(1, "[MH] m_iPremForce=%d", m_iPremForce);
a_LogOutput(1, "[MH] m_bShowByForce=%d", (int)m_bShowByForce);
a_LogOutput(1, "[MH] m_iPremForceReputation=%d", m_iPremForceReputation);
a_LogOutput(1, "[MH] m_bShowByForceReputation=%d", (int)m_bShowByForceReputation);
a_LogOutput(1, "[MH] m_iPremForceContribution=%d", m_iPremForceContribution);
a_LogOutput(1, "[MH] m_bShowByForceContribution=%d", (int)m_bShowByForceContribution);
a_LogOutput(1, "[MH] m_iPremForceExp=%d", m_iPremForceExp);
a_LogOutput(1, "[MH] m_bShowByForceExp=%d", (int)m_bShowByForceExp);
a_LogOutput(1, "[MH] m_iPremForceSP=%d", m_iPremForceSP);
a_LogOutput(1, "[MH] m_bShowByForceSP=%d", (int)m_bShowByForceSP);
a_LogOutput(1, "[MH] m_iPremForceActivityLevel=%d", m_iPremForceActivityLevel);
a_LogOutput(1, "[MH] m_bShowByForceActivityLevel=%d", (int)m_bShowByForceActivityLevel);
a_LogOutput(1, "[MH] m_bPremIsKing=%d", (int)m_bPremIsKing);
a_LogOutput(1, "[MH] m_bShowByKing=%d", (int)m_bShowByKing);
a_LogOutput(1, "[MH] m_bPremNotInTeam=%d", (int)m_bPremNotInTeam);
a_LogOutput(1, "[MH] m_bShowByNotInTeam=%d", (int)m_bShowByNotInTeam);
a_LogOutput(1, "[MH] m_iPremTitleNumTotal=%lu", m_iPremTitleNumTotal);
a_LogOutput(1, "[MH] m_iPremTitleNumRequired=%lu", m_iPremTitleNumRequired);
a_LogOutput(1, "[MH] m_bShowByTitle=%d", (int)m_bShowByTitle);
{
char buf[128];
snprintf(buf, sizeof(buf), "[%d,%d]", m_iPremHistoryStageIndex[0], m_iPremHistoryStageIndex[1]);
a_LogOutput(1, "[MH] m_iPremHistoryStageIndex=%s", buf);
}
a_LogOutput(1, "[MH] m_bShowByHistoryStage=%d", (int)m_bShowByHistoryStage);
a_LogOutput(1, "[MH] m_ulPremGeneralCardCount=%lu", m_ulPremGeneralCardCount);
a_LogOutput(1, "[MH] m_bShowByGeneralCard=%d", (int)m_bShowByGeneralCard);
a_LogOutput(1, "[MH] m_iPremGeneralCardRank=%d", m_iPremGeneralCardRank);
a_LogOutput(1, "[MH] m_ulPremGeneralCardRankCount=%lu", m_ulPremGeneralCardRankCount);
a_LogOutput(1, "[MH] m_bShowByGeneralCardRank=%d", (int)m_bShowByGeneralCardRank);
a_LogOutput(1, "[MH] m_enumMethod=%lu", m_enumMethod);
a_LogOutput(1, "[MH] m_enumFinishType=%lu", m_enumFinishType);
a_LogOutput(1, "[MH] m_ulPlayerWanted=%lu", m_ulPlayerWanted);
a_LogOutput(1, "[MH] m_ulMonsterWanted=%lu", m_ulMonsterWanted);
a_LogOutput(1, "[MH] m_ulItemsWanted=%lu", m_ulItemsWanted);
a_LogOutput(1, "[MH] m_ulGoldWanted=%lu", m_ulGoldWanted);
a_LogOutput(1, "[MH] m_iFactionContribWanted=%d", m_iFactionContribWanted);
a_LogOutput(1, "[MH] m_iFactionExpContribWanted=%d", m_iFactionExpContribWanted);
a_LogOutput(1, "[MH] m_ulNPCToProtect=%lu", m_ulNPCToProtect);
a_LogOutput(1, "[MH] m_ulProtectTimeLen=%lu", m_ulProtectTimeLen);
a_LogOutput(1, "[MH] m_ulNPCMoving=%lu", m_ulNPCMoving);
a_LogOutput(1, "[MH] m_ulNPCDestSite=%lu", m_ulNPCDestSite);
a_LogOutput(1, "[MH] m_ulReachSiteCnt=%lu", m_ulReachSiteCnt);
a_LogOutput(1, "[MH] m_ulReachSiteId=%lu", m_ulReachSiteId);
a_LogOutput(1, "[MH] m_ulWaitTime=%lu", m_ulWaitTime);
a_LogOutput(1, "[MH] m_TreasureStartZone={x=%f,y=%f,z=%f}", m_TreasureStartZone.x, m_TreasureStartZone.y, m_TreasureStartZone.z);
a_LogOutput(1, "[MH] m_ucZonesNumX=%u", (unsigned int)m_ucZonesNumX);
a_LogOutput(1, "[MH] m_ucZonesNumZ=%u", (unsigned int)m_ucZonesNumZ);
a_LogOutput(1, "[MH] m_ucZoneSide=%u", (unsigned int)m_ucZoneSide);
a_LogOutput(1, "[MH] m_ulLeaveSiteCnt=%lu", m_ulLeaveSiteCnt);
a_LogOutput(1, "[MH] m_ulLeaveSiteId=%lu", m_ulLeaveSiteId);
a_LogOutput(1, "[MH] m_bFinNeedComp=%d", (int)m_bFinNeedComp);
a_LogOutput(1, "[MH] m_nFinExp1AndOrExp2=%d", m_nFinExp1AndOrExp2);
a_LogOutput(1, "[MH] m_Fin1KeyValue={lType=%d,lNum=%ld,op=%d,rType=%d,rNum=%ld}", m_Fin1KeyValue.nLeftType, (long)m_Fin1KeyValue.lLeftNum, m_Fin1KeyValue.nCompOper, m_Fin1KeyValue.nRightType, (long)m_Fin1KeyValue.lRightNum);
a_LogOutput(1, "[MH] m_Fin2KeyValue={lType=%d,lNum=%ld,op=%d,rType=%d,rNum=%ld}", m_Fin2KeyValue.nLeftType, (long)m_Fin2KeyValue.lLeftNum, m_Fin2KeyValue.nCompOper, m_Fin2KeyValue.nRightType, (long)m_Fin2KeyValue.lRightNum);
a_LogOutput(1, "[MH] m_ulExpCnt=%lu", m_ulExpCnt);
a_LogOutput(1, "[MH] m_ulTaskCharCnt=%lu", m_ulTaskCharCnt);
a_LogOutput(1, "[MH] m_ucTransformedForm=%u", (unsigned int)m_ucTransformedForm);
a_LogOutput(1, "[MH] m_ulReachLevel=%lu", m_ulReachLevel);
a_LogOutput(1, "[MH] m_ulReachReincarnationCount=%lu", m_ulReachReincarnationCount);
a_LogOutput(1, "[MH] m_ulReachRealmLevel=%lu", m_ulReachRealmLevel);
a_LogOutput(1, "[MH] m_uiEmotion=%u", (unsigned int)m_uiEmotion);
a_LogOutput(1, "[MH] m_ulAwardType_S=%lu", m_ulAwardType_S);
a_LogOutput(1, "[MH] m_ulAwardType_F=%lu", m_ulAwardType_F);
a_LogOutput(1, "[MH] m_ulParent=%lu", m_ulParent);
a_LogOutput(1, "[MH] m_ulPrevSibling=%lu", m_ulPrevSibling);
a_LogOutput(1, "[MH] m_ulNextSibling=%lu", m_ulNextSibling);
a_LogOutput(1, "[MH] m_ulFirstChild=%lu", m_ulFirstChild);
a_LogOutput(1, "[MH] m_bIsLibraryTask=%d", (int)m_bIsLibraryTask);
a_LogOutput(1, "[MH] m_fLibraryTasksProbability=%f", m_fLibraryTasksProbability);
a_LogOutput(1, "[MH] m_bIsUniqueStorageTask=%d", (int)m_bIsUniqueStorageTask);
a_LogOutput(1, "[MH] m_iWorldContribution=%d", m_iWorldContribution);
}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: b430595362eaf4a248b120d46a7dc5e2
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -3,6 +3,8 @@ using System.Runtime.InteropServices;
using BrewMonster.Scripts.Task;
using UnityEngine;
namespace PerfectWorld.Scripts.Task
{
public class TaskProcess
{
@@ -174,3 +176,4 @@ public class ActiveTaskList
// int GetMaxSimultaneousCount() {return m_uMaxSimultaneousCount ? TASK_MAX_SIMULTANEOUS_COUT : TASK_DEFAULT_MAX_SIMULTANEOUS_COUT;}
// void ExpandMaxSimultaneousCount() {m_uMaxSimultaneousCount = 1;}
};
}
File diff suppressed because it is too large Load Diff
@@ -1,4 +1,9 @@
using BrewMonster;
using System;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using PerfectWorld.Scripts.Task;
using UnityEngine;
@@ -19,6 +24,80 @@ namespace BrewMonster.Scripts.Task
string path = Path.Combine(Application.streamingAssetsPath, "data/tasks.data");
m_pTaskMan.LoadTasksFromPack(path, true);
}
[ContextMenu("Test Size")]
void TestSize()
{
var size = Marshal.SizeOf(typeof(ATaskTemplFixedData));
BMLogger.Log("Size of ATaskTemplFixedData: " + size);
}
[ContextMenu("🧾 Log Struct Field Sizes (ATaskTemplFixedData)")]
private void LogStructFieldSizes()
{
Type structType = typeof(ATaskTemplFixedData);
FieldInfo[] fields = structType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
Debug.Log($"===== Struct: {structType.Name} =====");
foreach (var field in fields)
{
string name = field.Name;
Type fieldType = field.FieldType;
int sizeInBytes = -1;
string note = "";
// 🟢 1. Nếu field có [MarshalAs], lấy SizeConst
var marshalAttr = field.GetCustomAttribute<MarshalAsAttribute>();
if (marshalAttr != null && marshalAttr.SizeConst > 0)
{
int elemSize = GetElementSize(fieldType);
sizeInBytes = elemSize * marshalAttr.SizeConst;
note = $"(ByValArray × {marshalAttr.SizeConst})";
}
else
{
try
{
sizeInBytes = Marshal.SizeOf(fieldType);
}
catch
{
note = "(reference type / variable size)";
}
}
string sizeText = sizeInBytes >= 0 ? $"{sizeInBytes} bytes" : "unknown size";
Debug.Log($"{name,-40} | {fieldType.Name,-25} | {sizeText} {note}");
}
try
{
int total = Marshal.SizeOf(structType);
Debug.Log($"===== Total Struct Size: {total} bytes =====");
}
catch
{
Debug.Log($"⚠️ Struct {structType.Name} contains non-blittable fields; total size unknown.");
}
}
/// <summary>
/// Tính kích thước phần tử cơ bản của mảng blittable
/// </summary>
private int GetElementSize(Type type)
{
if (type.IsArray)
{
Type elemType = type.GetElementType();
if (elemType != null)
{
try { return Marshal.SizeOf(elemType); }
catch { return 1; } // fallback
}
}
return Marshal.SizeOf(type);
}
}
}
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ed55b9311227c0f488154c01c55301d8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: c0d05d66676da0c4d96f2bcba83c7cc8
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 090accfe9d104324c82102bc78156457
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: eb7ac5cca9fce714d99986697f9a5b31
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 0ef53828160078e4fbe4bcc8fe77f9ff
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 501d4db75e7e5b14194d3d712461efdd
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 7d85d3a0fdd9b40439507c98ed85c88e
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: c63d659da0623e748b4291c3e691009c
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: f846a8291c9575f47bed980f961d1c5c
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 8952f1d047c4925478f53c8b82bdf7c7
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 85941260470904640bac2e0775f84e28
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 49850d1c835347848a91823adea32d70
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: b620c7abd86f50146a7d78b114523e21
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: a582d9e37cad02e42892490b875bc744
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: