Merge pull request 'feature/gfx-action' (#425) from feature/gfx-action into develop

Reviewed-on: https://git.pthub.vn/Unity/perfect-world-unity/pulls/425
This commit is contained in:
hoangvd
2026-05-12 09:58:02 +00:00
22 changed files with 2042 additions and 536 deletions
@@ -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
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 598017775c842ef4ab72d8eabe909d6c
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+2 -2
View File
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:98acfc6d78af21396b1c3dcadcb4387954e34ff5863aa8a628f4011b26888168
size 313916
oid sha256:5caea7b0b45c434cbea3545800922c7604e8773fe7cbcf675b091934c7c39505
size 306512
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 51ffa1643315ae94f8efced3044b5d68
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -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"
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7a26a1c8cf0cc58478b7baa61913020d
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7e810e737f9dbd34c91dc8ea77c0caad
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 45f90f4f1beb54142ab4507a13118e9b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -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<string>();
List<SkillStateActionRow> 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<SkillStateActionConfig>();
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<string>();
List<SkillStateActionRow> 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)}");
}
/// <summary>
/// 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.
/// </summary>
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);
}
}
/// <summary>
/// Writes list via SerializedProperty so Unity persists nested structs reliably (Inspector shows Size &gt; 0).
/// </summary>
private static void WriteSerializedEntries(SkillStateActionConfig cfg, List<SkillStateActionRow> 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();
}
/// <summary>
/// Ensure the user picked gameplay config text (skill_state_action.txt), not a Unity YAML .asset/.meta.
/// </summary>
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<string> warnings)
{
if (warnings == null || warnings.Count == 0)
return;
foreach (string w in warnings)
Debug.LogWarning($"SkillStateActionConfigImporter: {w}");
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: a33fc0453d431914d9015eb9f0d89a63
@@ -0,0 +1,115 @@
using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
namespace BrewMonster.Config
{
/// <summary>One row of skill_state_action.txt: skill id, visible state id, be-hit action, optional stay-down action.</summary>
[Serializable]
public struct SkillStateActionRow
{
public int skill;
public int state;
public string beHitAction;
public string stayDownAction;
}
/// <summary>Parses the classic comma-separated skill_state_action table (same rules as legacy client / CECAttacksMan TextAsset loader).</summary>
public static class SkillStateActionTextParser
{
/// <summary>
/// Strip CSV-style wrapping quotes (Excel export often writes "2244","117",...).
/// Handles doubled-quote escapes inside a quoted field.
/// </summary>
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<SkillStateActionRow> Parse(string text, ICollection<string> warnings = null)
{
var rows = new List<SkillStateActionRow>();
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<SkillStateActionRow> entries = new List<SkillStateActionRow>();
public IReadOnlyList<SkillStateActionRow> Entries => entries;
#if UNITY_EDITOR
/// <summary>Editor / tools: replace serialized rows after import.</summary>
public void SetEntries(List<SkillStateActionRow> newEntries)
{
entries = newEntries ?? new List<SkillStateActionRow>();
}
#endif
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 922bd889af2211b488dc6019c1022191
@@ -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<CECAttacksMan>
{
[SerializeField] private SkillStateActionConfig skillStateActionConfig;
private struct SkillStateActionEntry
{
public int skill;
public int state;
public string beHitAction;
public string stayDownAction;
}
private readonly List<SkillStateActionEntry> m_SkillStateActionVec = new List<SkillStateActionEntry>();
private LinkedList<CECAttackEvent> m_targets = new LinkedList<CECAttackEvent>();
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();
}
/// <summary>
@@ -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;
}
/// <summary>
/// Loads skill/state → action names into <see cref="m_SkillStateActionVec"/> from <see cref="skillStateActionConfig"/> (parity with C++ <c>CECAttacksMan::LoadSkillStateActionConfig</c>).
/// </summary>
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<SkillStateActionRow> 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;
}
/// <summary>
/// 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<string, A3DSkillGfxComposer> m_SgcName2ComposerMap = new Dictionary<string, A3DSkillGfxComposer>();
private readonly Dictionary<string, A3DSkillGfxComposer> m_SgcName2ComposerMap =
new Dictionary<string, A3DSkillGfxComposer>();
// 多段技能组合器列表 / Multi-section skill composer list
private readonly List<SectionInfo> m_MultiSectionSkillComposerVec = new List<SectionInfo>();
@@ -357,6 +439,7 @@ namespace BrewMonster
public CECMultiSectionSkillMan()
{
}
~CECMultiSectionSkillMan()
{
Release();
@@ -424,16 +507,19 @@ namespace BrewMonster
/// <param name="Targets">Target data list / 目标数据列表</param>
/// <param name="bIsGoblinSkill">Is goblin skill / 是否为精灵技能</param>
public void Play(int nSkillID, int section, int nHostID, int nCastTargetID,
List<TARGET_DATA> Targets, bool bIsGoblinSkill = false)
List<TARGET_DATA> 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}");
}
/// <summary>
@@ -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
/// 从文件加载组合器
/// </summary>
public string hitGfxName;
public string flyGfxName;
public string hitGrdGfxName;
public async UniTask<bool> 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<GameObject>("GFX/" + "PlaceHolder");
}
if (m_szHitGfx == null && !string.IsNullOrEmpty(hitGfxName))
{
m_szHitGfx = Resources.Load<GameObject>("GFX/" + "PlaceHolder");
}
if (m_szHitGrndGfx == null && !string.IsNullOrEmpty(hitGrdGfxName))
{
m_szHitGrndGfx = Resources.Load<GameObject>("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状态机处理
/// <summary>
@@ -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);
}
}
/// <summary>
@@ -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<CECAttackEvent> m_list = new List<CECAttackEvent>();
@@ -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
};
+11 -16
View File
@@ -87,6 +87,8 @@ namespace BrewMonster
protected int NUM_WEAPON_TYPE = 15;
public static readonly int[] m_sciStateIDForStateAction = { 117 };
/// <summary>Skill id for pending skill/state hit reaction (see skill_state_action.txt).</summary>
protected int m_SkillIDForStateAction;
private static Dictionary<uint, PLAYER_ACTION_INFO_CONFIG> _default_skill_actions
= new Dictionary<uint, PLAYER_ACTION_INFO_CONFIG>();
@@ -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()
{
+2 -2
View File
@@ -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)
{
File diff suppressed because it is too large Load Diff
@@ -33,7 +33,6 @@ namespace BrewMonster.Scripts
/// </summary>
public void InitForWorld(int worldTag)
{
BMLogger.LogError("HoangDev: InitForWorld worldTag:"+worldTag);
AudioManager.Instance.StopBGM(1f);
SetupAudioSources(worldTag).Forget();
}
@@ -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;
@@ -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();
+279
View File
@@ -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)
}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: f219fd5cb4f73c944bedb14e6d305c8d
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+6 -6
View File
@@ -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<cmd_be_hurt>((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<cmd_hurt_result>((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)