diff --git a/Assets/PerfectWorld/Prefab/NPC Manager.prefab b/Assets/PerfectWorld/Prefab/NPC Manager.prefab new file mode 100644 index 0000000000..5a19060fad --- /dev/null +++ b/Assets/PerfectWorld/Prefab/NPC Manager.prefab @@ -0,0 +1,442 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &1543847492617740573 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6334829773751692483} + - component: {fileID: 6547720173392539073} + - component: {fileID: 8536791987006931629} + - component: {fileID: 4134555565657198633} + - component: {fileID: 2552605511170143642} + - component: {fileID: 1692684095153756201} + m_Layer: 0 + m_Name: DamageText + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6334829773751692483 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1543847492617740573} + m_LocalRotation: {x: 0.5536698, y: -0.42243594, z: -0.38702753, w: -0.60432386} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 8480017899206466389} + m_Father: {fileID: 8147088653703454787} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 9000} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 1} +--- !u!23 &6547720173392539073 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1543847492617740573} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!114 &8536791987006931629 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1543847492617740573} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9541d86e2fd84c1d9990edf0852d74ab, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: asdasd123123123213213123 + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 2 + m_fontSizeBase: 2 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_ActiveFontFeatures: 6e72656b + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 0 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + _SortingLayer: 0 + _SortingLayerID: 0 + _SortingOrder: 0 + m_hasFontAssetChanged: 0 + m_renderer: {fileID: 6547720173392539073} + m_maskType: 0 +--- !u!114 &4134555565657198633 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1543847492617740573} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1a05efb08a5fbef42b3e8414040b6c33, type: 3} + m_Name: + m_EditorClassIdentifier: + targetCamera: {fileID: 0} + mode: 0 +--- !u!114 &2552605511170143642 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1543847492617740573} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0515aed5525ee47d4b5249804a555471, type: 3} + m_Name: + m_EditorClassIdentifier: + text: {fileID: 8536791987006931629} + ingameIcon: {fileID: 3067997925100767011} +--- !u!114 &1692684095153756201 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1543847492617740573} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3} + m_Name: + m_EditorClassIdentifier: + m_HorizontalFit: 1 + m_VerticalFit: 1 +--- !u!1 &2762109714019950995 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8480017899206466389} + - component: {fileID: 3067997925100767011} + m_Layer: 0 + m_Name: Square + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8480017899206466389 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2762109714019950995} + 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: 6334829773751692483} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: -0.2, y: -0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!212 &3067997925100767011 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2762109714019950995} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 9dfc825aed78fcd4ba02077103263b40, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: 21300000, guid: 0a2f50f2fe381024996b30c94befd165, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 0 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!1 &6052681567744256686 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8147088653703454787} + - component: {fileID: 992389339466371540} + - component: {fileID: 6488498381958245340} + - component: {fileID: 4526882482662561821} + - component: {fileID: 3112717333377324765} + m_Layer: 0 + m_Name: NPC Manager + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &8147088653703454787 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6052681567744256686} + serializedVersion: 2 + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 741.23157, y: -3.0202653, z: 153.50998} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 6334829773751692483} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &992389339466371540 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6052681567744256686} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 87558530baa52164fbafe0b6dc828de0, type: 3} + m_Name: + m_EditorClassIdentifier: + modelPlayerCharacter: {fileID: 0} +--- !u!114 &6488498381958245340 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6052681567744256686} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 92009c5b4b0fd894790865cf674545fa, type: 3} + m_Name: + m_EditorClassIdentifier: + skillStateActionConfig: {fileID: 11400000, guid: 7a26a1c8cf0cc58478b7baa61913020d, type: 2} + m_AttackList: [] +--- !u!114 &4526882482662561821 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6052681567744256686} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: c410036615d7e2f4fb76258c665dc6ee, type: 3} + m_Name: + m_EditorClassIdentifier: + modelNPCList: + - {fileID: 6990335153834195374, guid: 28a9794edd04941a6ba1ab1a6e87bbd4, type: 3} + - {fileID: 4093304155662634189, guid: 70f8fa699f9ed4f88b1c335f2ccbb198, type: 3} + - {fileID: 6811279203144701007, guid: 64b5a0083181a4d30911efb9c3059678, type: 3} + - {fileID: 437287848253420420, guid: 6be116f35d3d446c7b8d3d61ca617690, type: 3} + - {fileID: 1737665070947335222, guid: 7cc56a2fa301a46db92681b17c10d6b0, type: 3} + - {fileID: 1816778744457515645, guid: 4dcc3634bebc24bebb88a7ba3e23753c, type: 3} + - {fileID: 4601171410544804222, guid: bc0279413de8f43fb899a8761a22f4f3, type: 3} + - {fileID: 8898003383210139779, guid: a32fc20843e62442ab1494d8a8e48794, type: 3} + - {fileID: 9064255407888235132, guid: 39e34e0b093c74c65a24bcfa1a655c51, type: 3} + - {fileID: 2903211823832813862, guid: ed84be8c5044746ca895fb75aca9bc66, type: 3} + - {fileID: 287010356842850335, guid: 09a50785f77bc43369476f9ab93a9b3a, type: 3} + - {fileID: 8599254418566033129, guid: 04e8f383637dd42a58a6a23c48c64eb5, type: 3} + - {fileID: 7945738885635973730, guid: 19ef711ad91474765a847a631f5da9ca, type: 3} + - {fileID: 8995620757399750888, guid: 03e5dab5f51374e55904db72229b775e, type: 3} + - {fileID: 5605758169409286178, guid: d865ad4bc902a4a299da74aaba68e9eb, type: 3} + - {fileID: 2657305733640386924, guid: d14e87db729e843a4b31c7b1065ab677, type: 3} + - {fileID: 5676130487765305938, guid: 62555210fd2944f329f43aa25b44d2c4, type: 3} + - {fileID: 4681428346907282479, guid: 47002ca46d55c4938b9315f763d1d66c, type: 3} + - {fileID: 7585364034339110012, guid: b058f8968d5aa4a8f9285fa891b7b9ba, type: 3} + - {fileID: 4491434428197274843, guid: 46453b542df6540ae817c89b1dfff21e, type: 3} + - {fileID: 5062117593937043970, guid: b2aa264cdbd9d4fb18f8df100175f4c3, type: 3} + - {fileID: 8373977607867880534, guid: fd4b330a3588f40a18d44e22798e3ddc, type: 3} + - {fileID: 4118378869440003053, guid: 6858c050d424a416a9a6aed20d93a150, type: 3} + - {fileID: 7231649790395308121, guid: 12e232ba9bff147e3bc0cc208f8b78a0, type: 3} + - {fileID: 2539724145744991562, guid: 0fb08f2ce83384471ac95b41dc602ace, type: 3} + - {fileID: 3742448964403956444, guid: a5922b6b6f63f46e7b047300c07948fa, type: 3} + - {fileID: 919132149155446097, guid: 91928ba4c1a3643b98bfadeb477ec8af, type: 3} + - {fileID: 1821586701514404843, guid: 3e3944509a65042eb8a31cfb74a0edf5, type: 3} + - {fileID: 4373439416244800714, guid: 5e76cb69b081a4673a5816fd9da89533, type: 3} + - {fileID: 6763320176570713132, guid: 576e84b3fd877477eb7f0a424f30d5df, type: 3} + - {fileID: 5552012344809293004, guid: 7daa10b47beb04798927c05cc7148951, type: 3} + - {fileID: 2358403188266590158, guid: c9c25f71f361f43f1aa0510d4f96312d, type: 3} + npcFolder: {fileID: 102900000, guid: 2193743d8dcc4db4792272c0a62fb72d, type: 3} +--- !u!114 &3112717333377324765 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6052681567744256686} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8635fe618431341d796413e99407c5fc, type: 3} + m_Name: + m_EditorClassIdentifier: + floatTextIconPrefab: {fileID: 2552605511170143642} + poolSize: 20 + offset: {x: 0, y: 2, z: 0} + riseDistance: 1.5 + riseDuration: 0.8 + staggerIntervalSeconds: 0.3 diff --git a/Assets/PerfectWorld/Prefab/NPC Manager.prefab.meta b/Assets/PerfectWorld/Prefab/NPC Manager.prefab.meta new file mode 100644 index 0000000000..c1e64e4012 --- /dev/null +++ b/Assets/PerfectWorld/Prefab/NPC Manager.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 598017775c842ef4ab72d8eabe909d6c +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PerfectWorld/Scene/Bootstrap.unity b/Assets/PerfectWorld/Scene/Bootstrap.unity index 03180c279f..b737300a12 100644 --- a/Assets/PerfectWorld/Scene/Bootstrap.unity +++ b/Assets/PerfectWorld/Scene/Bootstrap.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:98acfc6d78af21396b1c3dcadcb4387954e34ff5863aa8a628f4011b26888168 -size 313916 +oid sha256:5caea7b0b45c434cbea3545800922c7604e8773fe7cbcf675b091934c7c39505 +size 306512 diff --git a/Assets/PerfectWorld/ScriptableObjects/General.meta b/Assets/PerfectWorld/ScriptableObjects/General.meta new file mode 100644 index 0000000000..85954f407e --- /dev/null +++ b/Assets/PerfectWorld/ScriptableObjects/General.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 51ffa1643315ae94f8efced3044b5d68 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PerfectWorld/ScriptableObjects/General/skill_state_action.asset b/Assets/PerfectWorld/ScriptableObjects/General/skill_state_action.asset new file mode 100644 index 0000000000..5f91474339 --- /dev/null +++ b/Assets/PerfectWorld/ScriptableObjects/General/skill_state_action.asset @@ -0,0 +1,127 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 922bd889af2211b488dc6019c1022191, type: 3} + m_Name: skill_state_action + m_EditorClassIdentifier: + entries: + - skill: 2244 + state: 117 + beHitAction: "\u88AB\u51FB\u5012_\u901A\u7528" + stayDownAction: "\u762B\u75EA_\u901A\u7528" + - skill: 2245 + state: 117 + beHitAction: "\u88AB\u51FB\u5012_\u901A\u7528" + stayDownAction: "\u762B\u75EA_\u901A\u7528" + - skill: 2236 + state: 117 + beHitAction: "\u88AB\u51FB\u5012_\u901A\u7528" + stayDownAction: "\u762B\u75EA_\u901A\u7528" + - skill: 2237 + state: 117 + beHitAction: "\u88AB\u51FB\u5012_\u901A\u7528" + stayDownAction: "\u762B\u75EA_\u901A\u7528" + - skill: 2374 + state: 117 + beHitAction: "\u88AB\u6311\u8D77_\u901A\u7528" + stayDownAction: "\u762B\u75EA_\u901A\u7528" + - skill: 2375 + state: 117 + beHitAction: "\u88AB\u6311\u8D77_\u901A\u7528" + stayDownAction: "\u762B\u75EA_\u901A\u7528" + - skill: 2554 + state: 117 + beHitAction: "\u88AB\u6311\u8D77_\u901A\u7528" + stayDownAction: "\u762B\u75EA_\u901A\u7528" + - skill: 2568 + state: 117 + beHitAction: "\u88AB\u6311\u8D77_\u901A\u7528" + stayDownAction: "\u88AB\u51FB\u5012_\u901A\u7528" + - skill: 2558 + state: 117 + beHitAction: "\u88AB\u51FB\u5012_\u901A\u7528" + stayDownAction: "\u762B\u75EA_\u901A\u7528" + - skill: 2557 + state: 117 + beHitAction: "\u88AB\u51FB\u5012_\u901A\u7528" + stayDownAction: "\u762B\u75EA_\u901A\u7528" + - skill: 2551 + state: 117 + beHitAction: "\u88AB\u51FB\u5012_\u901A\u7528" + stayDownAction: "\u762B\u75EA_\u901A\u7528" + - skill: 2742 + state: 117 + beHitAction: "\u88AB\u6311\u8D77_\u901A\u7528" + stayDownAction: "\u762B\u75EA_\u901A\u7528" + - skill: 2743 + state: 117 + beHitAction: "\u88AB\u6311\u8D77_\u901A\u7528" + stayDownAction: "\u762B\u75EA_\u901A\u7528" + - skill: 2768 + state: 117 + beHitAction: "\u88AB\u6311\u8D77_\u901A\u7528" + stayDownAction: "\u88AB\u51FB\u5012_\u901A\u7528" + - skill: 2769 + state: 117 + beHitAction: "\u88AB\u6311\u8D77_\u901A\u7528" + stayDownAction: "\u88AB\u51FB\u5012_\u901A\u7528" + - skill: 2750 + state: 117 + beHitAction: "\u88AB\u51FB\u5012_\u901A\u7528" + stayDownAction: "\u762B\u75EA_\u901A\u7528" + - skill: 2751 + state: 117 + beHitAction: "\u88AB\u51FB\u5012_\u901A\u7528" + stayDownAction: "\u762B\u75EA_\u901A\u7528" + - skill: 2748 + state: 117 + beHitAction: "\u88AB\u51FB\u5012_\u901A\u7528" + stayDownAction: "\u762B\u75EA_\u901A\u7528" + - skill: 2749 + state: 117 + beHitAction: "\u88AB\u51FB\u5012_\u901A\u7528" + stayDownAction: "\u762B\u75EA_\u901A\u7528" + - skill: 2736 + state: 117 + beHitAction: "\u88AB\u51FB\u5012_\u901A\u7528" + stayDownAction: "\u762B\u75EA_\u901A\u7528" + - skill: 2737 + state: 117 + beHitAction: "\u88AB\u51FB\u5012_\u901A\u7528" + stayDownAction: "\u762B\u75EA_\u901A\u7528" + - skill: 2905 + state: 117 + beHitAction: "\u88AB\u51FB\u5012_\u901A\u7528" + stayDownAction: "\u762B\u75EA_\u901A\u7528" + - skill: 2906 + state: 117 + beHitAction: "\u88AB\u51FB\u5012_\u901A\u7528" + stayDownAction: "\u762B\u75EA_\u901A\u7528" + - skill: 3284 + state: 117 + beHitAction: "\u88AB\u51FB\u5012_\u901A\u7528" + stayDownAction: "\u762B\u75EA_\u901A\u7528" + - skill: 3285 + state: 117 + beHitAction: "\u88AB\u51FB\u5012_\u901A\u7528" + stayDownAction: "\u762B\u75EA_\u901A\u7528" + - skill: 3286 + state: 117 + beHitAction: "\u88AB\u6311\u8D77_\u901A\u7528" + stayDownAction: "\u762B\u75EA_\u901A\u7528" + - skill: 3287 + state: 117 + beHitAction: "\u88AB\u6311\u8D77_\u901A\u7528" + stayDownAction: "\u762B\u75EA_\u901A\u7528" + - skill: 3212 + state: 117 + beHitAction: "\u88AB\u51FB\u5012_\u901A\u7528" + stayDownAction: "\u762B\u75EA_\u901A\u7528" diff --git a/Assets/PerfectWorld/ScriptableObjects/General/skill_state_action.asset.meta b/Assets/PerfectWorld/ScriptableObjects/General/skill_state_action.asset.meta new file mode 100644 index 0000000000..6a696349ef --- /dev/null +++ b/Assets/PerfectWorld/ScriptableObjects/General/skill_state_action.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7a26a1c8cf0cc58478b7baa61913020d +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PerfectWorld/Scripts/Config.meta b/Assets/PerfectWorld/Scripts/Config.meta new file mode 100644 index 0000000000..bc64df8e4e --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Config.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7e810e737f9dbd34c91dc8ea77c0caad +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PerfectWorld/Scripts/Config/Editor.meta b/Assets/PerfectWorld/Scripts/Config/Editor.meta new file mode 100644 index 0000000000..d1710cf19e --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Config/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 45f90f4f1beb54142ab4507a13118e9b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PerfectWorld/Scripts/Config/Editor/SkillStateActionConfigImporter.cs b/Assets/PerfectWorld/Scripts/Config/Editor/SkillStateActionConfigImporter.cs new file mode 100644 index 0000000000..097af2d1ac --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Config/Editor/SkillStateActionConfigImporter.cs @@ -0,0 +1,237 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using BrewMonster.Config; +using UnityEditor; +using UnityEngine; + +namespace BrewMonster.Config.Editor +{ + public static class SkillStateActionConfigImporter + { + private const string MenuRoot = "PerfectWorld/Skill State Action/"; + + [MenuItem(MenuRoot + "Import TXT Into New Asset…")] + public static void ImportTxtIntoNewAsset() + { + string txtPath = EditorUtility.OpenFilePanel("Import skill_state_action.txt", "", "txt"); + if (string.IsNullOrEmpty(txtPath)) + return; + + string text; + try + { + text = ReadAllTextLegacyPwConfig(txtPath); + } + catch (IOException ex) + { + EditorUtility.DisplayDialog("Import failed", $"Could not read file:\n{ex.Message}", "OK"); + return; + } + + if (!ValidateImportedTxtSource(txtPath, text)) + return; + + var warnings = new List(); + List rows = SkillStateActionTextParser.Parse(text, warnings); + LogWarnings(warnings); + NotifyIfZeroRows(rows.Count); + + string assetPath = EditorUtility.SaveFilePanelInProject( + "Save Skill State Action Config", + "skill_state_action", + "asset", + "Choose asset path under Assets/"); + if (string.IsNullOrEmpty(assetPath)) + return; + + var asset = ScriptableObject.CreateInstance(); + AssetDatabase.CreateAsset(asset, assetPath); + WriteSerializedEntries(asset, rows); + EditorUtility.SetDirty(asset); + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); + EditorUtility.FocusProjectWindow(); + Selection.activeObject = asset; + Debug.Log($"SkillStateActionConfigImporter: wrote {rows.Count} rows to {assetPath}"); + } + + [MenuItem(MenuRoot + "Import TXT Into Selected Asset…", true)] + public static bool ImportTxtIntoSelectedValidate() + { + return Selection.activeObject is SkillStateActionConfig; + } + + [MenuItem(MenuRoot + "Import TXT Into Selected Asset…")] + public static void ImportTxtIntoSelected() + { + if (!(Selection.activeObject is SkillStateActionConfig cfg)) + return; + + string txtPath = EditorUtility.OpenFilePanel("Import skill_state_action.txt", "", "txt"); + if (string.IsNullOrEmpty(txtPath)) + return; + + string text; + try + { + text = ReadAllTextLegacyPwConfig(txtPath); + } + catch (IOException ex) + { + EditorUtility.DisplayDialog("Import failed", $"Could not read file:\n{ex.Message}", "OK"); + return; + } + + if (!ValidateImportedTxtSource(txtPath, text)) + return; + + var warnings = new List(); + List rows = SkillStateActionTextParser.Parse(text, warnings); + LogWarnings(warnings); + NotifyIfZeroRows(rows.Count); + + Undo.RecordObject(cfg, "Import Skill State Action"); + WriteSerializedEntries(cfg, rows); + EditorUtility.SetDirty(cfg); + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); + Debug.Log($"SkillStateActionConfigImporter: replaced {rows.Count} rows on {AssetDatabase.GetAssetPath(cfg)}"); + } + + /// + /// PW client configs are often GBK (Windows code page 936). Reading those bytes as UTF-8 produces mojibake (� / gibberish). + /// After optional UTF-8 BOM: decode as strict UTF-8; if invalid, use GBK — consistent with OctetsStream / globaldataman. + /// + private static string ReadAllTextLegacyPwConfig(string path) + { + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + byte[] bytes = File.ReadAllBytes(path); + int start = 0; + if (bytes.Length >= 3 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) + start = 3; + + int len = bytes.Length - start; + if (len <= 0) + return string.Empty; + + try + { + var utf8Strict = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true); + return utf8Strict.GetString(bytes, start, len); + } + catch (DecoderFallbackException) + { + return Encoding.GetEncoding(936).GetString(bytes, start, len); + } + } + + /// + /// Writes list via SerializedProperty so Unity persists nested structs reliably (Inspector shows Size > 0). + /// + private static void WriteSerializedEntries(SkillStateActionConfig cfg, List rows) + { + SerializedObject so = new SerializedObject(cfg); + SerializedProperty entriesProp = so.FindProperty("entries"); + if (entriesProp == null) + { + Debug.LogError("SkillStateActionConfigImporter: serialized field 'entries' not found — check SkillStateActionConfig."); + return; + } + + entriesProp.ClearArray(); + int n = rows?.Count ?? 0; + entriesProp.arraySize = n; + for (int i = 0; i < n; i++) + { + SerializedProperty elem = entriesProp.GetArrayElementAtIndex(i); + SkillStateActionRow r = rows[i]; + elem.FindPropertyRelative("skill").intValue = r.skill; + elem.FindPropertyRelative("state").intValue = r.state; + elem.FindPropertyRelative("beHitAction").stringValue = r.beHitAction ?? string.Empty; + elem.FindPropertyRelative("stayDownAction").stringValue = r.stayDownAction ?? string.Empty; + } + + so.ApplyModifiedProperties(); + } + + /// + /// Ensure the user picked gameplay config text (skill_state_action.txt), not a Unity YAML .asset/.meta. + /// + private static bool ValidateImportedTxtSource(string path, string text) + { + string ext = Path.GetExtension(path); + if (ext.Equals(".asset", StringComparison.OrdinalIgnoreCase) || + ext.Equals(".meta", StringComparison.OrdinalIgnoreCase)) + { + EditorUtility.DisplayDialog( + "Wrong file — pick skill_state_action.txt", + "You selected a Unity project file (" + ext + "), not the classic PW config.\n\n" + + "Use the plain text table exported from the game/client:\n" + + " skill_state_action.txt\n\n" + + "Each line looks like:\n" + + " skillId,stateId,beHitAction[,stayDownAction]\n\n" + + "Do not choose skill_state_action.asset (that is the ScriptableObject we fill).", + "OK"); + return false; + } + + if (string.IsNullOrEmpty(text)) + { + EditorUtility.DisplayDialog("Import failed", "The chosen file is empty.", "OK"); + return false; + } + + string head = text.Length <= 2048 ? text : text.Substring(0, 2048); + string trimmedHead = head.TrimStart('\uFEFF', ' ', '\t', '\r', '\n'); + if (trimmedHead.StartsWith("%YAML", StringComparison.Ordinal)) + { + EditorUtility.DisplayDialog( + "Wrong file — this is Unity YAML", + "The file begins with %YAML (Unity serialized asset).\n\n" + + "Select skill_state_action.txt instead — the comma-separated gameplay table — not .asset or scene YAML.", + "OK"); + return false; + } + + if (head.IndexOf("m_Script:", StringComparison.Ordinal) >= 0 && + head.IndexOf("fileID:", StringComparison.Ordinal) >= 0) + { + EditorUtility.DisplayDialog( + "Wrong file — Unity ScriptableObject YAML", + "This content looks like a Unity .asset (m_Script / fileID).\n\n" + + "You must pick skill_state_action.txt (plain rows: skillId,stateId,...).\n\n" + + "Tip: copy skill_state_action.txt from client configs or Assets/Resources if you still keep it there.", + "OK"); + return false; + } + + return true; + } + + private static void NotifyIfZeroRows(int count) + { + if (count != 0) + return; + EditorUtility.DisplayDialog( + "Skill State Action import", + "Parsed 0 rows.\n\n" + + "If you meant to import rows, check that you chose skill_state_action.txt, not .asset.\n\n" + + "Open the Console for line warnings.\n\n" + + "Expected per line:\n" + + " skillId,stateId,beHitAction[,stayDownAction]\n" + + "or the same columns separated by TAB.\n\n" + + "First two columns must be integers.", + "OK"); + } + + private static void LogWarnings(List warnings) + { + if (warnings == null || warnings.Count == 0) + return; + foreach (string w in warnings) + Debug.LogWarning($"SkillStateActionConfigImporter: {w}"); + } + } +} diff --git a/Assets/PerfectWorld/Scripts/Config/Editor/SkillStateActionConfigImporter.cs.meta b/Assets/PerfectWorld/Scripts/Config/Editor/SkillStateActionConfigImporter.cs.meta new file mode 100644 index 0000000000..6a5dcef14b --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Config/Editor/SkillStateActionConfigImporter.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: a33fc0453d431914d9015eb9f0d89a63 \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Config/SkillStateActionConfig.cs b/Assets/PerfectWorld/Scripts/Config/SkillStateActionConfig.cs new file mode 100644 index 0000000000..d0bf7e2f48 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Config/SkillStateActionConfig.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.IO; +using UnityEngine; + +namespace BrewMonster.Config +{ + /// One row of skill_state_action.txt: skill id, visible state id, be-hit action, optional stay-down action. + [Serializable] + public struct SkillStateActionRow + { + public int skill; + public int state; + public string beHitAction; + public string stayDownAction; + } + + /// Parses the classic comma-separated skill_state_action table (same rules as legacy client / CECAttacksMan TextAsset loader). + public static class SkillStateActionTextParser + { + /// + /// Strip CSV-style wrapping quotes (Excel export often writes "2244","117",...). + /// Handles doubled-quote escapes inside a quoted field. + /// + private static string UnquoteCsvField(string raw) + { + if (string.IsNullOrEmpty(raw)) + return string.Empty; + + string s = raw.Trim().TrimStart('\uFEFF'); + + while (s.Length >= 2 && s[0] == '"' && s[s.Length - 1] == '"') + { + s = s.Substring(1, s.Length - 2).Replace("\"\"", "\"").Trim(); + } + + // Odd exports / naive splits can leave stray " on one side. + s = s.Trim('"').Trim(); + return s; + } + + public static List Parse(string text, ICollection warnings = null) + { + var rows = new List(); + if (string.IsNullOrEmpty(text)) + return rows; + + // Saved-as-UTF-8-with-BOM breaks int.TryParse on the first column of line 1 (\ufeff123,...). + text = text.TrimStart('\uFEFF'); + + using (var reader = new StringReader(text)) + { + string line; + int lineNum = 0; + while ((line = reader.ReadLine()) != null) + { + lineNum++; + string trimmed = line.TrimStart('\uFEFF').Trim(); + if (trimmed.Length == 0 || trimmed.StartsWith("//") || trimmed.StartsWith("#")) + continue; + + string[] v = trimmed.Split(','); + // Some configs use tabs instead of commas. + if (v.Length < 3) + v = trimmed.Split('\t'); + if (v.Length < 3) + { + warnings?.Add($"Line {lineNum}: need at least 3 comma-separated fields"); + continue; + } + + string s0 = UnquoteCsvField(v[0]); + string s1 = UnquoteCsvField(v[1]); + if (!int.TryParse(s0, System.Globalization.NumberStyles.Integer, + System.Globalization.CultureInfo.InvariantCulture, out int skillId) || + !int.TryParse(s1, System.Globalization.NumberStyles.Integer, + System.Globalization.CultureInfo.InvariantCulture, out int stateId)) + { + warnings?.Add($"Line {lineNum}: invalid skill or state id (got \"{s0}\", \"{s1}\")"); + continue; + } + + string beHit = UnquoteCsvField(v[2]); + string stayDown = v.Length > 3 ? UnquoteCsvField(v[3]) : string.Empty; + + rows.Add(new SkillStateActionRow + { + skill = skillId, + state = stateId, + beHitAction = beHit, + stayDownAction = stayDown + }); + } + } + + return rows; + } + } + + [CreateAssetMenu(fileName = "skill_state_action", menuName = "PerfectWorld/Skill State Action Config")] + public class SkillStateActionConfig : ScriptableObject + { + [SerializeField] private List entries = new List(); + + public IReadOnlyList Entries => entries; + +#if UNITY_EDITOR + /// Editor / tools: replace serialized rows after import. + public void SetEntries(List newEntries) + { + entries = newEntries ?? new List(); + } +#endif + } +} diff --git a/Assets/PerfectWorld/Scripts/Config/SkillStateActionConfig.cs.meta b/Assets/PerfectWorld/Scripts/Config/SkillStateActionConfig.cs.meta new file mode 100644 index 0000000000..cc74701acc --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Config/SkillStateActionConfig.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 922bd889af2211b488dc6019c1022191 \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Managers/CECAttacksMan.cs b/Assets/PerfectWorld/Scripts/Managers/CECAttacksMan.cs index 328005ceeb..0a2d336dbd 100644 --- a/Assets/PerfectWorld/Scripts/Managers/CECAttacksMan.cs +++ b/Assets/PerfectWorld/Scripts/Managers/CECAttacksMan.cs @@ -7,9 +7,9 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices; -using System.Text; using ModelRenderer.Scripts.Common; using BrewMonster.Scripts; +using BrewMonster.Config; using UnityEngine; using Cysharp.Threading.Tasks; @@ -17,6 +17,18 @@ namespace BrewMonster { public class CECAttacksMan : MonoSingleton { + [SerializeField] private SkillStateActionConfig skillStateActionConfig; + + private struct SkillStateActionEntry + { + public int skill; + public int state; + public string beHitAction; + public string stayDownAction; + } + + private readonly List m_SkillStateActionVec = new List(); + private LinkedList m_targets = new LinkedList(); public CECMultiSectionSkillMan m_pMultiSkillGfxComposerMan; protected A3DSkillGfxComposerMan m_pSkillGfxComposerMan; @@ -27,16 +39,20 @@ namespace BrewMonster { base.Awake(); } + protected override void OnDestroy() { m_targets = null; + m_SkillStateActionVec.Clear(); SkillGfxMan.InstanceSub.Dispose(); base.OnDestroy(); } + private void Start() { StartLoad(); } + private async void StartLoad() { SetupAttacksMan(); @@ -50,7 +66,6 @@ namespace BrewMonster } LoadAllSkillGfxAsync(); - } /// @@ -74,7 +89,8 @@ namespace BrewMonster (string flyGFXPath, string hitGrdGFXPath, string hitGFXPath) = ElementSkill.GetAllGFX(skillId); // Pass skillStub to LoadOneComposerAsync / 将技能存根传递给LoadOneComposerAsync - bool loaded = await m_pSkillGfxComposerMan.LoadOneComposerAsync((int)skillId, skillStub, flyGFXPath, hitGrdGFXPath, hitGFXPath); + bool loaded = await m_pSkillGfxComposerMan.LoadOneComposerAsync((int)skillId, skillStub, flyGFXPath, + hitGrdGFXPath, hitGFXPath); if (!loaded) { BMLogger.LogWarning($"CECAttacksMan::LoadSkillGfxOnDemand() - Failed to load GFX for skill {skillId}"); @@ -106,7 +122,8 @@ namespace BrewMonster SkillStub skillStub = SkillStub.GetStub(idSkill); if (skillStub == null) { - BMLogger.LogWarning($"CECAttacksMan::LoadAllSkillGfxAsync() - SkillStub not found for skill {idSkill}"); + BMLogger.LogWarning( + $"CECAttacksMan::LoadAllSkillGfxAsync() - SkillStub not found for skill {idSkill}"); failedCount++; continue; } @@ -115,7 +132,8 @@ namespace BrewMonster // Use await instead of blocking .Result to prevent freezing // Pass skillStub to LoadOneComposerAsync / 将技能存根传递给LoadOneComposerAsync - bool loaded = await m_pSkillGfxComposerMan.LoadOneComposerAsync((int)idSkill, skillStub, flyGFXPath, hitGrdGFXPath, hitGFXPath); + bool loaded = await m_pSkillGfxComposerMan.LoadOneComposerAsync((int)idSkill, skillStub, flyGFXPath, + hitGrdGFXPath, hitGFXPath); if (loaded) loadedCount++; else @@ -128,20 +146,20 @@ namespace BrewMonster } } - BMLogger.Log($"CECAttacksMan::LoadAllSkillGfxAsync() - Complete. Loaded: {loadedCount}, Failed: {failedCount}"); + BMLogger.Log( + $"CECAttacksMan::LoadAllSkillGfxAsync() - Complete. Loaded: {loadedCount}, Failed: {failedCount}"); //TODO: convert this part - /* char szMultiSectionFile[MAX_PATH] = { 0 }; - strcpy(szMultiSectionFile, "configs\\multi_section_skill.txt"); - m_pMultiSkillGfxComposerMan = new CECMultiSectionSkillMan(); - if (!m_pMultiSkillGfxComposerMan || !m_pMultiSkillGfxComposerMan->LoadConfig(szMultiSectionFile)) - { - a_LogOutput(1, "CECAttacksMan::CECAttacksMan(), failed to load multi skill sgc config file [%s]", szMultiSectionFile); - } + m_pMultiSkillGfxComposerMan = new CECMultiSectionSkillMan(); + if (m_pMultiSkillGfxComposerMan == null || !m_pMultiSkillGfxComposerMan.LoadConfig("multi_section_skill")) + { + BMLogger.LogError("CECAttacksMan::CECAttacksMan(), failed to load multi skill sgc config file "); + } - strcpy(szMultiSectionFile, "configs\\skill_state_action.txt"); - if (!LoadSkillStateActionConfig(szMultiSectionFile)) - a_LogOutput(1, "CECAttacksMan::CECAttacksMan(), failed to load multi skill action config file [%s]", szMultiSectionFile);*/ + if (!LoadSkillStateActionConfig()) + BMLogger.LogError( + "CECAttacksMan::LoadSkillStateActionConfig(), failed — assign Skill State Action Config on CECAttacksMan."); } + public void SetupAttacksMan() { m_pSkillGfxComposerMan = new A3DSkillGfxComposerMan(); @@ -149,6 +167,62 @@ namespace BrewMonster uint idSkill = 0; } + /// + /// Loads skill/state → action names into from (parity with C++ CECAttacksMan::LoadSkillStateActionConfig). + /// + public bool LoadSkillStateActionConfig() + { + m_SkillStateActionVec.Clear(); + + SkillStateActionConfig cfg = skillStateActionConfig; + if (cfg == null) + { + BMLogger.LogWarning( + "CECAttacksMan::LoadSkillStateActionConfig(), skillStateActionConfig is not assigned on CECAttacksMan."); + return false; + } + + IReadOnlyList rows = cfg.Entries; + if (rows == null || rows.Count == 0) + { + BMLogger.LogWarning("CECAttacksMan::LoadSkillStateActionConfig(), config has no entries."); + return false; + } + + for (int i = 0; i < rows.Count; i++) + { + SkillStateActionRow r = rows[i]; + m_SkillStateActionVec.Add(new SkillStateActionEntry + { + skill = r.skill, + state = r.state, + beHitAction = r.beHitAction ?? string.Empty, + stayDownAction = r.stayDownAction ?? string.Empty + }); + } + + return true; + } + + public bool GetSkillStateActionName(int skill, int state, out string name1, out string name2) + { + name1 = string.Empty; + name2 = string.Empty; + + for (int i = 0; i < m_SkillStateActionVec.Count; i++) + { + SkillStateActionEntry e = m_SkillStateActionVec[i]; + if (e.skill == skill && e.state == state) + { + name1 = e.beHitAction ?? string.Empty; + name2 = e.stayDownAction ?? string.Empty; + return true; + } + } + + return false; + } + private void Update() { uint dwDeltaTime = (uint)(Time.deltaTime * 1000); @@ -168,6 +242,7 @@ namespace BrewMonster { node.Value.Tick(dwDeltaTime); } + node = next; } @@ -206,6 +281,7 @@ namespace BrewMonster //BMLogger.LogError($"[SKILL_GFX_DEBUG] OnDrawGizmos: Drawing {gizmoCount} gizmo(s)"); } } + SkillGfxGizmoDrawer.DrawGizmos(); } @@ -225,6 +301,7 @@ namespace BrewMonster string fullPath = Path.Combine(Application.streamingAssetsPath, relativePath); return System.IO.File.Exists(fullPath); } + public CECAttackerEvents FindAttackByAttacker(int idHost) { CECAttackerEvents result = new CECAttackerEvents(); @@ -240,30 +317,33 @@ namespace BrewMonster return result; } - public CECAttackEvent AddMeleeAttack(int idHost, int idTarget, int idWeapon, uint dwModifier, int nDamage, int nTimeFly = 10) + public CECAttackEvent AddMeleeAttack(int idHost, int idTarget, int idWeapon, uint dwModifier, int nDamage, + int nTimeFly = 10) { var newEvent = new CECAttackEvent( - this, - idHost, - 0, // idCastTarget - idTarget, - idWeapon, - 0, // idSkill - 0, // nSkillLevel - dwModifier, - nDamage, - 200, // timeToBeFired - nTimeFly // timeToDoDamage - ); + this, + idHost, + 0, // idCastTarget + idTarget, + idWeapon, + 0, // idSkill + 0, // nSkillLevel + dwModifier, + nDamage, + 200, // timeToBeFired + nTimeFly // timeToDoDamage + ); m_targets.AddLast(newEvent); newEvent.UpdateTargetFlag(); return m_targets.Last.Value; } + public A3DSkillGfxComposerMan GetSkillGfxComposerMan() { return m_pSkillGfxComposerMan; } + public bool GetSkillSectionActionSuffix(int skill, int section, out string suffix) { // TODO: Implement multi-section skill logic @@ -277,12 +357,14 @@ namespace BrewMonster return true; } } + suffix = null; return false; } - public CECAttackEvent AddSkillAttack(int idHost, int idCastTarget, int idTarget, int idWeapon, int idSkill, int nSkillLevel, uint dwModifier, int nDamage) - { + public CECAttackEvent AddSkillAttack(int idHost, int idCastTarget, int idTarget, int idWeapon, int idSkill, + int nSkillLevel, uint dwModifier, int nDamage) + { var newEvent = new CECAttackEvent( this, idHost, @@ -293,8 +375,8 @@ namespace BrewMonster nSkillLevel, dwModifier, nDamage, - 200, // timeToBeFired - 1000 // timeToDoDamage + 200, // timeToBeFired + 1000 // timeToDoDamage ); m_targets.AddLast(newEvent); #if UNITY_EDITOR @@ -311,16 +393,15 @@ namespace BrewMonster { m_targets.AddLast(evt); } - - - } + public class TARGET_DATA { public int idTarget; public uint dwModifier; public int nDamage; } + /// /// Manager for multi-section skills /// 多段技能管理器 @@ -334,10 +415,10 @@ namespace BrewMonster [Serializable] public class SectionInfo { - public int skill_id; // 技能ID / Skill ID - public byte section; // 段号 / Section number - public string action_suffix; // 动作后缀 / Action suffix - public A3DSkillGfxComposer pComposer; // 技能特效组合器 / Skill GFX composer + public int skill_id; // 技能ID / Skill ID + public byte section; // 段号 / Section number + public string action_suffix; // 动作后缀 / Action suffix + public A3DSkillGfxComposer pComposer; // 技能特效组合器 / Skill GFX composer public SectionInfo() { @@ -349,7 +430,8 @@ namespace BrewMonster } // 用于多段技能的sgc映射 / Map for multi-section skill SGC files - private readonly Dictionary m_SgcName2ComposerMap = new Dictionary(); + private readonly Dictionary m_SgcName2ComposerMap = + new Dictionary(); // 多段技能组合器列表 / Multi-section skill composer list private readonly List m_MultiSectionSkillComposerVec = new List(); @@ -357,6 +439,7 @@ namespace BrewMonster public CECMultiSectionSkillMan() { } + ~CECMultiSectionSkillMan() { Release(); @@ -424,16 +507,19 @@ namespace BrewMonster /// Target data list / 目标数据列表 /// Is goblin skill / 是否为精灵技能 public void Play(int nSkillID, int section, int nHostID, int nCastTargetID, - List Targets, bool bIsGoblinSkill = false) + List Targets, bool bIsGoblinSkill = false) { - BMLogger.Log($"[SKILL_GFX_FLOW] >>> CECMultiSectionSkillMan.Play called | SkillID: {nSkillID}, Section: {section}, HostID: {nHostID}, CastTargetID: {nCastTargetID}, Targets: {Targets?.Count ?? 0}, IsGoblin: {bIsGoblinSkill}"); - BMLogger.Log($"[SKILL_GFX_FLOW] >>> Searching through {m_MultiSectionSkillComposerVec.Count} multi-section skill entries"); + BMLogger.Log( + $"[SKILL_GFX_FLOW] >>> CECMultiSectionSkillMan.Play called | SkillID: {nSkillID}, Section: {section}, HostID: {nHostID}, CastTargetID: {nCastTargetID}, Targets: {Targets?.Count ?? 0}, IsGoblin: {bIsGoblinSkill}"); + BMLogger.Log( + $"[SKILL_GFX_FLOW] >>> Searching through {m_MultiSectionSkillComposerVec.Count} multi-section skill entries"); foreach (var info in m_MultiSectionSkillComposerVec) { if (nSkillID == info.skill_id && section == info.section && info.pComposer != null) { - BMLogger.Log($"[SKILL_GFX_FLOW] >>> Found matching multi-section skill composer! | ActionSuffix: {info.action_suffix}"); + BMLogger.Log( + $"[SKILL_GFX_FLOW] >>> Found matching multi-section skill composer! | ActionSuffix: {info.action_suffix}"); BMLogger.Log($"[SKILL_GFX_FLOW] >>> Calling multi-section composer.Play"); info.pComposer.Play(nHostID, nCastTargetID, Targets, bIsGoblinSkill); @@ -443,7 +529,8 @@ namespace BrewMonster } } - BMLogger.LogWarning($"[SKILL_GFX_FLOW] >>> No matching multi-section skill composer found for SkillID: {nSkillID}, Section: {section}"); + BMLogger.LogWarning( + $"[SKILL_GFX_FLOW] >>> No matching multi-section skill composer found for SkillID: {nSkillID}, Section: {section}"); } /// @@ -462,6 +549,7 @@ namespace BrewMonster return info.pComposer; } } + return null; } @@ -481,13 +569,14 @@ namespace BrewMonster return info; } } + return null; } } public partial class A3DSkillGfxComposer { - public uint m_dwFlyTime; // 飞行时间 / Fly time in milliseconds + public uint m_dwFlyTime; // 飞行时间 / Fly time in milliseconds private bool m_bTraceTarget; GfxCluster m_FlyCluster; GFX_SKILL_PARAM m_param; @@ -563,27 +652,37 @@ namespace BrewMonster /// 从文件加载组合器 /// public string hitGfxName; + public string flyGfxName; public string hitGrdGfxName; + public async UniTask Load(SkillStub skillStub, string flyGFXPath, string hitGrdGFXPath, string hitGFXPath) { flyGfxName = flyGFXPath; hitGfxName = hitGFXPath; hitGrdGfxName = hitGrdGFXPath; - m_szFlyGfx = string.IsNullOrEmpty(flyGfxName) ? null : await AddressableManager.Instance.LoadPrefabAsync("gfx/" + flyGfxName); - m_szHitGfx = string.IsNullOrEmpty(hitGfxName) ? null : await AddressableManager.Instance.LoadPrefabAsync("gfx/" + hitGfxName); - m_szHitGrndGfx = string.IsNullOrEmpty(hitGrdGfxName) ? null : await AddressableManager.Instance.LoadPrefabAsync("gfx/" + hitGrdGfxName); + m_szFlyGfx = string.IsNullOrEmpty(flyGfxName) + ? null + : await AddressableManager.Instance.LoadPrefabAsync("gfx/" + flyGfxName); + m_szHitGfx = string.IsNullOrEmpty(hitGfxName) + ? null + : await AddressableManager.Instance.LoadPrefabAsync("gfx/" + hitGfxName); + m_szHitGrndGfx = string.IsNullOrEmpty(hitGrdGfxName) + ? null + : await AddressableManager.Instance.LoadPrefabAsync("gfx/" + hitGrdGfxName); // BMLogger.LogError("HoangDev: Load A3DSkillGfxComposer GFX name: " + hitGfxName); if (m_szFlyGfx == null && !string.IsNullOrEmpty(flyGfxName)) { m_szFlyGfx = Resources.Load("GFX/" + "PlaceHolder"); } + if (m_szHitGfx == null && !string.IsNullOrEmpty(hitGfxName)) { m_szHitGfx = Resources.Load("GFX/" + "PlaceHolder"); } + if (m_szHitGrndGfx == null && !string.IsNullOrEmpty(hitGrdGfxName)) { m_szHitGrndGfx = Resources.Load("GFX/" + "PlaceHolder"); @@ -647,6 +746,7 @@ namespace BrewMonster return true; } + // SpawnGFX temp hack REMOVED — GFX spawning now handled by CECSkillGfxEvent state machine // SpawnGFX临时代码已删除 — GFX生成现在由CECSkillGfxEvent状态机处理 /// @@ -687,7 +787,8 @@ namespace BrewMonster } else { - BMLogger.LogWarning($"[SKILL_GFX_DEBUG] Composer.Play: Target {tar.idTarget} is destroyed, skipping"); + BMLogger.LogWarning( + $"[SKILL_GFX_DEBUG] Composer.Play: Target {tar.idTarget} is destroyed, skipping"); } } @@ -716,7 +817,8 @@ namespace BrewMonster // 在添加前验证施法目标是否存在 if (!ValidateTargetExists(nCastTargetID)) { - BMLogger.LogWarning($"[SKILL_GFX_DEBUG] Composer.Play: Cast target {nCastTargetID} is destroyed, skipping"); + BMLogger.LogWarning( + $"[SKILL_GFX_DEBUG] Composer.Play: Cast target {nCastTargetID} is destroyed, skipping"); return; } @@ -726,7 +828,6 @@ namespace BrewMonster AddOneTarget(nCastTargetID, nHostID, szFly, szHit, tar, false, bIsGoblinSkill); } - } /// @@ -765,8 +866,10 @@ namespace BrewMonster return false; } } + return false; } + public void AddOneTarget( int nCastTargetID, int nHostID, @@ -812,6 +915,7 @@ namespace BrewMonster { szFly = null; } + if (m_AttHitMode == GfxAttackMode.enumAttArea) { szHit = null; @@ -843,10 +947,10 @@ namespace BrewMonster bIsGoblinSkill, bReverse ); - } } } + [Serializable] public class CECAttackEvent { @@ -873,11 +977,13 @@ public class CECAttackEvent #if UNITY_EDITOR int debugCounter = 0; // Debug counter to track Tick calls #endif - public CECAttackEvent() { } + public CECAttackEvent() + { + } public CECAttackEvent(CECAttacksMan? pManager, int idHost, int idCastTarget, int idTarget, - int idWeapon, int idSkill, int nSkillLevel, uint dwModifier, - int nDamage, int nTimeToBeFired, int nTimeToDoDamage) + int idWeapon, int idSkill, int nSkillLevel, uint dwModifier, + int nDamage, int nTimeToBeFired, int nTimeToDoDamage) { m_pManager = pManager; m_idHost = idHost; @@ -894,6 +1000,7 @@ public class CECAttackEvent AddTarget(idTarget, dwModifier, nDamage); } + public bool Tick(uint dwDeltaTime) { m_timeLived += dwDeltaTime; @@ -939,14 +1046,18 @@ public class CECAttackEvent return true; } - public void SetSkillSection(int nSection) { m_nSkillSection = nSection; } + + public void SetSkillSection(int nSection) + { + m_nSkillSection = nSection; + } + bool DoFire() { m_bDoFired = true; if (GPDataTypeHelper.ISPLAYERID(m_idHost)) { - if (m_idSkill != 0) { A3DSkillGfxComposer pComposer = null; @@ -988,14 +1099,16 @@ public class CECAttackEvent } } - if (pComposer != null && pComposer.m_dwFlyTime == 0) // 技能gfx没有飞行实际,则马上头顶冒字 / Skill has no fly time, show damage immediately + if (pComposer != null && + pComposer.m_dwFlyTime == 0) // 技能gfx没有飞行实际,则马上头顶冒字 / Skill has no fly time, show damage immediately { m_timeToDoDamage = 1; } else { // now we estimated a time to do damage / 现在估算伤害时间 - if (m_targets.Count > 0 && GetPosByID(m_idHost, out Vector3 vecHost) && GetPosByID(m_targets[0].idTarget, out Vector3 vecTarget)) + if (m_targets.Count > 0 && GetPosByID(m_idHost, out Vector3 vecHost) && + GetPosByID(m_targets[0].idTarget, out Vector3 vecTarget)) { float distance = (vecHost - vecTarget).magnitude; m_timeToDoDamage = (uint)Mathf.Max(distance / 20.0f * 1000.0f, 10.0f); @@ -1004,7 +1117,6 @@ public class CECAttackEvent { } } - } else if (m_idWeapon != 0) { @@ -1014,7 +1126,8 @@ public class CECAttackEvent // using weapon gfx / 使用武器特效 DATA_TYPE dt = DATA_TYPE.DT_INVALID; - var pData = ElementDataManProvider.GetElementDataMan().get_data_ptr((uint)m_idWeapon, ID_SPACE.ID_SPACE_ESSENCE, ref dt); + var pData = ElementDataManProvider.GetElementDataMan() + .get_data_ptr((uint)m_idWeapon, ID_SPACE.ID_SPACE_ESSENCE, ref dt); if (dt == DATA_TYPE.DT_PROJECTILE_ESSENCE) { @@ -1028,14 +1141,16 @@ public class CECAttackEvent szHitGFX = ByteToStringUtils.ByteArrayToCP936String(pProjectile.file_hitgfx); - BMLogger.Log($"{ByteToStringUtils.UshortArrayToUnicodeString(pProjectile.name)} Use hit effect: {szHitGFX}"); + BMLogger.Log( + $"{ByteToStringUtils.UshortArrayToUnicodeString(pProjectile.name)} Use hit effect: {szHitGFX}"); } else if (dt == DATA_TYPE.DT_WEAPON_ESSENCE) { // 近程物理攻击,使用武器的效果 / Melee physical attack, use weapon effects WEAPON_ESSENCE pWeapon = (WEAPON_ESSENCE)pData; DATA_TYPE dtSub = DATA_TYPE.DT_INVALID; - var pWeaponTypeData = ElementDataManProvider.GetElementDataMan().get_data_ptr(pWeapon.id_sub_type, ID_SPACE.ID_SPACE_ESSENCE, ref dtSub); + var pWeaponTypeData = ElementDataManProvider.GetElementDataMan() + .get_data_ptr(pWeapon.id_sub_type, ID_SPACE.ID_SPACE_ESSENCE, ref dtSub); WEAPON_SUB_TYPE pWeaponType = (WEAPON_SUB_TYPE)pWeaponTypeData; // szflyGFX = null; @@ -1044,7 +1159,8 @@ public class CECAttackEvent szHitGFX = ByteToStringUtils.ByteArrayToCP936String(pWeaponType.file_hitgfx); - BMLogger.Log($"{ByteToStringUtils.UshortArrayToUnicodeString(pWeapon.name)} Use hit effect: {szHitGFX}"); + BMLogger.Log( + $"{ByteToStringUtils.UshortArrayToUnicodeString(pWeapon.name)} Use hit effect: {szHitGFX}"); } bool bHideFlyGfx = false; // TODO: !CECOptimize.Instance.GetGFX().CanShowFly(m_idHost); @@ -1054,13 +1170,14 @@ public class CECAttackEvent { TARGET_DATA data = m_targets[i]; - string pszflyGFX = "";//szflyGFX?.ToLower(); - string pszHitGFX = "";//szHitGFX?.ToLower(); + string pszflyGFX = ""; //szflyGFX?.ToLower(); + string pszHitGFX = ""; //szHitGFX?.ToLower(); if (!string.IsNullOrEmpty(szflyGFX)) { pszflyGFX = szflyGFX.ToLower().Replace("\\", "/"); } + if (!string.IsNullOrEmpty(szHitGFX)) { pszHitGFX = szHitGFX.ToLower().Replace("\\", "/"); @@ -1092,7 +1209,8 @@ public class CECAttackEvent // without weapon / 没有武器 // 使用拳套类的击中效果 / Use fist/glove hit effects DATA_TYPE dt = DATA_TYPE.DT_INVALID; - var pData = ElementDataManProvider.GetElementDataMan().get_data_ptr(183, ID_SPACE.ID_SPACE_ESSENCE, ref dt); + var pData = ElementDataManProvider.GetElementDataMan() + .get_data_ptr(183, ID_SPACE.ID_SPACE_ESSENCE, ref dt); WEAPON_SUB_TYPE pWeaponType = (WEAPON_SUB_TYPE)pData; bool bHideHitGfx = false; // TODO: !CECOptimize.Instance.GetGFX().CanShowHit(m_idHost); @@ -1130,7 +1248,6 @@ public class CECAttackEvent } else if (GPDataTypeHelper.ISNPCID(m_idHost)) { - if (m_idSkill != 0) { A3DSkillGfxComposer pComposer = null; @@ -1155,14 +1272,16 @@ public class CECAttackEvent } } - if (pComposer != null && pComposer.m_dwFlyTime == 0) // 技能没有飞行时间,则直接头顶冒字 / Skill has no fly time, show damage immediately + if (pComposer != null && + pComposer.m_dwFlyTime == 0) // 技能没有飞行时间,则直接头顶冒字 / Skill has no fly time, show damage immediately { m_timeToDoDamage = 1; } else { // now we estimated a time to do damage / 现在估算伤害时间 - if (m_targets.Count > 0 && GetPosByID(m_idHost, out Vector3 vecHost) && GetPosByID(m_targets[0].idTarget, out Vector3 vecTarget)) + if (m_targets.Count > 0 && GetPosByID(m_idHost, out Vector3 vecHost) && + GetPosByID(m_targets[0].idTarget, out Vector3 vecTarget)) { m_timeToDoDamage = (uint)Mathf.Max((vecHost - vecTarget).magnitude / 20.0f * 1000.0f, 10.0f); } @@ -1312,7 +1431,6 @@ public class CECAttackEvent } else if (GPDataTypeHelper.ISPLAYERID(idTarget)) { - CECPlayer pPlayer = EC_ManMessageMono.Instance.GetECManPlayer.GetPlayer(idTarget); //BMLogger.LogError("HoangDev: CECPlayer pPlayer = " + pPlayer ); @@ -1352,6 +1470,7 @@ public class CECAttackEvent }); return true; } + public bool UpdateTargetFlag() { int nNumTargets = m_targets.Count; @@ -1363,6 +1482,7 @@ public class CECAttackEvent return true; } } + public class CECAttackerEvents { private readonly List m_list = new List(); @@ -1383,6 +1503,7 @@ public class CECAttackerEvents if (evt.m_idSkill == idSkill && evt.m_nSkillSection == nSkillSection) return evt; } + return null; } @@ -1395,6 +1516,7 @@ public class CECAttackerEvents BMLogger.Log($"[SKILL_GFX_FLOW] Signaling event | SkillID: {evt.m_idSkill}, HostID: {evt.m_idHost}"); evt.m_bSignaled = true; } + m_list.Clear(); } @@ -1403,39 +1525,42 @@ public class CECAttackerEvents return !events.IsEmpty(); } } + public enum MOD { - MOD_PHYSIC_ATTACK_RUNE = 0x0001, // ÎïÀí¹¥»÷ÓÅ»¯·ûÉúЧ - MOD_MAGIC_ATTACK_RUNE = 0x0002, // ·¨Êõ¹¥»÷ÓÅ»¯·ûÉúЧ - MOD_PHYSIC_DEFENCE_RUNE = 0x0004, // ÎïÀí·ÀÓùÓÅ»¯·ûÉúЧ - MOD_MAGIC_DEFENCE_RUNE = 0x0008, // ·¨Êõ·ÀÓùÓÅ»¯·ûÉúЧ - MOD_CRITICAL_STRIKE = 0x0010, // ±¬»÷ - MOD_RETORT = 0x0020, // ·´Õð - MOD_NULLITY = 0x0040, // ÎÞЧ¹¥»÷ - MOD_IMMUNE = 0x0080, // ÃâÒßÁ˴˴ι¥»÷£¬ÓÅÏȼ¶¸ßÓÚÎÞЧ - MOD_ENCHANT_FAILED = 0x0100, // enchant ʧ°Ü - MOD_SUCCESS = 0x0200, // ³É¹¦ - MOD_DODGE_DAMAGE = 0x0400, // É˺¦¶ãÉÁ - MOD_DODGE_DEBUFF = 0x0800, // ״̬¶ãÉÁ - MOD_ATTACK_AURA = 0x1000, // ¹â»·¹¥»÷ - MOD_REBOUND = 0x2000, // ·´µ¯ - MOD_BEAT_BACK = 0x4000, // ·´»÷ + MOD_PHYSIC_ATTACK_RUNE = 0x0001, // ÎïÀí¹¥»÷ÓÅ»¯·ûÉúЧ + MOD_MAGIC_ATTACK_RUNE = 0x0002, // ·¨Êõ¹¥»÷ÓÅ»¯·ûÉúЧ + MOD_PHYSIC_DEFENCE_RUNE = 0x0004, // ÎïÀí·ÀÓùÓÅ»¯·ûÉúЧ + MOD_MAGIC_DEFENCE_RUNE = 0x0008, // ·¨Êõ·ÀÓùÓÅ»¯·ûÉúЧ + MOD_CRITICAL_STRIKE = 0x0010, // ±¬»÷ + MOD_RETORT = 0x0020, // ·´Õð + MOD_NULLITY = 0x0040, // ÎÞЧ¹¥»÷ + MOD_IMMUNE = 0x0080, // ÃâÒßÁ˴˴ι¥»÷£¬ÓÅÏȼ¶¸ßÓÚÎÞЧ + MOD_ENCHANT_FAILED = 0x0100, // enchant ʧ°Ü + MOD_SUCCESS = 0x0200, // ³É¹¦ + MOD_DODGE_DAMAGE = 0x0400, // É˺¦¶ãÉÁ + MOD_DODGE_DEBUFF = 0x0800, // ״̬¶ãÉÁ + MOD_ATTACK_AURA = 0x1000, // ¹â»·¹¥»÷ + MOD_REBOUND = 0x2000, // ·´µ¯ + MOD_BEAT_BACK = 0x4000, // ·´»÷ }; + public enum GfxMoveMode { - enumLinearMove = 0, // Linear - enumParabolicMove, // Parabolic - enumMissileMove, // Missile - enumMeteoricMove, // Meteoric (shooting star) - enumHelixMove, // Helix (spiral) - enumCurvedMove, // Curved - enumAccMove, // Accelerated - enumOnTarget, // Targeted - enumLink, // Linked - enumRandMove, // Random movement + enumLinearMove = 0, // Linear + enumParabolicMove, // Parabolic + enumMissileMove, // Missile + enumMeteoricMove, // Meteoric (shooting star) + enumHelixMove, // Helix (spiral) + enumCurvedMove, // Curved + enumAccMove, // Accelerated + enumOnTarget, // Targeted + enumLink, // Linked + enumRandMove, // Random movement enumMoveModeNum }; + public enum GfxTargetMode { enumHostToTarget = 0, @@ -1450,6 +1575,7 @@ public enum GfxTargetMode enumTargetLinkHost, enumTargetModeNum }; + public enum GfxAttackMode { enumAttPoint, @@ -1462,6 +1588,7 @@ public struct GfxCluster public uint m_ulCount; public uint m_dwInterv; }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct GFX_SKILL_PARAM { @@ -1474,16 +1601,14 @@ public struct GFX_SKILL_PARAM [StructLayout(LayoutKind.Explicit)] public struct ValueUnion { - [FieldOffset(0)] - public bool bVal; + [FieldOffset(0)] public bool bVal; - [FieldOffset(0)] - public int nVal; + [FieldOffset(0)] public int nVal; - [FieldOffset(0)] - public float fVal; + [FieldOffset(0)] public float fVal; } } + public enum EmitShape { enumBox = 0, @@ -1499,23 +1624,3 @@ public enum GfxSkillValType enumGfxSkillFloat, enumGfxSkillValTypeNum }; - - - - - - - - - - - - - - - - - - - - diff --git a/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs b/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs index 6540e7bb30..08d6361b9b 100644 --- a/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs +++ b/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs @@ -87,6 +87,8 @@ namespace BrewMonster protected int NUM_WEAPON_TYPE = 15; public static readonly int[] m_sciStateIDForStateAction = { 117 }; + /// Skill id for pending skill/state hit reaction (see skill_state_action.txt). + protected int m_SkillIDForStateAction; private static Dictionary _default_skill_actions = new Dictionary(); @@ -362,6 +364,7 @@ namespace BrewMonster m_aEquips = new int[(int)IndexOfIteminEquipmentInventory.SIZE_ALL_EQUIPIVTR]; queueActionEvent = new QueueActionEvent("", null, false, null, 200); TickInvoker.Instance.RegisterTickable(this); + m_SkillIDForStateAction = 0; } protected virtual void OnDestroy() @@ -2278,6 +2281,7 @@ namespace BrewMonster // Just play a wounded action if (!OnDamaged(skill)) { + BMLogger.LogError(("HoangDev PlayAction((int)PLAYER_ACTION_TYPE.ACT_WOUNDED);")); PlayAction((int)PLAYER_ACTION_TYPE.ACT_WOUNDED); } if ((dwModifier & (uint)MOD.MOD_IMMUNE) != 0) @@ -2299,7 +2303,9 @@ namespace BrewMonster p1 |= 0x0002; if (!OnDamaged(skill)) + { PlayAction((int)PLAYER_ACTION_TYPE.ACT_WOUNDED); + } if ((dwModifier & (uint)MOD.MOD_IMMUNE) != 0) BubbleText((int)BubbleTextType.BUBBLE_IMMUNE, 0); @@ -2531,15 +2537,17 @@ namespace BrewMonster string name1, name2; + BMLogger.LogError("HoangDev: OnDamaged skill:"+skill + ", m_sciStateIDForStateAction.Length:"+m_sciStateIDForStateAction.Length); for (int i = 0; i < m_sciStateIDForStateAction.Length; i++) { - /* if (atkMan.GetSkillStateActionName(skill, m_sciStateIDForStateAction[i], out name1, out name2)) + if (atkMan.GetSkillStateActionName(skill, m_sciStateIDForStateAction[i], out name1, out name2)) { m_SkillIDForStateAction = skill; + BMLogger.LogError("HoangDev: atkMan.GetSkillStateActionName(ski"); return true; - }*/ + } } - + BMLogger.LogError(("HoangDev: atkMan.GetSkillStateActionName(ski\" return false;")); return false; } public CECSkill GetCurSkill() { return m_pCurSkill; } @@ -2780,19 +2788,6 @@ namespace BrewMonster { return (m_dwStates & PlayerNPCState.GP_STATE_PARIAH) != 0; } - bool GetSkillStateActionName(int skill, int state, string name1, string name2) - { - /* for (int i = 0; i < (int)m_SkillStateActionVec.size(); i++) - { - if (m_SkillStateActionVec[i].skill == skill && m_SkillStateActionVec[i].state == state) - { - name1 = m_SkillStateActionVec[i].beHitAction; - name2 = m_SkillStateActionVec[i].stayDownAction; - return true; - } - }*/ - return false; - } public virtual bool IsFighting() { return m_bFight; } public float GetGroundSpeed() { diff --git a/Assets/PerfectWorld/Scripts/NPC/CECNPC.cs b/Assets/PerfectWorld/Scripts/NPC/CECNPC.cs index 3d9c6710ce..ddcdeb5fc4 100644 --- a/Assets/PerfectWorld/Scripts/NPC/CECNPC.cs +++ b/Assets/PerfectWorld/Scripts/NPC/CECNPC.cs @@ -262,7 +262,7 @@ public class CECNPC : CECObject // [中文] 处理服务器发来的扩展状态更新消息,驱动状态 GFX 的添加与移除 // [English] Handle server ext-state update message — drives state GFX add/remove - + // [中文] 更新扩展状态并刷新 GFX 显示 // [English] Update the ext-state arrays and refresh GFX display @@ -962,7 +962,7 @@ public class CECNPC : CECObject EventBus.PublishChannel(m_NPCInfo.nid, new ClearComActFlagEvent(true)); } - public void Damaged(int iDamage, uint dwModifier/* 0 */) + public void Damaged(int iDamage, uint dwModifier = 0/* 0 */) { if (iDamage == -1 || iDamage == -2) { diff --git a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs index c6bc63a45d..b92ddf8b37 100644 --- a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs +++ b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs @@ -23,15 +23,15 @@ namespace CSNetwork.GPDataType GP_MOVE_STAND = 2, GP_MOVE_FALL = 3, GP_MOVE_SLIDE = 4, - GP_MOVE_PUSH = 5, // only sent to NPC + GP_MOVE_PUSH = 5, // only sent to NPC GP_MOVE_FLYFALL = 6, GP_MOVE_RETURN = 7, GP_MOVE_JUMP = 8, - GP_MOVE_PULL = 9, // only sent to NPC - GP_MOVE_BLINK = 10, // only sent to NPC£¨Ë²ÒÆ£© + GP_MOVE_PULL = 9, // only sent to NPC + GP_MOVE_BLINK = 10, // only sent to NPC£¨Ë²ÒÆ£© GP_MOVE_MASK = 0x0f, - GP_MOVE_TURN = 0x10, // Turnaround + GP_MOVE_TURN = 0x10, // Turnaround GP_MOVE_DEAD = 0x20, GP_MOVE_AIR = 0x40, @@ -39,9 +39,9 @@ namespace CSNetwork.GPDataType GP_MOVE_ENVMASK = 0xc0, }; - public static class CommandID // Command ID + public static class CommandID // Command ID { - public const int PROTOCOL_COMMAND = -1; // Reserved for protocol + public const int PROTOCOL_COMMAND = -1; // Reserved for protocol public const int PLAYER_INFO_1 = 0; public const int PLAYER_INFO_2 = 1; @@ -523,131 +523,112 @@ namespace CSNetwork.GPDataType // NPC service type public static class NPC_service_type { - public const int GP_NPCSEV_SELL = 1, // 1, NPC sell to player - GP_NPCSEV_BUY = 2, // 2, NPC buy from player - GP_NPCSEV_REPAIR = 3, // 3 - GP_NPCSEV_HEAL = 4, // 4 - GP_NPCSEV_TRANSMIT = 5, // 5, Transmit to somewhere - - GP_NPCSEV_TASK_RETURN = 6, // 6, Return task - GP_NPCSEV_TASK_ACCEPT = 7, // 7, Accept task - GP_NPCSEV_TASK_MATTER = 8, // 8, Task matter - GP_NPCSEV_LEARN = 9, // 9, Learn skill - GP_NPCSEV_EMBED = 10, // 10, Embed stone - - GP_NPCSEV_CLEAR_TESSERA = 11, // 11, Clear tessear - GP_NPCSEV_MAKEITEM = 12, // 12 - GP_NPCSEV_BREAKITEM = 13, // 13 - GP_NPCSEV_TRASHPSW = 14, // 14, Change trash password - GP_NPCSEV_OPENTRASH = 15, // 15, Open trash - - GP_NPCSEV_RESERVED = 16, // 16 - GP_NPCSEV_IDENTIFY = 17, // 17, Identify item - GP_NPCSEV_FACTION = 18, // 18, About faction - GP_NPCSEV_BOOTHSELL = 19, // 19, Player booth sell - GP_NPCSEV_TRAVEL = 20, // 20, Travel - - GP_NPCSEV_BOOTHBUY = 21, // 21, Player booth buy - GP_NPCSEV_WAYPOINT = 22, // 22 - GP_NPCSEV_FORGETSKILL = 23, // 23 - GP_NPCSEV_FACECHANGE = 24, // 24 - GP_NPCSEV_MAIL = 25, // 25 - - GP_NPCSEV_VENDUE = 26, // 26 - GP_NPCSEV_DBLEXPTIME = 27, // 27 - GP_NPCSEV_HATCHPET = 28, // 28 - GP_NPCSEV_RESTOREPET = 29, // 29 - GP_NPCSEV_BATTLE = 30, // 30 - - GP_NPCSEV_BUILDTOWER = 31, // 31 - GP_NPCSEV_LEAVEBATTLE = 32, // 32 - GP_NPCSEV_RETURNSTATUSPT = 33, // 33 - GP_NPCSEV_ACCOUNTPOINT = 34, // 34 - GP_NPCSEV_REFINE = 35, // 35 - - GP_NPCSEV_PETNAME = 36, // 36, change pet name - GP_NPCSEV_PETSKILL_DEL = 37, // 37, Delete pet skill - GP_NPCSEV_PETSKILL_LEARN = 38, // 38, Learn pet skill - GP_NPCSEV_BIND_ITEM = 39, // 39, Bind item - GP_NPCSEV_DESTROY_BIND = 40, // 40, Destroy bind item - - CP_NPCSEV_CANCEL_DESTROY = 41, // 41, Cancel destroy bind item - GP_NPCSEV_STOCK_TRANSACTION = 42,// 42 - GP_NPCSEV_STOCK_OPERATION = 43, // 43 - GP_NPCSEV_DYE = 44, // 44 - GP_NPCSEV_REFINE_TRANS = 45, // 45 - - GP_NPCSEV_COMPOSE = 46, // 46 - GP_NPCSEV_MAKE_SLOT = 47, // 47 - GP_NPCSEV_GOBLIN_RETURNSTATUSPT = 48, // 48, Return goblin status point - GP_NPCSEV_GOBLIN_RETURNGENIUSPT = 49, // 49, Return goblin genius point - GP_NPCSEV_GOBLINSKILL_LEARN = 50, // 50, Learn goblin skill - - GP_NPCSEV_GOBLINSKILL_DEL = 51, // 51, delete goblin skill - GP_NPCSEV_GOBLIN_REFINE = 52, // 52, Refine goblin - GP_NPCSEV_GOBLIN_REFINETRANSFER = 53, // 53, Transfer refine level - GP_NPCSEV_GOBLIN_DESTROY = 54, // 54, Destroy goblin - GP_NPCSEV_GOBLINEQUIP_DESTROY = 55, // 55, Destroy goblin's equipment - - GP_NPCSEV_DYE_BY_SUIT = 56, // 56, Dye by suit - GP_NPCSEV_REPAIR_DESTROYING_ITEM = 57, // 57, Repair destroying item - GP_NPCSEV_LEVELUP_PRODUCE = 58, // 58, Level up produce - GP_NPCSEV_OPEN_ACCOUNT_BOX = 59, // 59, Open account box - GP_NPCSEV_WEBTRADE = 60, // 60, Web trade - - GP_NPCSEV_GODEVILCONVERT = 61, // 61, Convert between god and evil - GP_NPCSEV_WEDDING_BOOK = 62, // 62 - GP_NPCSEV_WEDDING_INVITE = 63, // 63 - GP_NPCSEV_FACTION_FORTRESS_SERVICE_1 = 64, // 64 - GP_NPCSEV_FACTION_FORTRESS_SERVICE_2 = 65, // 65 - - GP_NPCSEV_FACTION_FORTRESS_SERVICE_3 = 66, // 66 - GP_NPCSEV_PET_DYE = 67, // 67 - GP_NPCSEV_VIEW_TRASHBOX = 68, // 68, check the trash box without password - GP_NPCSEV_ENGRAVE = 69, // 69 - GP_NCPSEV_DPS_DPH_RANK = 70, // 70 - - GP_NPCSEV_ADDONREGEN = 71, // 71 - GP_NPCSEV_FORCE = 72, // 72 - GP_NPCSEV_TRANSMIT_DIRECT = 73, // 73 - GP_NPCSEV_PREVIEW_PRODUCE = 74, // 74 - GP_NPCSEV_COUNTRY_JOINLEAVE = 75,// 75 - - GP_NPCSEV_COUNTRY_LEAVEWAR = 76, // 76 - GP_NPCSEV_MARK = 77, // 77 - GP_NPCSEV_CROSSSERVER_GETIN = 78,// 78 - GP_NPCSEV_CROSSSERVER_GETOUT = 79,// 79 - - GP_NPCSEV_PLAYER_RENAME = 80, // 80 - GP_NPCSEV_STONE_TRANSFER = 81, // 81 - GP_NPCSEV_STONE_REPLACE = 82, // 82 - GP_NPCSEV_KINGSEV = 83, // 83 - GP_NPCSEV_SPLIT_FASHION = 84, // 84 - - GP_NPCSEV_OFFLINESHOP = 85, // 85 - GP_NPCSEV_REINCARNATION = 86, // 86 - GP_NPCSEV_GIFTCARD = 87, // 87 - - GP_NPCSEV_TRICKBATTLE = 88, // 88 - GP_NPCSEV_CARDRESPAWN = 89, // 89 - GP_NPCSEV_FLYSWORDIMPROVE = 90, // 90 - GP_NPCSEV_OPEN_FACTION_PVP = 91, // 91 - - GP_NPCSEV_ADVANCED_PRODUCE = 92, // 92 - GP_NPCSEV_GOLD_SHOP = 93, // 93 - GP_NPCSEV_DIVIDEND_GOLD_SHOP = 94, // 94 - GP_NPCSEV_PLAYER_CHANGE_GENDER = 95; // 95 + public const int GP_NPCSEV_SELL = 1, // 1, NPC sell to player + GP_NPCSEV_BUY = 2, // 2, NPC buy from player + GP_NPCSEV_REPAIR = 3, // 3 + GP_NPCSEV_HEAL = 4, // 4 + GP_NPCSEV_TRANSMIT = 5, // 5, Transmit to somewhere + GP_NPCSEV_TASK_RETURN = 6, // 6, Return task + GP_NPCSEV_TASK_ACCEPT = 7, // 7, Accept task + GP_NPCSEV_TASK_MATTER = 8, // 8, Task matter + GP_NPCSEV_LEARN = 9, // 9, Learn skill + GP_NPCSEV_EMBED = 10, // 10, Embed stone + GP_NPCSEV_CLEAR_TESSERA = 11, // 11, Clear tessear + GP_NPCSEV_MAKEITEM = 12, // 12 + GP_NPCSEV_BREAKITEM = 13, // 13 + GP_NPCSEV_TRASHPSW = 14, // 14, Change trash password + GP_NPCSEV_OPENTRASH = 15, // 15, Open trash + GP_NPCSEV_RESERVED = 16, // 16 + GP_NPCSEV_IDENTIFY = 17, // 17, Identify item + GP_NPCSEV_FACTION = 18, // 18, About faction + GP_NPCSEV_BOOTHSELL = 19, // 19, Player booth sell + GP_NPCSEV_TRAVEL = 20, // 20, Travel + GP_NPCSEV_BOOTHBUY = 21, // 21, Player booth buy + GP_NPCSEV_WAYPOINT = 22, // 22 + GP_NPCSEV_FORGETSKILL = 23, // 23 + GP_NPCSEV_FACECHANGE = 24, // 24 + GP_NPCSEV_MAIL = 25, // 25 + GP_NPCSEV_VENDUE = 26, // 26 + GP_NPCSEV_DBLEXPTIME = 27, // 27 + GP_NPCSEV_HATCHPET = 28, // 28 + GP_NPCSEV_RESTOREPET = 29, // 29 + GP_NPCSEV_BATTLE = 30, // 30 + GP_NPCSEV_BUILDTOWER = 31, // 31 + GP_NPCSEV_LEAVEBATTLE = 32, // 32 + GP_NPCSEV_RETURNSTATUSPT = 33, // 33 + GP_NPCSEV_ACCOUNTPOINT = 34, // 34 + GP_NPCSEV_REFINE = 35, // 35 + GP_NPCSEV_PETNAME = 36, // 36, change pet name + GP_NPCSEV_PETSKILL_DEL = 37, // 37, Delete pet skill + GP_NPCSEV_PETSKILL_LEARN = 38, // 38, Learn pet skill + GP_NPCSEV_BIND_ITEM = 39, // 39, Bind item + GP_NPCSEV_DESTROY_BIND = 40, // 40, Destroy bind item + CP_NPCSEV_CANCEL_DESTROY = 41, // 41, Cancel destroy bind item + GP_NPCSEV_STOCK_TRANSACTION = 42, // 42 + GP_NPCSEV_STOCK_OPERATION = 43, // 43 + GP_NPCSEV_DYE = 44, // 44 + GP_NPCSEV_REFINE_TRANS = 45, // 45 + GP_NPCSEV_COMPOSE = 46, // 46 + GP_NPCSEV_MAKE_SLOT = 47, // 47 + GP_NPCSEV_GOBLIN_RETURNSTATUSPT = 48, // 48, Return goblin status point + GP_NPCSEV_GOBLIN_RETURNGENIUSPT = 49, // 49, Return goblin genius point + GP_NPCSEV_GOBLINSKILL_LEARN = 50, // 50, Learn goblin skill + GP_NPCSEV_GOBLINSKILL_DEL = 51, // 51, delete goblin skill + GP_NPCSEV_GOBLIN_REFINE = 52, // 52, Refine goblin + GP_NPCSEV_GOBLIN_REFINETRANSFER = 53, // 53, Transfer refine level + GP_NPCSEV_GOBLIN_DESTROY = 54, // 54, Destroy goblin + GP_NPCSEV_GOBLINEQUIP_DESTROY = 55, // 55, Destroy goblin's equipment + GP_NPCSEV_DYE_BY_SUIT = 56, // 56, Dye by suit + GP_NPCSEV_REPAIR_DESTROYING_ITEM = 57, // 57, Repair destroying item + GP_NPCSEV_LEVELUP_PRODUCE = 58, // 58, Level up produce + GP_NPCSEV_OPEN_ACCOUNT_BOX = 59, // 59, Open account box + GP_NPCSEV_WEBTRADE = 60, // 60, Web trade + GP_NPCSEV_GODEVILCONVERT = 61, // 61, Convert between god and evil + GP_NPCSEV_WEDDING_BOOK = 62, // 62 + GP_NPCSEV_WEDDING_INVITE = 63, // 63 + GP_NPCSEV_FACTION_FORTRESS_SERVICE_1 = 64, // 64 + GP_NPCSEV_FACTION_FORTRESS_SERVICE_2 = 65, // 65 + GP_NPCSEV_FACTION_FORTRESS_SERVICE_3 = 66, // 66 + GP_NPCSEV_PET_DYE = 67, // 67 + GP_NPCSEV_VIEW_TRASHBOX = 68, // 68, check the trash box without password + GP_NPCSEV_ENGRAVE = 69, // 69 + GP_NCPSEV_DPS_DPH_RANK = 70, // 70 + GP_NPCSEV_ADDONREGEN = 71, // 71 + GP_NPCSEV_FORCE = 72, // 72 + GP_NPCSEV_TRANSMIT_DIRECT = 73, // 73 + GP_NPCSEV_PREVIEW_PRODUCE = 74, // 74 + GP_NPCSEV_COUNTRY_JOINLEAVE = 75, // 75 + GP_NPCSEV_COUNTRY_LEAVEWAR = 76, // 76 + GP_NPCSEV_MARK = 77, // 77 + GP_NPCSEV_CROSSSERVER_GETIN = 78, // 78 + GP_NPCSEV_CROSSSERVER_GETOUT = 79, // 79 + GP_NPCSEV_PLAYER_RENAME = 80, // 80 + GP_NPCSEV_STONE_TRANSFER = 81, // 81 + GP_NPCSEV_STONE_REPLACE = 82, // 82 + GP_NPCSEV_KINGSEV = 83, // 83 + GP_NPCSEV_SPLIT_FASHION = 84, // 84 + GP_NPCSEV_OFFLINESHOP = 85, // 85 + GP_NPCSEV_REINCARNATION = 86, // 86 + GP_NPCSEV_GIFTCARD = 87, // 87 + GP_NPCSEV_TRICKBATTLE = 88, // 88 + GP_NPCSEV_CARDRESPAWN = 89, // 89 + GP_NPCSEV_FLYSWORDIMPROVE = 90, // 90 + GP_NPCSEV_OPEN_FACTION_PVP = 91, // 91 + GP_NPCSEV_ADVANCED_PRODUCE = 92, // 92 + GP_NPCSEV_GOLD_SHOP = 93, // 93 + GP_NPCSEV_DIVIDEND_GOLD_SHOP = 94, // 94 + GP_NPCSEV_PLAYER_CHANGE_GENDER = 95; // 95 } // Constants used in moving control public struct MOVECONST { - public float fStepHei; // Maximum step height - public float fMinAirHei; // Minimum distance to terrain (or water) when fly + public float fStepHei; // Maximum step height + public float fMinAirHei; // Minimum distance to terrain (or water) when fly public float fMinWaterHei; // Minimum distance to terrain when swim - public float fShoreDepth; // Shore depth - public float fWaterSurf; // Water surface depth + public float fShoreDepth; // Shore depth + public float fWaterSurf; // Water surface depth public MOVECONST(float fStepHei, float fMinAirHei, float fMinWaterHei, float fShoreDepth, float fWaterSurf) { @@ -670,26 +651,28 @@ namespace CSNetwork.GPDataType // Profession public static class PROFESSION { - public const int PROF_WARRIOR = 0; // 0:ÎäÏÀ - public const int PROF_MAGE = 1; // 1:·¨Ê¦ - public const int PROF_MONK = 2; // 2:Î×ʦ - public const int PROF_HAG = 3; // 3:Ñý¾« - public const int PROF_ORC = 4; // 4:ÑýÊÞ - public const int PROF_GHOST = 5; // 5:´Ì¿Í - public const int PROF_ARCHOR = 6; // 6:Óðâ - public const int PROF_ANGEL = 7; // 7:ÓðÁé - public const int PROF_JIANLING = 8; // 8:½£Áé - public const int PROF_MEILING = 9; // 9:÷ÈÁé - public const int PROF_YEYING = 10; // 10:Ò¹Ó° - public const int PROF_YUEXIAN = 11; // 11:ÔÂÏÉ + public const int PROF_WARRIOR = 0; // 0:ÎäÏÀ + public const int PROF_MAGE = 1; // 1:·¨Ê¦ + public const int PROF_MONK = 2; // 2:Î×ʦ + public const int PROF_HAG = 3; // 3:Ñý¾« + public const int PROF_ORC = 4; // 4:ÑýÊÞ + public const int PROF_GHOST = 5; // 5:´Ì¿Í + public const int PROF_ARCHOR = 6; // 6:Óðâ + public const int PROF_ANGEL = 7; // 7:ÓðÁé + public const int PROF_JIANLING = 8; // 8:½£Áé + public const int PROF_MEILING = 9; // 9:÷ÈÁé + public const int PROF_YEYING = 10; // 10:Ò¹Ó° + public const int PROF_YUEXIAN = 11; // 11:ÔÂÏÉ public const int NUM_PROFESSION = 12; }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_npc_died { public int id; public int idKiller; }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_npc_died2 { @@ -701,9 +684,9 @@ namespace CSNetwork.GPDataType public struct cmd_equip_data { public ushort crc; - public int idPlayer; + public int idPlayer; public long mask; - public int[] data; //0 ~ 29 + public int[] data; //0 ~ 29 // bool CheckValid(size_t buf_size, size_t& sz) const // { @@ -724,7 +707,7 @@ namespace CSNetwork.GPDataType public static cmd_equip_data FromBytes(byte[] buffer) { cmd_equip_data cmd = new cmd_equip_data(); - + if (buffer.Length > 0) { byte[] tempBuf = new byte[2]; @@ -754,6 +737,7 @@ namespace CSNetwork.GPDataType Array.Copy(buffer, 14 + i * 4, tempBuf, 0, 4); cmd.data[i] = BitConverter.ToInt32(tempBuf, 0); } + return cmd; } @@ -772,7 +756,7 @@ namespace CSNetwork.GPDataType public static cmd_equip_data_changed FromBytes(byte[] buffer) { cmd_equip_data_changed cmd = new cmd_equip_data_changed(); - + if (buffer.Length > 0) { byte[] tempBuf = new byte[2]; @@ -801,8 +785,8 @@ namespace CSNetwork.GPDataType cmd.crc = ushort.MaxValue; return cmd; } - - + + cmd.data_add = new int[sz / 4]; for (int i = 0; i < cmd.data_add.Length; i++) { @@ -821,21 +805,23 @@ namespace CSNetwork.GPDataType public int attacker_id; public int target_id; public int damage; - public int attack_flag; //±ê¼Ç¸Ã¹¥»÷ÊÇ·ñÓй¥»÷ÓÅ»¯·ûºÍ·ÀÓùÓÅ»¯·ûºÍÖØ»÷·¢Éú - public char speed; //¹¥»÷ËÙ¶È speed * 50 ms + public int attack_flag; //±ê¼Ç¸Ã¹¥»÷ÊÇ·ñÓй¥»÷ÓÅ»¯·ûºÍ·ÀÓùÓÅ»¯·ûºÍÖØ»÷·¢Éú + public char speed; //¹¥»÷ËÙ¶È speed * 50 ms }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_object_disappear { public int id; }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_object_move { public int id; public A3DVECTOR3 dest; public ushort use_time; - public short sSpeed; // Move speed 8.8 fixed-point + public short sSpeed; // Move speed 8.8 fixed-point public byte move_mode; } @@ -844,7 +830,7 @@ namespace CSNetwork.GPDataType { public int id; public A3DVECTOR3 dest; - public short sSpeed; // Move speed 8.8 fix-point + public short sSpeed; // Move speed 8.8 fix-point public byte dir; public byte move_mode; } @@ -854,17 +840,20 @@ namespace CSNetwork.GPDataType { public int id; } + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_object_invisible { - public int id; //¿ÉÒÔÊÇplayerºÍnpc - public int invisible_degree; //0 ·ÇÒþÉí£» >0 ÒþÉíµÈ¼¶ + public int id; //¿ÉÒÔÊÇplayerºÍnpc + public int invisible_degree; //0 ·ÇÒþÉí£» >0 ÒþÉíµÈ¼¶ }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_object_stop_play_action { public int id; }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_multiobj_effect { @@ -872,15 +861,16 @@ namespace CSNetwork.GPDataType public int target; public byte type; }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_host_attacked { public int idAttacker; public int iDamage; - public char cEquipment; // The equipment which is mangled, ¸ßλ´ú±íÕâ´Î¹¥»÷ÊDz»ÊÇÓ¦¸Ã±ä³ÈÉ« + public char cEquipment; // The equipment which is mangled, ¸ßλ´ú±íÕâ´Î¹¥»÷ÊDz»ÊÇÓ¦¸Ã±ä³ÈÉ« - public int attack_flag; //±ê¼Ç¸Ã¹¥»÷ÊÇ·ñÓй¥»÷ÓÅ»¯·ûºÍ·ÀÓùÓÅ»¯·ûºÍÖØ»÷·¢Éú - public char speed; //¹¥»÷ËÙ¶È speed * 50 ms + public int attack_flag; //±ê¼Ç¸Ã¹¥»÷ÊÇ·ñÓй¥»÷ÓÅ»¯·ûºÍ·ÀÓùÓÅ»¯·ûºÍÖØ»÷·¢Éú + public char speed; //¹¥»÷ËÙ¶È speed * 50 ms }; [StructLayout(LayoutKind.Sequential, Pack = 1)] @@ -901,89 +891,91 @@ namespace CSNetwork.GPDataType public struct cmd_player_revive { public int idPlayer; - public short sReviveType; // Revive type + public short sReviveType; // Revive type public A3DVECTOR3 pos; }; + public enum CoolTimeIndex { - GP_CT_NULL = 0, // ¿Õ£¬±£Áô - GP_CT_PVP, // ûÓã¬ÏÈռλ - GP_CT_EMOTE, // ×ö±íÇéµÄÀäȴʱ¼ä - GP_CT_REJUVENATION_POTION, // ¾ÅÑôµ¤µÄÀäȴʱ¼ä - GP_CT_SWITCH_FASHION, // Çл»Ê±×°Ä£Ê½µÄÀäȴʱ¼ä - GP_CT_DROP_MONEY, // ÍùµØÉÏÈÓÇ®µÄÀäȴʱ¼ä - GP_CT_DROP_ITEM, // ÍùµØÉÏÈÓÎïÆ·µÄÀäȴʱ¼ä - GP_CT_FACEPILL, // ±äÐÎÍèµÄÀäȴʱ¼ä - GP_CT_FACETICKET, // ÕûÈݵÄÀäȴʱ¼ä - GP_CT_RECURRECT_SCROLL, // ±ðÈ˸´»î¾íµÄÀäȴʱ¼ä£¬´ËÎïÆ·²»´æÔÚ£¬Î´ÉúЧ - GP_CT_SOUL_STONE, // ÏÖÔÚ¸´»î¾íÖáµÄÀäȴʱ¼ä - GP_CT_HP_POTION, // »ØÑªÒ© - GP_CT_MP_POTION, // »ØÄ§Ò© - GP_CT_ANTIDOTE_POTION, // ½â¶¾¼Á - GP_CT_FLY_RUSH, // ¼ÓËÙ·ÉÐÐ - GP_CT_TOWNSCROLL, // »Ø³Ç¾íÖá - GP_CT_GM_GENITEM, // GM Éú³É¹ÖÎïµÄÎïÆ· - GP_CT_VIEWOTHEREQUIP, // ²é¿´±ðÈ˵Ä×°±¸ - GP_CT_FEED_PET, // Î¹Ñø³èÎï - GP_CT_FIREWORKS, // Ê©·ÅÑÌ»¨ - GP_CT_FARCRY, // far cry ƵµÀ˵»° - GP_CT_SKILLMATTER, // ʹÓü¼ÄÜÎïÆ· - GP_CT_REFINE, // ¾«Á¶ - GP_CT_ARMORRUNE, // ·ÀÓùÓÅ»¯·û - GP_CT_AUTOHP, // »¤Éí·ûÀäȴʱ¼ä - GP_CT_AUTOMP, // ÊØÉñ·ûÀäȴʱ¼ä - GP_CT_DOUBLEEXP, // Ë«±¶¾­ÑéµÀ¾ßÀäȴʱ¼ä - GP_CT_DYETICKET, // ȾɫµÀ¾ß - GP_CT_TEAMRELATION, // ×é¶Ó¹ØÏµÀäȴʱ¼ä - GP_CT_REFINETRANS, // ¾«Á¶µÈ¼¶×ªÒÆÀäȴʱ¼ä + GP_CT_NULL = 0, // ¿Õ£¬±£Áô + GP_CT_PVP, // ûÓã¬ÏÈռλ + GP_CT_EMOTE, // ×ö±íÇéµÄÀäȴʱ¼ä + GP_CT_REJUVENATION_POTION, // ¾ÅÑôµ¤µÄÀäȴʱ¼ä + GP_CT_SWITCH_FASHION, // Çл»Ê±×°Ä£Ê½µÄÀäȴʱ¼ä + GP_CT_DROP_MONEY, // ÍùµØÉÏÈÓÇ®µÄÀäȴʱ¼ä + GP_CT_DROP_ITEM, // ÍùµØÉÏÈÓÎïÆ·µÄÀäȴʱ¼ä + GP_CT_FACEPILL, // ±äÐÎÍèµÄÀäȴʱ¼ä + GP_CT_FACETICKET, // ÕûÈݵÄÀäȴʱ¼ä + GP_CT_RECURRECT_SCROLL, // ±ðÈ˸´»î¾íµÄÀäȴʱ¼ä£¬´ËÎïÆ·²»´æÔÚ£¬Î´ÉúЧ + GP_CT_SOUL_STONE, // ÏÖÔÚ¸´»î¾íÖáµÄÀäȴʱ¼ä + GP_CT_HP_POTION, // »ØÑªÒ© + GP_CT_MP_POTION, // »ØÄ§Ò© + GP_CT_ANTIDOTE_POTION, // ½â¶¾¼Á + GP_CT_FLY_RUSH, // ¼ÓËÙ·ÉÐÐ + GP_CT_TOWNSCROLL, // »Ø³Ç¾íÖá + GP_CT_GM_GENITEM, // GM Éú³É¹ÖÎïµÄÎïÆ· + GP_CT_VIEWOTHEREQUIP, // ²é¿´±ðÈ˵Ä×°±¸ + GP_CT_FEED_PET, // Î¹Ñø³èÎï + GP_CT_FIREWORKS, // Ê©·ÅÑÌ»¨ + GP_CT_FARCRY, // far cry ƵµÀ˵»° + GP_CT_SKILLMATTER, // ʹÓü¼ÄÜÎïÆ· + GP_CT_REFINE, // ¾«Á¶ + GP_CT_ARMORRUNE, // ·ÀÓùÓÅ»¯·û + GP_CT_AUTOHP, // »¤Éí·ûÀäȴʱ¼ä + GP_CT_AUTOMP, // ÊØÉñ·ûÀäȴʱ¼ä + GP_CT_DOUBLEEXP, // Ë«±¶¾­ÑéµÀ¾ßÀäȴʱ¼ä + GP_CT_DYETICKET, // ȾɫµÀ¾ß + GP_CT_TEAMRELATION, // ×é¶Ó¹ØÏµÀäȴʱ¼ä + GP_CT_REFINETRANS, // ¾«Á¶µÈ¼¶×ªÒÆÀäȴʱ¼ä - GP_CT_CAST_ELF_SKILL, // С¾«Áé¼¼ÄÜÀäÈ´ - GP_CT_ELF_CMD, // ÏÈռλ - GP_CT_GET_MALL_PRICE, // »ñÈ¡É̳ÇÊý¾ÝµÄÀäȴʱ¼ä - GP_CT_QUERY_OTHER_PROPERTY, // ²éѯĿ±êÊôÐÔ 5Ãë - GP_CT_SKILLTRIGGER2, // ʹÓü¼ÄÜÎïÆ·1Ãë + GP_CT_CAST_ELF_SKILL, // С¾«Áé¼¼ÄÜÀäÈ´ + GP_CT_ELF_CMD, // ÏÈռλ + GP_CT_GET_MALL_PRICE, // »ñÈ¡É̳ÇÊý¾ÝµÄÀäȴʱ¼ä + GP_CT_QUERY_OTHER_PROPERTY, // ²éѯĿ±êÊôÐÔ 5Ãë + GP_CT_SKILLTRIGGER2, // ʹÓü¼ÄÜÎïÆ·1Ãë - GP_CT_SKILLCOMMONCOOLDOWN0, // ÓÃÓÚ¼¼Äܹ«¹²ÀäÈ´ + GP_CT_SKILLCOMMONCOOLDOWN0, // ÓÃÓÚ¼¼Äܹ«¹²ÀäÈ´ GP_CT_SKILLCOMMONCOOLDOWN1, GP_CT_SKILLCOMMONCOOLDOWN2, GP_CT_SKILLCOMMONCOOLDOWN3, GP_CT_SKILLCOMMONCOOLDOWN4, - GP_CT_RUNECOMMONCOOLDOWN0, // ÓÃÓÚÎïÆ·¼¼Äܹ«¹²ÀäÈ´ + GP_CT_RUNECOMMONCOOLDOWN0, // ÓÃÓÚÎïÆ·¼¼Äܹ«¹²ÀäÈ´ GP_CT_RUNECOMMONCOOLDOWN1, GP_CT_RUNECOMMONCOOLDOWN2, GP_CT_RUNECOMMONCOOLDOWN3, GP_CT_RUNECOMMONCOOLDOWN4, - GP_CT_EQUIP_FASHION_ITEM, // ×Ô¶¯»»×°Àäȴʱ¼ä 60s - GP_CT_GET_DIVIDEND_MALL_PRICE, // »ñÈ¡ºèÀûÉ̳ÇÊý¾ÝµÄÀäȴʱ¼ä 30s - GP_CT_MULTI_EXCHANGE_ITEM, // ÕûÀí°ü¹üÀäȴʱ¼ä 30s + GP_CT_EQUIP_FASHION_ITEM, // ×Ô¶¯»»×°Àäȴʱ¼ä 60s + GP_CT_GET_DIVIDEND_MALL_PRICE, // »ñÈ¡ºèÀûÉ̳ÇÊý¾ÝµÄÀäȴʱ¼ä 30s + GP_CT_MULTI_EXCHANGE_ITEM, // ÕûÀí°ü¹üÀäȴʱ¼ä 30s - GP_CT_TEAM_CONGREGATE, // ¶ÓÎ鼯½áÁî - GP_CT_FACTION_CONGREGATE, // °ïÅɼ¯½áÁî - GP_CT_DPS_DPH_RANK, // »ñȡɳ°üÅÅÐаñ - GP_CT_JOIN_PLAYER_FORCE, // ¼ÓÈëÊÆÁ¦ - GP_CT_LEAVE_PLAYER_FORCE, // Àë¿ªÊÆÁ¦ - GP_CT_TOGGLE_ONLINE_AWARD, // Çл»¹Ò»úµºÔÚÏß½±Àø - GP_CT_COUNTRY_BATTLE_APPLY, // ¼ÓÈë¹úÕ½ÉêÇë - GP_CT_COUNTRY_CHAT, // ¹úսƵµÀ·¢ÑÔ - GP_CT_CROSS_SERVER_APPLY, // ǰÍù¿ç·þÉêÇë + GP_CT_TEAM_CONGREGATE, // ¶ÓÎ鼯½áÁî + GP_CT_FACTION_CONGREGATE, // °ïÅɼ¯½áÁî + GP_CT_DPS_DPH_RANK, // »ñȡɳ°üÅÅÐаñ + GP_CT_JOIN_PLAYER_FORCE, // ¼ÓÈëÊÆÁ¦ + GP_CT_LEAVE_PLAYER_FORCE, // Àë¿ªÊÆÁ¦ + GP_CT_TOGGLE_ONLINE_AWARD, // Çл»¹Ò»úµºÔÚÏß½±Àø + GP_CT_COUNTRY_BATTLE_APPLY, // ¼ÓÈë¹úÕ½ÉêÇë + GP_CT_COUNTRY_CHAT, // ¹úսƵµÀ·¢ÑÔ + GP_CT_CROSS_SERVER_APPLY, // ǰÍù¿ç·þÉêÇë - GP_CT_TOUCHTRADE, // Touch µã¹ºÎï»ò²éѯ - GP_CT_SWITCH_PARALLEL_WORLD, // Çл»·ÖÏß - GP_CT_QUERY_PARALLEL_WORLD, // ²éѯ·ÖÏß + GP_CT_TOUCHTRADE, // Touch µã¹ºÎï»ò²éѯ + GP_CT_SWITCH_PARALLEL_WORLD, // Çл»·ÖÏß + GP_CT_QUERY_PARALLEL_WORLD, // ²éѯ·ÖÏß GP_CT_GIFTCARD_REDEEM, - GP_CT_TRICKBATTLE_APPLY, // ¿ç·þ»î¶¯, Õ½³µ - GP_CT_AUTOTEAM, // ×Ô¶¯×é¶Ó²Ù×÷£¬µØÍ¼Ìø×ª - GP_CT_PLAYER_GATHER, // ·ÀÖ¹²É¼¯¹ý¿ì (GATHER_MATERIAL) - GP_CT_COUNTRYBATTLE_LIVESHOW, // ²éѯ¹úÕ½rankºÍËÀÍöÊý¾Ý (COUNTRYBATTLE_LIVE_SHOW) + GP_CT_TRICKBATTLE_APPLY, // ¿ç·þ»î¶¯, Õ½³µ + GP_CT_AUTOTEAM, // ×Ô¶¯×é¶Ó²Ù×÷£¬µØÍ¼Ìø×ª + GP_CT_PLAYER_GATHER, // ·ÀÖ¹²É¼¯¹ý¿ì (GATHER_MATERIAL) + GP_CT_COUNTRYBATTLE_LIVESHOW, // ²éѯ¹úÕ½rankºÍËÀÍöÊý¾Ý (COUNTRYBATTLE_LIVE_SHOW) - GP_CT_QUERY_MAFIA_PVP_INFO, // 65: °ïÅÉ PVP ÐÅÏ¢²éѯ (QUERY_MAFIA_PVP_INFO) + GP_CT_QUERY_MAFIA_PVP_INFO, // 65: °ïÅÉ PVP ÐÅÏ¢²éѯ (QUERY_MAFIA_PVP_INFO) GP_CT_MAX, GP_CT_SKILL_START = 1024, }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_notify_hostpos { @@ -1007,13 +999,19 @@ namespace CSNetwork.GPDataType public int matter_id; public int who; } + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct OBJECT_COORD { public string strMap; + public A3DVECTOR3 vPos; + //bool operator == (const ACString& rhsStr) const {return strMap == rhsStr;} - public bool Equals(string rhsStr) { return strMap == rhsStr; } + public bool Equals(string rhsStr) + { + return strMap == rhsStr; + } //override == method } @@ -1028,17 +1026,23 @@ namespace CSNetwork.GPDataType // Constructors public A3DVECTOR3(float m) { - x = m; y = m; z = m; + x = m; + y = m; + z = m; } public A3DVECTOR3(float x, float y, float z) { - this.x = x; this.y = y; this.z = z; + this.x = x; + this.y = y; + this.z = z; } public A3DVECTOR3(A3DVECTOR3 v) { - x = v.x; y = v.y; z = v.z; + x = v.x; + y = v.y; + z = v.z; } // Operators @@ -1053,6 +1057,7 @@ namespace CSNetwork.GPDataType public static A3DVECTOR3 operator *(float f, A3DVECTOR3 v) => v * f; + public static A3DVECTOR3 operator /(A3DVECTOR3 v, float f) { float inv = 1.0f / f; @@ -1099,8 +1104,11 @@ namespace CSNetwork.GPDataType Clear(); return 0f; } + float inv = 1f / mag; - x *= inv; y *= inv; z *= inv; + x *= inv; + y *= inv; + z *= inv; return mag; } @@ -1113,6 +1121,7 @@ namespace CSNetwork.GPDataType vOut = new A3DVECTOR3(0f, 0f, 0f); return 0f; } + float inv = 1f / mag; vOut = vIn * inv; return mag; @@ -1123,8 +1132,18 @@ namespace CSNetwork.GPDataType => v1 * (1f - t) + v2 * t; // Utils - public void Set(float _x, float _y, float _z) { x = _x; y = _y; z = _z; } - public void Clear() { x = y = z = 0f; } + public void Set(float _x, float _y, float _z) + { + x = _x; + y = _y; + z = _z; + } + + public void Clear() + { + x = y = z = 0f; + } + public bool IsZero() => x == 0f && y == 0f && z == 0f; public float MinMember() => Math.Min(x, Math.Min(y, z)); @@ -1132,12 +1151,47 @@ namespace CSNetwork.GPDataType public void Snap() { - if (x > 1f - 1e-5f) { Clear(); x = 1f; return; } - if (x < -1f + 1e-5f) { Clear(); x = -1f; return; } - if (y > 1f - 1e-5f) { Clear(); y = 1f; return; } - if (y < -1f + 1e-5f) { Clear(); y = -1f; return; } - if (z > 1f - 1e-5f) { Clear(); z = 1f; return; } - if (z < -1f + 1e-5f) { Clear(); z = -1f; return; } + if (x > 1f - 1e-5f) + { + Clear(); + x = 1f; + return; + } + + if (x < -1f + 1e-5f) + { + Clear(); + x = -1f; + return; + } + + if (y > 1f - 1e-5f) + { + Clear(); + y = 1f; + return; + } + + if (y < -1f + 1e-5f) + { + Clear(); + y = -1f; + return; + } + + if (z > 1f - 1e-5f) + { + Clear(); + z = 1f; + return; + } + + if (z < -1f + 1e-5f) + { + Clear(); + z = -1f; + return; + } } // Override Equals & GetHashCode @@ -1147,10 +1201,12 @@ namespace CSNetwork.GPDataType var v = (A3DVECTOR3)obj; return this == v; } + public override int GetHashCode() => (x, y, z).GetHashCode(); public override string ToString() => $"({x}, {y}, {z})"; } + // PVP mask [Flags] public enum PVPMask : byte @@ -1159,7 +1215,7 @@ namespace CSNetwork.GPDataType GP_PVPMASK_NOMAFIA = 0x0002, GP_PVPMASK_NOWHITE = 0x0004, GP_PVPMASK_NOALLIANCE = 0x0008, - GP_PVPMASK_NOFORCE = 0x0010,//²»¹¥»÷Í¬ÊÆÁ¦µÄ + GP_PVPMASK_NOFORCE = 0x0010, //²»¹¥»÷Í¬ÊÆÁ¦µÄ GP_BLSMASK_NORED = 0x0008, GP_BLSMASK_NOMAFIA = 0x0010, @@ -1167,6 +1223,7 @@ namespace CSNetwork.GPDataType GP_BLSMASK_NOALLIANCE = 0x0040, GP_BLSMASK_NOFORCE = 0x0080, // ÊÆÁ¦ÆÁ±Î }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_self_info_1 { @@ -1176,13 +1233,14 @@ namespace CSNetwork.GPDataType public A3DVECTOR3 pos; public ushort crc_e; public ushort crc_c; - public byte dir; // unsigned char → byte - public byte level2; // unsigned char → byte + public byte dir; // unsigned char → byte + public byte level2; // unsigned char → byte public int state; public int state2; //TO DO: Check Valid } + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_player_cast_rune_instant_skill { @@ -1191,6 +1249,7 @@ namespace CSNetwork.GPDataType public int skill; public byte level; }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_player_cast_rune_skill { @@ -1200,29 +1259,35 @@ namespace CSNetwork.GPDataType public ushort time; public byte level; }; + public struct cmd_skill_interrupted { public int caster; }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_object_forbid_be_selected { public int id; public byte b; // 1 ÏÞÖÆ 0 ²»ÏÞÖÆ }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_update_ext_state { public int id; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)OBJECT_EXT_STATE_COUNT.OBJECT_EXT_STATE_COUNT)] public uint[] states; }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_object_root { public int id; public A3DVECTOR3 pos; }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_object_skill_attack_result { @@ -1230,14 +1295,16 @@ namespace CSNetwork.GPDataType public int target_id; public int skill_id; public int damage; - public int attack_flag; //±ê¼Ç¸Ã¹¥»÷ÊÇ·ñÓй¥»÷ÓÅ»¯·ûºÍ·ÀÓùÓÅ»¯·ûºÍÖØ»÷·¢Éú - public byte speed; //¹¥»÷ËÙ¶È speed * 50 ms + public int attack_flag; //±ê¼Ç¸Ã¹¥»÷ÊÇ·ñÓй¥»÷ÓÅ»¯·ûºÍ·ÀÓùÓÅ»¯·ûºÍÖØ»÷·¢Éú + public byte speed; //¹¥»÷ËÙ¶È speed * 50 ms public byte section; }; + public enum OBJECT_EXT_STATE_COUNT { OBJECT_EXT_STATE_COUNT = 6, // Íæ¼Ò/NPC ÉíÉÏ״̬¹âЧ DWORD ¸öÊý }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_self_info_00 { @@ -1253,6 +1320,7 @@ namespace CSNetwork.GPDataType public int iAP; public int iMaxAP; }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_enchant_result { @@ -1264,6 +1332,7 @@ namespace CSNetwork.GPDataType public int attack_flag; public byte section; }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct info_player_1 { @@ -1373,11 +1442,13 @@ namespace CSNetwork.GPDataType public uint content_length; public byte[] content; }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_combo_skill_prepare { public int skill_id; public int timestamp; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public int[] args; }; @@ -1385,7 +1456,7 @@ namespace CSNetwork.GPDataType [StructLayout(LayoutKind.Sequential, Pack = 1)] struct cmd_host_start_attack { - public int idTarget; // target id + public int idTarget; // target id public ushort ammo_remain; public byte attack_speed; }; @@ -1400,8 +1471,8 @@ namespace CSNetwork.GPDataType public struct cmd_host_attack_result { public int idTarget; - public int iDamage; // Èç¹ûÊÇ0±íʾûÓл÷ÖÐ - public int attack_flag; // ±ê¼Ç¸Ã¹¥»÷ÊÇ·ñÓй¥»÷ÓÅ»¯·ûºÍ·ÀÓùÓÅ»¯·ûºÍÖØ»÷·¢Éú + public int iDamage; // Èç¹ûÊÇ0±íʾûÓл÷ÖÐ + public int attack_flag; // ±ê¼Ç¸Ã¹¥»÷ÊÇ·ñÓй¥»÷ÓÅ»¯·ûºÍ·ÀÓùÓÅ»¯·ûºÍÖØ»÷·¢Éú public byte attack_speed; }; @@ -1431,6 +1502,7 @@ namespace CSNetwork.GPDataType public int state; public uint count; public ushort crc; + public ushort content_length; //public byte[] content; }; @@ -1469,6 +1541,7 @@ namespace CSNetwork.GPDataType public uint amount; public uint max_amount; } + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct player_cash { @@ -1515,6 +1588,7 @@ namespace CSNetwork.GPDataType if (i > 0) sb.Append(", "); sb.Append($"[{slot}]=tid{tid}"); } + return sb.ToString(); } } @@ -1542,34 +1616,38 @@ namespace CSNetwork.GPDataType { public int idTarget; public int idSkill; - public int iDamage; // Èç¹ûÊÇ0±íʾûÓл÷ÖÐ - public int attack_flag; // ±ê¼Ç¸Ã¹¥»÷ÊÇ·ñÓй¥»÷ÓÅ»¯·ûºÍ·ÀÓùÓÅ»¯·ûºÍÖØ»÷·¢Éú + public int iDamage; // Èç¹ûÊÇ0±íʾûÓл÷ÖÐ + public int attack_flag; // ±ê¼Ç¸Ã¹¥»÷ÊÇ·ñÓй¥»÷ÓÅ»¯·ûºÍ·ÀÓùÓÅ»¯·ûºÍÖØ»÷·¢Éú public byte attack_speed; public byte section; }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_host_skill_attacked - { - public int idAttacker; - public int idSkill; - public int iDamage; - public byte cEquipment; // The equipment which is mangled, ��λ������ι����Dz���Ӧ�ñ��ɫ + { + public int idAttacker; + public int idSkill; + public int iDamage; + public byte cEquipment; // The equipment which is mangled, ��λ������ι����Dz���Ӧ�ñ��ɫ + + public int attack_flag; //��Ǹù����Ƿ��й����Ż����ͷ����Ż������ػ����� + public byte speed; //�����ٶ� speed * 50 ms + public byte section; // skill section + }; - public int attack_flag; //��Ǹù����Ƿ��й����Ż����ͷ����Ż������ػ����� - public byte speed; //�����ٶ� speed * 50 ms - public byte section; // skill section - }; [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_matter_info_list { public ushort count; public info_matter Info; } + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_matter_enter_world { public info_matter Info; }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_host_obtain_item { @@ -1580,6 +1658,7 @@ namespace CSNetwork.GPDataType public byte where; public byte index; }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_pickup_item { @@ -1590,6 +1669,7 @@ namespace CSNetwork.GPDataType public byte byPackage; public byte bySlot; } + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_pickup_money { @@ -1616,8 +1696,8 @@ namespace CSNetwork.GPDataType public int type; public uint amount; public uint slot_amount; - public byte where; // Which package: 0 standard, 2 trash, 1 equip - public byte index; // Which slot in that package + public byte where; // Which package: 0 standard, 2 trash, 1 equip + public byte index; // Which slot in that package } [StructLayout(LayoutKind.Sequential, Pack = 1)] @@ -1625,6 +1705,7 @@ namespace CSNetwork.GPDataType { public int type; } + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct info_matter { @@ -1645,6 +1726,7 @@ namespace CSNetwork.GPDataType public ushort count; public byte placeholder; // info_player_1 list } + public enum ChatChannel { //Õâ¸öö¾Ù¶¨ÒåÈç¹û¸Ä¶¯µÄ»°£¬ÒªÍ¨ÖªËùÓÐÈË£¬°üÀ¨·þÎñÆ÷³ÌÐòÔ± @@ -1666,69 +1748,71 @@ namespace CSNetwork.GPDataType GP_CHAT_COUNTRY, GP_CHAT_MAX, }; + // Player and NPC state public static class PlayerNPCState { public const int GP_STATE_SHAPE = 0x00000001, - GP_STATE_EMOTE = 0x00000002, - GP_STATE_INVADER = 0x00000004, - GP_STATE_SITDOWN = 0x00000020, - GP_STATE_EXTEND_PROPERTY = 0x00000040, - GP_STATE_CORPSE = 0x00000080, + GP_STATE_EMOTE = 0x00000002, + GP_STATE_INVADER = 0x00000004, + GP_STATE_SITDOWN = 0x00000020, + GP_STATE_EXTEND_PROPERTY = 0x00000040, + GP_STATE_CORPSE = 0x00000080, - // Used only by player - GP_STATE_PARIAH = 0x00000008, - GP_STATE_FLY = 0x00000010, - GP_STATE_TEAM = 0x00000100, - GP_STATE_TEAMLEADER = 0x00000200, - GP_STATE_ADV_MODE = 0x00000400, - GP_STATE_FACTION = 0x00000800, - GP_STATE_BOOTH = 0x00001000, - GP_STATE_FASHION = 0x00002000, - GP_STATE_GMFLAG = 0x00004000, - GP_STATE_PVPFLAG = 0x00008000, - GP_STATE_EFFECT = 0x00010000, - GP_STATE_INPVPCOMBAT = 0x00020000, - GP_STATE_IN_DUEL = 0x00040000, // ÊÇ·ñÕýÔÚ¾ö¶·ÖÐ - GP_STATE_IN_MOUNT = 0x00080000, // ÕýÔÚÆï³ËÖÐ - GP_STATE_IN_BIND = 0x00100000, // ºÍ±ðÈ˰óÔÚÒ»Æð - GP_STATE_BC_INVADER = 0x00200000, // Battle camp: invader - GP_STATE_BC_DEFENDER = 0x00400000, // Battle camp: defender - GP_STATE_SPOUSE = 0x00800000, // Åäżid - GP_STATE_GOBLINREFINE = 0x01000000, // С¾«ÁéÊÇ·ñÒѾ­¼¤»î - GP_STATE_SHIELDUSER = 0x02000000, // ÊÇ·ñÍêÃÀÉñ¶ÜÓû§ - GP_STATE_INVISIBLE = 0x04000000, // ÒþÉí - GP_STATE_EQUIPDISABLED = 0x08000000, // Equipment disabled - GP_STATE_FORBIDBESELECTED = 0x10000000, // ½ûÖ¹±»Ñ¡ÖÐ (NPCÒ²ÓÐЧ) - GP_STATE_PLAYERFORCE = 0x20000000, // ÒѼÓÈëÊÆÁ¦ - GP_STATE_MULTIOBJ_EFFECT = 0x40000000; // ÓëÆäËû¶ÔÏó´æÔÚÌØÊâЧ¹û - public const uint GP_STATE_COUNTRY = 0x80000000; //ÒѼÓÈë¹ú¼Ò + // Used only by player + GP_STATE_PARIAH = 0x00000008, + GP_STATE_FLY = 0x00000010, + GP_STATE_TEAM = 0x00000100, + GP_STATE_TEAMLEADER = 0x00000200, + GP_STATE_ADV_MODE = 0x00000400, + GP_STATE_FACTION = 0x00000800, + GP_STATE_BOOTH = 0x00001000, + GP_STATE_FASHION = 0x00002000, + GP_STATE_GMFLAG = 0x00004000, + GP_STATE_PVPFLAG = 0x00008000, + GP_STATE_EFFECT = 0x00010000, + GP_STATE_INPVPCOMBAT = 0x00020000, + GP_STATE_IN_DUEL = 0x00040000, // ÊÇ·ñÕýÔÚ¾ö¶·ÖÐ + GP_STATE_IN_MOUNT = 0x00080000, // ÕýÔÚÆï³ËÖÐ + GP_STATE_IN_BIND = 0x00100000, // ºÍ±ðÈ˰óÔÚÒ»Æð + GP_STATE_BC_INVADER = 0x00200000, // Battle camp: invader + GP_STATE_BC_DEFENDER = 0x00400000, // Battle camp: defender + GP_STATE_SPOUSE = 0x00800000, // Åäżid + GP_STATE_GOBLINREFINE = 0x01000000, // С¾«ÁéÊÇ·ñÒѾ­¼¤»î + GP_STATE_SHIELDUSER = 0x02000000, // ÊÇ·ñÍêÃÀÉñ¶ÜÓû§ + GP_STATE_INVISIBLE = 0x04000000, // ÒþÉí + GP_STATE_EQUIPDISABLED = 0x08000000, // Equipment disabled + GP_STATE_FORBIDBESELECTED = 0x10000000, // ½ûÖ¹±»Ñ¡ÖÐ (NPCÒ²ÓÐЧ) + GP_STATE_PLAYERFORCE = 0x20000000, // ÒѼÓÈëÊÆÁ¦ + GP_STATE_MULTIOBJ_EFFECT = 0x40000000; // ÓëÆäËû¶ÔÏó´æÔÚÌØÊâЧ¹û + + public const uint GP_STATE_COUNTRY = 0x80000000; //ÒѼÓÈë¹ú¼Ò // Used only by NPC public const int GP_STATE_NPC_DELAYDEAD = 0x00000008, - GP_STATE_NPC_ADDON1 = 0x00000100, - GP_STATE_NPC_ADDON2 = 0x00000200, - GP_STATE_NPC_ADDON3 = 0x00000400, - GP_STATE_NPC_ADDON4 = 0x00000800, - GP_STATE_NPC_ALLADDON = 0x00000F00, - GP_STATE_NPC_PET = 0x00001000, // Pet flag - GP_STATE_NPC_NAME = 0x00002000, - GP_STATE_NPC_FIXDIR = 0x00004000, // ·½Ïò¹Ì¶¨ - GP_STATE_NPC_MAFIA = 0x00008000, // ËùÊô°ïÅÉ£¨ÓÃÓÚ°ïÅÉPVPÖп󳵵ȣ© - GP_STATE_NPC_FLY = 0x00010000, - GP_STATE_NPC_SWIM = 0x00020000; + GP_STATE_NPC_ADDON1 = 0x00000100, + GP_STATE_NPC_ADDON2 = 0x00000200, + GP_STATE_NPC_ADDON3 = 0x00000400, + GP_STATE_NPC_ADDON4 = 0x00000800, + GP_STATE_NPC_ALLADDON = 0x00000F00, + GP_STATE_NPC_PET = 0x00001000, // Pet flag + GP_STATE_NPC_NAME = 0x00002000, + GP_STATE_NPC_FIXDIR = 0x00004000, // ·½Ïò¹Ì¶¨ + GP_STATE_NPC_MAFIA = 0x00008000, // ËùÊô°ïÅÉ£¨ÓÃÓÚ°ïÅÉPVPÖп󳵵ȣ© + GP_STATE_NPC_FLY = 0x00010000, + GP_STATE_NPC_SWIM = 0x00020000; }; // Player and NPC state2 public static class PlayerNPCState2 { - public const int GP_STATE2_ISKING = 0x00000001, // Íæ¼ÒÊÇ·ñ¹úÍõ - GP_STATE2_TITLE = 0x00000002, // ³ÆºÅ - GP_STATE2_REINCARNATION = 0x00000004, // תÉú - GP_STATE2_REALM = 0x00000008, // ¾³½ç - GP_STATE2_IN_BATTLE = 0x00000010, // Õ½¶·×´Ì¬ - GP_STATE2_FACTION_PVP_MASK = 0X00000020, // °ïÅÉ PVP Mask - GP_STATE2_GENDER = 0x00000040; // ÐÔ±ð + public const int GP_STATE2_ISKING = 0x00000001, // Íæ¼ÒÊÇ·ñ¹úÍõ + GP_STATE2_TITLE = 0x00000002, // ³ÆºÅ + GP_STATE2_REINCARNATION = 0x00000004, // תÉú + GP_STATE2_REALM = 0x00000008, // ¾³½ç + GP_STATE2_IN_BATTLE = 0x00000010, // Õ½¶·×´Ì¬ + GP_STATE2_FACTION_PVP_MASK = 0X00000020, // °ïÅÉ PVP Mask + GP_STATE2_GENDER = 0x00000040; // ÐÔ±ð } [Flags] @@ -1737,7 +1821,7 @@ namespace CSNetwork.GPDataType { MOVE_STAND = 0, - MOVE_MOVE, // Normal move, walk, run, swim or fly + MOVE_MOVE, // Normal move, walk, run, swim or fly MOVE_JUMP, MOVE_FREEFALL, MOVE_SLIDE, @@ -1752,16 +1836,36 @@ namespace CSNetwork.GPDataType MOVEENV_WATER, MOVEENV_AIR, }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_out_of_sight_list { public uint uCount; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public int[] idList; } + public static class NumberDWORDsPlayerNPC { - public const int OBJECT_EXT_STATE_COUNT = 6; // Íæ¼Ò/NPC ÉíÉÏ״̬¹âЧ DWORD ¸öÊý = Number of DWORDs for player/NPC status effects + public const int + OBJECT_EXT_STATE_COUNT = + 6; // Íæ¼Ò/NPC ÉíÉÏ״̬¹âЧ DWORD ¸öÊý = Number of DWORDs for player/NPC status effects + }; + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct cmd_be_hurt + { + public int attacker_id; + public int damage; + public byte flag; // 1, attacker ±ä³ÈÃû + }; + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct cmd_hurt_result + { + public int target_id; + public int damage; }; public static class GPDataTypeHelper @@ -1832,7 +1936,7 @@ namespace CSNetwork.GPDataType Marshal.FreeHGlobal(ptr); } } - + /// /// Convert data become byte array (Demo) /// @@ -1841,39 +1945,43 @@ namespace CSNetwork.GPDataType /// Removes the number of leading bytes /// Remove the last byte count /// - public static byte[] ContentBytes(int dataTypeLenght, int totalSize, int lenghtHeaderIgnore, int lenghtLastIgnore = 0) + public static byte[] ContentBytes(int dataTypeLenght, int totalSize, int lenghtHeaderIgnore, + int lenghtLastIgnore = 0) { int dataLength = totalSize - (lenghtHeaderIgnore + lenghtLastIgnore); - if(dataLength <= 0) throw new ArgumentException("Buffer không đủ dữ liệu"); + if (dataLength <= 0) throw new ArgumentException("Buffer không đủ dữ liệu"); byte[] dataContent = new byte[dataLength]; int offset = dataTypeLenght; - + for (int i = 0; i < dataLength; i++) { dataContent[i] = FromBytes(dataContent, offset); offset += dataTypeLenght; } + return dataContent; } - + public static byte[] ContentBytes(int totalSize, int lenghtHeaderIgnore, int lenghtLastIgnore = 0) { int dataLength = totalSize - (lenghtHeaderIgnore + lenghtLastIgnore); - if(dataLength <= 0) throw new ArgumentException("Buffer không đủ dữ liệu"); + if (dataLength <= 0) throw new ArgumentException("Buffer không đủ dữ liệu"); byte[] dataContent = new byte[dataLength]; int dataTypeSize = Marshal.SizeOf(); int offset = dataTypeSize; - + for (int i = 0; i < dataLength; i++) { dataContent[i] = FromBytes(dataContent, offset); offset += dataTypeSize; } + return dataContent; } - + /// Parse variable-length cmd_team_member_data from buffer. Returns (header, data[]) and bytes consumed. - public static (cmd_team_member_data_header header, cmd_team_member_data_MEMBER[] data) ParseTeamMemberData(byte[] data, int startIndex = 0) + public static (cmd_team_member_data_header header, cmd_team_member_data_MEMBER[] data) ParseTeamMemberData( + byte[] data, int startIndex = 0) { int hdrSize = Marshal.SizeOf(); if (data.Length - startIndex < hdrSize) @@ -1893,10 +2001,12 @@ namespace CSNetwork.GPDataType { return id != 0 && (id & 0x80000000) == 0; } + public static bool ISNPCID(int id) { return (id & 0x80000000) != 0 && (id & 0x40000000) == 0; } + public static string ReplacePercentD(string fmt, params object[] args) { if (string.IsNullOrEmpty(fmt) || args == null || args.Length == 0) @@ -1908,6 +2018,7 @@ namespace CSNetwork.GPDataType if (idx < 0) break; // hết %d fmt = fmt.Substring(0, idx) + args[i]?.ToString() + fmt.Substring(idx + 2); } + return fmt; } @@ -1932,12 +2043,14 @@ namespace CSNetwork.GPDataType i++; continue; } + if (fmt[i + 1] == '%') { sb.Append('%'); i += 2; continue; } + // %.Nf if (i + 2 < fmt.Length && fmt[i + 1] == '.' && char.IsDigit(fmt[i + 2])) { @@ -1952,6 +2065,7 @@ namespace CSNetwork.GPDataType continue; } } + if (fmt[i + 1] == 'd' && argIndex < args.Length) { object a = args[argIndex++]; @@ -1963,6 +2077,7 @@ namespace CSNetwork.GPDataType i += 2; continue; } + if (fmt[i + 1] == 'f' && argIndex < args.Length) { double val = Convert.ToDouble(args[argIndex++], CultureInfo.InvariantCulture); @@ -1970,11 +2085,14 @@ namespace CSNetwork.GPDataType i += 2; continue; } + sb.Append(fmt[i]); i++; } + return sb.ToString(); } + public static bool ISMONEYTID(int tid) { return tid == 3044; @@ -2047,36 +2165,39 @@ namespace CSNetwork.GPDataType Marshal.FreeHGlobal(buffer); } } - } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_skill_data { public uint skill_count; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct SKILL { public short id_skill; public byte level; public short ability; - } + public SKILL[] skill_list; } + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_scene_service_npc_list { public uint count; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct NpcEntry { - public int tid; // npc template id - public int nid; // npc id + public int tid; // npc template id + public int nid; // npc id } - public NpcEntry[] list; + public NpcEntry[] list; } + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_object_cast_skill { @@ -2086,6 +2207,7 @@ namespace CSNetwork.GPDataType public ushort time; public byte level; }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_npc_info_list { @@ -2129,12 +2251,14 @@ namespace CSNetwork.GPDataType public int nid; public int vis_tid; }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] // sizeof = 36 với padding 1 byte sau dir public struct cmd_cooltime_data { public ushort count; public item_t[] list; } + [StructLayout(LayoutKind.Sequential, Pack = 1)] // sizeof = 36 với padding 1 byte sau dir public struct item_t { @@ -2142,13 +2266,14 @@ namespace CSNetwork.GPDataType public int cooldown; public int max_cooltime; } + public struct cmd_set_cooldown { public int cooldown_index; public int cooldown_time; }; - [StructLayout(LayoutKind.Sequential, Pack = 1)] // sizeof = 36 với padding 1 byte sau dir + [StructLayout(LayoutKind.Sequential, Pack = 1)] // sizeof = 36 với padding 1 byte sau dir public struct cmd_npc_info_00 { public int idNPC; @@ -2156,15 +2281,18 @@ namespace CSNetwork.GPDataType public int iMaxHP; public int iTargetID; }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] // sizeof = 36 với padding 1 byte sau dir public struct info_npc { public int nid; - public int tid; // template id - public int vis_tid; // + public int tid; // template id + public int vis_tid; // public A3DVECTOR3 pos; - public ushort seed; // seed of customize data + public ushort seed; // seed of customize data + public byte dir; + // (1 byte padding ở đây để int tiếp theo align 4) public int state; public int state2; @@ -2173,7 +2301,9 @@ namespace CSNetwork.GPDataType // Offset và kích thước header theo layout ở trên (Pack=4) public static readonly int HEADER_SIZE = Marshal.SizeOf(); // sizeof(info_npc) với padding MSVC - public static readonly int STATE_OFFSET = Marshal.OffsetOf(nameof(state)).ToInt32(); // offset của 'state' trong header + + public static readonly int + STATE_OFFSET = Marshal.OffsetOf(nameof(state)).ToInt32(); // offset của 'state' trong header /// /// Bản chuyển C# tương đương CheckValid: kiểm tra buffer và tính kích thước tổng (sz). @@ -2242,6 +2372,7 @@ namespace CSNetwork.GPDataType return buffer.Length >= sz; } } + public enum OBJECT_EXT_STATE { OBJECT_EXT_STATE_COUNT = 6, // Íæ¼Ò/NPC ÉíÉÏ״̬¹âЧ DWORD ¸öÊý @@ -2251,8 +2382,8 @@ namespace CSNetwork.GPDataType public static class Player_camp_in_battle { public const int GP_BATTLE_CAMP_NONE = 0, - GP_BATTLE_CAMP_INVADER = 1, - GP_BATTLE_CAMP_DEFENDER = 2; + GP_BATTLE_CAMP_INVADER = 1, + GP_BATTLE_CAMP_DEFENDER = 2; }; // PVP mask @@ -2263,7 +2394,7 @@ namespace CSNetwork.GPDataType GP_PVPMASK_NOMAFIA = 0x0002, GP_PVPMASK_NOWHITE = 0x0004, GP_PVPMASK_NOALLIANCE = 0x0008, - GP_PVPMASK_NOFORCE = 0x0010,//²»¹¥»÷Í¬ÊÆÁ¦µÄ + GP_PVPMASK_NOFORCE = 0x0010, //²»¹¥»÷Í¬ÊÆÁ¦µÄ GP_BLSMASK_NORED = 0x0008, GP_BLSMASK_NOMAFIA = 0x0010, @@ -2276,12 +2407,14 @@ namespace CSNetwork.GPDataType { public int idTarget; }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_player_chgshape { public int idPlayer; public byte shape; }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_host_notify_root { @@ -2294,10 +2427,11 @@ namespace CSNetwork.GPDataType { public byte type; }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_npc_greeting { - public int idObject; // ID of NPC or player + public int idObject; // ID of NPC or player }; public struct cmd_activate_waypoint @@ -2307,7 +2441,7 @@ namespace CSNetwork.GPDataType public struct cmd_waypoint_list { - public uint count; + public uint count; public ushort[] list; public bool FromBytes(byte[] data) @@ -2362,19 +2496,21 @@ namespace CSNetwork.GPDataType public static class GNETRoles { public const int _R_UNMEMBER = 0, - _R_SYSTEM = 1, - _R_MASTER = 2, - _R_VICEMASTER = 3, - _R_BODYGUARD = 4, - _R_POINEER = 5, - _R_MEMBER = 6; + _R_SYSTEM = 1, + _R_MASTER = 2, + _R_VICEMASTER = 3, + _R_BODYGUARD = 4, + _R_POINEER = 5, + _R_MEMBER = 6; }; //end of Roles + public struct cmd_server_time { public int time; public int timebias; public int lua_version; }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_object_cast_instant_skill { @@ -2383,6 +2519,7 @@ namespace CSNetwork.GPDataType public int skill; public byte level; }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_object_cast_pos_skill { @@ -2393,12 +2530,14 @@ namespace CSNetwork.GPDataType public ushort time; public byte level; }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_query_title_re { public int roleid; public int titlescount; public int expirecount; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public ushort[] titles; @@ -2408,6 +2547,7 @@ namespace CSNetwork.GPDataType public ushort id; public int time; } + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public _entry[] data; @@ -2453,10 +2593,9 @@ namespace CSNetwork.GPDataType return true; } - }; - [StructLayout(LayoutKind.Sequential, Pack = 1)] + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_object_start_play_action { public int id; @@ -2466,6 +2605,7 @@ namespace CSNetwork.GPDataType public uint name_length; public char[] action_name; } + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_change_curr_title_re { @@ -2491,10 +2631,11 @@ namespace CSNetwork.GPDataType public struct cmd_task_notify { public uint size; + // In C++, placeholder is byte. It used to first byte of a byte[] data // but in C# we need to define it as byte[] to hold the whole data. //public byte placeholder; // Task data ... - public byte[] placeholder; // Task data ... + public byte[] placeholder; // Task data ... } // PLAYER_EXT_PROP_BASE @@ -2533,8 +2674,8 @@ namespace CSNetwork.GPDataType public struct cmd_own_ext_prop { public uint status_point; - public int attack_degree; //¹¥»÷µÈ¼¶ - public int defend_degree; //·ÀÓùµÈ¼¶ + public int attack_degree; //¹¥»÷µÈ¼¶ + public int defend_degree; //·ÀÓùµÈ¼¶ public int crit_rate; public int crit_damage_bonus; public int invisible_degree; @@ -2548,7 +2689,7 @@ namespace CSNetwork.GPDataType [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_auto_team_set_goal { - public int goal_type; // 0 unknown, 1 task, 2 Activity + public int goal_type; // 0 unknown, 1 task, 2 Activity public int op; public int goal_id; }; @@ -2593,7 +2734,7 @@ namespace CSNetwork.GPDataType [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_duel_reply { - public int who; // inviter character id (who sent the duel request) + public int who; // inviter character id (who sent the duel request) public int param; // 0 = accept (同意), non-zero = reject reason (拒绝原因) } @@ -2658,15 +2799,15 @@ namespace CSNetwork.GPDataType [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_player_gather_start { - public int pid; // player id - public int mid; // mine id + public int pid; // player id + public int mid; // mine id public byte use_time; // use time in sec; }; [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_player_gather_stop { - public int pid; // player id + public int pid; // player id }; [StructLayout(LayoutKind.Sequential, Pack = 1)] @@ -2678,7 +2819,6 @@ namespace CSNetwork.GPDataType }; [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct cmd_object_takeoff { public int object_id; @@ -2695,18 +2835,22 @@ namespace CSNetwork.GPDataType { public byte is_active; }; + public struct cmd_reincarnation_tome_info { public int tome_exp; - public char tome_active; // 1����0δ���� + public char tome_active; // 1����0δ���� public int count; + public struct _entry { public int level; public int timestamp; public int exp; }; + public _entry[] records; + public bool CheckValid(int buf_size, out int sz) { sz = 0; @@ -2723,10 +2867,10 @@ namespace CSNetwork.GPDataType { GP_PET_CLASS_INVALID = -1, GP_PET_CLASS_MOUNT = 0, // ��� - GP_PET_CLASS_COMBAT, // ս������ - GP_PET_CLASS_FOLLOW, // ������� - GP_PET_CLASS_SUMMON, // �ٻ����� - GP_PET_CLASS_PLANT, // ֲ�ֻ��Ϊ�˺ͷ�������ֵ����һ�£��ͻ���û���õ� + GP_PET_CLASS_COMBAT, // ս������ + GP_PET_CLASS_FOLLOW, // ������� + GP_PET_CLASS_SUMMON, // �ٻ����� + GP_PET_CLASS_PLANT, // ֲ�ֻ��Ϊ�˺ͷ�������ֵ����һ�£��ͻ���û���õ� GP_PET_CLASS_EVOLUTION, // ������ GP_PET_CLASS_MAX, }; @@ -2735,8 +2879,8 @@ namespace CSNetwork.GPDataType { public int skill; public int level; - } + public struct _evo_prop { public int r_attack; @@ -2746,40 +2890,47 @@ namespace CSNetwork.GPDataType public int r_def_lvl; public int nature; } + public enum GP_PET_SKILL_NUM { GP_PET_SKILL_NUM = 8 }; + public struct info_pet { - public int honor_point; // ºÃ¸Ð¶È - public int hunger; // ¼¢¶ö¶È - public int feed_time; // ÉÏ´ÎÎ¹Ñøµ½ÏÖÔÚµÄʱ¼ä - public int pet_tid; // ³èÎïµÄÄ£°åID - public int pet_vis_tid; // ³èÎïµÄ¿É¼ûID£¨Èç¹ûΪ0£¬Ôò±íʾÎÞÌØÊâ¿É¼ûID£© - public int pet_egg_tid; // ³èÎïµ°µÄID - public int pet_class; // ³èÎïÀàÐÍ Õ½³è£¬Æï³è£¬¹ÛÉͳè - public float hp_factor; // ѪÁ¿±ÈÀý£¨¸´»îºÍÊÕ»ØÊ±Ê¹Óã© 0ÔòΪËÀÍö - public short level; // ³èÎï¼¶±ð - public ushort color; // ³èÎïÑÕÉ«£¬×î¸ßλΪ1±íʾÓÐЧ£¬Ä¿Ç°½ö¶ÔÆï³èÓÐЧ - public int exp; // ³èÎﵱǰ¾­Ñé - public int skill_point; // Ê£Ó༼Äܵã - public char is_bind; // ÊÇ·ñÌìÈ˺ÏÒ»£¬ÏÖÔÚÊÇÒ»¸öMask£¬0x01 ÌìÈ˺ÏÒ»£¬0x02 Ѱ±¦Íø¿É½»Ò× - public char unused; // Ŀǰ´ËÏîÎÞЧ - public ushort name_len; // Ãû×Ö³¤¶È Ŀǰ´ËÏîÎÞЧ£¨ÒòΪ²ß»®ÉÐÎÞÃû×ÖÐèÇó£© + public int honor_point; // ºÃ¸Ð¶È + public int hunger; // ¼¢¶ö¶È + public int feed_time; // ÉÏ´ÎÎ¹Ñøµ½ÏÖÔÚµÄʱ¼ä + public int pet_tid; // ³èÎïµÄÄ£°åID + public int pet_vis_tid; // ³èÎïµÄ¿É¼ûID£¨Èç¹ûΪ0£¬Ôò±íʾÎÞÌØÊâ¿É¼ûID£© + public int pet_egg_tid; // ³èÎïµ°µÄID + public int pet_class; // ³èÎïÀàÐÍ Õ½³è£¬Æï³è£¬¹ÛÉͳè + public float hp_factor; // ѪÁ¿±ÈÀý£¨¸´»îºÍÊÕ»ØÊ±Ê¹Óã© 0ÔòΪËÀÍö + public short level; // ³èÎï¼¶±ð + public ushort color; // ³èÎïÑÕÉ«£¬×î¸ßλΪ1±íʾÓÐЧ£¬Ä¿Ç°½ö¶ÔÆï³èÓÐЧ + public int exp; // ³èÎﵱǰ¾­Ñé + public int skill_point; // Ê£Ó༼Äܵã + public char is_bind; // ÊÇ·ñÌìÈ˺ÏÒ»£¬ÏÖÔÚÊÇÒ»¸öMask£¬0x01 ÌìÈ˺ÏÒ»£¬0x02 Ѱ±¦Íø¿É½»Ò× + public char unused; // Ŀǰ´ËÏîÎÞЧ + public ushort name_len; // Ãû×Ö³¤¶È Ŀǰ´ËÏîÎÞЧ£¨ÒòΪ²ß»®ÉÐÎÞÃû×ÖÐèÇó£© public _evo_prop evo_prop; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] - public char[] name; // Ãû×ÖÄÚÈÝ + public char[] name; // Ãû×ÖÄÚÈÝ + [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)GP_PET_SKILL_NUM.GP_PET_SKILL_NUM)] public _skills[] skills; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] public int[] reserved; // δÓà }; + public enum REFUSE_BLESS_MASK : byte { - REFUSE_NEUTRAL_BLESS = 0x0001, // ²»½ÓÊÜÖÐÐÔ×£¸£ + REFUSE_NEUTRAL_BLESS = 0x0001, // ²»½ÓÊÜÖÐÐÔ×£¸£ REFUSE_NON_TEAMMATE_BLESS = 0x0002, // ²»½ÓÊܷǶÓÓÑ×£¸£ }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_notify_force_attack { @@ -2819,21 +2970,21 @@ namespace CSNetwork.GPDataType public struct cmd_plant_pet_disapper { public int plant_nid; - public char reason; // 0 ËÀÍö£¬1 ÊÙÃüµ½£¬2 ³¬³ö·¶Î§£¬3 ×Ô±¬£¬4 ÊýÁ¿³¬³ö×éÉÏÏÞ + public char reason; // 0 ËÀÍö£¬1 ÊÙÃüµ½£¬2 ³¬³ö·¶Î§£¬3 ×Ô±¬£¬4 ÊýÁ¿³¬³ö×éÉÏÏÞ }; [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_gain_pet { - public int slot_index; // ´Ë³èÎï·ÅÓÚ³èÎïÀ¸ÄÚµÄλÖà - public info_pet data; // pet data + public int slot_index; // ´Ë³èÎï·ÅÓÚ³èÎïÀ¸ÄÚµÄλÖà + public info_pet data; // pet data }; [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_free_pet { public int slot_index; - public int pet_id; // ³èÎïµÄid£¬ÎÞ´óÓà + public int pet_id; // ³èÎïµÄid£¬ÎÞ´óÓà }; [StructLayout(LayoutKind.Sequential, Pack = 1)] @@ -2855,10 +3006,10 @@ namespace CSNetwork.GPDataType public enum PET_RECALL_REASON { - PET_RECALL_DEFAULT, // ĬÈÏÕٻأ¬Ö÷ÒªÔ­ÒòÎªÍæ¼ÒÖ÷¶¯Õٻء¢Íæ¼ÒÕÙ»½³öÆäËüÔ­Òòµ¼ÖÂÔ­ÓгèÎïÕÙ»ØµÈ - PET_RECALL_DEATH, // ³èÎïËÀÍöµ¼ÖÂÕÙ»ØÏûÏ¢ - PET_RECALL_LIFE_EXHAUST, // ³èÎïʱÏÞµ½ - PET_RECALL_SACRIFICE, // ³èÎïÎþÉü£¨Íæ¼ÒʹÓü¼Äܵȵ¼Ö£© + PET_RECALL_DEFAULT, // ĬÈÏÕٻأ¬Ö÷ÒªÔ­ÒòÎªÍæ¼ÒÖ÷¶¯Õٻء¢Íæ¼ÒÕÙ»½³öÆäËüÔ­Òòµ¼ÖÂÔ­ÓгèÎïÕÙ»ØµÈ + PET_RECALL_DEATH, // ³èÎïËÀÍöµ¼ÖÂÕÙ»ØÏûÏ¢ + PET_RECALL_LIFE_EXHAUST, // ³èÎïʱÏÞµ½ + PET_RECALL_SACRIFICE, // ³èÎïÎþÉü£¨Íæ¼ÒʹÓü¼Äܵȵ¼Ö£© }; [StructLayout(LayoutKind.Sequential, Pack = 1)] @@ -2866,8 +3017,8 @@ namespace CSNetwork.GPDataType { public int slot_index; public int pet_id; - public int delay; // ÑÓ³Ùʱ¼ä£¬µ¥Î»ÊÇ50msµÄtick - public int op; // ²Ù×÷ÀàÐÍ 0:·Å³ö 1:ÕÙ»Ø 2:·ÅÉú + public int delay; // ÑÓ³Ùʱ¼ä£¬µ¥Î»ÊÇ50msµÄtick + public int op; // ²Ù×÷ÀàÐÍ 0:·Å³ö 1:ÕÙ»Ø 2:·ÅÉú }; [StructLayout(LayoutKind.Sequential, Pack = 1)] @@ -2883,8 +3034,8 @@ namespace CSNetwork.GPDataType { public int slot_index; public int pet_id; - public int level; // м¶±ð - public int exp; // µ±Ç°µÄ¾­ÑéÖµ + public int level; // м¶±ð + public int exp; // µ±Ç°µÄ¾­ÑéÖµ }; [StructLayout(LayoutKind.Sequential, Pack = 1)] @@ -2933,8 +3084,8 @@ namespace CSNetwork.GPDataType [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_pet_ai_state { - public byte attack; // 0 ·ÀÓùÐÍ; 1 Ö÷¶¯ÐÍ; 2 ±»¶¯ÐÍ - public byte move; // 0 ¸úËæ; 1 Ô­µØÍ£Áô + public byte attack; // 0 ·ÀÓùÐÍ; 1 Ö÷¶¯ÐÍ; 2 ±»¶¯ÐÍ + public byte move; // 0 ¸úËæ; 1 Ô­µØÍ£Áô }; [StructLayout(LayoutKind.Sequential, Pack = 1)] @@ -2956,7 +3107,7 @@ namespace CSNetwork.GPDataType public struct cmd_set_player_limit { public int index; - public char b; // 1 ÏÞÖÆ 0 ²»ÏÞÖÆ + public char b; // 1 ÏÞÖÆ 0 ²»ÏÞÖÆ }; [StructLayout(LayoutKind.Sequential, Pack = 1)] @@ -2966,11 +3117,13 @@ namespace CSNetwork.GPDataType public int mount_id; public ushort mount_color; }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_set_move_stamp { public ushort move_stamp; }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_summon_plant_pet { @@ -2988,12 +3141,14 @@ namespace CSNetwork.GPDataType public float mp_factor; public int cur_mp; }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_clear_tessera { public ushort equip_idx; public uint cost; }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_icon_state_notify { @@ -3060,22 +3215,27 @@ namespace CSNetwork.GPDataType else { // Not enough parameters decoded - return false; + return false; } } + states.Add(dummy); } + return true; } } + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct IconState { public ushort id; public int pcount; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public int[] param; }; + // player leaves the world [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_player_leave_world @@ -3086,19 +3246,19 @@ namespace CSNetwork.GPDataType [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_object_enter_sanctuary { - public int id; // self id or pet id. + public int id; // self id or pet id. }; [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_object_leave_sanctuary { - public int id; // self id or pet id. + public int id; // self id or pet id. }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_receive_exp - { - public int exp; - public int sp; - }; + { + public int exp; + public int sp; + }; } - diff --git a/Assets/PerfectWorld/Scripts/Sound/WorldMusicController.cs b/Assets/PerfectWorld/Scripts/Sound/WorldMusicController.cs index cb0e5e4dd7..dab862bc9b 100644 --- a/Assets/PerfectWorld/Scripts/Sound/WorldMusicController.cs +++ b/Assets/PerfectWorld/Scripts/Sound/WorldMusicController.cs @@ -33,7 +33,6 @@ namespace BrewMonster.Scripts /// public void InitForWorld(int worldTag) { - BMLogger.LogError("HoangDev: InitForWorld worldTag:"+worldTag); AudioManager.Instance.StopBGM(1f); SetupAudioSources(worldTag).Forget(); } diff --git a/Assets/PerfectWorld/Scripts/UI/GamePlay/SkillUI/CDlgSkillSubListItem.cs b/Assets/PerfectWorld/Scripts/UI/GamePlay/SkillUI/CDlgSkillSubListItem.cs index 5fd18450fc..1b1ffd1083 100644 --- a/Assets/PerfectWorld/Scripts/UI/GamePlay/SkillUI/CDlgSkillSubListItem.cs +++ b/Assets/PerfectWorld/Scripts/UI/GamePlay/SkillUI/CDlgSkillSubListItem.cs @@ -276,8 +276,6 @@ namespace BrewMonster int curSp = GetHostPlayer().GetBasicProps().iSP; uint curMoney = GetHostPlayer().GetMoneyAmount(); - if (m_skillID == 1) - BMLogger.LogError($"HoangDev: UpdateUpgradeBtn curSp:{curSp}, needSp:{needSp}, curMoney:{curMoney}, needMoney:{needMoney}"); bool spOK = curSp >= needSp; bool moneyOK = curMoney >= needMoney; bool preSkillOK = true; diff --git a/Assets/PerfectWorld/Scripts/UI/SkillUI/DlgAssignSlots.cs b/Assets/PerfectWorld/Scripts/UI/SkillUI/DlgAssignSlots.cs index 2754b955ae..c22c24898d 100644 --- a/Assets/PerfectWorld/Scripts/UI/SkillUI/DlgAssignSlots.cs +++ b/Assets/PerfectWorld/Scripts/UI/SkillUI/DlgAssignSlots.cs @@ -528,7 +528,6 @@ namespace BrewMonster ClearPendingComboAssign(); ClearPendingActionAssign(); assignedSkill = CECGameRun.Instance.GetHostPlayer().GetPositiveSkillByID(obj.skillID); - Debug.Log($"HoangDev: OnAssignSkillSelectionChanged: skillID={obj.skillID} currentSelectedSlotIndex={currentSelectedSlotIndex}"); if (currentSelectedSlotIndex != -1) { CreateSkillShortcut(); diff --git a/Assets/Resources/multi_section_skill.txt b/Assets/Resources/multi_section_skill.txt new file mode 100644 index 0000000000..11079476a9 --- /dev/null +++ b/Assets/Resources/multi_section_skill.txt @@ -0,0 +1,279 @@ +skill: 2212 +{ +(1,1,gfx\\sgc\\̿__.sgc), +(2,2,gfx\\sgc\\̿__.sgc) +} + +skill: 2213 +{ +(1,1,gfx\\sgc\\̿__.sgc), +(2,2,gfx\\sgc\\̿__.sgc) +} + +skill: 2214 +{ +(1,1,gfx\\sgc\\̿_նɱ_.sgc), +(2,2,gfx\\sgc\\̿_նɱ_.sgc), +(3,3,gfx\\sgc\\̿_նɱ_.sgc), +(4,4,gfx\\sgc\\̿_նɱ_.sgc), +(5,5,gfx\\sgc\\̿_նɱ_.sgc) +} + +skill: 2215 +{ +(1,1,gfx\\sgc\\̿_նɱ_.sgc), +(2,2,gfx\\sgc\\̿_նɱ_.sgc), +(3,3,gfx\\sgc\\̿_նɱ_.sgc), +(4,4,gfx\\sgc\\̿_նɱ_.sgc), +(5,5,gfx\\sgc\\̿_նɱ_.sgc) +} + +skill: 2452 +{ +(1,1,gfx\\sgc\\ʦ__.sgc), +(2,2,gfx\\sgc\\ʦ__.sgc) +} + +skill: 2453 +{ +(1,1,gfx\\sgc\\ʦ__.sgc), +(2,2,gfx\\sgc\\ʦ__.sgc) +} + +skill: 2316 +{ +(1,1,gfx\\sgc\\̿__.sgc), +(2,2,gfx\\sgc\\̿__.sgc) +} + +skill: 2366 +{ +(1,1,gfx\\sgc\\̿__.sgc), +(2,2,gfx\\sgc\\̿__.sgc), +(3,3,gfx\\sgc\\̿__.sgc), +(4,4,gfx\\sgc\\̿__.sgc) +} + +skill: 2451 +{ +(1,1,gfx\\sgc\\̿__.sgc), +(2,2,gfx\\sgc\\̿__.sgc), +(3,3,gfx\\sgc\\̿__.sgc), +(4,4,gfx\\sgc\\̿__.sgc) +} +skill: 2591 +{ +(1,1,gfx\\sgc\\_»_.sgc), +(2,2,gfx\\sgc\\_»_.sgc), +(3,3,gfx\\sgc\\_»_.sgc), +(4,4,gfx\\sgc\\_»_.sgc) +} +skill: 2582 +{ +(1,1,gfx\\sgc\\_ˮ_.sgc), +(2,2,gfx\\sgc\\_ˮ_.sgc), +(3,3,gfx\\sgc\\_ˮ_.sgc) +} +skill: 2557 +{ +(1,1,gfx\\sgc\\ҹӰ_粨_.sgc), +(2,2,gfx\\sgc\\ҹӰ_粨_.sgc), +(3,3,gfx\\sgc\\ҹӰ_粨_.sgc), +(4,4,gfx\\sgc\\ҹӰ_粨_.sgc) +} +skill: 2558 +{ +(1,1,gfx\\sgc\\ҹӰ_Ӱ_.sgc), +(2,2,gfx\\sgc\\ҹӰ_Ӱ_.sgc) +} +skill: 2567 +{ +(1,1,gfx\\sgc\\ҹӰ__.sgc), +(2,2,gfx\\sgc\\ҹӰ__.sgc), +(3,3,gfx\\sgc\\ҹӰ__.sgc) +} +skill: 2568 +{ +(1,1,gfx\\sgc\\ҹӰ__01.sgc), +(2,2,gfx\\sgc\\ҹӰ__02.sgc) +} +skill: 2551 +{ +(1,1,gfx\\sgc\\ҹӰ__.sgc), +(2,2,gfx\\sgc\\ҹӰ__.sgc), +(3,3,gfx\\sgc\\ҹӰ__.sgc), +(4,4,gfx\\sgc\\ҹӰ__.sgc) +} +skill: 2775 +{ +(1,1,gfx\\sgc\\ҹӰ__.sgc), +(2,2,gfx\\sgc\\ҹӰ__.sgc), +(3,3,gfx\\sgc\\ҹӰ__.sgc), +(4,4,gfx\\sgc\\ҹӰ__.sgc) +} +skill: 2821 +{ +(1,1,gfx\\sgc\\ҹӰ__.sgc), +(2,2,gfx\\sgc\\ҹӰ__.sgc), +(3,3,gfx\\sgc\\ҹӰ__.sgc), +(4,4,gfx\\sgc\\ҹӰ__.sgc) +} +skill: 2768 +{ +(1,1,gfx\\sgc\\ҹӰ__01.sgc), +(2,2,gfx\\sgc\\ҹӰ__02.sgc) +} +skill: 2769 +{ +(1,1,gfx\\sgc\\ҹӰ__01.sgc), +(2,2,gfx\\sgc\\ҹӰ__02.sgc) +} +skill: 2811 +{ +(1,1,gfx\\sgc\\_»_.sgc), +(2,2,gfx\\sgc\\_»_.sgc), +(3,3,gfx\\sgc\\_»_.sgc), +(4,4,gfx\\sgc\\_»_.sgc) +} +skill: 2812 +{ +(1,1,gfx\\sgc\\_»_.sgc), +(2,2,gfx\\sgc\\_»_.sgc), +(3,3,gfx\\sgc\\_»_.sgc), +(4,4,gfx\\sgc\\_»_.sgc) +} +skill: 2793 +{ +(1,1,gfx\\sgc\\_ˮ_.sgc), +(2,2,gfx\\sgc\\_ˮ_.sgc), +(3,3,gfx\\sgc\\_ˮ_.sgc) +} +skill: 2794 +{ +(1,1,gfx\\sgc\\_ˮ_.sgc), +(2,2,gfx\\sgc\\_ˮ_.sgc), +(3,3,gfx\\sgc\\_ˮ_.sgc) +} +skill: 2736 +{ +(1,1,gfx\\sgc\\ҹӰ__.sgc), +(2,2,gfx\\sgc\\ҹӰ__.sgc), +(3,3,gfx\\sgc\\ҹӰ__.sgc), +(4,4,gfx\\sgc\\ҹӰ__.sgc) +} +skill: 2737 +{ +(1,1,gfx\\sgc\\ҹӰ__.sgc), +(2,2,gfx\\sgc\\ҹӰ__.sgc), +(3,3,gfx\\sgc\\ҹӰ__.sgc), +(4,4,gfx\\sgc\\ҹӰ__.sgc) +} +skill: 2748 +{ +(1,1,gfx\\sgc\\ҹӰ_粨_.sgc), +(2,2,gfx\\sgc\\ҹӰ_粨_.sgc), +(3,3,gfx\\sgc\\ҹӰ_粨_.sgc), +(4,4,gfx\\sgc\\ҹӰ_粨_.sgc) +} +skill: 2749 +{ +(1,1,gfx\\sgc\\ҹӰ_粨_.sgc), +(2,2,gfx\\sgc\\ҹӰ_粨_.sgc), +(3,3,gfx\\sgc\\ҹӰ_粨_.sgc), +(4,4,gfx\\sgc\\ҹӰ_粨_.sgc) +} +skill: 2750 +{ +(1,1,gfx\\sgc\\ҹӰ_Ӱ_.sgc), +(2,2,gfx\\sgc\\ҹӰ_Ӱ_.sgc) +} +skill: 2751 +{ +(1,1,gfx\\sgc\\ҹӰ_Ӱ_.sgc), +(2,2,gfx\\sgc\\ҹӰ_Ӱ_.sgc) +} +skill: 2766 +{ +(1,1,gfx\\sgc\\ҹӰ__.sgc), +(2,2,gfx\\sgc\\ҹӰ__.sgc), +(3,3,gfx\\sgc\\ҹӰ__.sgc) +} +skill: 2767 +{ +(1,1,gfx\\sgc\\ҹӰ__.sgc), +(2,2,gfx\\sgc\\ҹӰ__.sgc), +(3,3,gfx\\sgc\\ҹӰ__.sgc) +} +skill: 2905 +{ +(1,1,gfx\\sgc\\ҹӰ_Ӱ_.sgc), +(2,2,gfx\\sgc\\ҹӰ_Ӱ_.sgc) +} +skill: 2906 +{ +(1,1,gfx\\sgc\\ҹӰ_Ӱ_.sgc), +(2,2,gfx\\sgc\\ҹӰ_Ӱ_.sgc) +} +skill: 2922 +{ +(1,1,gfx\\sgc\\ҹӰ__.sgc), +(2,2,gfx\\sgc\\ҹӰ__.sgc), +(3,3,gfx\\sgc\\ҹӰ__.sgc), +(4,4,gfx\\sgc\\ҹӰ__.sgc) +} +skill: 2923 +{ +(1,1,gfx\\sgc\\ҹӰ__.sgc), +(2,2,gfx\\sgc\\ҹӰ__.sgc), +(3,3,gfx\\sgc\\ҹӰ__.sgc), +(4,4,gfx\\sgc\\ҹӰ__.sgc) +} +skill: 2901 +{ +(1,1,gfx\\sgc\\ҹӰ__.sgc), +(2,2,gfx\\sgc\\ҹӰ__.sgc), +(3,3,gfx\\sgc\\ҹӰ__.sgc) +} +skill: 2902 +{ +(1,1,gfx\\sgc\\ҹӰ__.sgc), +(2,2,gfx\\sgc\\ҹӰ__.sgc), +(3,3,gfx\\sgc\\ҹӰ__.sgc) +} +skill: 2913 +{ +(1,1,gfx\\sgc\\_»_.sgc), +(2,2,gfx\\sgc\\_»_.sgc), +(3,3,gfx\\sgc\\_»_.sgc), +(4,4,gfx\\sgc\\_»_.sgc) +} +skill: 2914 +{ +(1,1,gfx\\sgc\\_»_.sgc), +(2,2,gfx\\sgc\\_»_.sgc), +(3,3,gfx\\sgc\\_»_.sgc), +(4,4,gfx\\sgc\\_»_.sgc) +} + +skill: 3284 +{ +(1,1,gfx\\sgc\\ҹӰ_粨_.sgc), +(2,2,gfx\\sgc\\ҹӰ_粨_.sgc), +(3,3,gfx\\sgc\\ҹӰ_粨_.sgc), +(4,4,gfx\\sgc\\ҹӰ_粨_.sgc) +} +skill: 3285 +{ +(1,1,gfx\\sgc\\ҹӰ_粨_.sgc), +(2,2,gfx\\sgc\\ҹӰ_粨_.sgc), +(3,3,gfx\\sgc\\ҹӰ_粨_.sgc), +(4,4,gfx\\sgc\\ҹӰ_粨_.sgc) +} +skill: 3217 +{ +(1,1,gfx\\sgc\\_ɫ.sgc), +(2,2,gfx\\sgc\\_ɫ.sgc), +(3,3,gfx\\sgc\\_ɫ.sgc), +(4,4,gfx\\sgc\\_ɫ.sgc), +(5,5,gfx\\sgc\\_ɫ.sgc) +} \ No newline at end of file diff --git a/Assets/Resources/multi_section_skill.txt.meta b/Assets/Resources/multi_section_skill.txt.meta new file mode 100644 index 0000000000..0149759c15 --- /dev/null +++ b/Assets/Resources/multi_section_skill.txt.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: f219fd5cb4f73c944bedb14e6d305c8d +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/CECHostPlayer.Combat.cs b/Assets/Scripts/CECHostPlayer.Combat.cs index c2344247e2..6b8cc4070a 100644 --- a/Assets/Scripts/CECHostPlayer.Combat.cs +++ b/Assets/Scripts/CECHostPlayer.Combat.cs @@ -129,32 +129,32 @@ namespace BrewMonster private void OnMsgHstHurtResult(ECMSG Msg) { //BMLogger.LogError("HoangDev : OnMsgHstHurtResult"); - /* int cmd = Convert.ToInt32(Msg.dwParam2); + int cmd = Convert.ToInt32(Msg.dwParam2); if (cmd == CommandID.BE_HURT) { - cmd_be_hurt pCmd = (cmd_be_hurt)Msg.dwParam1; + cmd_be_hurt pCmd = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1 ); if (pCmd.damage != 0) Damaged(pCmd.damage); } else if (cmd == CommandID.HURT_RESULT) { - cmd_hurt_result pCmd = (cmd_hurt_result)Msg.dwParam1; + cmd_hurt_result pCmd = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1 ); if (pCmd.target_id == m_PlayerInfo.cid) return; // Host himself will receive BE_HURT, so ignore this. if (UnityGameSession.Instance.GameSession.ISPLAYERID(pCmd.target_id)) { - CECElsePlayer pTarget = m_pPlayerMan.GetElsePlayer(pCmd.target_id); + EC_ElsePlayer pTarget = m_pPlayerMan.GetElsePlayer(pCmd.target_id); if (pTarget) pTarget.Damaged(pCmd.damage); } else if (UnityGameSession.Instance.GameSession.ISNPCID(pCmd.target_id)) { - CECNPC pTarget = EC_ManMessageMono.Instance._CECNPCMan.GetNPC(pCmd.target_id); + CECNPC pTarget = EC_ManMessageMono.Instance.CECNPCMan.GetNPC(pCmd.target_id); if (pTarget) pTarget.Damaged(pCmd.damage); } - }*/ + } } private void OnMsgHstStartAttack(in ECMSG Msg)