Merge branch 'develop' into feature/create-skill-combo

This commit is contained in:
NguyenVanDat
2026-04-09 09:14:29 +07:00
97 changed files with 9791 additions and 24145 deletions
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 521751511619950448}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 854.7991, y: -45.19295, z: 168.2162}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.467, y: -0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &4643159729352802538
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7283797167087943104}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 854.7991, y: -45.19295, z: 168.2162}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.55, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &6689449885943493666
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 9037966901010172822}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 854.7991, y: -45.19295, z: 168.2162}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.52, y: 0.08, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &6431048551573909870
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4146391136452590312}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 854.7991, y: -45.19295, z: 168.2162}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.608, y: 0.03, z: 0.031}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &8380308436026247008
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6005744050955720459}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 854.7991, y: -45.19295, z: 168.2162}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.439, y: -0, z: -0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &2976794322645826365
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3657562976579592623}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 854.7991, y: -45.19295, z: 168.2162}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.47, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &6576187325239959967
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6287696647157729657}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 854.7991, y: -45.19295, z: 168.2162}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.58, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &2542169234980971614
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3072237174258024572}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.42, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &1487446899476086846
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7691330745472418625}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.58, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &3901653839846202411
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4687492501342321793}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.46, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &2934905636045033890
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4523807140502598285}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.57, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &7671732475859138332
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1673886386918577840}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.51, y: -0.08, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &49109103213565591
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4960158712494693704}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.59, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &103797880579185270
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4514596060253920102}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.44, y: -0.04, z: 0.032}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &5836441970844709889
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2804193919963264657}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.5, y: 0.06, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &1936149815519356261
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6024913029217443269}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0.7071068, y: 0.7071068, z: 0, w: 0}
m_LocalPosition: {x: 0.45, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 180, z: 90}
--- !u!33 &5390486599911108339
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8954426676829949006}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.46, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &3386378493831336341
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8544343499760376834}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.423, y: 0.008, z: 0.009}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &8732503029651716070
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 9089679423287464323}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.439, y: 0.007, z: -0.014}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &8817967967612133426
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1750589402820721523}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.44, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &1726312771557601477
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7898490744125074255}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.442, y: -0.04, z: 0.027}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &7727499927744400604
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 431507536254419338}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.47, y: 0, z: 0.03}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &2070642545782787102
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1113794091115841783}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.45, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &7932516146755324214
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6611500696103112802}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.359, y: 0.006, z: 0.006}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &5567964522934692172
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8934191901732488851}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.347, y: -0.012, z: 0.012}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &1458943245607846802
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3843642197624191562}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.27, y: -0.08, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &2942293025938461444
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5369271364955280410}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.25, y: -0.09, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &3165116075288726831
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1627728301949147503}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.25, y: 0, z: 0.03}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &7621110774882610367
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3218176555537563708}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.235, y: 0.001, z: 0.015}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &4570469791566163120
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4001841694840385047}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.33, y: -0.1, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &805389305525483483
MeshFilter:
m_ObjectHideFlags: 0
@@ -27,7 +27,7 @@ Transform:
m_GameObject: {fileID: 4649913178893672652}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalPosition: {x: 0.14, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4296978685365805745}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.09, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &3010680041828916761
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 114588174620003303}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.24, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &5738622860265099348
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1871826936208277503}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.13, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &5622821162627514245
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6657025351343012753}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.19, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &4710983591303832989
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 582524068872390062}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.34, y: 0, z: 0.11}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &551222743829696411
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 612928185602746483}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.76, y: -0.14, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &877854830967665102
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4720678646282004868}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.564, y: -0.061, z: -0.005}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &2558500868448674905
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2916308637203925776}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.564, y: -0.061, z: -0.005}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &2359515785900208490
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 252742027917821622}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.66, y: -0.14, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &2067319665948465769
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5251377079602931302}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.98, y: -0.06, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &8337534583944483472
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4858308094309864508}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.84, y: -0.064, z: -0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &5945091725935784906
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7515438785474843149}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.564, y: -0.013, z: -0.005}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &4684279536110930119
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3632554605594395393}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0.015733898, y: 0.7069317, z: -0.015733898, w: 0.7069317}
m_LocalPosition: {x: 0.7, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 2.55, y: 90, z: 0}
--- !u!33 &5757475931190928569
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6015463627169791726}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.564, y: -0.013, z: -0.005}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &5659237752439739352
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1004382166946238604}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.78, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &7739687131419528944
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1197563511380039097}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.564, y: -0.013, z: -0.005}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &133678441249318870
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6982793425996143688}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.564, y: -0.013, z: -0.005}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &1783189990820706467
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8118372724377232535}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: -0.40557975, y: 0.579228, z: 0.40557975, w: 0.579228}
m_LocalPosition: {x: 2, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: -70, y: 90, z: 0}
--- !u!33 &7702346965493637044
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3708902834663212576}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: -0.45451945, y: 0.54167527, z: 0.45451945, w: 0.54167527}
m_LocalPosition: {x: 0.91, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: -80, y: 90, z: 0}
--- !u!33 &215318870199670359
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3386362935637178495}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: -0.37680045, y: 0.5983489, z: 0.37680045, w: 0.5983489}
m_LocalPosition: {x: 1.82, y: 0.049, z: 0.012}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: -64.4, y: 90, z: 0}
--- !u!33 &2249869016674504523
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5744228263443585635}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: -0.4181191, y: 0.57024246, z: 0.4181191, w: 0.57024246}
m_LocalPosition: {x: 2, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: -72.5, y: 90, z: 0}
--- !u!33 &767111472807305304
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2426238636354042165}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: -0.4131269, y: 0.5738695, z: 0.4131269, w: 0.5738695}
m_LocalPosition: {x: 2, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: -71.5, y: 90, z: 0}
--- !u!33 &1817264271704911385
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8478865665253152939}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: -0.42307937, y: 0.566572, z: 0.42307937, w: 0.566572}
m_LocalPosition: {x: 2, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: -73.5, y: 90, z: 0}
--- !u!33 &1875442124140011855
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8787341145026669753}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.652, y: -0, z: -0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &6886144341852739131
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6078192489162540850}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.64, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &5938416084853196401
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7583996414051340456}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.87, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &5068162253037144888
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 514324012645713218}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.57, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &6641818280837675681
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7423421571527749171}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.73, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &7563941420482788221
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1125368435937452624}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0.008453601, y: 0.7070563, z: -0.008453601, w: 0.7070563}
m_LocalPosition: {x: 0.66, y: -0.14, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 1.37, y: 90, z: 0}
--- !u!33 &1430035286846886459
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5812609165759687500}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 1, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &872845287390182096
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4202528123455853326}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0.95, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &4574804706647375284
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 120385328447347559}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 1, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &6881055716062663917
MeshFilter:
m_ObjectHideFlags: 0
@@ -26,13 +26,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5641955314571368359}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 1.06, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!33 &5990592806001361267
MeshFilter:
m_ObjectHideFlags: 0
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:543e09f5571b2d48dd57646eee06f8efbc71e6aaa62d6e8a98a529dec44b7364
size 322591
oid sha256:f85e6e6bc4d5b6af2e103cf46a846213439f86c209bed0512839f28b8c23a7c6
size 326984
@@ -26,6 +26,7 @@ namespace BrewMonster
private float _lastPinchDistance;
private bool _pinchZoomActive;
private int _touchCount = 0;
public CinemachineOrbitalFollow Orbital { get => orbital;}
@@ -63,11 +64,19 @@ namespace BrewMonster
public void OnPointerDown(PointerEventData eventData)
{
fingerDown = true;
if(_touchCount < 2)
{
_touchCount++;
}
}
public void OnPointerUp(PointerEventData eventData)
{
fingerDown = false;
if(_touchCount > 0)
{
_touchCount--;
}
}
private void OnValidate()
@@ -133,7 +142,7 @@ namespace BrewMonster
return;
}
if (Input.touchCount == 2)
if (_touchCount == 2)
{
Touch t0 = Input.GetTouch(0);
Touch t1 = Input.GetTouch(1);
@@ -151,6 +151,8 @@ namespace BrewMonster
pEvent.SetIsCluster(bCluster);
pEvent.SetFadeOut(bFadeOut);
pEvent.SetGoblinSkill(bIsGoblinSkill);
pEvent.SetShowFlyGfx(!string.IsNullOrEmpty(szFlyGfx));
pEvent.SetShowHitGfx(!string.IsNullOrEmpty(szHitGfx));
ECMODEL_GFX_PROPERTY Prop = new ECMODEL_GFX_PROPERTY();
if (GetPropertyById(nHostID, ref Prop))
@@ -192,7 +194,9 @@ namespace BrewMonster
protected long m_nHostID;
protected long m_nTargetID;
protected uint m_dwModifier;
protected bool m_bIsGoblinSkill;
protected bool m_bIsGoblinSkill;
protected bool m_bShowFlyGfx;
protected bool m_bShowHitGfx;
protected Vector3 m_vHostPos;
protected Vector3 m_vTargetPos;
@@ -222,6 +226,8 @@ namespace BrewMonster
m_enumState = GfxSkillEventState.enumWait;
m_bHitGfxInfinite = false;
m_bIsGoblinSkill = false;
m_bShowFlyGfx = true;
m_bShowHitGfx = true;
m_bTargetDirAndUpExist = false;
m_bGfxUseLod = true;
m_bGfxDisableCamShake = false;
@@ -336,12 +342,16 @@ namespace BrewMonster
public void SetModifier(uint dwModifier) { m_dwModifier = dwModifier; }
public void SetGoblinSkill(bool bGoblinSkill) { m_bIsGoblinSkill = bGoblinSkill; }
public bool GetGoblinSkill() { return m_bIsGoblinSkill; }
public void SetShowFlyGfx(bool b) { m_bShowFlyGfx = b; }
public void SetShowHitGfx(bool b) { m_bShowHitGfx = b; }
public void Resume()
{
//ReleaseGfx();
m_enumState = GfxSkillEventState.enumWait;
m_dwCurSpan = 0;
m_bShowFlyGfx = true;
m_bShowHitGfx = true;
}
// Virtual functions
@@ -329,6 +329,7 @@ namespace BrewMonster
/// </summary>
private void SpawnFlyGfx()
{
if (!m_bShowFlyGfx) return;
if (m_pComposer == null)
{
@@ -411,6 +412,7 @@ namespace BrewMonster
/// </summary>
private void SpawnHitGfx(Vector3 vTarget)
{
if (!m_bShowHitGfx) return;
if (m_pComposer == null)
{
@@ -3,6 +3,7 @@ using BrewMonster.Network;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
using PerfectWorld.Scripts;
using PerfectWorld.Scripts.Managers;
using CSNetwork;
using UnityEngine;
using static BrewMonster.Scripts.CECHPWork;
@@ -610,6 +611,36 @@ namespace BrewMonster
return bOK;
}
/// <summary>
/// HUD / shortcut: walk to and pick up the nearest ground item or money (not mines) within range.
/// </summary>
/// <param name="maxSearchRadiusH">Max horizontal distance to search (meters).</param>
/// <returns>True if a matter was found and <see cref="PickupObject"/> started.</returns>
public bool TryPickupNearestGroundMatter(float maxSearchRadiusH = 80f)
{
if (IsDead() || m_pWorkMan == null)
return false;
if (m_pWorkMan.IsSitting())
{
UnityGameSession.c2s_CmdStandUp();
return false;
}
if (!CanDo(ActionCanDo.CANDO_MOVETO))
return false;
EC_ManMatter matterMan = EC_ManMessageMono.Instance?.EC_ManMatter;
if (matterMan == null)
return false;
CECMatter nearest = matterMan.GetNearestPickupableMatter(GetPos(), maxSearchRadiusH);
if (nearest == null)
return false;
return PickupObject(nearest.GetMatterID(), false);
}
// Check whether host can gather specified matter / Check whether host can gather specified matter
public bool CanGatherMatter(CECMatter pMatter)
{
@@ -81,6 +81,7 @@ namespace BrewMonster.Scripts
var old = m_aItems[iSlot];
m_aItems[iSlot] = pItem;
EventBus.Publish(new InventoryChangedEvent());
return old;
}
@@ -92,6 +93,7 @@ namespace BrewMonster.Scripts
}
m_aItems[iSlot] = pItem;
EventBus.Publish(new InventoryChangedEvent());
}
public EC_IvtrItem GetItem(int iSlot, bool bRemove = false)
@@ -144,6 +146,7 @@ namespace BrewMonster.Scripts
m_aItems[iSlot] = newItem;
piLastSlot = iSlot;
piLastAmount = iAmount;
EventBus.Publish(new InventoryChangedEvent());
return true;
}
if (slotItem.GetTemplateID() != tid)
@@ -156,6 +159,7 @@ namespace BrewMonster.Scripts
slotItem.AddAmount(add);
piLastSlot = iSlot;
piLastAmount = slotItem.GetCount();
EventBus.Publish(new InventoryChangedEvent());
return true;
}
@@ -179,6 +183,7 @@ namespace BrewMonster.Scripts
{
piLastSlot = i;
piLastAmount = slotItem.GetCount();
EventBus.Publish(new InventoryChangedEvent());
return true;
}
}
@@ -201,6 +206,7 @@ namespace BrewMonster.Scripts
m_aItems[firstEmpty] = newItem;
piLastSlot = firstEmpty;
piLastAmount = iAmount;
EventBus.Publish(new InventoryChangedEvent());
return true;
}
@@ -240,6 +246,7 @@ namespace BrewMonster.Scripts
}
RemoveItem(iSrc, iAmount);
EventBus.Publish(new InventoryChangedEvent());
return true;
}
@@ -258,6 +265,7 @@ namespace BrewMonster.Scripts
if (newCount <= 0)
m_aItems[iSlot] = null;
EventBus.Publish(new InventoryChangedEvent());
return true;
}
@@ -341,5 +349,21 @@ namespace BrewMonster.Scripts
m_aItems[i].Freeze(false);
}
}
public void GetAllItemsOfType<T>(out List<T> items) where T : EC_IvtrItem
{
items = new List<T>();
for (int i = 0; i < m_aItems.Length; i++)
{
if (m_aItems[i] != null)
if (m_aItems[i] is T item)
items.Add(item);
}
}
}
/// <summary>
/// Fired when any client-side inventory pack mutates (add/remove/move/merge).
/// Used by UI (quickbar HP/MP auto-pick) to re-evaluate best potions.
/// </summary>
public struct InventoryChangedEvent { }
}
@@ -1133,7 +1133,6 @@ namespace BrewMonster.Scripts.Managers
{
if (button == null || itemData == null)
{
Debug.LogWarning("[UpdateCooldownOverlay] Button or itemData is null");
return;
}
@@ -1146,7 +1145,6 @@ namespace BrewMonster.Scripts.Managers
{
// Cached but destroyed, remove and search again
// 已缓存但被销毁,移除并重新查找
Debug.LogWarning($"[UpdateCooldownOverlay] Cached overlay was destroyed for button {button.name}");
_overlayImages.Remove(button);
}
}
@@ -1165,12 +1163,12 @@ namespace BrewMonster.Scripts.Managers
}
else
{
Debug.LogWarning($"[UpdateCooldownOverlay] Found transform but no Image component on image_overlay for button {button.name}");
}
}
else
{
Debug.LogWarning($"[UpdateCooldownOverlay] Cannot find image_overlay child in button {button.name}");
}
}
@@ -1435,6 +1433,7 @@ namespace BrewMonster.Scripts.Managers
string fullDesc = null;
if (showEquipmentDetails && currentSelectedEquipment != null)
{
currentSelectedEquipment.SetPriceScale((int)EC_IvtrItem.ScaleType.SCALE_SELL, 1f);
fullDesc = currentSelectedEquipment.GetDesc(EC_IvtrItem.DescType.DESC_NORMAL, EC_Game.GetGameRun().GetHostPlayer().GetEquipment());
}
else
@@ -171,10 +171,8 @@ namespace BrewMonster.Scripts
/// class id
/// </summary>
public int CID { get; set; }
public int Price { get; set; }
public int Count { get; set; }
public float PriceScale { get; set; }
public int ScaleType { get; set; }
//public int ScaleType { get; set; }
// Equipment Requirements
public int LevelReq { get; set; }
@@ -569,10 +567,10 @@ namespace BrewMonster.Scripts
TemplateId = tid;
ExpireDate = expireDate;
CID = (int)InventoryClassId.ICID_EQUIP;
Price = 0;
m_iPrice = 0;
Count = 1;
PriceScale = 1.0f;
ScaleType = 0;
m_fPriceScale = 1.0f;
//ScaleType = 0;
LevelReq = 0;
StrengthReq = 0;
@@ -600,10 +598,10 @@ namespace BrewMonster.Scripts
TemplateId = other.TemplateId;
ExpireDate = other.ExpireDate;
CID = other.CID;
Price = other.Price;
m_iPrice = other.m_iPrice;
Count = other.Count;
PriceScale = other.PriceScale;
ScaleType = other.ScaleType;
m_fPriceScale = other.m_fPriceScale;
//ScaleType = other.ScaleType;
// Copy equipment properties
LevelReq = other.LevelReq;
@@ -751,10 +749,10 @@ namespace BrewMonster.Scripts
if (len < 16 + 6 * 2 + 8 + 2) return false;
// A legacy format we used earlier that prefixed price/scale before requirements
Price = BitConverter.ToInt32(data, offset); offset += 4;
m_iPrice = BitConverter.ToInt32(data, offset); offset += 4;
Count = BitConverter.ToInt32(data, offset); offset += 4;
PriceScale = BitConverter.ToSingle(data, offset); offset += 4;
ScaleType = BitConverter.ToInt32(data, offset); offset += 4;
m_fPriceScale = BitConverter.ToSingle(data, offset); offset += 4;
//ScaleType = BitConverter.ToInt32(data, offset); offset += 4;
LevelReq = BitConverter.ToInt16(data, offset); offset += 2;
ProfReq = BitConverter.ToInt16(data, offset); offset += 2;
@@ -980,17 +978,25 @@ namespace BrewMonster.Scripts
/// <summary>
/// Get scaled item price
/// </summary>
public int GetScaledPrice()
public override int GetScaledPrice()
{
if (ScaleType != SCALE_SELL)
return (int)(Price * Count * PriceScale + 0.5f);
int price = Price * Count;
Debug.Log($"GetScaledPrice: m_iScaleType: {m_iScaleType}");
if (m_iScaleType != (int)EC_IvtrItem.ScaleType.SCALE_SELL)
return base.GetScaledPrice();
int price = m_iPrice * Count;
if (MaxEndurance == CurEndurance || MaxEndurance == 0)
return (int)(price * PriceScale + 0.5f);
{
Debug.Log($"GetScaledPrice: price: {price}, MaxEndurance: {m_fPriceScale}");
return (int)(price * m_fPriceScale + 0.5f);
}
else
return (int)(price * PriceScale * CurEndurance / (float)MaxEndurance + 0.5f);
{
Debug.Log($"GetScaledPrice: price: {price}, PriceScale: {m_fPriceScale}, CurEndurance: {CurEndurance}, MaxEndurance: {MaxEndurance}, factor: {CurEndurance / (float)MaxEndurance}");
return (int)(price * m_fPriceScale * CurEndurance / (float)MaxEndurance + 0.5f);
}
}
/// <summary>
@@ -1876,7 +1882,7 @@ namespace BrewMonster.Scripts
/// <summary>
/// Add price description
/// </summary>
public void AddPriceDesc(int col, bool repair)
protected override void AddPriceDesc(int col, bool repair)
{
if (repair)
AddDescText(col, false, GetItemDescString(DescriptipionMsg.ITEMDESC_REPAIRCOST), GetRepairCost());
@@ -165,7 +165,7 @@ namespace BrewMonster.Scripts
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
m_pDBEssence = (GOBLIN_ESSENCE)pDB.get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
m_iPileLimit = m_pDBEssence.pile_num_max;
Price = m_pDBEssence.price;
m_iPrice = m_pDBEssence.price;
m_iShopPrice = m_pDBEssence.shop_price;
m_iProcType = (int)m_pDBEssence.proc_type;
m_bNeedUpdate = false;
@@ -1141,6 +1141,8 @@ namespace BrewMonster.Scripts
public virtual int GetScaledPrice()
{
int iPrice = m_iScaleType == (int)ScaleType.SCALE_BUY ? m_iShopPrice : m_iPrice;
string str = m_iScaleType == (int)ScaleType.SCALE_BUY ? "ShopPrice" : "Price";
Debug.Log($"GetScaledPrice: iPrice: {iPrice} is {str}, m_iScaleType: {m_iScaleType}, m_fPriceScale: {m_fPriceScale}");
return GetScaledPrice(iPrice, m_iCount, m_iScaleType, m_fPriceScale);
}
@@ -18,6 +18,13 @@ namespace BrewMonster.Scripts
protected MEDICINE_ESSENCE m_pDBEssence;
protected int m_iLevelReq;
// Expose data needed by UI/shortcut logic.
// 暴露给UI/快捷栏需要的数据 (Expose data needed by UI/quickbar).
public int GetMajorTypeId() => (int)m_pDBMajorType.id;
public int GetLevelReq() => m_iLevelReq;
public int GetHpAddTotal() => m_pDBEssence.hp_add_total;
public int GetMpAddTotal() => m_pDBEssence.mp_add_total;
/// <summary>
/// Create medicine item (cac loai thuoc)
/// </summary>
@@ -171,14 +178,16 @@ namespace BrewMonster.Scripts
}
// Check item use condition
protected bool CheckUseCondition()
public override bool CheckUseCondition()
{
CECHostPlayer pHost = CECGameRun.Instance.GetHostPlayer();
if (pHost == null)
return false;
if (pHost.GetMaxLevelSofar() < m_iLevelReq)
return false;
return true;
return IsUseable() && GetCount() > 0;
}
// Get drop model for shown
@@ -314,6 +314,31 @@ namespace PerfectWorld.Scripts.Managers
}
return null;
}
/// <summary>
/// Nearest ground item or money matter within horizontal <paramref name="maxRadiusH"/> of <paramref name="hostPos"/>.
/// Mines (gather nodes) are excluded — use direct click / gather flow for those.
/// </summary>
public CECMatter GetNearestPickupableMatter(A3DVECTOR3 hostPos, float maxRadiusH)
{
CECMatter best = null;
float bestDist = float.MaxValue;
foreach (var kv in m_MatterTab)
{
CECMatter m = kv.Value;
if (m == null || !m)
continue;
if (m.IsMine())
continue;
float d = m.CalcDist(hostPos, false);
if (d > maxRadiusH || d >= bestDist)
continue;
bestDist = d;
best = m;
}
return best;
}
public CECMatter CreateMatter(info_matter info)
{
@@ -707,43 +707,40 @@ namespace BrewMonster.Scripts.Task
return false;
}
// 可接任务列表 // Available tasks list
// 可接任务列表(全量一次扫完;分帧接口见 ProcessAvailableTasksChunk
// Available tasks list (full scan in one call; time-sliced API: ProcessAvailableTasksChunk)
public void GetAvailableTasks(TaskInterface pPlayer, List<ATaskTempl> lst)
{
if (lst == null) return;
if (lst.Capacity < 256) lst.Capacity = 256; // 预留容量 // reserve capacity
string log = "";
int count = m_TasksCanSeekOut.Count;
for (int i = 0; i < count; i++)
lst.Clear();
int cursor = 0;
bool completed;
do
{
ATaskTempl pTempl = m_TasksCanSeekOut[i];
ProcessAvailableTasksChunk(pPlayer, lst, ref cursor, int.MaxValue, out completed);
} while (!completed);
}
/// <summary>
/// Process up to maxSteps templates from m_TasksCanSeekOut; cursor is next index (0 = start of list).
/// 每次最多处理 maxSteps 个 m_TasksCanSeekOut 项;cursor 为下一待处理下标。
/// </summary>
public void ProcessAvailableTasksChunk(TaskInterface pPlayer, List<ATaskTempl> lst, ref int cursor, int maxSteps, out bool completed)
{
int count = m_TasksCanSeekOut.Count;
int processed = 0;
while (cursor < count && processed < maxSteps)
{
ATaskTempl pTempl = m_TasksCanSeekOut[cursor];
cursor++;
processed++;
if (pTempl == null) continue;
// 如果等级条件不满足则跳过 // Skip if level requirements are not met
if (!pTempl.CheckReachLevel(pPlayer)) continue;
// 玩家可接此任务则加入列表 // If player can accept this task, add to list
var failCode = pPlayer.CanDeliverTask(pTempl.m_FixedData.m_ID);
if (failCode == 0)
{
if (pPlayer.CanDeliverTask(pTempl.m_FixedData.m_ID) == 0)
lst.Add(pTempl);
}
else
{
log += $"Task ID {pTempl.m_FixedData.m_ID} Fail : {failCode} \n";
}
// if (i % 1000 == 0)
// {
// Debug.Log($"--- {i % 1000} Find Available Task --- \n {log}");
// log = "";
// }
}
completed = cursor >= count;
}
public uint GetTaskStorageId(uint id)
+23 -9
View File
@@ -384,6 +384,8 @@ namespace BrewMonster.Scripts.Task.UI
public void OnCommand_showtrace(string szCommand,bool state) {
m_bShowTrace = state;
Debug.Log($"[DlgTask] OnCommand_showtrace: state={m_bShowTrace}");
if (state)
RebuildAcceptableQuestCache();
ShowTraceDialog();
}
public void TraceTask(uint idTask)
@@ -607,8 +609,6 @@ namespace BrewMonster.Scripts.Task.UI
public void OnEventLButtonDown_Tv_Quest(uint itemData)
{
// UpdateTask((int)itemData);
// POINT ptPos = pObj->GetPos();
// A3DVIEWPORTPARAM *p = m_pA3DEngine->GetActiveViewport()->GetParam();
// int x = GET_X_LPARAM(lParam) - ptPos.x - p->X;
@@ -635,7 +635,7 @@ namespace BrewMonster.Scripts.Task.UI
// if(pTree->GetHitArea(x,y) == AUITREEVIEW_RECT_FRAME)
// CDlgWikiShortcut::PopQuestWiki(GetGameUIMan(),idTask);
// }
m_idSelTask = idTask;
}
// void OnEventMouseMove_Txt_QuestItem(WPARAM wParam, LPARAM lParam, AUIObject *pObj);
@@ -917,9 +917,8 @@ namespace BrewMonster.Scripts.Task.UI
}
else if(showType2 == ShowType2.ST_NOT_RECIEVED)
{
// Re-run GetAvailableTasks every trace refresh; m_vecTasksCanGet was only filled on quest UI events and stayed stale.
// 每次追踪刷新重新计算可接任务;原先仅在任务界面事件里更新列表,游戏中会一直停留在开局数据
RefreshVecTasksCanGet(pTask);
// Can-get list is refreshed only on level-up, quest state change (UpdateQuestView), trace toggle on, or minimion "可接" tab — not every tick.
// 可接列表仅在升级、任务变更、打开追踪、小窗切到可接时刷新,避免每帧扫全表拖垮 FPS
tasks.Capacity = m_vecTasksCanGet.Count;
tasks.AddRange(m_vecTasksCanGet);
}
@@ -1298,8 +1297,8 @@ namespace BrewMonster.Scripts.Task.UI
}
}
// Search view already rebuilt m_vecTasksCanGet inside SearchForTask(-1).
// 搜索页SearchForTask 内已更新 m_vecTasksCanGet。
// Have-quest tab: rebuild can-get cache for trace minimion. Search tab: SearchForTask(-1) already filled m_vecTasksCanGet.
// 已接任务页:重建可接缓存。搜索页SearchForTask 已写 m_vecTasksCanGet,勿二次全表扫描
if (m_iType == 0)
RefreshVecTasksCanGet();
@@ -1413,9 +1412,24 @@ namespace BrewMonster.Scripts.Task.UI
/// 用 GetAvailableTasks 重建可接任务 ID 列表,与可接任务搜索树数据源一致。
/// </summary>
private void RefreshVecTasksCanGet(CECTaskInterface pTaskIfKnown = null)
{
RebuildAcceptableQuestCache(pTaskIfKnown);
}
/// <summary>
/// Rebuilds the cached list of quests the host may accept (trace minimion "可接", etc.).
/// Safe without a DlgTask instance — call from UI manager on level-up and similar.
/// 重建玩家当前可接任务 ID 缓存;可无对话框实例,由 UI 管理器在升级等时机调用。
/// </summary>
public static void RebuildAcceptableQuestCache(CECTaskInterface pTaskIfKnown = null)
{
m_vecTasksCanGet.Clear();
CECTaskInterface pTask = pTaskIfKnown ?? GetHostPlayer()?.GetTaskInterface();
CECTaskInterface pTask = pTaskIfKnown;
if (pTask == null)
{
var run = EC_Game.GetGameRun();
pTask = run?.GetHostPlayer()?.GetTaskInterface();
}
if (pTask == null) return;
ATaskTemplMan pMan = EC_Game.GetTaskTemplateMan();
if (pMan == null) return;
@@ -134,6 +134,7 @@ namespace BrewMonster.Scripts.Task.UI
if(value)
{
m_nLastShowType2 = ShowType2.ST_NOT_RECIEVED;
DlgTask.RebuildAcceptableQuestCache();
}
}
public void OnShowDialog()
@@ -0,0 +1,52 @@
using UnityEngine;
using TMPro;
namespace BrewMonster.Assets.PerfectWorld.Scripts.UI.GamePlay
{
public class AUIImageHPMPItem : AUIImagePicture
{
[SerializeField] TMP_Text m_TextAmount;
private int _lastTemplateId = int.MinValue;
private int _lastCount = int.MinValue;
public bool TrySetTemplateId(int templateId)
{
if (_lastTemplateId == templateId)
return false;
_lastTemplateId = templateId;
return true;
}
public bool TrySetCount(int count)
{
if (_lastCount == count)
return false;
_lastCount = count;
return true;
}
public void ResetRenderCache()
{
_lastTemplateId = int.MinValue;
_lastCount = int.MinValue;
}
public void SetText(string text)
{
if(m_TextAmount != null)
m_TextAmount.text = text;
}
/// <summary>
/// HP/MP item button should only execute its assigned shortcut.
/// It must NOT open the assign-skill UI when empty.
/// </summary>
public override void Execute()
{
if (pSC != null)
{
pSC.Execute();
}
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 9b2df34c4410f46b5865b5178bfe3058
@@ -52,7 +52,7 @@ namespace BrewMonster.Assets.PerfectWorld.Scripts.UI.GamePlay
}
}
public void Execute()
public virtual void Execute()
{
if (pSC != null )
{
@@ -20,18 +20,44 @@ namespace BrewMonster
//[SerializeField] List<Image> m_aSkillImage = new List<Image>();
//[SerializeField] List<Button> m_aSkillButton = new List<Button>();
[SerializeField] List<AUIImagePicture> AUIImagePictureList = new List<AUIImagePicture>();
public int m_nCurPanel1 = 1;
public int m_nCurPanel2 = 1;
[SerializeField] AUIImageHPMPItem HpItemButton = new AUIImageHPMPItem();
[SerializeField] AUIImageHPMPItem MpItemButton = new AUIImageHPMPItem();
private bool _hpmpReselectDirty = true;
int currentListIndex = 0;
CECSkill assignedSkill = null;
public override void OnEnable()
{
base.OnEnable();
EventBus.Subscribe<InventoryChangedEvent>(OnInventoryChanged);
EventBus.Subscribe<CECHostPlayer.HostPlayerLevelUpUIEvent>(OnHostLevelUp);
_hpmpReselectDirty = true;
}
public override void OnDisable()
{
EventBus.Unsubscribe<InventoryChangedEvent>(OnInventoryChanged);
EventBus.Unsubscribe<CECHostPlayer.HostPlayerLevelUpUIEvent>(OnHostLevelUp);
base.OnDisable();
}
private void OnInventoryChanged(InventoryChangedEvent _)
{
_hpmpReselectDirty = true;
}
private void OnHostLevelUp(CECHostPlayer.HostPlayerLevelUpUIEvent _)
{
_hpmpReselectDirty = true;
}
/// <summary>
/// Apply for a license remove later
/// </summary>
/// <returns></returns>
// public int m_nCurPanel1 = 1;
// public int m_nCurPanel2 = 1;
public int m_nCurPanel1 = 1;
public int m_nCurPanel2 = 1;
public bool m_bShowAll1 = false;
public bool m_bShowAll2 = false;
public int m_nDisplayPanels1 = 0;
@@ -59,7 +85,7 @@ namespace BrewMonster
AUIImagePicture pCell;
CECSkill pSkill = new CECSkill(-1, -1);
AUIClockIcon pClock;
int iIconFile, nMax = 0;
int iIconFile = 0, nMax = 0;
int nCurPanel9 = GetCurPanel1();
int nCurPanel8 = GetCurPanel2();
@@ -432,9 +458,234 @@ namespace BrewMonster
pCell.Clear();
}
}
UpdateHpMpItem();
return true;
}
public void UpdateHpMpItem()
{
const int HP_MAJOR_TYPE_ID = 1794;
const int MP_MAJOR_TYPE_ID = 1802;
CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer();
if (pHost == null)
return;
bool forceReselect = _hpmpReselectDirty;
_hpmpReselectDirty = false;
// Pick the first level-usable medicine with the lowest required level.
// Prefer highest heal amount first, then lowest required level.
// 优先选择“回复量最高”的药品,其次选择需求等级最低的 (Prefer max heal, tie-break by level).
static bool TryFindBestMedicine(CECHostPlayer host, int majorTypeId, out int pack, out int slot, out EC_IvtrMedicine med)
{
pack = -1;
slot = -1;
med = null;
int bestHeal = int.MinValue;
int bestReqLevel = int.MaxValue;
int[] packsToSearch = new int[]
{
InventoryConst.IVTRTYPE_PACK,
InventoryConst.IVTRTYPE_TASKPACK,
};
for (int p = 0; p < packsToSearch.Length; p++)
{
int curPack = packsToSearch[p];
EC_Inventory inv = host.GetPack(curPack);
if (inv == null)
continue;
int size = inv.GetSize();
for (int i = 0; i < size; i++)
{
EC_IvtrItem item = inv.GetItem(i);
if (item is not EC_IvtrMedicine m)
continue;
if (m.GetMajorTypeId() != majorTypeId)
continue;
if (!m.CheckUseCondition())
continue;
int heal = 0;
// HP potion: use hp_add_total; MP potion: use mp_add_total.
// 回血药用 hp_add_total;回蓝药用 mp_add_total。
if (majorTypeId == 1794)
heal = m.GetHpAddTotal();
else if (majorTypeId == 1802)
heal = m.GetMpAddTotal();
int req = m.GetLevelReq();
if (heal > bestHeal || (heal == bestHeal && req < bestReqLevel))
{
bestHeal = heal;
bestReqLevel = req;
pack = curPack;
slot = i;
med = m;
}
}
}
return med != null && pack >= 0 && slot >= 0;
}
static bool TryGetShortcutItem(CECHostPlayer host, CECShortcut sc, out EC_IvtrItem item)
{
item = null;
if (host == null || sc is not CECSCItem scItem)
return false;
EC_Inventory inv = host.GetPack(scItem.GetInventory());
if (inv == null)
return false;
item = inv.GetItem(scItem.GetIvtrSlot());
return item != null;
}
static int GetHealScore(EC_IvtrMedicine med, int majorTypeId)
{
if (med == null) return 0;
return majorTypeId == 1794 ? med.GetHpAddTotal() : med.GetMpAddTotal();
}
void ApplyItemToButton(AUIImageHPMPItem button, CECShortcut sc, EC_IvtrItem item)
{
if (button == null)
return;
if (sc == null || item == null)
{
button.ResetRenderCache();
button.Clear();
button.SetText(string.Empty);
return;
}
// Skill-slot logic pattern: if the shortcut ptr hasn't changed and we're not forced to reselect,
// avoid re-applying icon/text every frame.
// 复用技能格的思路:快捷键指针没变且非强制刷新时,不要每帧重刷图标/数量。
if (button.GetDataPtr() != sc)
{
button.SetDataPtr(sc);
button.ResetRenderCache();
}
int tid = item.GetTemplateID();
if (button.TrySetTemplateId(tid))
{
// Inventory UI path is more reliable than icon-file string matching.
// 背包UI的路径更稳定:按模板ID解析Sprite,而不是匹配图标文件名字符串
var sp = EC_IvtrItemUtils.Instance.ResolveItemIconSprite(tid);
if (sp != null)
button.SetImage(sp);
else
button.Clear();
}
// Amount text / 数量文本
int count = Mathf.Max(0, item.GetCount());
if (button.TrySetCount(count))
{
button.SetText(count > 0 ? count.ToString() : string.Empty);
}
// Cooldown overlay / 冷却遮罩
var clock = button.GetClockIcon();
int max = -1;
int cool = 0;
if (clock != null)
{
cool = item.GetCoolTime(out max);
if (cool > 0 && max > 0)
{
clock.SetProgressRange(0, max);
clock.SetProgressPos(max - cool);
clock.SetColor(new Color32(0, 0, 0, 128));
}
else
{
clock.SetProgressRange(0, 1);
clock.SetProgressPos(1);
}
}
// Interactable state should reflect usability.
// 可交互状态应该反映物品是否可使用
// Mirror host-side restrictions like `UseItemInPack` uses (CANDO_USEITEM etc.)
// 同步宿主侧限制(例如 CANDO_USEITEM),与 UseItemInPack 的限制保持一致
bool hostCanUseItem = pHost.CanDo(CECHostPlayer.ActionCanDo.CANDO_USEITEM);
bool usable = hostCanUseItem && item.CheckUseCondition() && !item.IsFrozen();
bool cooling = (cool > 0 && max > 0);
bool interact = usable && !cooling;
button.SetInteract(interact);
}
void EnsureAssignedAndRefresh(AUIImageHPMPItem button, int majorTypeId)
{
if (button == null)
return;
CECShortcut sc = button.GetDataPtr();
// Resolve current shortcut item (if any).
bool hasCurrent = TryGetShortcutItem(pHost, sc, out EC_IvtrItem item);
// Find best candidate (used both for initial assign and reselect-on-change).
bool hasBest = TryFindBestMedicine(pHost, majorTypeId, out int bestPack, out int bestSlot, out EC_IvtrMedicine bestMed);
// If there is no valid shortcut item, auto assign the best available potion.
if (!hasCurrent)
{
if (hasBest)
{
var newSc = new CECSCItem();
newSc.Init(bestPack, bestSlot, bestMed);
sc = newSc;
item = bestMed;
hasCurrent = true;
}
}
else if (forceReselect && hasBest)
{
// Upgrade to best potion when inventory changes or level changes.
// 背包变化或升级时,自动切换到“最优药品”
var curMed = item as EC_IvtrMedicine;
if (curMed == null || curMed.GetMajorTypeId() != majorTypeId || !curMed.CheckUseCondition())
{
var newSc = new CECSCItem();
newSc.Init(bestPack, bestSlot, bestMed);
sc = newSc;
item = bestMed;
}
else
{
int curHeal = GetHealScore(curMed, majorTypeId);
int bestHeal = GetHealScore(bestMed, majorTypeId);
int curReq = curMed.GetLevelReq();
int bestReq = bestMed.GetLevelReq();
if (bestHeal > curHeal || (bestHeal == curHeal && bestReq < curReq))
{
var newSc = new CECSCItem();
newSc.Init(bestPack, bestSlot, bestMed);
sc = newSc;
item = bestMed;
}
}
}
ApplyItemToButton(button, sc, item);
}
EnsureAssignedAndRefresh(HpItemButton, HP_MAJOR_TYPE_ID);
EnsureAssignedAndRefresh(MpItemButton, MP_MAJOR_TYPE_ID);
}
private void GetQuickBarNameAndSC(CECHostPlayer pHost, List<string> pszPanel, List<CECShortcutSet> pSCS, int panel9, int panel8)
{
string dlgName;
@@ -30,6 +30,7 @@ namespace BrewMonster.UI
private const string SKILL_ICONLIST_NAME = "iconlist_skill_multisprite";
private const string ACTION_ICONLIST_NAME = "ActionIcon/iconlist_action_multisprite";
private const string INVENTORY_ICONLIST_NAME = "UI/IconSprites/iconlist_ivtrm_multisprite";
private const string STATE_ICONLIST_NAME = "iconlist_state";
public CDlgMiniMap m_pDlgMiniMap;
@@ -357,6 +358,12 @@ namespace BrewMonster.UI
return false;
}
/// <summary>Quest main dialog (Win_Quest), created in Init. / 任务主界面,Init 时创建。</summary>
public DlgTask GetDlgTask()
{
return m_pDlgTask;
}
public override void Init()
{
base.Init();
@@ -369,11 +376,25 @@ namespace BrewMonster.UI
m_IconMap[(byte)EC_GAMEUI_ICONS.ICONS_SKILL] = (SKILL_ICONLIST_NAME, Resources.LoadAll<Sprite>(SKILL_ICONLIST_NAME));
m_IconMap[(byte)EC_GAMEUI_ICONS.ICONS_ACTION] = (ACTION_ICONLIST_NAME, Resources.LoadAll<Sprite>(ACTION_ICONLIST_NAME));
m_IconMap[(byte)EC_GAMEUI_ICONS.ICONS_INVENTORY] = (INVENTORY_ICONLIST_NAME, Resources.LoadAll<Sprite>(INVENTORY_ICONLIST_NAME));
m_IconMap[(byte)EC_GAMEUI_ICONS.ICONS_STATE] = (STATE_ICONLIST_NAME, Resources.LoadAll<Sprite>(STATE_ICONLIST_NAME));
}
public void SetCover(AUIImagePictureBase pImgPic, string nameImage, EC_GAMEUI_ICONS iCONS_TYPE)
{
pImgPic.SetImage(m_IconMap[(byte)iCONS_TYPE].Item2.FirstOrDefault(s => s.name == nameImage));
if (pImgPic == null)
return;
if (m_IconMap == null || !m_IconMap.TryGetValue((byte)iCONS_TYPE, out var tuple) || tuple.Item2 == null)
{
pImgPic.Clear();
return;
}
var sprite = tuple.Item2.FirstOrDefault(s => s != null && s.name == nameImage);
if (sprite != null)
pImgPic.SetImage(sprite);
else
pImgPic.Clear();
}
/// <summary>Refresh team UI (Arrange Team dialog). Called after team join/leave/member data.</summary>
@@ -2,12 +2,13 @@
// Creator : Converted from C++ EC_Shop
// Date : 2024
using BrewMonster.Network;
using BrewMonster.Scripts;
using CSNetwork.C2SCommand;
using System.Text.RegularExpressions;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using BrewMonster.Scripts;
using BrewMonster.Network;
using CSNetwork.C2SCommand;
public class NPCShopDetailPanel : MonoBehaviour
{
@@ -47,7 +48,7 @@ public class NPCShopDetailPanel : MonoBehaviour
UpdateDisplay();
}
void UpdateDisplay()
public void UpdateDisplay()
{
if (currentItem.id == 0)
{
@@ -59,6 +60,9 @@ public class NPCShopDetailPanel : MonoBehaviour
if (itemDescriptionText != null)
{
string description = GetItemDescription((int)currentItem.id);
Debug.Log("[NPCShopDetail] RAW:\n" + description);
description = SanitizeDescription(description);
Debug.Log("[NPCShopDetail] Sanitized:\n" + description);
itemDescriptionText.Set(description);
}
@@ -85,7 +89,57 @@ public class NPCShopDetailPanel : MonoBehaviour
LoadItemIcon(itemIconImage, (int)currentItem.id);
}
}
private string SanitizeDescription(string desc)
{
if (string.IsNullOrWhiteSpace(desc))
return string.Empty;
// Normalize escaped + real line breaks (including unicode line separators)
desc = Regex.Replace(
desc,
@"\\r\\n|\\n|\\r|\r\n|\r|\u2028|\u2029",
"\n",
RegexOptions.CultureInvariant);
desc = Regex.Replace(
desc,
@"\^[0-9A-Fa-f]{6}",
string.Empty,
RegexOptions.CultureInvariant);
string[] lines = desc.Split('\n');
var sb = new System.Text.StringBuilder();
for (int i = 0; i < lines.Length; i++)
{
string line = lines[i];
if (string.IsNullOrWhiteSpace(line))
continue;
line = Regex.Replace(line, @"[\u200B-\u200D\uFEFF]", string.Empty, RegexOptions.CultureInvariant);
string plain = Regex.Replace(line, @"<[^>]*>", string.Empty, RegexOptions.CultureInvariant)
.Replace('', ':')
.Trim();
if (Regex.IsMatch(plain, @"^(?:ID|Price)\s*:", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant))
continue;
line = Regex.Replace(
line,
@"(?i)\b(?:ID|Price)\b\s*[:]\s*\d+\b",
string.Empty,
RegexOptions.CultureInvariant).Trim();
if (string.IsNullOrWhiteSpace(line))
continue;
if (sb.Length > 0)
sb.AppendLine();
sb.Append(line);
}
return sb.ToString().Trim();
}
void LoadItemIcon(Image iconImage, int itemId)
{
if (itemId <= 0 || iconImage == null)
@@ -161,6 +215,12 @@ public class NPCShopDetailPanel : MonoBehaviour
return "No description available.";
}
public void ClearText()
{
if(itemDescriptionText != null)
itemDescriptionText.Set(string.Empty);
}
void OnCloseClicked()
{
@@ -223,6 +283,7 @@ public class NPCShopDetailPanel : MonoBehaviour
{
[SerializeField] public Text legacy;
[SerializeField] public TMPro.TextMeshProUGUI tmp;
Color myColorDecimal = new Color(1f, 0.816f, 0.365f, 1f);
public void Set(string value)
{
@@ -233,6 +294,7 @@ public class NPCShopDetailPanel : MonoBehaviour
if (tmp != null)
{
tmp.text = EC_Utility.FormatForTextMeshPro(value ?? string.Empty);
Debug.Log($"[TextOutlet] Set text: {tmp.text}");
}
}
}
@@ -26,13 +26,16 @@ public class NPCShopUIManager : AUIDialog
public GameObject contentRight;
public GameObject contentMidSell;
public GameObject item_info;
public ScrollRect scrollDetailItem;
public ScrollRect scrollListItem;
[Header("Texts")]
public TextMeshProUGUI itemDetailNameText;
public TextMeshProUGUI itemMoneyText;
public TextOutlet itemDescriptionText;
public NPCShopDetailPanel itemDescriptionText;
public TextMeshProUGUI itemsBuyAmountText;
public TextMeshProUGUI itemsBuyTotalMoneyText;
public TextMeshProUGUI itemsSellTotalMoneyText;
[Header("Tabs")]
public Transform tabButtonContainer;
@@ -82,7 +85,6 @@ public class NPCShopUIManager : AUIDialog
/// <summary>Current NPC id for this shop session. Send SEVNPC_HELLO with this before buy.</summary>
public uint CurrentNPCID => currentNPCID;
private NPCShopDetailPanel detailPanelScript;
public override void OnEnable()
{
@@ -392,45 +394,47 @@ public class NPCShopUIManager : AUIDialog
// Initialize buy array with at least one option
shopItem.buy = new GShopBuyOption[4]; // GShopItem supports up to 4 buy options
// Resolve display name/price in a type-agnostic way.
// Some element types come back as DATA_TYPE values we don't special-case here (arrows, flyswords, fashion, etc).
string itemName = EC_IvtrItemUtils.Instance.ResolveItemName(unchecked((int)good.id));
if (string.IsNullOrWhiteSpace(itemName))
itemName = $"Item_{good.id}";
static int ExtractInt(object data, params string[] fieldOrPropNames)
// Get item name and price based on type
string itemName = "Unknown";
int shopPrice = 0;
switch (itemDataType)
{
if (data == null || fieldOrPropNames == null || fieldOrPropNames.Length == 0)
return 0;
var t = data.GetType();
for (int i = 0; i < fieldOrPropNames.Length; i++)
{
string name = fieldOrPropNames[i];
if (string.IsNullOrEmpty(name))
continue;
var field = t.GetField(name, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.IgnoreCase);
if (field != null && field.FieldType == typeof(int))
{
try { return (int)field.GetValue(data); } catch { }
}
var prop = t.GetProperty(name, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.IgnoreCase);
if (prop != null && prop.PropertyType == typeof(int) && prop.CanRead)
{
try { return (int)prop.GetValue(data); } catch { }
}
}
return 0;
case DATA_TYPE.DT_WEAPON_ESSENCE:
var weaponEssence = (WEAPON_ESSENCE)itemData;
itemName = weaponEssence.Name;
shopPrice = weaponEssence.shop_price;
break;
case DATA_TYPE.DT_ARMOR_ESSENCE:
var armorEssence = (ARMOR_ESSENCE)itemData;
itemName = armorEssence.Name;
shopPrice = armorEssence.shop_price;
break;
case DATA_TYPE.DT_MEDICINE_ESSENCE:
var medicineEssence = (MEDICINE_ESSENCE)itemData;
itemName = ByteToStringUtils.UshortArrayToUnicodeString(medicineEssence.name);
shopPrice = medicineEssence.shop_price;
break;
case DATA_TYPE.DT_DECORATION_ESSENCE:
var decorationEssence = (DECORATION_ESSENCE)itemData;
itemName = ByteToStringUtils.UshortArrayToUnicodeString(decorationEssence.name);
shopPrice = decorationEssence.shop_price;
break;
case DATA_TYPE.DT_STONE_ESSENCE:
var stoneEssence = (STONE_ESSENCE)itemData;
itemName = ByteToStringUtils.UshortArrayToUnicodeString(stoneEssence.name);
shopPrice = stoneEssence.shop_price;
break;
case DATA_TYPE.DT_MATERIAL_ESSENCE:
var materialEssence = (MATERIAL_ESSENCE)itemData;
itemName = ByteToStringUtils.UshortArrayToUnicodeString(materialEssence.name);
shopPrice = materialEssence.shop_price;
break;
default:
itemName = $"Item_{good.id}";
break;
}
// Prefer shop_price; fall back to base price if that's all we have.
int shopPrice = ExtractInt(itemData, "shop_price");
if (shopPrice <= 0)
shopPrice = ExtractInt(itemData, "price");
shopItem.name = itemName;
// Set price from contribution cost or shop price
@@ -458,7 +462,42 @@ public class NPCShopUIManager : AUIDialog
{
if (itemPanelPrefab == null || itemContainer == null)
return;
if(scrollListItem != null)
{
scrollListItem.verticalNormalizedPosition = 1f;
}
if (scrollDetailItem != null)
{
scrollDetailItem.verticalNormalizedPosition = 1f;
}
if (itemDetailNameText != null)
{
itemDetailNameText.text = string.Empty;
}
if (itemMoneyText != null)
{
itemMoneyText.text = string.Empty;
}
if (itemDescriptionText != null)
{
itemDescriptionText.ClearText();
}
if (itemIconImage != null)
{
itemIconImage.sprite = khung_item;
}
if (itemsBuyTotalMoneyText != null)
{
itemsBuyTotalMoneyText.text = string.Empty;
}
GameObject itemPanel = Instantiate(itemPanelPrefab, itemContainer);
itemPanel.SetActive(true);
@@ -494,27 +533,41 @@ public class NPCShopUIManager : AUIDialog
return;
SetupDetailPanel(item, this, shopItemIndex);
// Ensure detail panel script is available
if (detailPanelScript == null)
{
}
if (detailPanelScript != null)
{
}
else
{
Debug.LogError("[NPCShopUIManager] NPCShopDetailPanel component not found on npcShopDetailPanel GameObject!");
}
}
public override void CloseDialogue()
{
base.CloseDialogue();
if (itemDetailNameText != null)
{
itemDetailNameText.text = string.Empty;
}
if (itemMoneyText != null)
{
itemMoneyText.text = string.Empty;
}
if (itemDescriptionText != null)
{
itemDescriptionText.ClearText();
}
if (itemIconImage != null)
{
itemIconImage.sprite = khung_item;
}
if(itemsBuyTotalMoneyText != null)
{
itemsBuyTotalMoneyText.text = string.Empty;
}
contentMidBuy.SetActive(true);
contentRight.SetActive(true);
contentMidSell.SetActive(false);
EC_Game.GetGameRun().GetUIManager().GetInGameUIMan().EndNPCService();
}
@@ -590,14 +643,18 @@ public class NPCShopUIManager : AUIDialog
itemMoneyText.text = BuyUiEmptyValue;
}
if (scrollDetailItem != null)
{
scrollDetailItem.verticalNormalizedPosition = 1f;
}
buyCount = BuyCountMin;
UpdateBuyPriceTexts();
// Set item description
if (itemDescriptionText != null)
{
string description = GetItemDescription((int)currentItem.id);
itemDescriptionText.Set(description);
itemDescriptionText.SetupDetailPanel(currentItem, this, shopItemIndex);
}
// if (itemPriceText != null)
@@ -708,7 +765,26 @@ public class NPCShopUIManager : AUIDialog
if (itemsBuyTotalMoneyText != null)
{
itemsBuyTotalMoneyText.text = total.ToString();
uint playerMoney = 0;
try
{
var host = CECGameRun.Instance?.GetHostPlayer();
if (host != null)
{
playerMoney = host.GetMoneyAmount();
}
}
catch
{
playerMoney = 0;
}
string totalText = total.ToString();
string playerMoneyStr = playerMoney.ToString();
itemsBuyTotalMoneyText.text = total > playerMoney
? $"<color=red>{total}</color>/{playerMoney}"
: $"{total}/{playerMoney}";
}
if (m_btn_buy != null)
@@ -1138,28 +1214,6 @@ public class NPCShopUIManager : AUIDialog
m_use_Item.onClick.RemoveListener(OnUseItemClicked);
}
// === Text Outlet Helper ===
[System.Serializable]
public class TextOutlet
{
[SerializeField] public Text legacy;
[SerializeField] public TMPro.TextMeshProUGUI tmp;
public void Set(string value)
{
if (legacy != null)
{
legacy.text = EC_Utility.FormatForLegacyText(value ?? string.Empty);
}
if (tmp != null)
{
string formatTextDeail = EC_Utility.FormatForTextMeshPro(value ?? string.Empty);
formatTextDeail.Replace("<color=#FFFFFF>", "<color=#FFD05D>");
tmp.text = formatTextDeail;
}
}
}
private void SetupSellReadySlotListeners()
{
if (itemReadySell == null)
@@ -1237,7 +1291,75 @@ public class NPCShopUIManager : AUIDialog
private void UpdateSellTotalPriceText()
{
// Sell total text removed from this manager.
return;
long totalSellValue = 0;
int stageCount = 0;
try
{
var host = CECGameRun.Instance?.GetHostPlayer();
var inv = host?.GetInventory(0);
if (inv == null || sellSlotToSourceSlot == null)
{
if (itemsSellTotalMoneyText != null)
itemsSellTotalMoneyText.text = BuyUiEmptyValue;
if (m_btn_sell != null)
m_btn_sell.interactable = false;
return;
}
foreach (var pair in sellSlotToSourceSlot)
{
int sourceSlot = pair.Value;
if (sourceSlot < 0 || sourceSlot >= inv.GetSize())
continue;
var item = inv.GetItem(sourceSlot, false);
if (item == null || item.m_iCount <= 0)
continue;
if (!item.IsSellable())
continue;
try
{
item.GetDetailDataFromLocal();
}
catch
{
}
int unitPrice = item.GetScaledPrice();
long itemTotal = (long)unitPrice * item.m_iCount;
if (itemTotal > 0)
{
totalSellValue += itemTotal;
stageCount++;
}
}
}
catch(Exception ex)
{
}
if (itemsSellTotalMoneyText != null)
{
if(stageCount == 0 || totalSellValue <= 0)
{
itemsSellTotalMoneyText.text = BuyUiEmptyValue;
}
else
{
itemsSellTotalMoneyText.text = totalSellValue.ToString();
}
}
if (m_btn_sell != null)
{
m_btn_sell.interactable = stageCount > 0 && totalSellValue > 0;
}
}
}
@@ -0,0 +1,44 @@
using UnityEngine;
using UnityEngine.UI;
namespace BrewMonster.UI
{
/// <summary>
/// HUD button: pick up the nearest ground item or money (host trace + TryPickupNearestGroundMatter).
/// Assign to a Button or leave unassigned to use the component's own Button.
/// </summary>
public class PickupNearestButtonHandler : MonoBehaviour
{
[SerializeField] private Button button;
[Tooltip("Horizontal search radius around the player (meters).")]
[SerializeField] private float maxSearchRadius = 80f;
private void Start()
{
if (button == null)
button = GetComponent<Button>();
if (button != null)
button.onClick.AddListener(OnPickupNearestClicked);
else
Debug.LogWarning("PickupNearestButtonHandler: No Button component found.");
}
public void OnPickupNearestClicked()
{
var host = CECGameRun.Instance?.GetHostPlayer();
if (host == null)
{
Debug.LogWarning("PickupNearestButtonHandler: Host player not found.");
return;
}
host.TryPickupNearestGroundMatter(maxSearchRadius);
}
private void OnDestroy()
{
if (button != null)
button.onClick.RemoveListener(OnPickupNearestClicked);
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 3e67d421887e31f4ea9eee290568e9d2
+47 -7
View File
@@ -1840,11 +1840,11 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 777847736648841921, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_fontSize
value: 48.2
value: 36
objectReference: {fileID: 0}
- target: {fileID: 777847736648841921, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_fontSizeBase
value: 48.2
value: 36
objectReference: {fileID: 0}
- target: {fileID: 777847736648841921, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_enableAutoSizing
@@ -1934,25 +1934,49 @@ PrefabInstance:
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1900527214026617767, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_AnchorMax.y
value: 1
objectReference: {fileID: 0}
- target: {fileID: 1900527214026617767, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_AnchorMin.y
value: 1
objectReference: {fileID: 0}
- target: {fileID: 1900527214026617767, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_SizeDelta.x
value: 200
value: 171
objectReference: {fileID: 0}
- target: {fileID: 1900527214026617767, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_SizeDelta.y
value: 67.9
value: 56.91
objectReference: {fileID: 0}
- target: {fileID: 1900527214026617767, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_AnchoredPosition.x
value: 532
value: 85.5
objectReference: {fileID: 0}
- target: {fileID: 1900527214026617767, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_AnchoredPosition.y
value: -37
value: -28.455
objectReference: {fileID: 0}
- target: {fileID: 4313766541946487796, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_AnchorMax.y
value: 1
objectReference: {fileID: 0}
- target: {fileID: 4313766541946487796, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_AnchorMin.y
value: 1
objectReference: {fileID: 0}
- target: {fileID: 4313766541946487796, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_AnchoredPosition.x
value: 85.5
objectReference: {fileID: 0}
- target: {fileID: 4313766541946487796, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_AnchoredPosition.y
value: -152.91
objectReference: {fileID: 0}
- target: {fileID: 6102967088919909530, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_AnchoredPosition.y
value: 10.8
value: 8
objectReference: {fileID: 0}
- target: {fileID: 6830833846243993097, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_Name
@@ -1962,6 +1986,22 @@ PrefabInstance:
propertyPath: m_IsActive
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6900679650323527362, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_AnchorMax.y
value: 1
objectReference: {fileID: 0}
- target: {fileID: 6900679650323527362, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_AnchorMin.y
value: 1
objectReference: {fileID: 0}
- target: {fileID: 6900679650323527362, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_AnchoredPosition.x
value: 85.5
objectReference: {fileID: 0}
- target: {fileID: 6900679650323527362, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_AnchoredPosition.y
value: -88.91
objectReference: {fileID: 0}
- target: {fileID: 7209086543831860202, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_AnchorMax.y
value: 1
File diff suppressed because it is too large Load Diff
+10 -9
View File
@@ -2752,9 +2752,9 @@ RectTransform:
- {fileID: 4504331075840543341}
m_Father: {fileID: 1361524257611413148}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 469.781, y: -34.01085}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 179.9124, y: 68.0217}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &8804506040386004496
@@ -5515,9 +5515,9 @@ RectTransform:
- {fileID: 2027606699309904338}
m_Father: {fileID: 1361524257611413148}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 109.9562, y: -34.01085}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 179.9124, y: 68.0217}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &6741821173640675138
@@ -17685,6 +17685,7 @@ MonoBehaviour:
m_contentRootSkill: {fileID: 0}
m_scrollRect: {fileID: 0}
m_windowScale: 1
totalSPText: {fileID: 0}
m_isEvil: 0
--- !u!1 &7758409605357852732
GameObject:
@@ -19226,9 +19227,9 @@ RectTransform:
- {fileID: 911293677621153352}
m_Father: {fileID: 1361524257611413148}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 289.8686, y: -34.01085}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 179.9124, y: 68.0217}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &5623009994815814977
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+47 -7
View File
@@ -1980,11 +1980,11 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 777847736648841921, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_fontSize
value: 48.2
value: 36
objectReference: {fileID: 0}
- target: {fileID: 777847736648841921, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_fontSizeBase
value: 48.2
value: 36
objectReference: {fileID: 0}
- target: {fileID: 777847736648841921, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_enableAutoSizing
@@ -2074,25 +2074,49 @@ PrefabInstance:
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1900527214026617767, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_AnchorMax.y
value: 1
objectReference: {fileID: 0}
- target: {fileID: 1900527214026617767, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_AnchorMin.y
value: 1
objectReference: {fileID: 0}
- target: {fileID: 1900527214026617767, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_SizeDelta.x
value: 200
value: 171
objectReference: {fileID: 0}
- target: {fileID: 1900527214026617767, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_SizeDelta.y
value: 67.9
value: 55.9082
objectReference: {fileID: 0}
- target: {fileID: 1900527214026617767, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_AnchoredPosition.x
value: 532
value: 85.5
objectReference: {fileID: 0}
- target: {fileID: 1900527214026617767, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_AnchoredPosition.y
value: -37
value: -27.9541
objectReference: {fileID: 0}
- target: {fileID: 4313766541946487796, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_AnchorMax.y
value: 1
objectReference: {fileID: 0}
- target: {fileID: 4313766541946487796, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_AnchorMin.y
value: 1
objectReference: {fileID: 0}
- target: {fileID: 4313766541946487796, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_AnchoredPosition.x
value: 85.5
objectReference: {fileID: 0}
- target: {fileID: 4313766541946487796, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_AnchoredPosition.y
value: -151.9082
objectReference: {fileID: 0}
- target: {fileID: 6102967088919909530, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_AnchoredPosition.y
value: 10.8
value: 3.5
objectReference: {fileID: 0}
- target: {fileID: 6830833846243993097, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_Name
@@ -2102,6 +2126,22 @@ PrefabInstance:
propertyPath: m_IsActive
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6900679650323527362, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_AnchorMax.y
value: 1
objectReference: {fileID: 0}
- target: {fileID: 6900679650323527362, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_AnchorMin.y
value: 1
objectReference: {fileID: 0}
- target: {fileID: 6900679650323527362, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_AnchoredPosition.x
value: 85.5
objectReference: {fileID: 0}
- target: {fileID: 6900679650323527362, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_AnchoredPosition.y
value: -87.9082
objectReference: {fileID: 0}
- target: {fileID: 7209086543831860202, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
propertyPath: m_AnchorMax.y
value: 1
+33 -120
View File
@@ -2771,8 +2771,8 @@ namespace BrewMonster
return m_idSelTarget;
}
// Auto select a attackable target / 自动选择一个可攻击的目标
// Auto select a attackable target / 自动选择一个可攻击目标
// Auto select a attackable target — cycle by distance (nearest → farthest, then repeat)
// 自动选择可攻击目标 — 按距离循环(从近到远,再回到最近)
public int AutoSelectTarget()
{
if (!CanDo(ActionCanDo.CANDO_CHANGESELECT))
@@ -2780,145 +2780,53 @@ namespace BrewMonster
int idCurSel = (m_idSelTarget != 0 && m_idSelTarget != m_PlayerInfo.cid) ? m_idSelTarget : 0;
// Clean up invalid targets from tab selection array / 清理无效目标
if (idCurSel == 0)
{
// Rebuild selected table / 重建选中表
m_aTabSels.Clear();
}
else
{
// Remove targets that are too far / 移除距离过远的目标
for (int i = m_aTabSels.Count - 1; i >= 0; i--)
{
CECObject pObject = m_aTabSels[i];
if (pObject == null)
{
m_aTabSels.RemoveAt(i);
continue;
}
float fDistToHost = 0.0f;
if (pObject is EC_ElsePlayer pPlayer)
fDistToHost = pPlayer.GetDistToHost();
else if (pObject is CECNPC pNPC)
fDistToHost = pNPC.GetDistToHost();
if (fDistToHost > EC_RoleTypes.EC_TABSEL_DIST || !CanSafelySelectWith(fDistToHost))
{
m_aTabSels.RemoveAt(i);
}
}
}
float fMinDist = 10000.0f;
CECObject pCand = null;
int idCandidate = 0;
// Get player candidates / 获取玩家候选列表
// idCurSel == 0 so TabSelectCandidates includes current target for index-based cycling
List<EC_ElsePlayer> aCandPlayers = new List<EC_ElsePlayer>();
EC_ManMessageMono.Instance.EC_ManPlayer.TabSelectCandidates(idCurSel, aCandPlayers);
EC_ManMessageMono.Instance.EC_ManPlayer.TabSelectCandidates(0, aCandPlayers);
List<CECNPC> aCandNPCs = new List<CECNPC>();
EC_ManMessageMono.Instance.CECNPCMan.TabSelectCandidates(0, aCandNPCs);
var sorted = new List<(float dist, int id, CECObject obj)>();
foreach (var pPlayer in aCandPlayers)
{
if (pPlayer == null)
continue;
// Check whether this player is in selected array / 检查此玩家是否已在选中数组中
if (m_aTabSels.Contains(pPlayer))
continue; // This player has been in selected array / 此玩家已在选中数组中
// Record the nearest one as candidate / 记录最近的一个作为候选
float fDist = pPlayer.GetDistToHost();
if (fDist < fMinDist)
{
fMinDist = fDist;
pCand = pPlayer;
idCandidate = pPlayer.GetCharacterID();
}
sorted.Add((pPlayer.GetDistToHost(), pPlayer.GetCharacterID(), pPlayer));
}
// Get NPC candidates / 获取NPC候选列表
List<CECNPC> aCandNPCs = new List<CECNPC>();
EC_ManMessageMono.Instance.CECNPCMan.TabSelectCandidates(idCurSel, aCandNPCs);
foreach (var pNPC in aCandNPCs)
{
if (pNPC == null)
continue;
// Check whether this npc is in selected array / 检查此NPC是否已在选中数组中
if (m_aTabSels.Contains(pNPC))
continue; // This npc has been in selected array / 此NPC已在选中数组中
// Record the nearest one as candidate / 记录最近的一个作为候选
float fDist = pNPC.GetDistToHost();
if (fDist < fMinDist)
{
fMinDist = fDist;
pCand = pNPC;
idCandidate = pNPC.GetNPCID();
}
sorted.Add((pNPC.GetDistToHost(), pNPC.GetNPCID(), pNPC));
}
sorted.Sort((a, b) =>
{
int c = a.dist.CompareTo(b.dist);
return c != 0 ? c : a.id.CompareTo(b.id);
});
m_aTabSels.Clear();
for (int i = 0; i < sorted.Count; i++)
m_aTabSels.Add(sorted[i].obj);
// Maximum number of candidates in tab selection array / 标签选择数组中的最大候选数
// Increased from 9 to 20 to allow more targets / 从9增加到20以允许更多目标
const int iMaxCand = 9;
int idNewSel = 0;
if (pCand != null && idCandidate != 0)
if (sorted.Count == 0)
{
// Add candidate to tab selection array / 将候选添加到标签选择数组
if (m_aTabSels.Count >= iMaxCand)
{
m_aTabSels.RemoveAt(m_aTabSels.Count - 1);
m_aTabSels.Insert(0, pCand);
}
else
{
m_aTabSels.Add(pCand);
}
idNewSel = idCandidate;
idNewSel = idCurSel;
}
else // No proper candidate was found / 未找到合适的候选
else
{
if (m_aTabSels.Count == 0)
int idx = -1;
for (int i = 0; i < sorted.Count; i++)
{
idNewSel = idCurSel;
}
else // Try to select one which has been in selected array / 尝试选择已在选中数组中的一个
{
int iIndex = -1;
for (int i = 0; i < m_aTabSels.Count; i++)
if (sorted[i].id == idCurSel)
{
CECObject pObject = m_aTabSels[i];
if (pObject == null)
continue;
int objId = 0;
if (pObject is EC_ElsePlayer pElsePlayer)
objId = pElsePlayer.GetCharacterID();
else if (pObject is CECNPC pNPC)
objId = pNPC.GetNPCID();
if (objId == idCurSel)
{
iIndex = i;
break;
}
}
iIndex = (iIndex + 1) % m_aTabSels.Count;
CECObject pSelectedObj = m_aTabSels[iIndex];
if (pSelectedObj != null)
{
if (pSelectedObj is EC_ElsePlayer pSelPlayer)
idNewSel = pSelPlayer.GetCharacterID();
else if (pSelectedObj is CECNPC pSelNPC)
idNewSel = pSelNPC.GetNPCID();
idx = i;
break;
}
}
int nextIdx = idx < 0 ? 0 : (idx + 1) % sorted.Count;
idNewSel = sorted[nextIdx].id;
}
// Select the target if found / 如果找到目标则选择它
@@ -3159,6 +3067,8 @@ namespace BrewMonster
// m_pLevelUpGFX.Start(true);
PlayGfx(EC_Resource.res_GFXFile((int)GfxResourceType.RES_GFX_LEVELUP), null, 1f, 1); //PLAYERMODEL_TYPEALL
EventBus.Publish(new HostPlayerLevelUpUIEvent());
// // Popup notify bubble text
// BubbleText(BUBBLE_LEVELUP, 0);
//
@@ -3714,6 +3624,9 @@ namespace BrewMonster
/// <summary>Fired when selected target HUD should be hidden (deselect or switch).</summary>
public struct TargetHUDClearEvent { }
/// <summary>Host leveled up — UI layer may refresh quest-offer lists, popups, etc. 玩家升级,UI 可刷新可接任务等。</summary>
public struct HostPlayerLevelUpUIEvent { }
public struct GNDINFO
{
public float fGndHei; // Ground height
+41 -19
View File
@@ -6,6 +6,8 @@ using System.Collections.Generic;
using BrewMonster.PerfectWorld.Scripts.Utility.ChatFilter;
using BrewMonster.Scripts.Chat.EmotionData;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts.Task.UI;
using BrewMonster.Scripts.UI;
using UnityEngine;
using TMPro;
@@ -55,6 +57,7 @@ public class CECUIManager : MonoSingleton<CECUIManager>
EventBus.Subscribe<CECHostPlayer.NPCINFO>(ShowUINPC);
EventBus.Subscribe<CECHostPlayer.TargetHUDClearEvent>(OnTargetHUDClear);
EventBus.Subscribe<CECHostPlayer.HostPlayerLevelUpUIEvent>(OnHostPlayerLevelUpUI);
EventBus.Subscribe<NPCDiedEvent>(TryHideUINPC);
EventBus.Subscribe<MessageBoxEvent>(OnMessageBox);
@@ -85,22 +88,26 @@ public class CECUIManager : MonoSingleton<CECUIManager>
m_pDlgQuickBar1.UpdateShortcuts();
}
// Periodically update task UI (DlgTask and DlgTaskTrace) / 定期更新任务UIDlgTask和DlgTaskTrace
if (Time.unscaledTime >= _nextTaskUpdateTime)
{
_nextTaskUpdateTime = Time.unscaledTime + TASK_UPDATE_INTERVAL;
//if hostplayer is null, return
var hostPlayer = EC_Game.GetGameRun()?.GetHostPlayer();
if(hostPlayer == null)
{
return;
}
UpdateTaskUI();
// Task UI must run from this Update(): TickInvoker often never calls CECUIManager.Tick in practice
// (registration order, DDOL instance, or no TickInvoker in scene), so logs/body there never ran.
// 任务 UI 必须在此 Update 驱动:TickInvoker 在部分场景下根本不会调到本类 Tick。
if (Time.unscaledTime < _nextTaskUpdateTime)
return;
_nextTaskUpdateTime = Time.unscaledTime + TASK_UPDATE_INTERVAL;
// Hiển thị thông tin đăng nhập khi người chơi đã vào game an toàn / Show login info when host player is ready
// Hàm này bên trong đã có cờ m_bAccountLoginInfoShown để tránh bị gọi nhiều lần, nên đặt ở Update là an toàn.
UpdateTaskUI();
if (EC_Game.GetGameRun()?.GetHostPlayer() != null)
EC_Game.GetGameRun()?.ShowAccountLoginInfo();
}
}
/// <summary>
/// Rebuild acceptable-quest cache after host levels up (heavy scan; not on player code path).
/// 升级后重建可接任务缓存(全表扫描放在 UI 层)。
/// </summary>
private void OnHostPlayerLevelUpUI(CECHostPlayer.HostPlayerLevelUpUIEvent _)
{
DlgTask.RebuildAcceptableQuestCache();
}
/// <summary>
@@ -113,13 +120,27 @@ public class CECUIManager : MonoSingleton<CECUIManager>
var inGameUIMan = GetInGameUIMan();
if (inGameUIMan == null) return;
var dlgTaskDialog = inGameUIMan.GetDialog("Win_Quest");
var bShowTrace = inGameUIMan.IsDialogShow("Win_QuestMinion");
if (dlgTaskDialog != null && dlgTaskDialog is BrewMonster.Scripts.Task.UI.DlgTask dlgTask)
// Prefer cached DlgTask from Init (Win_Quest). Do not rely on `is DlgTask` on AUIDialog:
// prefab may register as AUIDialog while DlgTask is the concrete component on the same GO.
// 优先使用 Init 里缓存的 DlgTask;字典里可能是 AUIDialog 引用,`is DlgTask` 会为 false。
DlgTask dlgTask = null;
if (inGameUIMan is CECGameUIMan gameUi && gameUi.GetDlgTask() != null)
dlgTask = gameUi.GetDlgTask();
if (dlgTask == null)
{
dlgTask.RefreshTaskTrace(bShowTrace);
dlgTask.Tick();
var dlg = inGameUIMan.GetDialog(CECUIHelper.DlgTaskName);
dlgTask = dlg != null ? dlg.GetComponent<DlgTask>() : null;
}
if (dlgTask == null)
return;
if (EC_Game.GetGameRun()?.GetHostPlayer() == null)
return;
var bShowTrace = inGameUIMan.IsDialogShow("Win_QuestMinion");
dlgTask.RefreshTaskTrace(bShowTrace);
dlgTask.Tick();
}
catch (System.Exception)
{
@@ -132,6 +153,7 @@ public class CECUIManager : MonoSingleton<CECUIManager>
{
EventBus.Unsubscribe<CECHostPlayer.NPCINFO>(ShowUINPC);
EventBus.Unsubscribe<CECHostPlayer.TargetHUDClearEvent>(OnTargetHUDClear);
EventBus.Unsubscribe<CECHostPlayer.HostPlayerLevelUpUIEvent>(OnHostPlayerLevelUpUI);
EventBus.Unsubscribe<NPCDiedEvent>(TryHideUINPC);
EventBus.Unsubscribe<MessageBoxEvent>(OnMessageBox);
}