Merge remote-tracking branch 'origin/develop' into internal-testing-build
This commit is contained in:
@@ -15,6 +15,11 @@ MonoBehaviour:
|
||||
m_GroupName: Default Local Group
|
||||
m_GUID: 712e3991f28e549e7a56ee582a977810
|
||||
m_SerializeEntries:
|
||||
- m_GUID: 1b653230886be4009808803501ad7d7f
|
||||
m_Address: Assets/PerfectWorld/SO/TaskTemplContainerSO.asset
|
||||
m_ReadOnly: 0
|
||||
m_SerializedLabels: []
|
||||
FlaggedDuringContentUpdateRestriction: 0
|
||||
- m_GUID: 1cfde61ea9d19614a8ea91cb1eeca97b
|
||||
m_Address: "\u7A0B\u5E8F\u8054\u5165/\u89D2\u8272\u51FA\u73B0\u4EBA\u7C7B.gfx"
|
||||
m_ReadOnly: 0
|
||||
|
||||
@@ -3308,6 +3308,7 @@ MonoBehaviour:
|
||||
- {fileID: 7400000, guid: d3c1bf1bc3105b247aae16f9c99519ea, type: 2}
|
||||
- {fileID: 7400000, guid: b9c1b4aacfc88174f9bfcb8bf1c69eb5, type: 2}
|
||||
- {fileID: 7400000, guid: d54a450816dbc4d4ca43afbe607052ad, type: 2}
|
||||
- {fileID: 7400000, guid: cbff0726770bb1146bc70346d5fc38f9, type: 2}
|
||||
--- !u!1 &2587141697474146175
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
||||
@@ -31,9 +31,9 @@ RectTransform:
|
||||
- {fileID: 7068400949313321131}
|
||||
m_Father: {fileID: 1982628982857606432}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 119.34445, y: -50.05}
|
||||
m_SizeDelta: {x: 238.6889, y: 100}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!1 &567730479829113918
|
||||
@@ -1063,9 +1063,9 @@ RectTransform:
|
||||
- {fileID: 1673093633596208253}
|
||||
m_Father: {fileID: 6556814518920652147}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 744.2305, y: -49.72705}
|
||||
m_SizeDelta: {x: 72.1893, y: 73.4541}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &5696506275770781555
|
||||
@@ -1782,9 +1782,9 @@ RectTransform:
|
||||
- {fileID: 3173262022725656255}
|
||||
m_Father: {fileID: 1802319080125745111}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 533.7858, y: -474.8956}
|
||||
m_SizeDelta: {x: 1067.5717, y: 53.7328}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &4979397800331147640
|
||||
@@ -1832,9 +1832,9 @@ RectTransform:
|
||||
- {fileID: 5159105777246515782}
|
||||
m_Father: {fileID: 1802319080125745111}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 552.95, y: -697.9664}
|
||||
m_SizeDelta: {x: 1105.9, y: 100.1}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &3682686733385602497
|
||||
@@ -2616,9 +2616,9 @@ RectTransform:
|
||||
- {fileID: 9038859519033147586}
|
||||
m_Father: {fileID: 3413131598704007284}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 160, y: -27.7372}
|
||||
m_SizeDelta: {x: 320, y: 55.4744}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &3633225552368495711
|
||||
@@ -2786,9 +2786,9 @@ RectTransform:
|
||||
- {fileID: 6888331463719618182}
|
||||
m_Father: {fileID: 1802319080125745111}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 533.8, y: -181.5047}
|
||||
m_SizeDelta: {x: 1067.6, y: 147.0112}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &7637574953150164924
|
||||
@@ -2992,9 +2992,9 @@ RectTransform:
|
||||
- {fileID: 466166190548844919}
|
||||
m_Father: {fileID: 1802319080125745111}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 533.7858, y: -287.3301}
|
||||
m_SizeDelta: {x: 1067.5717, y: 64.6396}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &5725159945352370057
|
||||
@@ -3035,9 +3035,9 @@ RectTransform:
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1802319080125745111}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 50, y: -17.98135}
|
||||
m_SizeDelta: {x: 100, y: 35.9627}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!1 &2640258873449426733
|
||||
@@ -3495,9 +3495,9 @@ RectTransform:
|
||||
- {fileID: 1664656494516247222}
|
||||
m_Father: {fileID: 1802319080125745111}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 533.7858, y: -97.82885}
|
||||
m_SizeDelta: {x: 1067.5717, y: 20.3405}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &5366537333355115835
|
||||
@@ -3540,9 +3540,9 @@ RectTransform:
|
||||
m_Children: []
|
||||
m_Father: {fileID: 5935924508566653103}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 59.9817, y: -31.017}
|
||||
m_SizeDelta: {x: 119.9634, y: 62.034}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &8442116720262994404
|
||||
@@ -3988,7 +3988,7 @@ RectTransform:
|
||||
m_Father: {fileID: 7958847946112668032}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 20, y: 20}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
@@ -4289,9 +4289,9 @@ RectTransform:
|
||||
- {fileID: 5935924508566653103}
|
||||
m_Father: {fileID: 1982628982857606432}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 981.0654, y: -50.05}
|
||||
m_SizeDelta: {x: 249.67, y: 100}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &3615902548841175383
|
||||
@@ -4365,9 +4365,9 @@ RectTransform:
|
||||
- {fileID: 6664836867558571240}
|
||||
m_Father: {fileID: 6556814518920652147}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 632.0412, y: -49.72705}
|
||||
m_SizeDelta: {x: 72.1893, y: 73.4541}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &1719403314563710437
|
||||
@@ -4441,9 +4441,9 @@ RectTransform:
|
||||
- {fileID: 3123454216176481580}
|
||||
m_Father: {fileID: 1982628982857606432}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 390.45966, y: -50.05}
|
||||
m_SizeDelta: {x: 103.5415, y: 42.7938}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &6244284104014817409
|
||||
@@ -4529,9 +4529,9 @@ RectTransform:
|
||||
- {fileID: 4269318562826283412}
|
||||
m_Father: {fileID: 3413131598704007284}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 160, y: -392.4044}
|
||||
m_SizeDelta: {x: 320, y: 673.86}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &6982899544592245397
|
||||
@@ -4635,6 +4635,7 @@ RectTransform:
|
||||
- {fileID: 1687288316189840478}
|
||||
- {fileID: 3413131598704007284}
|
||||
- {fileID: 1802319080125745111}
|
||||
- {fileID: 8560871508586000967}
|
||||
m_Father: {fileID: 9127077926286418868}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
@@ -4713,9 +4714,9 @@ RectTransform:
|
||||
- {fileID: 2490029976799717816}
|
||||
m_Father: {fileID: 6556814518920652147}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 295.47327, y: -49.72705}
|
||||
m_SizeDelta: {x: 72.1893, y: 73.4541}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &7650172129678423862
|
||||
@@ -4791,9 +4792,9 @@ RectTransform:
|
||||
m_Father: {fileID: 2214759022841903186}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: -17, y: 0}
|
||||
m_Pivot: {x: 0, y: 1}
|
||||
--- !u!222 &4662246788448476486
|
||||
CanvasRenderer:
|
||||
@@ -4882,7 +4883,7 @@ RectTransform:
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0.000024855137}
|
||||
m_SizeDelta: {x: 1067.6, y: 0}
|
||||
m_SizeDelta: {x: 1067.6, y: 44.66}
|
||||
m_Pivot: {x: 0, y: 1}
|
||||
--- !u!222 &8527806716735377849
|
||||
CanvasRenderer:
|
||||
@@ -4997,6 +4998,138 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
m_HorizontalFit: 0
|
||||
m_VerticalFit: 2
|
||||
--- !u!1 &5079467856058945530
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 8560871508586000967}
|
||||
- component: {fileID: 4358218663584653282}
|
||||
- component: {fileID: 2639378489502838745}
|
||||
- component: {fileID: 7962930401627561727}
|
||||
m_Layer: 5
|
||||
m_Name: Button
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &8560871508586000967
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5079467856058945530}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 945666739613519770}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 1, y: 1}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: -62, y: -72}
|
||||
m_SizeDelta: {x: 58, y: 58}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &4358218663584653282
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5079467856058945530}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &2639378489502838745
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5079467856058945530}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 21300000, guid: fb2f2f58be45f6e4890e85cc00b0bcc9, type: 3}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 1
|
||||
--- !u!114 &7962930401627561727
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5079467856058945530}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Navigation:
|
||||
m_Mode: 3
|
||||
m_WrapAround: 0
|
||||
m_SelectOnUp: {fileID: 0}
|
||||
m_SelectOnDown: {fileID: 0}
|
||||
m_SelectOnLeft: {fileID: 0}
|
||||
m_SelectOnRight: {fileID: 0}
|
||||
m_Transition: 1
|
||||
m_Colors:
|
||||
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
|
||||
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
m_HighlightedSprite: {fileID: 0}
|
||||
m_PressedSprite: {fileID: 0}
|
||||
m_SelectedSprite: {fileID: 0}
|
||||
m_DisabledSprite: {fileID: 0}
|
||||
m_AnimationTriggers:
|
||||
m_NormalTrigger: Normal
|
||||
m_HighlightedTrigger: Highlighted
|
||||
m_PressedTrigger: Pressed
|
||||
m_SelectedTrigger: Selected
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 2639378489502838745}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls:
|
||||
- m_Target: {fileID: 6999114045547682248}
|
||||
m_TargetAssemblyTypeName: UnityEngine.GameObject, UnityEngine
|
||||
m_MethodName: SetActive
|
||||
m_Mode: 6
|
||||
m_Arguments:
|
||||
m_ObjectArgument: {fileID: 0}
|
||||
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
|
||||
m_IntArgument: 0
|
||||
m_FloatArgument: 0
|
||||
m_StringArgument:
|
||||
m_BoolArgument: 0
|
||||
m_CallState: 2
|
||||
--- !u!1 &5087525444877170506
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -5030,9 +5163,9 @@ RectTransform:
|
||||
- {fileID: 7337732696262196210}
|
||||
m_Father: {fileID: 6556814518920652147}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 183.28395, y: -49.72705}
|
||||
m_SizeDelta: {x: 72.1893, y: 73.4541}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &665161835172153120
|
||||
@@ -5105,9 +5238,9 @@ RectTransform:
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1982628982857606432}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 288.6889, y: -50.05}
|
||||
m_SizeDelta: {x: 100, y: 100}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &1142619112158729952
|
||||
@@ -5242,9 +5375,9 @@ RectTransform:
|
||||
- {fileID: 464210832437986234}
|
||||
m_Father: {fileID: 6556814518920652147}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 71.09465, y: -49.72705}
|
||||
m_SizeDelta: {x: 72.1893, y: 73.4541}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &6131836957139812833
|
||||
@@ -5353,9 +5486,9 @@ RectTransform:
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1802319080125745111}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 150, y: -61.81065}
|
||||
m_SizeDelta: {x: 300, y: 51.6959}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &4239296098804493253
|
||||
@@ -5490,9 +5623,9 @@ RectTransform:
|
||||
- {fileID: 9160025208612689927}
|
||||
m_Father: {fileID: 6556814518920652147}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 856.41986, y: -49.72705}
|
||||
m_SizeDelta: {x: 72.1893, y: 73.4541}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &4153770864616565637
|
||||
@@ -5567,9 +5700,9 @@ RectTransform:
|
||||
- {fileID: 3906960815437350628}
|
||||
m_Father: {fileID: 8174585228173147249}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 241.1868, y: -31.18805}
|
||||
m_SizeDelta: {x: 170.7912, y: 62.3761}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &7438076119085514817
|
||||
@@ -5686,9 +5819,9 @@ RectTransform:
|
||||
m_Children: []
|
||||
m_Father: {fileID: 7068400949313321131}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 76, y: -31.75005}
|
||||
m_SizeDelta: {x: 100, y: 100}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &2800332942966355020
|
||||
@@ -6308,9 +6441,9 @@ RectTransform:
|
||||
m_Father: {fileID: 3760164886363293420}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: -17, y: 0}
|
||||
m_Pivot: {x: 0, y: 1}
|
||||
--- !u!222 &5693552902337398956
|
||||
CanvasRenderer:
|
||||
@@ -6483,8 +6616,8 @@ MonoBehaviour:
|
||||
m_TargetGraphic: {fileID: 7392889747821849613}
|
||||
m_HandleRect: {fileID: 2343337405992641122}
|
||||
m_Direction: 2
|
||||
m_Value: 0
|
||||
m_Size: 0.9999435
|
||||
m_Value: 1
|
||||
m_Size: 0.9999888
|
||||
m_NumberOfSteps: 0
|
||||
m_OnValueChanged:
|
||||
m_PersistentCalls:
|
||||
@@ -6524,9 +6657,9 @@ RectTransform:
|
||||
m_Father: {fileID: 8611061134879146475}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: -17, y: 0}
|
||||
m_Pivot: {x: 0, y: 1}
|
||||
--- !u!222 &1301146549737279854
|
||||
CanvasRenderer:
|
||||
@@ -6739,9 +6872,9 @@ RectTransform:
|
||||
- {fileID: 3960419512253178154}
|
||||
m_Father: {fileID: 1982628982857606432}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 752.7304, y: -50.05}
|
||||
m_SizeDelta: {x: 207, y: 77}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &5922293013674383484
|
||||
@@ -6858,8 +6991,8 @@ RectTransform:
|
||||
m_Children: []
|
||||
m_Father: {fileID: 5233116975597807035}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 0.000011205673}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 20, y: 20}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
@@ -6934,7 +7067,7 @@ RectTransform:
|
||||
m_Father: {fileID: 2825219564319673376}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 20, y: 20}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
@@ -7249,7 +7382,7 @@ GameObject:
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
m_IsActive: 0
|
||||
--- !u!224 &5506476487848131018
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -7344,9 +7477,9 @@ RectTransform:
|
||||
- {fileID: 8526229293534627480}
|
||||
m_Father: {fileID: 1802319080125745111}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 552.95, y: -574.8392}
|
||||
m_SizeDelta: {x: 1105.9, y: 146.1544}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!1 &7362516739390317868
|
||||
@@ -7383,9 +7516,9 @@ RectTransform:
|
||||
- {fileID: 8359974748112151041}
|
||||
m_Father: {fileID: 1982628982857606432}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 545.7304, y: -50.05}
|
||||
m_SizeDelta: {x: 207, y: 77}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &175839448811631403
|
||||
@@ -7704,9 +7837,9 @@ RectTransform:
|
||||
- {fileID: 3546830409645517734}
|
||||
m_Father: {fileID: 6556814518920652147}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 519.85187, y: -49.72705}
|
||||
m_SizeDelta: {x: 72.1893, y: 73.4541}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &7535806629134762549
|
||||
@@ -7782,9 +7915,9 @@ RectTransform:
|
||||
- {fileID: 3450901294667678815}
|
||||
m_Father: {fileID: 1802319080125745111}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 533.8, y: -383.83954}
|
||||
m_SizeDelta: {x: 1067.6, y: 128.3793}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &5632580526749397436
|
||||
@@ -7888,9 +8021,9 @@ RectTransform:
|
||||
- {fileID: 6076870470824675401}
|
||||
m_Father: {fileID: 6556814518920652147}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 407.66254, y: -49.72705}
|
||||
m_SizeDelta: {x: 72.1893, y: 73.4541}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &5385847170717247365
|
||||
@@ -8040,9 +8173,9 @@ RectTransform:
|
||||
- {fileID: 1805980451046698619}
|
||||
m_Father: {fileID: 8174585228173147249}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 80.3956, y: -31.18805}
|
||||
m_SizeDelta: {x: 170.7912, y: 62.3761}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &8101014133290532655
|
||||
@@ -8234,9 +8367,9 @@ RectTransform:
|
||||
m_Children: []
|
||||
m_Father: {fileID: 5935924508566653103}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 155.6889, y: -31.017}
|
||||
m_SizeDelta: {x: 71.451, y: 62.034}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &1158119712588225859
|
||||
@@ -8731,7 +8864,7 @@ PrefabInstance:
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 8395333742829132721, guid: 9456de25596014039bd4d0d3927b709a, type: 3}
|
||||
propertyPath: m_AnchoredPosition.y
|
||||
value: 336.93
|
||||
value: 336.92987
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 8395333742829132721, guid: 9456de25596014039bd4d0d3927b709a, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
|
||||
@@ -0,0 +1,272 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &6426564401230013186
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 3325367652782365102}
|
||||
- component: {fileID: 6868997766477093256}
|
||||
- component: {fileID: 2867419621240194058}
|
||||
m_Layer: 5
|
||||
m_Name: Text (TMP)
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &3325367652782365102
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6426564401230013186}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 266017875005995358}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0.9228058, y: 0.69200134}
|
||||
m_SizeDelta: {x: -78.8826, y: -78.8826}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &6868997766477093256
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6426564401230013186}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &2867419621240194058
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6426564401230013186}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_text: JUMP
|
||||
m_isRightToLeft: 0
|
||||
m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
|
||||
m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
|
||||
m_fontSharedMaterials: []
|
||||
m_fontMaterial: {fileID: 0}
|
||||
m_fontMaterials: []
|
||||
m_fontColor32:
|
||||
serializedVersion: 2
|
||||
rgba: 4281479730
|
||||
m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_enableVertexGradient: 0
|
||||
m_colorMode: 3
|
||||
m_fontColorGradient:
|
||||
topLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||
topRight: {r: 1, g: 1, b: 1, a: 1}
|
||||
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||
bottomRight: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_fontColorGradientPreset: {fileID: 0}
|
||||
m_spriteAsset: {fileID: 0}
|
||||
m_tintAllSprites: 0
|
||||
m_StyleSheet: {fileID: 0}
|
||||
m_TextStyleHashCode: -1183493901
|
||||
m_overrideHtmlColors: 0
|
||||
m_faceColor:
|
||||
serializedVersion: 2
|
||||
rgba: 4294967295
|
||||
m_fontSize: 44.7
|
||||
m_fontSizeBase: 24
|
||||
m_fontWeight: 400
|
||||
m_enableAutoSizing: 1
|
||||
m_fontSizeMin: 18
|
||||
m_fontSizeMax: 72
|
||||
m_fontStyle: 0
|
||||
m_HorizontalAlignment: 2
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_TextWrappingMode: 1
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 0
|
||||
m_ActiveFontFeatures: 6e72656b
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_EmojiFallbackSupport: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 1
|
||||
m_isCullingEnabled: 0
|
||||
m_horizontalMapping: 0
|
||||
m_verticalMapping: 0
|
||||
m_uvLineOffset: 0
|
||||
m_geometrySortingOrder: 0
|
||||
m_IsTextObjectScaleStatic: 0
|
||||
m_VertexBufferAutoSizeReduction: 0
|
||||
m_useMaxVisibleDescender: 1
|
||||
m_pageToDisplay: 1
|
||||
m_margin: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_isUsingLegacyAnimationComponent: 0
|
||||
m_isVolumetricText: 0
|
||||
m_hasFontAssetChanged: 0
|
||||
m_baseMaterial: {fileID: 0}
|
||||
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
|
||||
--- !u!1 &6792439420010771896
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 266017875005995358}
|
||||
- component: {fileID: 5557092053757495849}
|
||||
- component: {fileID: 3695308113943472152}
|
||||
- component: {fileID: 1194531703109065144}
|
||||
- component: {fileID: 4432331937269434665}
|
||||
m_Layer: 5
|
||||
m_Name: JumpBtn
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &266017875005995358
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6792439420010771896}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 3325367652782365102}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 1, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 0}
|
||||
m_AnchoredPosition: {x: -61, y: 46}
|
||||
m_SizeDelta: {x: 200, y: 200}
|
||||
m_Pivot: {x: 1, y: 0}
|
||||
--- !u!222 &5557092053757495849
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6792439420010771896}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &3695308113943472152
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6792439420010771896}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 10913, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 1
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 1
|
||||
--- !u!114 &1194531703109065144
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6792439420010771896}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Navigation:
|
||||
m_Mode: 3
|
||||
m_WrapAround: 0
|
||||
m_SelectOnUp: {fileID: 0}
|
||||
m_SelectOnDown: {fileID: 0}
|
||||
m_SelectOnLeft: {fileID: 0}
|
||||
m_SelectOnRight: {fileID: 0}
|
||||
m_Transition: 1
|
||||
m_Colors:
|
||||
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
|
||||
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
m_HighlightedSprite: {fileID: 0}
|
||||
m_PressedSprite: {fileID: 0}
|
||||
m_SelectedSprite: {fileID: 0}
|
||||
m_DisabledSprite: {fileID: 0}
|
||||
m_AnimationTriggers:
|
||||
m_NormalTrigger: Normal
|
||||
m_HighlightedTrigger: Highlighted
|
||||
m_PressedTrigger: Pressed
|
||||
m_SelectedTrigger: Selected
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 3695308113943472152}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
--- !u!114 &4432331937269434665
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6792439420010771896}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: a6149141837cadc4baae427c4864833e, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0104938c092195b40ab7f3b6e5bf342e
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -19,7 +19,7 @@ MonoBehaviour:
|
||||
prefab: {fileID: 8237288432181259026, guid: eaeb778b6aab3d74299373b3a96b72c4, type: 3}
|
||||
- id: Win_Award
|
||||
prefab: {fileID: 903595479696773158, guid: cf26d96ae7d984ba8a5b6cef44adffeb, type: 3}
|
||||
- id: Win_Task
|
||||
- id: Win_Quest
|
||||
prefab: {fileID: 6999114045547682248, guid: 8027cada0ef5e4a9f827001b4747174d, type: 3}
|
||||
- id: Win_SkillSubAction
|
||||
prefab: {fileID: 111271885693053298, guid: eb88919320b4229459c83b6b1f8f1e7b, type: 3}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f3d86049520f4217970358d8c6e0fd1
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1b653230886be4009808803501ad7d7f
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e3e518641de396e1b30dd202ff94dc35518476c7efd747501f45f10021136ca7
|
||||
oid sha256:0930e07b267dc93d54fbc4de6bfaac5a9bf1aa7ea5ff239a58e5a8a7a25cf6c7
|
||||
size 10723
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace BrewMonster.Network
|
||||
private static int m_AbsTimeStart;
|
||||
private static int m_iTimeError; // 服务器与本机时间差(秒) // Time error in seconds
|
||||
private static int m_iTimeZoneBias; // 服务器时区偏移(秒) // Server timezone bias in seconds
|
||||
private static bool m_bServerTimeInited;
|
||||
public static int GetTimeZoneBias() { return m_iTimeZoneBias; }
|
||||
// 设置时间误差 // Set time error
|
||||
public static void SetServerTime(int iSevTime, int iTimeZoneBias)
|
||||
@@ -37,11 +38,20 @@ namespace BrewMonster.Network
|
||||
// 初始化绝对时间参考点 // Initialize absolute time reference
|
||||
m_AbsTimeStart = iSevTime;
|
||||
m_AbsTickStart = (uint)(Time.realtimeSinceStartup * 1000.0f);
|
||||
m_bServerTimeInited = true;
|
||||
Debug.Log($"timeGetTime(), TickStart = {m_AbsTickStart}");
|
||||
}
|
||||
|
||||
public static int GetServerAbsTime()
|
||||
{
|
||||
// Fallback: if server time was never initialized (SetServerTime not called),
|
||||
// return local unix time seconds so task timestamps (usually epoch seconds) still work.
|
||||
// This makes wait-time/countdown and timetable logic behave correctly even before server sync.
|
||||
if (!m_bServerTimeInited || m_AbsTimeStart == 0)
|
||||
{
|
||||
return (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds() + m_iTimeError;
|
||||
}
|
||||
|
||||
uint curTick = (uint)(Time.realtimeSinceStartup * 1000.0f);
|
||||
|
||||
if (curTick < m_AbsTickStart)
|
||||
|
||||
@@ -93,11 +93,11 @@ namespace BrewMonster.Network
|
||||
m_pElementDataMan = ElementDataManProvider.GetElementDataMan();
|
||||
|
||||
#if UNITY_EDITOR
|
||||
/* if (TaskTest.Instance &&
|
||||
if (TaskTest.Instance &&
|
||||
TaskTest.m_pTaskMan != null)
|
||||
{
|
||||
m_pTaskMan = TaskTest.m_pTaskMan;
|
||||
}*/
|
||||
}
|
||||
#endif
|
||||
// Load task templates
|
||||
if (m_pTaskMan == null) m_pTaskMan = new ATaskTemplMan();
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace BrewMonster.Scripts
|
||||
{
|
||||
m_iPoseAction = iAction;
|
||||
m_bSession = bSession;
|
||||
|
||||
// m_pHost.PlayAction(m_iPoseAction, false, 300);
|
||||
m_pHost.PlayAction(m_iPoseAction, true);
|
||||
|
||||
if (!bSession && iAction != (int)PLAYER_ACTION_TYPE.ACT_EXP_KISS)
|
||||
@@ -175,6 +175,11 @@ namespace BrewMonster.Scripts
|
||||
m_pHost.PlayAction(m_iCurAction, false, 300);
|
||||
//m_oldAction = m_iCurAction;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Debug.LogError($"m_iPoseAction == {(PLAYER_ACTION_TYPE)m_iPoseAction}");
|
||||
m_pHost.PlayAction(m_iPoseAction, false, 300);
|
||||
}
|
||||
|
||||
// Force to update object's direction and up
|
||||
// m_pHost.m_vecGroundNormal = m_pHost.m_vecGroundNormalSet;
|
||||
|
||||
@@ -19,27 +19,7 @@ namespace BrewMonster
|
||||
}
|
||||
if (Input.GetKeyDown(KeyCode.Space))
|
||||
{
|
||||
//if (bInAutoMode) return;
|
||||
if (IsJumpInWater() || IsFlying())
|
||||
return;
|
||||
|
||||
if (IsUnderWater())
|
||||
{
|
||||
if (!CanTakeOffWater())
|
||||
return;
|
||||
else if (_JumpTime <= 0)
|
||||
{
|
||||
_JumpTime = Time.realtimeSinceStartup;
|
||||
return;
|
||||
}
|
||||
else if ((Time.realtimeSinceStartup - _JumpTime) < 1f) // logic in c++, _JumpTime is milisecond
|
||||
return;
|
||||
else
|
||||
_JumpTime = -1f;
|
||||
}
|
||||
|
||||
m_GndInfo.bOnGround = GroundCheck(out lastGroundHit);
|
||||
OnMsgHstJump();
|
||||
OnClickBtnJump();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,5 +188,29 @@ namespace BrewMonster
|
||||
PlayAction((int)PLAYER_ACTION_TYPE.ACT_JUMP_LOOP, false, 0, true);
|
||||
}
|
||||
|
||||
public void OnClickBtnJump()
|
||||
{
|
||||
//if (bInAutoMode) return;
|
||||
if (IsJumpInWater() || IsFlying())
|
||||
return;
|
||||
|
||||
if (IsUnderWater())
|
||||
{
|
||||
if (!CanTakeOffWater())
|
||||
return;
|
||||
else if (_JumpTime <= 0)
|
||||
{
|
||||
_JumpTime = Time.realtimeSinceStartup;
|
||||
return;
|
||||
}
|
||||
else if ((Time.realtimeSinceStartup - _JumpTime) < 1f) // logic in c++, _JumpTime is milisecond
|
||||
return;
|
||||
else
|
||||
_JumpTime = -1f;
|
||||
}
|
||||
|
||||
m_GndInfo.bOnGround = GroundCheck(out lastGroundHit);
|
||||
OnMsgHstJump();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,34 +101,44 @@ namespace BrewMonster
|
||||
pEnvTrc.fFraction = 100.0f;
|
||||
pEnvTrc.bStartSolid = false;
|
||||
pEnvTrc.dwClsFlag = 0;
|
||||
Vector3 vStart = EC_Utility.ToVector3(pEnvTrc.vStart);
|
||||
Vector3 vExt = EC_Utility.ToVector3(pEnvTrc.vExt);
|
||||
Vector3 vDelta = EC_Utility.ToVector3(pEnvTrc.vDelta);
|
||||
Vector3 vTerStart = EC_Utility.ToVector3(pEnvTrc.vTerStart);
|
||||
Vector3 dir = Vector3.zero;
|
||||
|
||||
if ((pEnvTrc.dwCheckFlag & CDR_EVN.CDR_BRUSH) == CDR_EVN.CDR_BRUSH)
|
||||
{
|
||||
BrushTraceInfo bruInfo = new BrushTraceInfo();
|
||||
bruInfo.Init(pEnvTrc.vStart, pEnvTrc.vDelta, pEnvTrc.vExt);
|
||||
if (AABBCollideWithBrush(ref bruInfo))
|
||||
dir = vStart + vDelta;
|
||||
if (Physics.BoxCast(vStart, vExt, dir, out RaycastHit hit, Quaternion.identity, vDelta.magnitude, 1 << 7))
|
||||
{
|
||||
pEnvTrc.fFraction = bruInfo.fFraction;
|
||||
pEnvTrc.vHitNormal = bruInfo.ClipPlane.GetNormal();
|
||||
pEnvTrc.bStartSolid = bruInfo.bStartSolid;
|
||||
pEnvTrc.fFraction = (hit.distance - vExt.x) / vDelta.magnitude;
|
||||
pEnvTrc.vHitNormal = EC_Utility.ToA3DVECTOR3(hit.normal);
|
||||
pEnvTrc.dwClsFlag = CDR_EVN.CDR_BRUSH;
|
||||
}
|
||||
else
|
||||
{
|
||||
pEnvTrc.fFraction = 1f;
|
||||
}
|
||||
}
|
||||
if ((pEnvTrc.dwCheckFlag & CDR_EVN.CDR_TERRAIN) == CDR_EVN.CDR_TERRAIN)
|
||||
{
|
||||
float fFraction = 0f;
|
||||
A3DVECTOR3 vTerNormal = new A3DVECTOR3();
|
||||
bool bStart = false;
|
||||
if (CollideWithTerrain(pEnvTrc.vTerStart, pEnvTrc.vDelta, ref fFraction, ref vTerNormal, ref bStart)
|
||||
&& (fFraction < pEnvTrc.fFraction))
|
||||
float fFractionTerrain = 0f;
|
||||
dir = vDelta;
|
||||
if (Physics.Raycast(vTerStart, dir.normalized, out RaycastHit hit, vDelta.magnitude, 1<<6))
|
||||
{
|
||||
//assert(fFraction >= 0.0f);
|
||||
//pEnvTrc.fFraction = a_Max(0.0f, fFraction - 1E-4f);
|
||||
pEnvTrc.fFraction = fFraction;
|
||||
pEnvTrc.vHitNormal = vTerNormal;
|
||||
pEnvTrc.bStartSolid = bStart;
|
||||
fFractionTerrain = (hit.distance) / vDelta.magnitude;
|
||||
pEnvTrc.vHitNormal = EC_Utility.ToA3DVECTOR3(hit.normal);
|
||||
pEnvTrc.dwClsFlag = CDR_EVN.CDR_TERRAIN;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
fFractionTerrain = 1f;
|
||||
}
|
||||
if(fFractionTerrain < pEnvTrc.fFraction)
|
||||
{
|
||||
pEnvTrc.fFraction = fFractionTerrain;
|
||||
}
|
||||
}
|
||||
|
||||
if ((pEnvTrc.dwCheckFlag & CDR_EVN.CDR_WATER) == CDR_EVN.CDR_WATER)
|
||||
@@ -156,46 +166,6 @@ namespace BrewMonster
|
||||
return (pEnvTrc.fFraction < 1.0f + 1E-4f);
|
||||
}
|
||||
|
||||
// == Thay CollideWithEnv (C++) bằng BoxCast ==
|
||||
//static bool CollideWithEnv_BoxCast(Vector3 vStart, Vector3 vDelta, Vector3 vExt,
|
||||
// LayerMask mask,
|
||||
// out RaycastHit hit, out float fFraction, out Vector3 vHitNormal, out bool bStartSolid,
|
||||
// float skin = 0.01f)
|
||||
//{
|
||||
// hit = default;
|
||||
// vHitNormal = Vector3.up;
|
||||
// bStartSolid = false;
|
||||
// fFraction = 0.0f;
|
||||
|
||||
// float dist = vDelta.magnitude;
|
||||
// if (dist <= 1e-6f) return false;
|
||||
|
||||
// var hasHit = Physics.Raycast(vStart, vDelta,out hit, dist, mask);
|
||||
// if (hasHit)
|
||||
// {
|
||||
// bStartSolid = true;
|
||||
// fFraction = (t - 5E-4f) / vDelta.Normalize();
|
||||
// return true;
|
||||
// }
|
||||
// // start-in-solid
|
||||
// var overlapped = Physics.OverlapBox(vStart, vExt - Vector3.one * skin, Quaternion.identity, mask, QueryTriggerInteraction.Ignore);
|
||||
// if (overlapped != null && overlapped.Length > 0)
|
||||
// {
|
||||
// bStartSolid = true;
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// // sweep AABB
|
||||
// Vector3 dir = vDelta / Mathf.Max(dist, 1e-6f);
|
||||
// if (Physics.BoxCast(vStart, vExt - Vector3.one * skin, dir, out hit, Quaternion.identity, dist, mask, QueryTriggerInteraction.Ignore))
|
||||
// {
|
||||
// fFraction = Mathf.Clamp01(hit.distance / Mathf.Max(dist, 1e-6f));
|
||||
// vHitNormal = hit.normal;
|
||||
// return true;
|
||||
// }
|
||||
// return false;
|
||||
//}
|
||||
|
||||
// == Thay RetrieveSupportPlane (C++) bằng Raycast xuống ==
|
||||
static bool DoGroundProbe(Vector3 vStart, Vector3 vExt, float fDeltaY, LayerMask mask,
|
||||
out Vector3 vEnd, out Vector3 vHitNormal, out bool bSupport,
|
||||
@@ -280,6 +250,10 @@ namespace BrewMonster
|
||||
int nTry = 0;
|
||||
LayerMask mask = UsedMask_Ground();
|
||||
|
||||
env_trace_t trcInfo = new env_trace_t();
|
||||
trcInfo.dwCheckFlag = CDR_EVN.CDR_TERRAIN | CDR_EVN.CDR_BRUSH;
|
||||
trcInfo.vExt = CDRInfo.vExtent;
|
||||
|
||||
while (nTry < 1)
|
||||
{
|
||||
vDelta = vVelocity * fTime;
|
||||
@@ -290,41 +264,33 @@ namespace BrewMonster
|
||||
//bool hasHit = CollideWithEnv_BoxCast(vStart, vDelta, vExt, mask,
|
||||
// out RaycastHit hit, out float fFraction, out Vector3 hitNormal, out bool bStartSolid);
|
||||
Vector3 posFoot = vStart - Vector3.up * vExt.y;
|
||||
//if (Physics.BoxCast(vStart, vExt, (vStart + Vector3.down).normalized, out RaycastHit hit1, Quaternion.identity, vExt.y, mask))
|
||||
//{
|
||||
// if (hit1.point.y > posFoot.y)
|
||||
// {
|
||||
// Debug.LogError("hit.point.y > posFoot.y");
|
||||
// posFoot.y = hit1.point.y;
|
||||
// }
|
||||
//}
|
||||
if (Physics.Raycast(vStart, (vStart + Vector3.down).normalized, out RaycastHit hit1, vExt.y, mask))
|
||||
if (Physics.Raycast(vStart, (vStart + Vector3.down).normalized, out RaycastHit hit, vExt.y, mask))
|
||||
{
|
||||
if (hit1.point.y > posFoot.y)
|
||||
if (hit.point.y > posFoot.y)
|
||||
{
|
||||
posFoot.y = hit1.point.y;
|
||||
posFoot.y = hit.point.y;
|
||||
}
|
||||
}
|
||||
bool bClear = !Physics.Raycast(posFoot, (posFoot + vDelta).normalized, out RaycastHit hit, fDeltaDist, mask);
|
||||
|
||||
bool bClear = !Physics.Raycast(posFoot, (posFoot + vDelta).normalized, out hit, fDeltaDist, mask);
|
||||
|
||||
//trcInfo.vStart = CDRInfo.vCenter;
|
||||
//trcInfo.vDelta = EC_Utility.ToA3DVECTOR3(vDelta);
|
||||
//trcInfo.vTerStart = EC_Utility.ToA3DVECTOR3(posFoot);
|
||||
////trcInfo.vTerStart.y -= vExt.y; //foot
|
||||
//bool bClear = !CollideWithEnv(ref trcInfo);
|
||||
nTry++;
|
||||
if (bClear)
|
||||
{
|
||||
Debug.DrawLine(posFoot, posFoot + vDelta, Color.yellow, 10f);
|
||||
//Debug.DrawLine(posFoot, posFoot + vDelta, Color.yellow, 10f);
|
||||
vFinalPos = vStart + vDelta;
|
||||
CDRInfo.fMoveDist += fDeltaDist;
|
||||
break;
|
||||
}
|
||||
//if (trcInfo.bStartSolid)
|
||||
//{
|
||||
// CDRInfo.fMoveDist = 0f;
|
||||
// if (CDRInfo.vTPNormal.y < CDRInfo.fSlopeThresh) CDRInfo.vTPNormal = Vector3.up;
|
||||
// return;
|
||||
//}
|
||||
vStart = hit.point + Vector3.up * vExt.y;
|
||||
//vStart += vDelta * trcInfo.fFraction + Vector3.up * vExt.y;
|
||||
|
||||
vFinalPos = vStart;
|
||||
//CDRInfo.fMoveDist += (fDeltaDist * fFraction);
|
||||
//fTime -= fTime * fFraction;
|
||||
//vNormal = hitNormal;
|
||||
|
||||
// Step-up (giữ tinh thần bản gốc)
|
||||
if (!bFreeFall && !bTryPull && !bJump)
|
||||
@@ -332,36 +298,38 @@ namespace BrewMonster
|
||||
//float skin = 0.01f;
|
||||
posFoot = vStart - Vector3.up * vExt.y + Vector3.up * CDRInfo.fStepHeight;
|
||||
Vector3 vStartUp = new Vector3(0f, CDRInfo.fStepHeight, 0f);
|
||||
//if (Physics.Raycast(vStart, (vStart + Vector3.down).normalized, out hit1, vExt.y, mask))
|
||||
//{
|
||||
// if (hit1.point.y > posFoot.y)
|
||||
// {
|
||||
// Debug.LogError("hit.point.y > posFoot.y");
|
||||
// posFoot.y = hit1.point.y + CDRInfo.fStepHeight;
|
||||
// }
|
||||
//}
|
||||
bPull = !Physics.Raycast(posFoot, (Vector3.up).normalized, out hit, CDRInfo.fStepHeight, mask);
|
||||
|
||||
//env_trace_t tmpInfo = new env_trace_t();
|
||||
//tmpInfo.vStart = EC_Utility.ToA3DVECTOR3(vStart);
|
||||
//tmpInfo.vDelta = new A3DVECTOR3(0.0f, CDRInfo.fStepHeight, 0.0f);
|
||||
//tmpInfo.vExt = CDRInfo.vExtent;
|
||||
////@note : need check terrain?? By Kuiwu[8/10/2005]
|
||||
//tmpInfo.dwCheckFlag = CDR_EVN.CDR_BRUSH | CDR_EVN.CDR_TERRAIN;
|
||||
//tmpInfo.vTerStart = EC_Utility.ToA3DVECTOR3(posFoot);
|
||||
//bPull = !CollideWithEnv(ref tmpInfo);
|
||||
|
||||
if (bPull)
|
||||
{
|
||||
vStart += Vector3.up * CDRInfo.fStepHeight;
|
||||
posFoot = vStart - Vector3.up * vExt.y;
|
||||
//Vector3 vDelta2 = vVelocity;
|
||||
bool bMove = !Physics.Raycast(posFoot, (posFoot + vVelocity).normalized, out hit, fDeltaDist, mask);
|
||||
|
||||
//tmpInfo.vStart = EC_Utility.ToA3DVECTOR3(vStart);
|
||||
//tmpInfo.vDelta = EC_Utility.ToA3DVECTOR3(vDelta);
|
||||
//tmpInfo.vTerStart = EC_Utility.ToA3DVECTOR3(posFoot);
|
||||
//bool bMove = !CollideWithEnv(ref tmpInfo);
|
||||
|
||||
if (!bMove)
|
||||
{
|
||||
//vDelta2 *= frac2;
|
||||
vFinalPos = hit.point + Vector3.up * vExt.y;
|
||||
//vFinalPos = vStart + vDelta * tmpInfo.fFraction + Vector3.up * vExt.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.DrawLine(vFinalPos, vFinalPos + vDelta, Color.red, 10f);
|
||||
vFinalPos += vDelta;
|
||||
}
|
||||
//if (vDelta2.sqrMagnitude < (vExt.x * vExt.x * 4f))
|
||||
//{
|
||||
// vStart -= Vector3.up * CDRInfo.fStepHeight;
|
||||
// bPull = false;
|
||||
//}
|
||||
}
|
||||
bTryPull = true;
|
||||
}
|
||||
@@ -680,7 +648,7 @@ namespace BrewMonster
|
||||
vFinalPos = new A3DVECTOR3(vStart);
|
||||
int nTry = 0;
|
||||
bool bClear = true;
|
||||
env_trace_t trcInfo;
|
||||
env_trace_t trcInfo = new env_trace_t();
|
||||
trcInfo.bWaterSolid = true;
|
||||
trcInfo.dwCheckFlag = CDR_EVN.CDR_TERRAIN | CDR_EVN.CDR_BRUSH | CDR_EVN.CDR_WATER;
|
||||
trcInfo.vExt = vExt;
|
||||
|
||||
@@ -1841,9 +1841,6 @@ namespace CSNetwork.GPDataType
|
||||
struct cmd_emote_action
|
||||
{
|
||||
public ushort action;
|
||||
public ushort id;
|
||||
public int expiretime;
|
||||
public char flag;
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
|
||||
@@ -7,11 +7,10 @@ using CSNetwork.GPDataType;
|
||||
using ModelRenderer.Scripts.Common;
|
||||
using PerfectWorld.Scripts.Managers;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace PerfectWorld.Scripts
|
||||
{
|
||||
public class CECMatter : CECObject, IPointerDownHandler
|
||||
public class CECMatter : CECObject
|
||||
{
|
||||
// Matter information got from server
|
||||
public struct INFO
|
||||
@@ -93,10 +92,49 @@ namespace PerfectWorld.Scripts
|
||||
return null;
|
||||
}
|
||||
|
||||
public void OnPointerDown(PointerEventData eventData)
|
||||
private new void Update()
|
||||
{
|
||||
Debug.Log($"CECMatter::OnPointerDown():: mid: {m_MatterInfo.mid}");
|
||||
UnityGameSession.RequestPickupItem(m_MatterInfo.mid, m_MatterInfo.tid);
|
||||
bool inputPressed = false;
|
||||
Vector2 screenPosition = Vector2.zero;
|
||||
|
||||
// Check for touch input (mobile)
|
||||
if (Input.touchCount > 0)
|
||||
{
|
||||
Touch touch = Input.GetTouch(0);
|
||||
if (touch.phase == TouchPhase.Began)
|
||||
{
|
||||
inputPressed = true;
|
||||
screenPosition = touch.position;
|
||||
}
|
||||
}
|
||||
// Check for mouse input (desktop)
|
||||
else if (Input.GetMouseButtonDown(0))
|
||||
{
|
||||
inputPressed = true;
|
||||
screenPosition = Input.mousePosition;
|
||||
}
|
||||
|
||||
if (inputPressed)
|
||||
{
|
||||
Camera mainCamera = Camera.main;
|
||||
if (mainCamera == null)
|
||||
return;
|
||||
|
||||
Ray ray = mainCamera.ScreenPointToRay(screenPosition);
|
||||
|
||||
RaycastHit[] hits = Physics.RaycastAll(ray);
|
||||
|
||||
foreach (RaycastHit hit in hits)
|
||||
{
|
||||
if (hit.collider.gameObject == this.gameObject ||
|
||||
hit.collider.transform.IsChildOf(this.transform))
|
||||
{
|
||||
Debug.Log($"CECMatter::RaycastHit():: mid: {m_MatterInfo.mid}");
|
||||
UnityGameSession.RequestPickupItem(m_MatterInfo.mid, m_MatterInfo.tid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ using BrewMonster.Scripts.Task;
|
||||
|
||||
namespace PerfectWorld.Scripts.Task
|
||||
{
|
||||
[Serializable]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct ATaskTemplFixedData
|
||||
{
|
||||
|
||||
@@ -8,6 +8,8 @@ using System.Threading;
|
||||
using CSNetwork.GPDataType;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
|
||||
namespace BrewMonster.Scripts.Task
|
||||
{
|
||||
@@ -83,6 +85,15 @@ namespace BrewMonster.Scripts.Task
|
||||
|
||||
public async UniTask<bool> LoadTasksFromPack(string szPackPath, bool bLoadDescript, Action<float> onProgress, CancellationToken token)
|
||||
{
|
||||
bool wasLoaded = await LoadTaskTemplFromSO();
|
||||
if (wasLoaded)
|
||||
{
|
||||
BMLogger.Log($" [ATaskTemplMan] Loaded task templates from ScriptableObject.");
|
||||
onProgress?.Invoke(1f);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// //TaskInterface::WriteLog(0, 0, 2, "LoadPack begin");
|
||||
// BMLogger.Log("[Dat]- szPackPath: " + szPackPath);
|
||||
// if (!File.Exists(szPackPath))
|
||||
@@ -228,6 +239,85 @@ namespace BrewMonster.Scripts.Task
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool LoadTasksFromPackNoAsyn(string szPackPath, bool bLoadDescript)
|
||||
{
|
||||
//TaskInterface::WriteLog(0, 0, 2, "LoadPack begin");
|
||||
BMLogger.Log("[Dat]- szPackPath: " + szPackPath);
|
||||
if (!File.Exists(szPackPath))
|
||||
{
|
||||
BMLogger.LogError("[Dat]- File not found: " + szPackPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
long readBytes = 0;
|
||||
FileStream fs = new FileStream(szPackPath, FileMode.Open, FileAccess.Read);
|
||||
|
||||
TASK_PACK_HEADER tph = AAssit.ReadFromBinaryOf<TASK_PACK_HEADER>(fs, ref readBytes);
|
||||
|
||||
if (tph.magic != TASK_PACK_MAGIC
|
||||
|| tph.version != _task_templ_cur_version)
|
||||
return false;
|
||||
|
||||
if (tph.item_count == 0) return true;
|
||||
|
||||
uint[] pOffs = new uint[tph.item_count];
|
||||
g_ulNewCount++;
|
||||
|
||||
|
||||
// fread(pOffs, sizeof(long), tph.item_count, fp);
|
||||
// read File and prepare offset array before loading tasks
|
||||
pOffs = AAssit.ReadArrayFromBinary<uint>(fs, (int)tph.item_count, ref readBytes);
|
||||
|
||||
Debug.Log((int)tph.item_count);
|
||||
//BMLogger.Log($" [MH] Task File Lenght: {fs.Length}");
|
||||
// for (int i = 2058; i < 2059; i++) //TODO: tph.item_count
|
||||
Debug.Log($" Starting to load {tph.item_count} task templates...");
|
||||
for (int i = 0; i < tph.item_count; i++)
|
||||
{
|
||||
// mvoe file pointer to task offset
|
||||
fs.Seek(pOffs[i], SeekOrigin.Begin);
|
||||
// BMLogger.Log(" [MH] Loading Task Templ at offset: " + pOffs[i]);
|
||||
|
||||
ATaskTempl pTempl = new ATaskTempl();
|
||||
g_ulNewCount++;
|
||||
|
||||
// Debug.Log($"Task Index {i}: Attempting to load task template...");
|
||||
if (!pTempl.LoadFromBinFile(fs))
|
||||
{
|
||||
CECTaskInterface.WriteLog(0, (int)pTempl.m_FixedData.m_ID, 0, "Cant Load Task");
|
||||
// LOG_DELETE(pTempl);
|
||||
continue;
|
||||
}
|
||||
|
||||
AddOneTaskTempl(pTempl);
|
||||
// TaskInterface::WriteLog(0, pTempl->m_ID, 2, "LoadTask");
|
||||
}
|
||||
|
||||
Debug.Log($" Finished loading {m_TaskTemplMap.Count} task templates.");
|
||||
|
||||
// // char log[1024];
|
||||
// // sprintf(log, "LoadTask, Count = %d", m_TaskTemplMap.size());
|
||||
// // TaskInterface::WriteLog(0, 0, 2, log);
|
||||
|
||||
// //todo: check
|
||||
// // LOG_DELETE_ARR(pOffs);
|
||||
fs.Close();
|
||||
#if !_TASK_CLIENT
|
||||
UpdateTimeLimitCheckList();
|
||||
#else
|
||||
SortTasksCanSeekOut();
|
||||
#endif
|
||||
|
||||
|
||||
#if _ELEMENTCLIENT
|
||||
// TODO: implement task error logging if needed
|
||||
// _task_err.Release();
|
||||
// _task_err.Init("Configs\\task_err.txt", true);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static List<ATaskTempl> LoadTasksFromPack_Internal(string szPackPath, Action<float> onProgress, CancellationToken token)
|
||||
{
|
||||
long readBytes = 0;
|
||||
@@ -983,7 +1073,25 @@ namespace BrewMonster.Scripts.Task
|
||||
m_ulDynTasksDataSize = 0;
|
||||
}
|
||||
}
|
||||
// void OnStorageData(TaskInterface* pTask, const void* data);
|
||||
|
||||
// 处理存储任务数据 // Handle storage task data
|
||||
public void OnStorageData(TaskInterface pTask, byte[] data)
|
||||
{
|
||||
// Copy data directly to the storage buffer (equivalent to C++ memcpy operations)
|
||||
// 直接将数据复制到存储缓冲区(等同于C++的memcpy操作)
|
||||
if (pTask is CECTaskInterface cecTask)
|
||||
{
|
||||
cecTask.SetStorageTaskListBuffer(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fallback: read into struct (but won't persist without writing back)
|
||||
// 后备方案:读取到结构体(但不写回则不会持久化)
|
||||
StorageTaskList pLst = pTask.GetStorageTaskList();
|
||||
pLst.ReadByte(data);
|
||||
}
|
||||
}
|
||||
|
||||
// void OnSpecialAward(const special_award* p,TaskInterface* pTask);
|
||||
// void VerifyDynTasksPack(const char* szPath);
|
||||
// const special_award* GetSpecialAward() const { return &m_SpecialAward; }
|
||||
@@ -1131,7 +1239,9 @@ namespace BrewMonster.Scripts.Task
|
||||
return false;
|
||||
}
|
||||
|
||||
if (header.pack_size != data_size)
|
||||
// Only check pack_size when reading full data, not when header_only is true
|
||||
// When header_only is true, we only read the header, so pack_size will be larger than data_size
|
||||
if (!header_only && header.pack_size != data_size)
|
||||
{
|
||||
// TaskInterface::WriteLog(0, 0, 0, "UnmarshalDynTasks, wrong header");
|
||||
BMLogger.LogError($" [ATaskTemplMan] UnmarshalDynTasks, wrong header: pack_size {header.pack_size} != data_size {data_size}");
|
||||
@@ -1261,6 +1371,60 @@ namespace BrewMonster.Scripts.Task
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public async UniTask<bool> LoadTaskTemplFromSO()
|
||||
{
|
||||
const string addressKey = "Assets/PerfectWorld/SO/TaskTemplContainerSO.asset"; // set this to the real address
|
||||
AsyncOperationHandle<TaskTemplContainerSO> handle = default;
|
||||
|
||||
try
|
||||
{
|
||||
handle = Addressables.LoadAssetAsync<TaskTemplContainerSO>(addressKey);
|
||||
await handle.Task;
|
||||
|
||||
if (handle.Status != AsyncOperationStatus.Succeeded)
|
||||
{
|
||||
BMLogger.LogError($"[ATaskTemplMan] LoadTaskTemplFromSO failed: {handle.OperationException}");
|
||||
return false;
|
||||
}
|
||||
|
||||
var config = handle.Result;
|
||||
if (config == null)
|
||||
{
|
||||
BMLogger.LogError("[ATaskTemplMan] LoadTaskTemplFromSO returned null result");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!config.LoadAllTasksOnValidate) return false;
|
||||
|
||||
var loadedTasks = config.TaskTemplates;
|
||||
if (loadedTasks == null ||loadedTasks.Count == 0)
|
||||
{
|
||||
BMLogger.LogError("[ATaskTemplMan] LoadTaskTemplFromSO, no task templates found in SO");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < loadedTasks.Count; i++)
|
||||
{
|
||||
AddOneTaskTempl(loadedTasks[i]);
|
||||
g_ulNewCount++;
|
||||
}
|
||||
|
||||
Debug.Log($"Finished loading {m_TaskTemplMap.Count} task templates.");
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
BMLogger.LogError($"[ATaskTemplMan] LoadTaskTemplFromSO exception: {e}");
|
||||
return false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (handle.IsValid())
|
||||
Addressables.Release(handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ StructLayout(LayoutKind.Sequential, Pack = 1) ]
|
||||
|
||||
@@ -10,6 +10,7 @@ using CSNetwork;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
using System;
|
||||
|
||||
namespace BrewMonster.Scripts.Task
|
||||
{
|
||||
@@ -437,6 +438,7 @@ namespace BrewMonster.Scripts.Task
|
||||
pTaskMan.TaskLoadedCount > 100)
|
||||
{
|
||||
Debug.Log($" [TaskInterface] Using TaskTest loaded data with {pTaskMan.TaskLoadedCount} tasks.");
|
||||
LoadingSceneController.Instance.ShowLoadingScene(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -524,24 +526,7 @@ namespace BrewMonster.Scripts.Task
|
||||
|
||||
public void CheckPQEnterWorldInit()
|
||||
{
|
||||
return;
|
||||
ActiveTaskList pList = GetActiveTaskList();
|
||||
List<ActiveTaskEntry> aEntries = new List<ActiveTaskEntry>(pList.m_TaskEntries);
|
||||
|
||||
for(var i = 0; i < pList.m_uTaskCount; i++)
|
||||
{
|
||||
var CurEntry = aEntries[i];
|
||||
|
||||
if (CurEntry.m_ulTemplAddr == 0)
|
||||
continue;
|
||||
|
||||
ATaskTempl pTempl = CurEntry.GetTempl();
|
||||
if (pTempl == null || !pTempl.m_FixedData.m_bPQTask)
|
||||
continue;
|
||||
|
||||
pTempl.IncValidCount();
|
||||
// _notify_svr(this, TASK_CLT_NOTIFY_PQ_CHECK_INIT, CurEntry.m_ID);
|
||||
}
|
||||
// TODO: implement PQ enter-world init if needed
|
||||
}
|
||||
|
||||
public static void WriteLog(int nPlayerId, int nTaskId, int nType, string szLog)
|
||||
@@ -552,7 +537,6 @@ namespace BrewMonster.Scripts.Task
|
||||
public bool IsDeliverLegal()
|
||||
{
|
||||
return !m_pHost.IsTrading() && m_pHost.GetBoothState() == 0 && !m_pHost.IsDead();
|
||||
return true;
|
||||
}
|
||||
|
||||
public int GetCommonItemCount(uint ulCommonItem)
|
||||
@@ -1294,12 +1278,6 @@ namespace BrewMonster.Scripts.Task
|
||||
|
||||
// return pTempl.CheckPrerequisite(this, static_cast<ActiveTaskList*>(GetActiveTaskList()), GetCurTime(), true, true, false);
|
||||
return pTempl.CheckPrerequisite(this, GetActiveTaskList(), GetCurTime(), true, true, false);
|
||||
|
||||
// if (!pTempl.CheckReachLevel(this)) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_BELOW_LEVEL;
|
||||
// uint keyCheck = pTempl.CheckGlobalKeyValue(this, false);
|
||||
// if (keyCheck != 0u) return keyCheck;
|
||||
|
||||
return 0u;
|
||||
}
|
||||
public bool CanDeliverCommonItem(uint ulTypes)
|
||||
{
|
||||
@@ -1371,8 +1349,7 @@ namespace BrewMonster.Scripts.Task
|
||||
ActiveTaskList pLst = GetActiveTaskList();
|
||||
uint ulCurTime = GetCurTime(); // 当前时间 // current time
|
||||
ATaskTempl pTempl = null;
|
||||
ActiveTaskEntry foundEntry = default;
|
||||
bool hasFoundEntry = false;
|
||||
int foundEntryIndex = -1; // Keep track of entry index like C++ code does
|
||||
|
||||
if (bActiveTask)
|
||||
{
|
||||
@@ -1383,8 +1360,7 @@ namespace BrewMonster.Scripts.Task
|
||||
if (CurEntry.m_ID != ulTaskId || CurEntry.m_ulTemplAddr == 0) continue;
|
||||
|
||||
pTempl = CurEntry.GetTempl();
|
||||
foundEntry = CurEntry;
|
||||
hasFoundEntry = true;
|
||||
foundEntryIndex = i; // Store index to access entry later
|
||||
|
||||
// 检查任务是否可以完成 // Check if task can be completed
|
||||
if (pTempl != null && pTempl.CanFinishTask(this, CurEntry, ulCurTime))
|
||||
@@ -1459,9 +1435,11 @@ namespace BrewMonster.Scripts.Task
|
||||
pInfo.m_MonsterWanted[ulMonsterCount].m_ulMonsterId = mw.m_ulMonsterTemplId;
|
||||
pInfo.m_MonsterWanted[ulMonsterCount].m_ulMonstersToKill = mw.m_ulMonsterNum;
|
||||
|
||||
if (bActiveTask && hasFoundEntry)
|
||||
// Access the entry directly from the list using stored index, like C++ code does
|
||||
if (bActiveTask && foundEntryIndex >= 0)
|
||||
{
|
||||
pInfo.m_MonsterWanted[ulMonsterCount].m_ulMonstersKilled = foundEntry.m_wMonsterNum[j];
|
||||
ActiveTaskEntry CurEntry = pLst.m_TaskEntries[foundEntryIndex];
|
||||
pInfo.m_MonsterWanted[ulMonsterCount].m_ulMonstersKilled = CurEntry.m_wMonsterNum[j];
|
||||
}
|
||||
|
||||
ulMonsterCount++;
|
||||
@@ -1488,9 +1466,11 @@ namespace BrewMonster.Scripts.Task
|
||||
{
|
||||
pInfo.m_PlayerWanted[ulPlayerCount].m_ulPlayersToKill = pw.m_ulPlayerNum;
|
||||
|
||||
if (bActiveTask && hasFoundEntry)
|
||||
// Access the entry directly from the list using stored index, like C++ code does
|
||||
if (bActiveTask && foundEntryIndex >= 0)
|
||||
{
|
||||
pInfo.m_PlayerWanted[ulPlayerCount].m_ulPlayersKilled = foundEntry.m_wMonsterNum[j];
|
||||
ActiveTaskEntry CurEntry = pLst.m_TaskEntries[foundEntryIndex];
|
||||
pInfo.m_PlayerWanted[ulPlayerCount].m_ulPlayersKilled = CurEntry.m_wMonsterNum[j];
|
||||
}
|
||||
|
||||
pInfo.m_PlayerWanted[ulPlayerCount].m_Requirements = pw.m_Requirements;
|
||||
@@ -1643,7 +1623,16 @@ namespace BrewMonster.Scripts.Task
|
||||
public StorageTaskList GetStorageTaskList()
|
||||
{
|
||||
StorageTaskList ret = new StorageTaskList();
|
||||
ret.ReadByte(m_pStorageTaskListBuf);
|
||||
// Initialize arrays before use
|
||||
ret.EnsureInitialized();
|
||||
|
||||
// Check if buffer is initialized before reading
|
||||
if (m_pStorageTaskListBuf != null)
|
||||
{
|
||||
ret.ReadByte(m_pStorageTaskListBuf);
|
||||
}
|
||||
// If buffer is null, return empty/default StorageTaskList
|
||||
// This can happen if Init() hasn't been called yet or failed
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1749,6 +1738,39 @@ namespace BrewMonster.Scripts.Task
|
||||
ret.ReadFromBytes(m_pFinishedListBuf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 记录任务完成/失败到已完成列表(用于前置任务/可重复接任务判断)
|
||||
// English: Record task finish/fail into FinishedTaskList (used by prerequisite checks)
|
||||
public void RecordFinishedTask(uint taskId, bool success)
|
||||
{
|
||||
if (m_pFinishedListBuf == null) return;
|
||||
FinishedTaskList lst = new FinishedTaskList();
|
||||
lst.ReadFromBytes(m_pFinishedListBuf);
|
||||
lst.AddOneTask(taskId, success);
|
||||
// Persist back into buffer
|
||||
if (lst.m_Buf != null && lst.m_Buf.Length == m_pFinishedListBuf.Length)
|
||||
{
|
||||
global::System.Buffer.BlockCopy(lst.m_Buf, 0, m_pFinishedListBuf, 0, m_pFinishedListBuf.Length);
|
||||
}
|
||||
}
|
||||
|
||||
// Persist an updated FinishedTaskList back into the underlying buffer.
|
||||
public void WriteFinishedTaskList(FinishedTaskList lst)
|
||||
{
|
||||
if (m_pFinishedListBuf == null) return;
|
||||
if (lst.m_Buf == null || lst.m_Buf.Length != m_pFinishedListBuf.Length) return;
|
||||
global::System.Buffer.BlockCopy(lst.m_Buf, 0, m_pFinishedListBuf, 0, m_pFinishedListBuf.Length);
|
||||
}
|
||||
|
||||
// Reset role-based finish counter for a task when period rolls over (used by CheckDeliverTime).
|
||||
public void ResetRoleFinishCount(uint taskId)
|
||||
{
|
||||
if (m_pFinishedListBuf == null) return;
|
||||
FinishedTaskList lst = new FinishedTaskList();
|
||||
lst.ReadFromBytes(m_pFinishedListBuf);
|
||||
lst.ResetFinishCount(taskId);
|
||||
WriteFinishedTaskList(lst);
|
||||
}
|
||||
|
||||
public int GetPlayerId()
|
||||
{
|
||||
|
||||
@@ -17,6 +17,9 @@ namespace BrewMonster.Scripts.Task
|
||||
|
||||
private const uint FINISH_DLG_SHOWN_TIME = 3000; // TODO: Confirm correct value
|
||||
private static uint s_finishDlgShownTime = 0;
|
||||
|
||||
// Throttle CHECK_FINISH notifications per task to avoid spamming the server every tick.
|
||||
private static readonly System.Collections.Generic.Dictionary<uint, uint> s_lastCheckFinishAt = new();
|
||||
|
||||
public static void OnTaskCheckStatus(TaskInterface pTask)
|
||||
{
|
||||
@@ -77,7 +80,16 @@ namespace BrewMonster.Scripts.Task
|
||||
// 绝对失效时间判断 // Absolute fail time check
|
||||
if (pTempl.m_FixedData.m_bAbsFail)
|
||||
{
|
||||
// TODO: Time zone bias and 'task_tm.before' not ported; skipping precise comparison
|
||||
// Mirror C++: if abs-fail time has passed, ask server to check/finish (will mark fail if needed).
|
||||
long sec = ulCurTime - (long)(TaskInterface.GetTimeZoneBias() * 60);
|
||||
if (sec < 0) sec = 0;
|
||||
DateTime cur = DateTimeOffset.FromUnixTimeSeconds(sec).UtcDateTime;
|
||||
if (pTempl.m_FixedData.m_tmAbsFailTime.before(cur))
|
||||
{
|
||||
pTempl.IncValidCount();
|
||||
_notify_svr(pTask, (int)ClientNotificationConstants.TASK_CLT_NOTIFY_CHECK_FINISH, CurEntry.m_ID);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// 进入或离开区域导致失败 // Entering or leaving region causes failure
|
||||
@@ -245,8 +257,8 @@ namespace BrewMonster.Scripts.Task
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: UpdateTaskToConfirm not ported; implement confirmation UI/state if needed
|
||||
UpdateTaskToConfirm(pTask, pTempl, bNeedServerCheck);
|
||||
// Minimal behavior: for wait-time tasks, auto request server check when time is up.
|
||||
UpdateTaskToConfirm(pTask, pTempl, CurEntry, bNeedServerCheck, ulCurTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -295,10 +307,27 @@ namespace BrewMonster.Scripts.Task
|
||||
ATaskTempl._notify_svr(pTask, uReason, uTaskID);
|
||||
}
|
||||
|
||||
// 更新“待确认任务” // Update task to confirm
|
||||
private static void UpdateTaskToConfirm(TaskInterface pTask, ATaskTempl pTempl, bool needServerCheck)
|
||||
// 更新“待确认任务” / 最小实现:当客户端确认已满足完成条件时,发一次 CHECK_FINISH 给服务器(节流)
|
||||
// English: Minimal port: when conditions are met client-side, send CHECK_FINISH once (throttled).
|
||||
private static void UpdateTaskToConfirm(TaskInterface pTask, ATaskTempl pTempl, ActiveTaskEntry entry, bool needServerCheck, uint ulCurTime)
|
||||
{
|
||||
// TODO: Implement confirmation queue/UI if required by design
|
||||
if (!needServerCheck || pTask == null || pTempl == null || entry == null) return;
|
||||
|
||||
// Only auto-check for wait-time tasks (the reported broken case).
|
||||
if ((TaskCompletionMethod)pTempl.m_FixedData.m_enumMethod != TaskCompletionMethod.enumTMWaitTime)
|
||||
return;
|
||||
|
||||
if (entry.IsFinished()) return;
|
||||
|
||||
uint id = entry.m_ID;
|
||||
if (id == 0) return;
|
||||
|
||||
if (s_lastCheckFinishAt.TryGetValue(id, out uint last) && ulCurTime <= last + 1)
|
||||
return;
|
||||
s_lastCheckFinishAt[id] = ulCurTime;
|
||||
|
||||
pTempl.IncValidCount();
|
||||
_notify_svr(pTask, (int)ClientNotificationConstants.TASK_CLT_NOTIFY_CHECK_FINISH, (ushort)id);
|
||||
}
|
||||
|
||||
// Handle server notification for task updates
|
||||
@@ -383,18 +412,15 @@ namespace BrewMonster.Scripts.Task
|
||||
// Handle storage data notification
|
||||
else if (pNotify.reason == TaskTemplConstants.TASK_SVR_NOTIFY_STORAGE)
|
||||
{
|
||||
// TODO: StorageTaskList struct not defined; need to define or use alternative
|
||||
// if (sz != Marshal.SizeOf<task_notify_base>() + Marshal.SizeOf<StorageTaskList>()) return;
|
||||
// TODO: OnStorageData method not found in ATaskTemplMan; implement if needed
|
||||
// ATaskTemplMan pMan = GetTaskTemplMan(pTask);
|
||||
// if (pMan != null)
|
||||
// {
|
||||
// byte[] storageData = new byte[Marshal.SizeOf<StorageTaskList>()];
|
||||
// Array.Copy(pBuf, Marshal.SizeOf<task_notify_base>(), storageData, 0, storageData.Length);
|
||||
// pMan.OnStorageData(pTask, storageData);
|
||||
// }
|
||||
// TODO: UpdateTaskUI static method not found; implement UI update if needed
|
||||
// TaskInterface.UpdateTaskUI(pNotify.task, pNotify.reason);
|
||||
if (sz != Marshal.SizeOf<task_notify_base>() + Marshal.SizeOf<StorageTaskList>()) return;
|
||||
ATaskTemplMan pMan = GetTaskTemplMan();
|
||||
if (pMan != null)
|
||||
{
|
||||
byte[] storageData = new byte[Marshal.SizeOf<StorageTaskList>()];
|
||||
Array.Copy(pBuf, Marshal.SizeOf<task_notify_base>(), storageData, 0, storageData.Length);
|
||||
pMan.OnStorageData(pTask, storageData);
|
||||
}
|
||||
pTask.UpdateTaskUI(pNotify.task, pNotify.reason);
|
||||
return;
|
||||
}
|
||||
// Handle special award notification
|
||||
|
||||
@@ -24,20 +24,21 @@ namespace BrewMonster.Scripts.Task
|
||||
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
|
||||
public struct TaskFinishCountList
|
||||
{
|
||||
public static ushort m_uCount;
|
||||
public ushort m_uCount;
|
||||
|
||||
public static TaskFinishCountEntry[] m_aList = new TaskFinishCountEntry[(uint)TaskInterfaceConstants.TASK_FINISH_COUNT_MAX_LEN];
|
||||
public TaskFinishCountEntry[] m_aList;
|
||||
|
||||
|
||||
public uint Search(uint ulID, ref uint ulTime)
|
||||
|
||||
{
|
||||
for (ushort i = 0; i < TaskFinishCountList.m_uCount; i++)
|
||||
if (m_aList == null) return 0u;
|
||||
for (ushort i = 0; i < m_uCount; i++)
|
||||
{
|
||||
if (TaskFinishCountList.m_aList[i].m_uTaskId == (ushort)ulID)
|
||||
if (m_aList[i].m_uTaskId == (ushort)ulID)
|
||||
{
|
||||
ulTime = TaskFinishCountList.m_aList[i].m_ulFinishTime;
|
||||
return TaskFinishCountList.m_aList[i].m_ulFinishCount;
|
||||
ulTime = m_aList[i].m_ulFinishTime;
|
||||
return m_aList[i].m_ulFinishCount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,12 +48,17 @@ namespace BrewMonster.Scripts.Task
|
||||
public void ResetAt(uint ulID)
|
||||
{
|
||||
for (ushort i = 0; i < m_uCount; i++)
|
||||
if (m_aList[i].m_uTaskId == (ushort)ulID)
|
||||
m_aList[i].m_ulFinishCount = 0;
|
||||
{
|
||||
if (m_aList != null && m_aList[i].m_uTaskId == (ushort)ulID)
|
||||
m_aList[i].m_ulFinishCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddOrUpdate(uint ulID, uint ulFinishTime)
|
||||
{
|
||||
if (m_aList == null || m_aList.Length != TaskInterfaceConstants.TASK_FINISH_COUNT_MAX_LEN)
|
||||
m_aList = new TaskFinishCountEntry[TaskInterfaceConstants.TASK_FINISH_COUNT_MAX_LEN];
|
||||
|
||||
for (ushort i = 0; i < m_uCount; i++)
|
||||
{
|
||||
if (m_aList[i].m_uTaskId == (ushort)ulID)
|
||||
@@ -74,7 +80,7 @@ namespace BrewMonster.Scripts.Task
|
||||
public void RemoveAll()
|
||||
{
|
||||
m_uCount = 0;
|
||||
m_aList = new TaskFinishCountEntry[(uint)TaskInterfaceConstants.TASK_FINISH_COUNT_MAX_LEN];
|
||||
m_aList = new TaskFinishCountEntry[TaskInterfaceConstants.TASK_FINISH_COUNT_MAX_LEN];
|
||||
}
|
||||
public bool IsValid() { return m_uCount <= TaskInterfaceConstants.TASK_FINISH_COUNT_MAX_LEN; }
|
||||
|
||||
@@ -104,6 +110,31 @@ namespace BrewMonster.Scripts.Task
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Persist list back into a buffer returned by TaskInterface.GetFinishedCntList().
|
||||
// Layout: ushort count + TASK_FINISH_COUNT_MAX_LEN * TaskFinishCountEntry bytes
|
||||
public void WriteToBuffer(byte[] data)
|
||||
{
|
||||
if (data == null) return;
|
||||
int entrySize = Marshal.SizeOf<TaskFinishCountEntry>();
|
||||
int expectedSize = 2 + entrySize * TaskInterfaceConstants.TASK_FINISH_COUNT_MAX_LEN;
|
||||
if (data.Length < expectedSize) return;
|
||||
|
||||
Array.Copy(BitConverter.GetBytes(m_uCount), 0, data, 0, 2);
|
||||
if (m_aList == null || m_aList.Length != TaskInterfaceConstants.TASK_FINISH_COUNT_MAX_LEN)
|
||||
{
|
||||
Array.Clear(data, 2, data.Length - 2);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < TaskInterfaceConstants.TASK_FINISH_COUNT_MAX_LEN; i++)
|
||||
{
|
||||
int offset = 2 + i * entrySize;
|
||||
// TaskFinishCountEntry is blittable with Pack=1, use helper
|
||||
byte[] entryBytes = GPDataTypeHelper.ToBytes(m_aList[i]);
|
||||
Array.Copy(entryBytes, 0, data, offset, Math.Min(entryBytes.Length, entrySize));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
@@ -148,7 +179,9 @@ namespace BrewMonster.Scripts.Task
|
||||
// unsigned char m_BufData[TASK_DATA_BUF_MAX_LEN-sizeof(TASK_ENTRY_FIXED_DATA)];
|
||||
public byte[] m_BufData = new byte[TaskInterfaceConstants.TASK_DATA_BUF_MAX_LEN - Marshal.SizeOf<TASK_ENTRY_FIXED_DATA>() ]; // Raw data buffer
|
||||
// nsigned short m_wMonsterNum[MAX_MONSTER_WANTED];
|
||||
public ushort[] m_wMonsterNum // Monster numbers
|
||||
// 注意:这个属性返回的是拷贝数组,不能用 m_wMonsterNum[i] = x 来写入(不会回写到底层缓冲)
|
||||
// English: This property returns a COPY. Do not mutate via m_wMonsterNum[i] = x (it won't persist).
|
||||
public ushort[] m_wMonsterNum // Monster numbers (copy)
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -170,6 +203,21 @@ namespace BrewMonster.Scripts.Task
|
||||
}
|
||||
}
|
||||
|
||||
// 读取/写入怪物计数(直接回写到底层缓冲) // English: Get/set monster count (writes through to backing buffer)
|
||||
public ushort GetMonsterNum(int index)
|
||||
{
|
||||
if (index < 0 || index >= TaskInterfaceConstants.MAX_MONSTER_WANTED) return 0;
|
||||
return BitConverter.ToUInt16(m_BufData, index * 2);
|
||||
}
|
||||
|
||||
public void SetMonsterNum(int index, ushort value)
|
||||
{
|
||||
if (index < 0 || index >= TaskInterfaceConstants.MAX_MONSTER_WANTED) return;
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
m_BufData[index * 2] = bytes[0];
|
||||
m_BufData[index * 2 + 1] = bytes[1];
|
||||
}
|
||||
|
||||
public int m_iUsefulData1
|
||||
{
|
||||
get => BitConverter.ToInt32(m_BufData, TaskInterfaceConstants.MAX_MONSTER_WANTED * 2);
|
||||
@@ -239,6 +287,7 @@ namespace BrewMonster.Scripts.Task
|
||||
public bool IsContributionFinish() => (m_uState & (byte)TaskState.TASK_STATE_CONTRIBUTION_FINISH) != 0;
|
||||
|
||||
public void SetFinished() { m_uState |= (char)TaskState.TASK_STATE_FINISHED; }
|
||||
public void SetSuccess() { m_uState |= (char)TaskState.TASK_STATE_SUCCESS; } // 设置成功标志 // English: Mark success flag
|
||||
// void ClearFinished() { m_uState &= ~TASK_STATE_FINISHED; }
|
||||
// void SetSuccess() { m_uState |= TASK_STATE_SUCCESS; }
|
||||
public void ClearSuccess() { m_uState &= (char)~TaskState.TASK_STATE_SUCCESS; }
|
||||
@@ -259,8 +308,15 @@ namespace BrewMonster.Scripts.Task
|
||||
var man = BrewMonster.Network.EC_Game.GetTaskTemplateMan();
|
||||
if (man != null)
|
||||
{
|
||||
var templ = man.GetTaskTemplByID(m_ID);
|
||||
if (templ != null) return templ;
|
||||
// NOTE: Some project configurations report an "ambiguous call" error for direct calls
|
||||
// into ATaskTemplMan methods (likely due to duplicate symbols/assemblies). Use reflection
|
||||
// here to keep compilation stable while still using the manager at runtime.
|
||||
var mi = man.GetType().GetMethod("GetTaskTemplByID", new[] { typeof(uint) });
|
||||
if (mi != null)
|
||||
{
|
||||
var templObj = mi.Invoke(man, new object[] { (uint)m_ID });
|
||||
if (templObj is ATaskTempl templ) return templ;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
@@ -424,106 +480,157 @@ namespace BrewMonster.Scripts.Task
|
||||
m_uUsedCount += pTempl.m_uDepth;
|
||||
}
|
||||
}
|
||||
void RealignTask(ActiveTaskEntry pEntry, byte uReserve)
|
||||
/// <summary>
|
||||
/// Shift-based realign that matches original C++ ActiveTaskList::RealignTask.
|
||||
/// It only adjusts indices in a controlled range instead of globally compacting the list.
|
||||
/// This is critical for keeping Parent/Child/Sibling indices stable during subtask progression.
|
||||
/// </summary>
|
||||
public void RealignTask(ActiveTaskEntry pEntry, byte uReserve)
|
||||
{
|
||||
// TODO: implement RealignTask logic
|
||||
// // unsigned char uCurIndex = static_cast<unsigned char>(pEntry - m_TaskEntries);
|
||||
// byte uCurIndex = (byte)Array.IndexOf(m_TaskEntries, pEntry);
|
||||
//
|
||||
// uint ulCount = (uint)m_uTaskCount - uCurIndex; // ʣ���������
|
||||
//
|
||||
// if (ulCount == 0) return; // ���һ������
|
||||
//
|
||||
// byte uEmptyCount = 0;
|
||||
// for (int uEmpty = uCurIndex; uEmpty < TaskInterfaceConstants.TASK_ACTIVE_LIST_MAX_LEN; uEmpty++)
|
||||
// {
|
||||
// if (m_TaskEntries[uEmpty].m_ID == 0)
|
||||
// uEmptyCount++;
|
||||
// else
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// if (uReserve == uEmptyCount) return;
|
||||
//
|
||||
// // ActiveTaskEntry* pSrc = pEntry + uEmptyCount;
|
||||
// int pSrcIndex = uCurIndex + uEmptyCount;
|
||||
// ActiveTaskEntry[] pSrc = new ActiveTaskEntry[ulCount];
|
||||
// Array.Copy(m_TaskEntries, pSrcIndex, pSrc, 0, ulCount);
|
||||
//
|
||||
// // ActiveTaskEntry* pInsert = pEntry + uReserve;
|
||||
// int pInsertIndex = uCurIndex + uReserve;
|
||||
// ActiveTaskEntry[] pInsert = new ActiveTaskEntry[ulCount];
|
||||
// Array.Copy(m_TaskEntries, pInsertIndex, pInsert, 0, ulCount);
|
||||
//
|
||||
// // move it
|
||||
// // memmove(pInsert, pSrc, sizeof(ActiveTaskEntry) * ulCount);
|
||||
// Array.Copy(pSrc, 0, m_TaskEntries, 0, ulCount);
|
||||
//
|
||||
// // clear reserve part
|
||||
// ActiveTaskEntry[] pClearStart, pClearEnd;
|
||||
// int pClearStartIndex = 0, pClearEndIndex = 0;
|
||||
//
|
||||
// // if (pInsert > pSrc) // C++ pointer compare
|
||||
// if (pInsertIndex > pSrcIndex) // C# index compare
|
||||
// {
|
||||
// pClearStart = pSrc;
|
||||
// pClearEnd = pInsert;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // pClearStart = pInsert + ulCount;
|
||||
// pClearStartIndex = pInsertIndex + (int)ulCount;
|
||||
// // pClearEnd = pSrc + ulCount;
|
||||
// pClearEndIndex = pSrcIndex + (int)ulCount;
|
||||
// }
|
||||
//
|
||||
// // while (pClearStart < pClearEnd)
|
||||
// while (pClearStartIndex < pClearEndIndex)
|
||||
// {
|
||||
// pClearStart.m_ulTemplAddr = 0;
|
||||
// pClearStart.m_ID = 0;
|
||||
// pClearStart++;
|
||||
// }
|
||||
//
|
||||
// // calc gap
|
||||
// unsigned char uGap = static_cast<unsigned char>(pInsert - pSrc);
|
||||
// unsigned long i = 0;
|
||||
//
|
||||
// for (; i < static_cast<unsigned long>(uCurIndex); i++)
|
||||
// {
|
||||
// // Parent, Prev��uCurIndex
|
||||
// ActiveTaskEntry& CurEntry = m_TaskEntries[i];
|
||||
//
|
||||
// if(!CurEntry.m_ID)
|
||||
// continue;
|
||||
//
|
||||
// if (CurEntry.m_ChildIndex != 0xff && CurEntry.m_ChildIndex >= uCurIndex)
|
||||
// CurEntry.m_ChildIndex += uGap;
|
||||
// if (CurEntry.m_NextSblIndex != 0xff && CurEntry.m_NextSblIndex >= uCurIndex)
|
||||
// CurEntry.m_NextSblIndex += uGap;
|
||||
// }
|
||||
//
|
||||
// for (i = 0; i < ulCount; i++)
|
||||
// {
|
||||
// ActiveTaskEntry& CurEntry = *(pInsert + i);
|
||||
// if(!CurEntry.m_ID)
|
||||
// continue;
|
||||
//
|
||||
// if (CurEntry.m_ParentIndex != 0xff && CurEntry.m_ParentIndex >= uCurIndex)
|
||||
// CurEntry.m_ParentIndex += uGap;
|
||||
// if (CurEntry.m_PrevSblIndex != 0xff && CurEntry.m_PrevSblIndex >= uCurIndex)
|
||||
// CurEntry.m_PrevSblIndex += uGap;
|
||||
// if (CurEntry.m_ChildIndex != 0xff)
|
||||
// CurEntry.m_ChildIndex += uGap;
|
||||
// if (CurEntry.m_NextSblIndex != 0xff)
|
||||
// CurEntry.m_NextSblIndex += uGap;
|
||||
// }
|
||||
if (pEntry == null) return;
|
||||
int uCurIndex = Array.IndexOf(m_TaskEntries, pEntry);
|
||||
if (uCurIndex < 0) return;
|
||||
RealignTaskAtIndex(uCurIndex, uReserve);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Index-based variant used by deliver/award flows where the "slot" matters (C++ passes an entry pointer).
|
||||
/// </summary>
|
||||
public void RealignTaskAtIndex(int uCurIndex, byte uReserve)
|
||||
{
|
||||
if (uCurIndex < 0 || uCurIndex >= TaskInterfaceConstants.TASK_ACTIVE_LIST_MAX_LEN) return;
|
||||
|
||||
int ulCount = m_uTaskCount - uCurIndex; // remaining entries from uCurIndex
|
||||
if (ulCount == 0) return;
|
||||
|
||||
// Count consecutive empty entries starting from uCurIndex
|
||||
int uEmptyCount = 0;
|
||||
for (int uEmpty = uCurIndex; uEmpty < TaskInterfaceConstants.TASK_ACTIVE_LIST_MAX_LEN; uEmpty++)
|
||||
{
|
||||
var e = m_TaskEntries[uEmpty];
|
||||
if (e == null || e.m_ID == 0) uEmptyCount++;
|
||||
else break;
|
||||
}
|
||||
|
||||
if (uReserve == uEmptyCount) return;
|
||||
|
||||
int srcIndex = uCurIndex + uEmptyCount;
|
||||
int insertIndex = uCurIndex + uReserve;
|
||||
int uGap = insertIndex - srcIndex;
|
||||
if (uGap == 0) return;
|
||||
|
||||
// Move the block [srcIndex, srcIndex + ulCount) -> [insertIndex, insertIndex + ulCount)
|
||||
if (uGap > 0)
|
||||
{
|
||||
for (int i = ulCount - 1; i >= 0; i--)
|
||||
m_TaskEntries[insertIndex + i] = m_TaskEntries[srcIndex + i];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < ulCount; i++)
|
||||
m_TaskEntries[insertIndex + i] = m_TaskEntries[srcIndex + i];
|
||||
}
|
||||
|
||||
// Clear vacated slots
|
||||
int clearStart, clearEnd;
|
||||
if (insertIndex > srcIndex)
|
||||
{
|
||||
clearStart = srcIndex;
|
||||
clearEnd = insertIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
clearStart = insertIndex + ulCount;
|
||||
clearEnd = srcIndex + ulCount;
|
||||
}
|
||||
for (int i = clearStart; i < clearEnd; i++)
|
||||
m_TaskEntries[i] = null;
|
||||
|
||||
// Adjust indices for entries before uCurIndex (child + next sibling that point into >= uCurIndex)
|
||||
for (int i = 0; i < uCurIndex; i++)
|
||||
{
|
||||
var cur = m_TaskEntries[i];
|
||||
if (cur == null || cur.m_ID == 0) continue;
|
||||
|
||||
if (cur.m_ChildIndex != 0xff && cur.m_ChildIndex >= uCurIndex)
|
||||
cur.m_ChildIndex = (char)(cur.m_ChildIndex + uGap);
|
||||
if (cur.m_NextSblIndex != 0xff && cur.m_NextSblIndex >= uCurIndex)
|
||||
cur.m_NextSblIndex = (char)(cur.m_NextSblIndex + uGap);
|
||||
}
|
||||
|
||||
// Adjust indices for moved entries (the inserted block)
|
||||
for (int i = 0; i < ulCount; i++)
|
||||
{
|
||||
var cur = m_TaskEntries[insertIndex + i];
|
||||
if (cur == null || cur.m_ID == 0) continue;
|
||||
|
||||
if (cur.m_ParentIndex != 0xff && cur.m_ParentIndex >= uCurIndex)
|
||||
cur.m_ParentIndex = (char)(cur.m_ParentIndex + uGap);
|
||||
if (cur.m_PrevSblIndex != 0xff && cur.m_PrevSblIndex >= uCurIndex)
|
||||
cur.m_PrevSblIndex = (char)(cur.m_PrevSblIndex + uGap);
|
||||
if (cur.m_ChildIndex != 0xff)
|
||||
cur.m_ChildIndex = (char)(cur.m_ChildIndex + uGap);
|
||||
if (cur.m_NextSblIndex != 0xff)
|
||||
cur.m_NextSblIndex = (char)(cur.m_NextSblIndex + uGap);
|
||||
}
|
||||
|
||||
RecountTaskCounters();
|
||||
}
|
||||
|
||||
// 重新统计顶部任务计数与使用量 // English: Recount top task counters and used count
|
||||
public void RecountTaskCounters()
|
||||
{
|
||||
m_uTopShowTaskCount = 0;
|
||||
m_uTopHideTaskCount = 0;
|
||||
m_uTitleTaskCount = 0;
|
||||
m_uUsedCount = 0;
|
||||
|
||||
for (int i = 0; i < m_uTaskCount; i++)
|
||||
{
|
||||
var e = m_TaskEntries[i];
|
||||
if (e == null || e.m_ID == 0) continue;
|
||||
var templ = e.GetTempl();
|
||||
if (templ == null) continue;
|
||||
if (templ.m_pParent != null) continue;
|
||||
|
||||
if (templ.m_FixedData.m_bHidden) m_uTopHideTaskCount++;
|
||||
else if (templ.m_FixedData.m_bDisplayInTitleTaskUI) m_uTitleTaskCount++;
|
||||
else m_uTopShowTaskCount++;
|
||||
|
||||
// used count is an 8-bit field in the original packed header; clamp to byte range
|
||||
int used = m_uUsedCount + templ.m_uDepth;
|
||||
m_uUsedCount = (byte)Math.Clamp(used, 0, byte.MaxValue);
|
||||
}
|
||||
}
|
||||
public void ClearTask(TaskInterface pTask, ActiveTaskEntry pEntry, bool bRemoveItem)
|
||||
{
|
||||
RecursiveClearTask(pTask, pEntry, bRemoveItem, true, true);
|
||||
RealignTask(pEntry, 0);
|
||||
}
|
||||
|
||||
// void ClearChildrenOf(TaskInterface* pTask, ActiveTaskEntry* pParent, bool bRemoveItem = true);
|
||||
// 清除指定父节点的所有子任务(不清除父节点自身) // English: Clear all children of a parent entry (but keep the parent entry)
|
||||
public void ClearChildrenOf(TaskInterface pTask, ActiveTaskEntry pParent, bool bRemoveItem = true)
|
||||
{
|
||||
if (pParent == null) return;
|
||||
|
||||
// Mirror C++: while parent has a first child, recursively clear that child subtree.
|
||||
while (pParent.m_ChildIndex != 0xff)
|
||||
{
|
||||
int childIndex = (byte)pParent.m_ChildIndex;
|
||||
if (childIndex < 0 || childIndex >= TaskInterfaceConstants.TASK_ACTIVE_LIST_MAX_LEN) break;
|
||||
|
||||
var child = m_TaskEntries[childIndex];
|
||||
if (child == null || child.m_ID == 0)
|
||||
{
|
||||
// Broken link: stop to avoid infinite loop
|
||||
pParent.m_ChildIndex = (char)0xff;
|
||||
break;
|
||||
}
|
||||
|
||||
RecursiveClearTask(pTask, child, bRemoveItem, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
void RecursiveClearTask(
|
||||
TaskInterface pTask,
|
||||
@@ -610,7 +717,6 @@ namespace BrewMonster.Scripts.Task
|
||||
|
||||
return null;
|
||||
}
|
||||
// void ClearChildrenOf(TaskInterface* pTask, ActiveTaskEntry* pParent, bool bRemoveItem = true);
|
||||
// ActiveTaskEntry* GetEntry(unsigned long ulId)
|
||||
// {
|
||||
// for (unsigned char i = 0; i < m_uTaskCount; i++)
|
||||
@@ -644,5 +750,29 @@ namespace BrewMonster.Scripts.Task
|
||||
{
|
||||
m_uMaxSimultaneousCount = true;
|
||||
}
|
||||
|
||||
// 从列表中移除指定条目(并重新对齐列表) // English: Remove an entry from the list (and realign)
|
||||
public void RemoveEntry(ActiveTaskEntry entry)
|
||||
{
|
||||
if (entry == null || entry.m_ID == 0) return;
|
||||
|
||||
// Best-effort unlink from sibling chain
|
||||
if (entry.m_ParentIndex != 0xff)
|
||||
{
|
||||
if (entry.m_PrevSblIndex != 0xff && m_TaskEntries[entry.m_PrevSblIndex] != null)
|
||||
m_TaskEntries[entry.m_PrevSblIndex].m_NextSblIndex = entry.m_NextSblIndex;
|
||||
else if (m_TaskEntries[entry.m_ParentIndex] != null)
|
||||
m_TaskEntries[entry.m_ParentIndex].m_ChildIndex = entry.m_NextSblIndex;
|
||||
|
||||
if (entry.m_NextSblIndex != 0xff && m_TaskEntries[entry.m_NextSblIndex] != null)
|
||||
m_TaskEntries[entry.m_NextSblIndex].m_PrevSblIndex = entry.m_PrevSblIndex;
|
||||
}
|
||||
|
||||
// Mark empty + decrement count, then realign from this slot.
|
||||
entry.m_ulTemplAddr = 0;
|
||||
entry.m_ID = 0;
|
||||
if (m_uTaskCount > 0) m_uTaskCount--;
|
||||
RealignTask(entry, 0);
|
||||
}
|
||||
};
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -100,8 +100,23 @@ namespace BrewMonster.Scripts.Task
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.TASK_STORAGE_COUNT)]
|
||||
public byte[] m_StoragesReceivePerDay;
|
||||
|
||||
// Initialize arrays if they are null
|
||||
// In C++, arrays are automatically allocated on the stack, but in C# they need explicit initialization
|
||||
public void EnsureInitialized()
|
||||
{
|
||||
if (m_Storages == null)
|
||||
m_Storages = new ushort[TaskTemplConstants.TASK_STORAGE_COUNT * TaskTemplConstants.TASK_STORAGE_LEN];
|
||||
if (m_StoragesTaskSetCount == null)
|
||||
m_StoragesTaskSetCount = new ushort[TaskTemplConstants.TASK_STORAGE_COUNT];
|
||||
if (m_StoragesRefreshTime == null)
|
||||
m_StoragesRefreshTime = new uint[TaskTemplConstants.TASK_STORAGE_COUNT];
|
||||
if (m_StoragesReceivePerDay == null)
|
||||
m_StoragesReceivePerDay = new byte[TaskTemplConstants.TASK_STORAGE_COUNT];
|
||||
}
|
||||
|
||||
public void RemoveAll()
|
||||
{
|
||||
EnsureInitialized();
|
||||
for (int i = 0; i < TaskTemplConstants.TASK_STORAGE_COUNT; i++)
|
||||
{
|
||||
for (int j = 0; j < TaskTemplConstants.TASK_STORAGE_LEN; j++)
|
||||
@@ -117,6 +132,11 @@ namespace BrewMonster.Scripts.Task
|
||||
|
||||
public void ReadByte(byte[] data)
|
||||
{
|
||||
if (data == null)
|
||||
return;
|
||||
|
||||
EnsureInitialized();
|
||||
|
||||
int offset = 0;
|
||||
for (int i=0; i < TaskTemplConstants.TASK_STORAGE_COUNT; i++)
|
||||
{
|
||||
@@ -227,37 +247,52 @@ namespace BrewMonster.Scripts.Task
|
||||
[FieldOffset(8)]
|
||||
public ulong m_ulRcvUpdateTime;
|
||||
|
||||
void AddRevNum() { m_ulReceiverNum++; }
|
||||
public void AddRevNum() { m_ulReceiverNum++; }
|
||||
|
||||
void CheckRcvUpdateTime(uint ulCurTime, int nFrequency)
|
||||
public void CheckRcvUpdateTime(uint ulCurTime, int nFrequency)
|
||||
{
|
||||
// TODO: implement time-based receiver number reset logic
|
||||
// if (nFrequency == TaskCompletionMethod.enumTAFNormal || m_ulRcvUpdateTime == 0)
|
||||
// return;
|
||||
//
|
||||
// tm tmCur = *localtime((time_t*)&ulCurTime);
|
||||
// tm tmRcv = *localtime((time_t*)&m_ulRcvUpdateTime);
|
||||
//
|
||||
// if (nFrequency == enumTAFEachDay)
|
||||
// {
|
||||
// if (tmCur.tm_year != tmRcv.tm_year || tmCur.tm_yday != tmRcv.tm_yday)
|
||||
// m_ulReceiverNum = 0;
|
||||
// }
|
||||
// else if (nFrequency == enumTAFEachWeek)
|
||||
// {
|
||||
// if (!_is_same_week(&tmCur, &tmRcv, ulCurTime, m_ulRcvUpdateTime))
|
||||
// m_ulReceiverNum = 0;
|
||||
// }
|
||||
// else if (nFrequency == enumTAFEachMonth)
|
||||
// {
|
||||
// if (tmCur.tm_year != tmRcv.tm_year || tmCur.tm_mon != tmRcv.tm_mon)
|
||||
// m_ulReceiverNum = 0;
|
||||
// }
|
||||
// else if (nFrequency == enumTAFEachYear)
|
||||
// {
|
||||
// if (tmCur.tm_year != tmRcv.tm_year)
|
||||
// m_ulReceiverNum = 0;
|
||||
// }
|
||||
// C++ semantics: based on localtime() period boundaries, reset receiver count when period changes.
|
||||
// Use the same "task local time" conversion as timetable (timezone bias path) so behavior is consistent.
|
||||
if (nFrequency == (int)TaskAwardFreq.enumTAFNormal || m_ulRcvUpdateTime == 0)
|
||||
return;
|
||||
|
||||
long curSec = ulCurTime - (long)(TaskInterface.GetTimeZoneBias() * 60);
|
||||
if (curSec < 0) curSec = 0;
|
||||
DateTime cur = DateTimeOffset.FromUnixTimeSeconds(curSec).UtcDateTime;
|
||||
|
||||
long rcvSec = (long)m_ulRcvUpdateTime - (long)(TaskInterface.GetTimeZoneBias() * 60);
|
||||
if (rcvSec < 0) rcvSec = 0;
|
||||
DateTime rcv = DateTimeOffset.FromUnixTimeSeconds(rcvSec).UtcDateTime;
|
||||
|
||||
bool reset = false;
|
||||
if (nFrequency == (int)TaskAwardFreq.enumTAFEachDay)
|
||||
{
|
||||
reset = cur.Year != rcv.Year || cur.Month != rcv.Month || cur.Day != rcv.Day;
|
||||
}
|
||||
else if (nFrequency == (int)TaskAwardFreq.enumTAFEachWeek)
|
||||
{
|
||||
int curDow = (int)cur.DayOfWeek; // Sunday=0
|
||||
int rcvDow = (int)rcv.DayOfWeek;
|
||||
int curDiff = (curDow == 0) ? 6 : (curDow - 1); // Monday-start week
|
||||
int rcvDiff = (rcvDow == 0) ? 6 : (rcvDow - 1);
|
||||
DateTime curWeekStart = cur.Date.AddDays(-curDiff);
|
||||
DateTime rcvWeekStart = rcv.Date.AddDays(-rcvDiff);
|
||||
reset = curWeekStart != rcvWeekStart;
|
||||
}
|
||||
else if (nFrequency == (int)TaskAwardFreq.enumTAFEachMonth)
|
||||
{
|
||||
reset = cur.Year != rcv.Year || cur.Month != rcv.Month;
|
||||
}
|
||||
else if (nFrequency == (int)TaskAwardFreq.enumTAFEachYear)
|
||||
{
|
||||
reset = cur.Year != rcv.Year;
|
||||
}
|
||||
|
||||
if (reset)
|
||||
{
|
||||
m_ulReceiverNum = 0;
|
||||
m_ulRcvUpdateTime = ulCurTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -436,8 +471,58 @@ namespace BrewMonster.Scripts.Task
|
||||
|
||||
public void AddOneTask(uint ulID, bool bSuccess)
|
||||
{
|
||||
// TODO: Implement logic to add one task (for future use)
|
||||
//throw new NotImplementedException();
|
||||
// 将任务写入已完成列表(按任务ID有序) // English: Insert/update into finished list (sorted by task id)
|
||||
if (m_Buf == null || m_Buf.Length != TaskInterfaceConstants.TASK_FINISHED_LIST_BUF_SIZE)
|
||||
{
|
||||
m_Buf = new byte[TaskInterfaceConstants.TASK_FINISHED_LIST_BUF_SIZE];
|
||||
}
|
||||
|
||||
var header = m_FnshHeader;
|
||||
ushort count = header.m_uTaskCount;
|
||||
if (count >= TaskInterfaceConstants.TASK_FINISHED_LIST_MAX_LEN) return;
|
||||
|
||||
int entrySize = Marshal.SizeOf<FnshedTaskEntry>(); // should be 4
|
||||
int pos = GetTaskPos(ulID);
|
||||
|
||||
byte mask = (byte)(bSuccess ? 0 : 1);
|
||||
|
||||
if (pos >= 0)
|
||||
{
|
||||
// Update existing entry
|
||||
int start = 4 + pos * entrySize;
|
||||
// m_uTaskId
|
||||
Array.Copy(BitConverter.GetBytes((ushort)ulID), 0, m_Buf, start, 2);
|
||||
// m_Buf (mask + reserved bits)
|
||||
m_Buf[start + 2] = (byte)((m_Buf[start + 2] & 0xFE) | (mask & 0x1));
|
||||
// m_FnshedCount: keep at least 1
|
||||
if (m_Buf[start + 3] == 0) m_Buf[start + 3] = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// Find insertion index to keep sorted order
|
||||
int insert = 0;
|
||||
for (; insert < count; insert++)
|
||||
{
|
||||
ushort existingId = BitConverter.ToUInt16(m_Buf, 4 + insert * entrySize);
|
||||
if (ulID < existingId) break;
|
||||
}
|
||||
|
||||
// Shift bytes to make room
|
||||
int srcStart = 4 + insert * entrySize;
|
||||
int bytesToMove = (count - insert) * entrySize;
|
||||
if (bytesToMove > 0)
|
||||
{
|
||||
Buffer.BlockCopy(m_Buf, srcStart, m_Buf, srcStart + entrySize, bytesToMove);
|
||||
}
|
||||
|
||||
// Write new entry
|
||||
int dst = 4 + insert * entrySize;
|
||||
Array.Copy(BitConverter.GetBytes((ushort)ulID), 0, m_Buf, dst, 2);
|
||||
m_Buf[dst + 2] = (byte)(mask & 0x1); // reserved bits 0
|
||||
m_Buf[dst + 3] = 1; // finish count
|
||||
|
||||
header.m_uTaskCount = (ushort)(count + 1);
|
||||
m_FnshHeader = header;
|
||||
}
|
||||
|
||||
public void RemoveTask(uint ulID)
|
||||
@@ -461,22 +546,34 @@ namespace BrewMonster.Scripts.Task
|
||||
|
||||
public byte SearchTaskFinishCount(ulong ulID)
|
||||
{
|
||||
// TODO: Implement logic to search task finish count
|
||||
//throw new NotImplementedException();
|
||||
|
||||
return 0;
|
||||
int pos = GetTaskPos((uint)ulID);
|
||||
if (pos < 0) return 0;
|
||||
int entrySize = Marshal.SizeOf<FnshedTaskEntry>();
|
||||
int start = 4 + pos * entrySize;
|
||||
return m_Buf[start + 3]; // m_FnshedCount
|
||||
}
|
||||
|
||||
public void ResetFinishCount(ulong ulID)
|
||||
{
|
||||
// TODO: Implement logic to reset finish count
|
||||
//throw new NotImplementedException();
|
||||
int pos = GetTaskPos((uint)ulID);
|
||||
if (pos < 0) return;
|
||||
int entrySize = Marshal.SizeOf<FnshedTaskEntry>();
|
||||
int start = 4 + pos * entrySize;
|
||||
m_Buf[start + 3] = 0;
|
||||
}
|
||||
|
||||
public void AddForFinishCount(ulong ulID, bool bSuccess)
|
||||
{
|
||||
// TODO: Implement logic to add for finish count
|
||||
//throw new NotImplementedException();
|
||||
// 只用于计数:如果不存在则插入;如果存在则递增 m_FnshedCount
|
||||
// English: Finish-count bookkeeping: insert if missing; otherwise increment m_FnshedCount.
|
||||
AddOneTask((uint)ulID, bSuccess);
|
||||
|
||||
int pos = GetTaskPos((uint)ulID);
|
||||
if (pos < 0) return;
|
||||
int entrySize = Marshal.SizeOf<FnshedTaskEntry>();
|
||||
int start = 4 + pos * entrySize;
|
||||
byte cur = m_Buf[start + 3];
|
||||
if (cur < byte.MaxValue) m_Buf[start + 3] = (byte)(cur + 1);
|
||||
}
|
||||
|
||||
public void RemoveAll()
|
||||
|
||||
@@ -873,6 +873,131 @@ namespace BrewMonster.Scripts.Task
|
||||
{
|
||||
return string.Format("{0}-{1}-{2} {3}:{4} (wday:{5})", year, month, day, hour, min, wday);
|
||||
}
|
||||
|
||||
// ===== C++ task_tm time comparison helpers =====
|
||||
// [中文] 对齐 C++ 的 task_tm::after/before 等比较逻辑(含“月/周/日”模式)
|
||||
// [English] Parity with C++ task_tm::after/before and per-month/week/day variants
|
||||
|
||||
// C++: bool after(const tm* _tm) const
|
||||
public bool after(DateTime t)
|
||||
{
|
||||
int ty = t.Year;
|
||||
int tm = t.Month;
|
||||
int td = t.Day;
|
||||
int th = t.Hour;
|
||||
int tmin = t.Minute;
|
||||
|
||||
if (year < ty) return false;
|
||||
if (year > ty) return true;
|
||||
|
||||
if (month < tm) return false;
|
||||
if (month > tm) return true;
|
||||
|
||||
if (day < td) return false;
|
||||
if (day > td) return true;
|
||||
|
||||
if (hour < th) return false;
|
||||
return hour > th || min > tmin;
|
||||
}
|
||||
|
||||
// C++: bool before(const tm* _tm) const
|
||||
public bool before(DateTime t)
|
||||
{
|
||||
int ty = t.Year;
|
||||
int tm = t.Month;
|
||||
int td = t.Day;
|
||||
int th = t.Hour;
|
||||
int tmin = t.Minute;
|
||||
|
||||
if (year > ty) return false;
|
||||
if (year < ty) return true;
|
||||
|
||||
if (month > tm) return false;
|
||||
if (month < tm) return true;
|
||||
|
||||
if (day > td) return false;
|
||||
if (day < td) return true;
|
||||
|
||||
if (hour > th) return false;
|
||||
return hour < th || min <= tmin;
|
||||
}
|
||||
|
||||
// C++: bool after_per_month(const tm* _tm, bool bLastDay) const
|
||||
public bool after_per_month(DateTime t, bool bLastDay)
|
||||
{
|
||||
int td = t.Day;
|
||||
int th = t.Hour;
|
||||
int tmin = t.Minute;
|
||||
|
||||
if (day < td) return false;
|
||||
if (!bLastDay && day > td) return true;
|
||||
|
||||
if (hour < th) return false;
|
||||
return hour > th || min > tmin;
|
||||
}
|
||||
|
||||
// C++: bool before_per_month(const tm* _tm, bool bLastDay) const
|
||||
public bool before_per_month(DateTime t, bool bLastDay)
|
||||
{
|
||||
int td = t.Day;
|
||||
int th = t.Hour;
|
||||
int tmin = t.Minute;
|
||||
|
||||
if (day < td) return true;
|
||||
if (!bLastDay && day > td) return false;
|
||||
|
||||
if (hour > th) return false;
|
||||
return hour < th || min <= tmin;
|
||||
}
|
||||
|
||||
// task_week_map (C++): { 7,1,2,3,4,5,6 } with tm_wday Sunday=0
|
||||
private static readonly int[] s_task_week_map = { 7, 1, 2, 3, 4, 5, 6 };
|
||||
|
||||
// C++: bool after_per_week(const tm* _tm) const
|
||||
public bool after_per_week(DateTime t)
|
||||
{
|
||||
int w = s_task_week_map[(int)t.DayOfWeek];
|
||||
|
||||
if (wday < w) return false;
|
||||
if (wday > w) return true;
|
||||
|
||||
int th = t.Hour;
|
||||
int tmin = t.Minute;
|
||||
if (hour < th) return false;
|
||||
return hour > th || min > tmin;
|
||||
}
|
||||
|
||||
// C++: bool before_per_week(const tm* _tm) const
|
||||
public bool before_per_week(DateTime t)
|
||||
{
|
||||
int w = s_task_week_map[(int)t.DayOfWeek];
|
||||
|
||||
if (wday > w) return false;
|
||||
if (wday < w) return true;
|
||||
|
||||
int th = t.Hour;
|
||||
int tmin = t.Minute;
|
||||
if (hour > th) return false;
|
||||
return hour < th || min <= tmin;
|
||||
}
|
||||
|
||||
// C++: bool after_per_day(const tm* _tm) const
|
||||
public bool after_per_day(DateTime t)
|
||||
{
|
||||
int th = t.Hour;
|
||||
int tmin = t.Minute;
|
||||
if (hour < th) return false;
|
||||
return hour > th || min > tmin;
|
||||
}
|
||||
|
||||
// C++: bool before_per_day(const tm* _tm) const
|
||||
public bool before_per_day(DateTime t)
|
||||
{
|
||||
int th = t.Hour;
|
||||
int tmin = t.Minute;
|
||||
if (hour > th) return false;
|
||||
return hour < th || min <= tmin;
|
||||
}
|
||||
}
|
||||
|
||||
// Define task_team_member_info struct required by TEAM_MEM_WANTED
|
||||
@@ -1444,6 +1569,35 @@ namespace BrewMonster.Scripts.Task
|
||||
}
|
||||
}
|
||||
public bool IsValid() { return m_uCount <= TaskInterfaceConstants.TASK_FINISH_TIME_MAX_LEN; }
|
||||
|
||||
// Persist this list back into the underlying buffer returned by TaskInterface.GetFinishedTimeList().
|
||||
// Buffer layout: ushort count + TASK_FINISH_TIME_MAX_LEN * (ushort taskId + uint timeMark)
|
||||
public void WriteToBuffer(byte[] data)
|
||||
{
|
||||
if (data == null) return;
|
||||
int entrySize = sizeof(ushort) + sizeof(uint);
|
||||
int expected = sizeof(ushort) + entrySize * TaskInterfaceConstants.TASK_FINISH_TIME_MAX_LEN;
|
||||
if (data.Length < expected) return;
|
||||
|
||||
int offset = 0;
|
||||
Array.Copy(BitConverter.GetBytes(m_uCount), 0, data, offset, sizeof(ushort));
|
||||
offset += sizeof(ushort);
|
||||
|
||||
if (m_aList == null || m_aList.Length != TaskInterfaceConstants.TASK_FINISH_TIME_MAX_LEN)
|
||||
{
|
||||
// Keep buffer consistent even if list isn't initialized.
|
||||
Array.Clear(data, offset, data.Length - offset);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < TaskInterfaceConstants.TASK_FINISH_TIME_MAX_LEN; i++)
|
||||
{
|
||||
Array.Copy(BitConverter.GetBytes(m_aList[i].m_uTaskId), 0, data, offset, sizeof(ushort));
|
||||
offset += sizeof(ushort);
|
||||
Array.Copy(BitConverter.GetBytes(m_aList[i].m_ulTimeMark), 0, data, offset, sizeof(uint));
|
||||
offset += sizeof(uint);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1486,8 +1640,10 @@ namespace BrewMonster.Scripts.Task
|
||||
/// 任务模板类 // Task Template Class
|
||||
/// include
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public partial class ATaskTempl
|
||||
{
|
||||
[SerializeField]
|
||||
public ATaskTemplFixedData m_FixedData;
|
||||
|
||||
public bool is_in_zone(ZONE_VERT _min, ZONE_VERT _max, float[] pos)
|
||||
@@ -1690,6 +1846,8 @@ namespace BrewMonster.Scripts.Task
|
||||
uint ulTopCount = 0;
|
||||
byte uBudget = 0;
|
||||
long lReputation = 0;
|
||||
// Suppress unused warnings until RecursiveCalcAward is fully ported.
|
||||
_ = ulCmnCount; _ = ulTskCount; _ = lReputation;
|
||||
|
||||
// 任务屏蔽检查 // Task forbid check
|
||||
if (pTask.CheckTaskForbid(m_FixedData.m_ID)) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_TASK_FORBID;
|
||||
@@ -4476,7 +4634,7 @@ namespace BrewMonster.Scripts.Task
|
||||
|
||||
return true;
|
||||
}
|
||||
public uint GetType() { return m_FixedData.m_ulType; }
|
||||
public new uint GetType() { return m_FixedData.m_ulType; }
|
||||
|
||||
void Init()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BrewMonster.Scripts.Task
|
||||
{
|
||||
[ CreateAssetMenu(fileName = "TaskTemplContainerSO", menuName = "BrewMonster/Task/TaskTemplContainerSO")]
|
||||
public class TaskTemplContainerSO : ScriptableObject
|
||||
{
|
||||
|
||||
public const ulong TASK_PACK_MAGIC = 0x93858361;
|
||||
public const ulong _task_templ_cur_version = 121;
|
||||
|
||||
[SerializeField] private bool _loadAllTasksOnValidate = false;
|
||||
[SerializeField] private List<ATaskTempl> _taskTemplates = new List<ATaskTempl>();
|
||||
|
||||
public List<ATaskTempl> TaskTemplates { get { return _taskTemplates; } }
|
||||
public int TaskLoadedCount;
|
||||
public bool LoadAllTasksOnValidate => _loadAllTasksOnValidate;
|
||||
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
TaskLoadedCount = _taskTemplates ==null ? 0 : _taskTemplates.Count;
|
||||
}
|
||||
|
||||
[ContextMenu(" Load All Tasks From Pack")]
|
||||
public void LoadAllTasksFromPack()
|
||||
{
|
||||
string task_data_path = Path.Combine(Application.streamingAssetsPath, "data/tasks.data");
|
||||
_taskTemplates = LoadTasksFromPack_Internal(task_data_path);
|
||||
|
||||
Debug.Log($"[TaskTemplContainerSO] Loaded {_taskTemplates.Count} task templates from pack.");
|
||||
}
|
||||
|
||||
private static List<ATaskTempl> LoadTasksFromPack_Internal(string szPackPath)
|
||||
{
|
||||
long readBytes = 0;
|
||||
var tasks = new List<ATaskTempl>();
|
||||
|
||||
using (var fs = new FileStream(
|
||||
szPackPath,
|
||||
FileMode.Open,
|
||||
FileAccess.Read,
|
||||
FileShare.Read))
|
||||
{
|
||||
TASK_PACK_HEADER tph =
|
||||
AAssit.ReadFromBinaryOf<TASK_PACK_HEADER>(fs, ref readBytes);
|
||||
|
||||
if (tph.magic != TASK_PACK_MAGIC ||
|
||||
tph.version != _task_templ_cur_version)
|
||||
throw new Exception("Invalid task pack header");
|
||||
|
||||
if (tph.item_count == 0)
|
||||
return tasks;
|
||||
|
||||
uint[] pOffs =
|
||||
AAssit.ReadArrayFromBinary<uint>(fs, (int)tph.item_count, ref readBytes);
|
||||
|
||||
const float TASK_LOAD_WEIGHT = 0.8f;
|
||||
for (int i = 0; i < tph.item_count; i++)
|
||||
{
|
||||
fs.Seek(pOffs[i], SeekOrigin.Begin);
|
||||
|
||||
ATaskTempl templ = new ATaskTempl();
|
||||
|
||||
if (!templ.LoadFromBinFile(fs))
|
||||
continue;
|
||||
|
||||
tasks.Add(templ);
|
||||
}
|
||||
}
|
||||
|
||||
return tasks;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: da89386b7a1d4c75b768f686888bac2a
|
||||
timeCreated: 1765890592
|
||||
@@ -56,7 +56,7 @@ namespace BrewMonster.Scripts.Task
|
||||
#if UNITY_EDITOR
|
||||
if (Input.GetKeyDown(KeyCode.Q))
|
||||
{
|
||||
var dlgTaskGO = CECUIManager.Instance.GetInGameUIMan().GetDialog("Win_Task");
|
||||
var dlgTaskGO = CECUIManager.Instance.GetInGameUIMan().GetDialog(CECUIHelper.DlgTaskName);
|
||||
var dlgTask = (dlgTaskGO) as DlgTask;
|
||||
if (dlgTask && !dlgTask.gameObject.activeInHierarchy)
|
||||
{
|
||||
@@ -129,8 +129,9 @@ namespace BrewMonster.Scripts.Task
|
||||
m_pTaskMan = new ATaskTemplMan();
|
||||
}
|
||||
|
||||
if (_cts == null) _cts = new CancellationTokenSource();
|
||||
string path = Path.Combine(Application.streamingAssetsPath, "data/tasks.data");
|
||||
WasLoadTaskData = await m_pTaskMan.LoadTasksFromPack(path, true,(x)=>{},_cts.Token);
|
||||
WasLoadTaskData = m_pTaskMan.LoadTasksFromPackNoAsyn(path, true);
|
||||
}
|
||||
|
||||
[ContextMenu("Test Size")]
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text.RegularExpressions;
|
||||
using BrewMonster.Managers;
|
||||
using BrewMonster.Scripts.Managers;
|
||||
using BrewMonster.Network;
|
||||
@@ -15,6 +16,7 @@ using PerfectWorld.Scripts.Task;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using TMPro;
|
||||
using Unity.VisualScripting;
|
||||
|
||||
namespace BrewMonster.Scripts.Task.UI
|
||||
{
|
||||
@@ -135,14 +137,25 @@ namespace BrewMonster.Scripts.Task.UI
|
||||
// [English] Task trace counter
|
||||
private CECCounter m_TaskTraceCounter = new (); // CECCounter -> object placeholder
|
||||
|
||||
// ===== Time-gated task UI refresh (search list) =====
|
||||
// Timetable/time-window tasks become available/unavailable as server time moves.
|
||||
// The original C++ client periodically re-evaluates prerequisites; in this port we refresh the search list
|
||||
// at a low frequency while the Search view is open so players can see time-gated tasks appear/disappear.
|
||||
private uint _lastSearchRefreshMinuteKey = uint.MaxValue;
|
||||
private uint _pendingReselectTaskId = 0;
|
||||
|
||||
// Active-task timer refresh (wait-time / time-limit / protect-time)
|
||||
private float _nextActiveTimerUiRefreshAt = 0f;
|
||||
|
||||
#region Unity METHODS
|
||||
|
||||
private void OnEnable()
|
||||
private new void OnEnable()
|
||||
{
|
||||
OnShowDialog();
|
||||
OnCommand_havequest();
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
private new void Awake()
|
||||
{
|
||||
EventBus.Subscribe<TaskItemClickEvent>(evt =>
|
||||
{
|
||||
@@ -357,6 +370,63 @@ namespace BrewMonster.Scripts.Task.UI
|
||||
//
|
||||
private bool Tick()
|
||||
{
|
||||
// Time-window task refresh: while in Search view, refresh the list when server time crosses a minute boundary.
|
||||
// This is throttled to avoid rebuilding large task lists every frame.
|
||||
if (m_iType == 1)
|
||||
{
|
||||
var host = GetHostPlayer();
|
||||
var task = host != null ? host.GetTaskInterface() : null;
|
||||
if (task != null)
|
||||
{
|
||||
uint now = task.GetCurTime();
|
||||
uint minuteKey = now / 60u;
|
||||
if (minuteKey != _lastSearchRefreshMinuteKey)
|
||||
{
|
||||
_lastSearchRefreshMinuteKey = minuteKey;
|
||||
|
||||
// Preserve current selection if any, so refreshing doesn't feel disruptive.
|
||||
var curItem = m_pTv_Quest != null ? m_pTv_Quest.GetSelectedItem() : null;
|
||||
_pendingReselectTaskId = (curItem != null) ? m_pTv_Quest.GetItemData(curItem) : 0u;
|
||||
|
||||
// Rebuild available task list according to current time-based prerequisites.
|
||||
SearchForTask(-1);
|
||||
|
||||
// Restore selection best-effort (TaskTreeView selection is driven by EventBus).
|
||||
if (_pendingReselectTaskId != 0u)
|
||||
{
|
||||
EventBus.Publish(new TaskItemClickEvent { Data = _pendingReselectTaskId });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Active view: refresh selected task detail periodically so countdown UI updates in real time.
|
||||
// (Wait-time tasks depend on m_ulTimePassed which changes with server time; without this, UI looks "stuck".)
|
||||
if (m_iType == 0 && Time.unscaledTime >= _nextActiveTimerUiRefreshAt)
|
||||
{
|
||||
_nextActiveTimerUiRefreshAt = Time.unscaledTime + 0.5f; // 2 Hz is plenty for countdown text
|
||||
|
||||
var pTree = m_pTv_Quest;
|
||||
var pItem = pTree != null ? pTree.GetSelectedItem() : null;
|
||||
if (pItem != null && pTree.transform != pItem.transform.parent)
|
||||
{
|
||||
uint selectedTaskId = pTree.GetItemData(pItem);
|
||||
if (selectedTaskId > 0)
|
||||
{
|
||||
var task = GetHostPlayer()?.GetTaskInterface();
|
||||
if (task != null)
|
||||
{
|
||||
Task_State_info tsi = default;
|
||||
task.GetTaskStateInfo(selectedTaskId, ref tsi, true);
|
||||
if (tsi.m_ulWaitTime > 0 || tsi.m_ulTimeLimit > 0 || tsi.m_ulProtectTime > 0)
|
||||
{
|
||||
UpdateTask((int)selectedTaskId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if( m_szName == "Win_Quest" && IsShow() )
|
||||
{
|
||||
var pTree = m_pTv_Quest;
|
||||
@@ -404,10 +474,12 @@ namespace BrewMonster.Scripts.Task.UI
|
||||
// void RefreshTaskTrace();
|
||||
public bool UpdateTask(int idTask = -1)
|
||||
{
|
||||
// if( m_szName != "Win_Quest" || m_iType != 0)
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
// Only rebuild the list if viewing "Have Quest" (m_iType == 0)
|
||||
// But always allow updating specific task details regardless of view type
|
||||
if (idTask < 0 && m_iType != 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// ATaskTemplMan *pMan = GetGame()->GetTaskTemplateMan();
|
||||
ATaskTemplMan pMan = EC_Game.GetTaskTemplateMan();
|
||||
@@ -440,6 +512,7 @@ namespace BrewMonster.Scripts.Task.UI
|
||||
ATaskTempl pTemp = pMan.GetTaskTemplByID((uint)idTask);
|
||||
if (pTemp != null)
|
||||
{
|
||||
// Only update description and name if task changed
|
||||
if( idTask != m_idLastTask )
|
||||
{
|
||||
_nameTaskText.SetText(EC_Utility.FormatForTextMeshPro(GetTaskNameWithColor(pTemp)));
|
||||
@@ -452,9 +525,11 @@ namespace BrewMonster.Scripts.Task.UI
|
||||
|
||||
m_pBtn_Abandon.interactable = pMan.CanGiveUpTask((uint)idTask);
|
||||
|
||||
// Get info
|
||||
// Always refresh task state info to get latest progress data
|
||||
// This ensures real-time updates when task progress changes
|
||||
// When viewing "Have Quest" (m_iType == 0), tasks are active, so pass true to read kill counts
|
||||
Task_State_info tsi = new Task_State_info();
|
||||
pTask.GetTaskStateInfo((uint)idTask, ref tsi, false);
|
||||
pTask.GetTaskStateInfo((uint)idTask, ref tsi, m_iType == 0);
|
||||
|
||||
// Clear first
|
||||
strNewTextItem = "";
|
||||
@@ -466,19 +541,19 @@ namespace BrewMonster.Scripts.Task.UI
|
||||
int nANPC = (int)pTemp.GetAwardNPC();
|
||||
UpdateAwardNPC(ref strNewTextItem, nANPC);
|
||||
|
||||
// Complete condition
|
||||
// Complete condition - always refresh to show updated progress
|
||||
UpdateCompleteCondition(ref strNewTextItem, ref strNewHintItem, tsi);
|
||||
|
||||
// Wanted Item
|
||||
// Wanted Item - always refresh to show updated item counts
|
||||
UpdateItemWanted(ref strNewTextItem, tsi, idTask);
|
||||
|
||||
// Treasure Map
|
||||
UpdateTreasureMap(ref strNewTextItem);
|
||||
|
||||
// Task Confirm
|
||||
// Task Confirm - always refresh to update button state
|
||||
UpdateTaskConfirm(idTask, pTemp.m_FixedData.m_enumFinishType == (uint)TaskFinishType.enumTFTConfirm);
|
||||
|
||||
// Award
|
||||
// Award - always refresh to show updated award preview
|
||||
Task_Award_Preview award = default;
|
||||
pTask.GetTaskAwardPreview((uint)idTask, ref award);
|
||||
|
||||
@@ -526,6 +601,8 @@ namespace BrewMonster.Scripts.Task.UI
|
||||
// Guard: only handle search list when current UI type is 1 (search)
|
||||
public bool SearchForTask(int idTask = -1)
|
||||
{
|
||||
// Only process search list when in search view (m_iType == 1)
|
||||
// This prevents clearing the wrong list when updating
|
||||
if (m_iType != 1)
|
||||
{
|
||||
return true;
|
||||
@@ -647,10 +724,49 @@ namespace BrewMonster.Scripts.Task.UI
|
||||
return true;
|
||||
}
|
||||
//
|
||||
// //�������������б��������ɽ�������ѽ����� zhangyitian
|
||||
// //�������������б��������ɽ�������ѽ�������ѽ����� zhangyitian
|
||||
// When task updates, the available task list also needs to be updated, otherwise the available task list won't update
|
||||
public bool UpdateQuestView()
|
||||
{
|
||||
return UpdateTask() && SearchForTask();
|
||||
// Refresh the list for the current view type
|
||||
// This ensures that when tasks are taken/completed/abandoned, the visible list is updated
|
||||
bool result = true;
|
||||
|
||||
if (m_iType == 0)
|
||||
{
|
||||
// Refresh "Have Quest" list (taken tasks)
|
||||
result = UpdateTask(-1);
|
||||
}
|
||||
else if (m_iType == 1)
|
||||
{
|
||||
// Refresh "Search Quest" list (available tasks)
|
||||
result = SearchForTask(-1);
|
||||
}
|
||||
|
||||
// Refresh the currently selected task details if one is selected
|
||||
// This ensures task progress updates are reflected in real-time
|
||||
var pTree = m_pTv_Quest;
|
||||
var pItem = pTree?.GetSelectedItem();
|
||||
|
||||
if (pItem != null && pTree.transform != pItem.transform.parent)
|
||||
{
|
||||
uint selectedTaskId = pTree.GetItemData(pItem);
|
||||
if (selectedTaskId > 0)
|
||||
{
|
||||
if (m_iType == 0)
|
||||
{
|
||||
// Refresh the selected task's details to show updated progress
|
||||
UpdateTask((int)selectedTaskId);
|
||||
}
|
||||
else if (m_iType == 1)
|
||||
{
|
||||
// For search view, refresh the selected task
|
||||
SearchForTask((int)selectedTaskId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// bool IsPQTaskOrSubTask(int idTask);
|
||||
@@ -724,7 +840,7 @@ namespace BrewMonster.Scripts.Task.UI
|
||||
return default(T);
|
||||
}
|
||||
|
||||
public CECHostPlayer GetHostPlayer()
|
||||
public new CECHostPlayer GetHostPlayer()
|
||||
{
|
||||
if(EC_Game.GetGameRun() == null)
|
||||
{
|
||||
@@ -782,6 +898,52 @@ namespace BrewMonster.Scripts.Task.UI
|
||||
child = child.m_pNextSibling;
|
||||
}
|
||||
}
|
||||
|
||||
// [中文] 仅插入“已接任务(Active)”中的子任务(基于 ActiveTaskList 的 Child/NextSbl 索引)
|
||||
// [English] Insert only active subtasks (based on ActiveTaskList Child/NextSbl indices)
|
||||
private void InsertActiveTaskChildren(TaskTreeViewItem pRoot, uint idTask)
|
||||
{
|
||||
var pTreeTask = m_pTv_Quest;
|
||||
var pMan = EC_Game.GetTaskTemplateMan();
|
||||
var pTask = GetHostPlayer()?.GetTaskInterface();
|
||||
if (pTreeTask == null || pMan == null || pTask == null) return;
|
||||
|
||||
ActiveTaskList pList = pTask.GetActiveTaskList();
|
||||
if (pList == null) return;
|
||||
|
||||
ActiveTaskEntry parentEntry = pList.GetEntry(idTask);
|
||||
if (parentEntry == null) return;
|
||||
|
||||
char idx = parentEntry.m_ChildIndex;
|
||||
while (idx != (char)0xff)
|
||||
{
|
||||
int childIndex = (byte)idx;
|
||||
if (childIndex < 0 || childIndex >= TaskInterfaceConstants.TASK_ACTIVE_LIST_MAX_LEN) break;
|
||||
|
||||
ActiveTaskEntry childEntry = pList.m_TaskEntries[childIndex];
|
||||
if (childEntry == null || childEntry.m_ID == 0) break;
|
||||
|
||||
uint childId = childEntry.m_ID;
|
||||
ATaskTempl childTempl = pMan.GetTaskTemplByID(childId);
|
||||
string text = childTempl != null ? GetTaskNameWithColor(childTempl) : $"Task {childId}";
|
||||
|
||||
var pItem = pTreeTask.InsertItem(text, pRoot, null);
|
||||
if (pItem != null)
|
||||
{
|
||||
pTreeTask.SetItemData(pItem, childId);
|
||||
if ((int)childId == m_idSelTask)
|
||||
{
|
||||
if (m_pBtn_Abandon != null) m_pBtn_Abandon.interactable = true;
|
||||
UpdateTask((int)childId);
|
||||
}
|
||||
|
||||
// recurse into active children
|
||||
InsertActiveTaskChildren(pItem, childId);
|
||||
}
|
||||
|
||||
idx = childEntry.m_NextSblIndex;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetTextItemText(string strNewTextItem, bool keepScrollPos, string strNewHintItem)
|
||||
{
|
||||
@@ -818,49 +980,52 @@ namespace BrewMonster.Scripts.Task.UI
|
||||
// update task content in dialog (converted from C++)
|
||||
private void UpdateBaseAward(Task_Award_Preview award)
|
||||
{
|
||||
// Ported from original C++: strTemp.Format(GetStringFromTable(3201), award.m_ulGold);
|
||||
var sb = new System.Text.StringBuilder();
|
||||
int colCount = 0;
|
||||
const int col = 3;
|
||||
int cellSpace = 50; // adjust as needed for spacing
|
||||
|
||||
void AppendWithSpacing(int stringId, string value)
|
||||
{
|
||||
var title = EC_Utility.FormatForTextMeshPro(GetStringFromTable(stringId));
|
||||
var text = $"{title} {value}";
|
||||
sb.Append( EC_Utility.FormatForTextMeshPro(text));
|
||||
sb.Append(' ', Mathf.Abs(cellSpace - text.Length));
|
||||
if ((++colCount) % col == 0) sb.Append("\n");
|
||||
}
|
||||
|
||||
|
||||
string strTemp;
|
||||
if (award.m_ulGold > 0)
|
||||
{
|
||||
AppendWithSpacing(3201 , award.m_ulGold.ToString());
|
||||
strTemp = Format(GetStringFromTable(3201), award.m_ulGold);
|
||||
sb.Append(strTemp);
|
||||
if ((++colCount) % col == 0) sb.Append("\n");
|
||||
}
|
||||
if (award.m_ulExp > 0)
|
||||
{
|
||||
AppendWithSpacing(3202 , award.m_ulExp.ToString());
|
||||
strTemp = Format(GetStringFromTable(3202), award.m_ulExp);
|
||||
sb.Append(strTemp);
|
||||
if ((++colCount) % col == 0) sb.Append("\n");
|
||||
}
|
||||
if (award.m_ulSP > 0)
|
||||
{
|
||||
AppendWithSpacing(3203 , award.m_ulSP.ToString());
|
||||
strTemp = Format(GetStringFromTable(3203), award.m_ulSP);
|
||||
sb.Append(strTemp);
|
||||
if ((++colCount) % col == 0) sb.Append("\n");
|
||||
}
|
||||
if (award.m_ulRealmExp > 0)
|
||||
{
|
||||
AppendWithSpacing( 3207, award.m_ulRealmExp.ToString());
|
||||
strTemp = Format(GetStringFromTable(3207), award.m_ulRealmExp);
|
||||
sb.Append(strTemp);
|
||||
if ((++colCount) % col == 0) sb.Append("\n");
|
||||
}
|
||||
if (award.m_iForceContrib > 0)
|
||||
{
|
||||
AppendWithSpacing(3205, award.m_iForceContrib.ToString());
|
||||
strTemp = Format(GetStringFromTable(3205), award.m_iForceContrib);
|
||||
sb.Append(strTemp);
|
||||
if ((++colCount) % col == 0) sb.Append("\n");
|
||||
}
|
||||
if (award.m_iForceRepu > 0)
|
||||
{
|
||||
AppendWithSpacing(3206, award.m_iForceRepu.ToString());
|
||||
strTemp = Format(GetStringFromTable(3206), award.m_iForceRepu);
|
||||
sb.Append(strTemp);
|
||||
if ((++colCount) % col == 0) sb.Append("\n");
|
||||
}
|
||||
|
||||
if (sb.Length > 0 && m_pTxt_BaseAward != null)
|
||||
{
|
||||
m_pTxt_BaseAward.text = sb.ToString();
|
||||
m_pTxt_BaseAward.text = EC_Utility.FormatForTextMeshPro(sb.ToString());
|
||||
m_pTxt_BaseAward.gameObject.SetActive(true);
|
||||
}
|
||||
}
|
||||
@@ -937,7 +1102,7 @@ namespace BrewMonster.Scripts.Task.UI
|
||||
sb.Append(szMsg);
|
||||
string strTemp;
|
||||
if (tsi.m_ulErrCode == TaskInterfaceConstants.TASK_AWARD_FAIL_LEVEL_CHECK)
|
||||
strTemp = string.Format(GetStringFromTable(7637), tsi.m_ulPremLevelMin);
|
||||
strTemp = Format(GetStringFromTable(7637), tsi.m_ulPremLevelMin);
|
||||
else
|
||||
strTemp = GetStringFromTable(807);
|
||||
sb.Append(strTemp);
|
||||
@@ -965,7 +1130,7 @@ namespace BrewMonster.Scripts.Task.UI
|
||||
if (tsi.m_ulNPCToProtect > 0)
|
||||
{
|
||||
// Fallback text with NPC id; detailed name lookup omitted
|
||||
sb.Append(string.Format(GetStringFromTable(257) ?? "Protect NPC: {0}", tsi.m_ulNPCToProtect));
|
||||
sb.Append(Format(GetStringFromTable(257) ?? "Protect NPC: %d", tsi.m_ulNPCToProtect));
|
||||
sb.Append(FormatTime((int)tsi.m_ulProtectTime, GetStringFromTable(258), 0));
|
||||
int remain = System.Math.Max(0, (int)tsi.m_ulProtectTime - (int)tsi.m_ulTimePassed);
|
||||
sb.Append(FormatTime(remain, GetStringFromTable(259), 0));
|
||||
@@ -1206,7 +1371,7 @@ namespace BrewMonster.Scripts.Task.UI
|
||||
// 金币需求
|
||||
if (tsi.m_ulGoldWanted != 0)
|
||||
{
|
||||
string strTemp = string.Format(GetStringFromTable(7636), tsi.m_ulGoldWanted);
|
||||
string strTemp = Format(GetStringFromTable(7636), tsi.m_ulGoldWanted);
|
||||
strText += strTemp;
|
||||
}
|
||||
|
||||
@@ -1218,10 +1383,10 @@ namespace BrewMonster.Scripts.Task.UI
|
||||
string strColor = (iLevel < (int)tsi.m_ulReachReincarnation) ? "^ff0000" : "^00ff00";
|
||||
if (iLevel < (int)tsi.m_ulReachReincarnation)
|
||||
{
|
||||
strHint += string.Format(GetStringFromTable(11144), iLevel);
|
||||
strHint += Format(GetStringFromTable(11144), iLevel);
|
||||
}
|
||||
strText += strColor;
|
||||
strText += string.Format(GetStringFromTable(11141), tsi.m_ulReachReincarnation);
|
||||
strText += Format(GetStringFromTable(11141), tsi.m_ulReachReincarnation);
|
||||
}
|
||||
|
||||
// Level requirement
|
||||
@@ -1232,10 +1397,10 @@ namespace BrewMonster.Scripts.Task.UI
|
||||
string strColor = (iLevel < (int)tsi.m_ulReachLevel) ? "^ff0000" : "^00ff00";
|
||||
if (iLevel < (int)tsi.m_ulReachLevel)
|
||||
{
|
||||
strHint += string.Format(GetStringFromTable(11143), iLevel);
|
||||
strHint += Format(GetStringFromTable(11143), iLevel);
|
||||
}
|
||||
strText += strColor;
|
||||
strText += string.Format(GetStringFromTable(11140), tsi.m_ulReachLevel);
|
||||
strText += Format(GetStringFromTable(11140), tsi.m_ulReachLevel);
|
||||
}
|
||||
|
||||
// Realm requirement
|
||||
@@ -1246,10 +1411,10 @@ namespace BrewMonster.Scripts.Task.UI
|
||||
string strColor = (iLevel < (int)tsi.m_ulReachRealm) ? "^ff0000" : "^00ff00";
|
||||
if (iLevel < (int)tsi.m_ulReachRealm)
|
||||
{
|
||||
strHint += string.Format(GetStringFromTable(11145), iLevel);
|
||||
strHint += Format(GetStringFromTable(11145), iLevel);
|
||||
}
|
||||
strText += strColor;
|
||||
strText += string.Format(GetStringFromTable(11142), (int)tsi.m_ulReachRealm);
|
||||
strText += Format(GetStringFromTable(11142), (int)tsi.m_ulReachRealm);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1299,7 +1464,7 @@ namespace BrewMonster.Scripts.Task.UI
|
||||
|
||||
// Compose line: name and progress (gained/toGet)
|
||||
// 组合文本:名称与进度(已获得/所需)
|
||||
string strTemp = string.Format(GetStringFromTable(7625), itemName,
|
||||
string strTemp = Format(GetStringFromTable(7625), itemName,
|
||||
tsi.m_ItemsWanted[i].m_ulItemsGained,
|
||||
tsi.m_ItemsWanted[i].m_ulItemsToGet);
|
||||
|
||||
@@ -1423,7 +1588,11 @@ namespace BrewMonster.Scripts.Task.UI
|
||||
pItem.SetItemTextColor(GetTaskColor((int)ENUM_TASK_TYPE.enumTTLevel2));
|
||||
// pTreeTask.SetItemHint(pItem, pTemp->GetSignature()); // TODO
|
||||
pTreeTask.SetItemData(pItem, (uint)id);
|
||||
InsertTaskChildren(pItem, (uint)id, true, pTemp.IsKeyTask());
|
||||
// HaveQuest view: children should reflect ActiveTaskList, not template tree (otherwise they never disappear on completion)
|
||||
if (m_iType == 0)
|
||||
InsertActiveTaskChildren(pItem, (uint)id);
|
||||
else
|
||||
InsertTaskChildren(pItem, (uint)id, true, pTemp.IsKeyTask());
|
||||
|
||||
if( (int)id == m_idSelTask )
|
||||
{
|
||||
@@ -1464,29 +1633,206 @@ namespace BrewMonster.Scripts.Task.UI
|
||||
|
||||
string Format( string formatStr, params object[] args )
|
||||
{
|
||||
var newStr = "";
|
||||
int argIndex = 0;
|
||||
// Ported from original C++ ACString::Format() which uses vsprintf/vswprintf
|
||||
// Original implementation: AString& AString::Format(const char* szFormat, ...) { vsprintf(m_pStr, szFormat, argList); }
|
||||
// This converts printf-style format specifiers to C# format specifiers
|
||||
if (string.IsNullOrEmpty(formatStr))
|
||||
return formatStr;
|
||||
|
||||
// Process format string character by character to convert %d, %s, etc. to {0}, {1}, etc.
|
||||
// This matches the original vsprintf behavior exactly
|
||||
var sb = new System.Text.StringBuilder();
|
||||
int paramIndex = 0;
|
||||
|
||||
for (int i = 0; i < formatStr.Length; i++)
|
||||
{
|
||||
if (formatStr[i] == '%' && i + 1 < formatStr.Length)
|
||||
{
|
||||
char formatSpec = formatStr[i + 1];
|
||||
i++; // Skip the format specifier character
|
||||
|
||||
if (argIndex < args.Length)
|
||||
// Check for %% (literal %)
|
||||
if (formatStr[i + 1] == '%')
|
||||
{
|
||||
newStr += args[argIndex].ToString();
|
||||
argIndex++;
|
||||
sb.Append('%');
|
||||
i++; // Skip the second %
|
||||
continue;
|
||||
}
|
||||
|
||||
// Parse format specifier: %[flags][width][.precision][length]type
|
||||
int startPos = i;
|
||||
i++; // Skip the %
|
||||
|
||||
// Track flags
|
||||
bool hasMinus = false;
|
||||
bool hasPlus = false;
|
||||
bool hasZero = false;
|
||||
|
||||
// Parse flags: +, -, 0, space
|
||||
while (i < formatStr.Length && (formatStr[i] == '+' || formatStr[i] == '-' || formatStr[i] == '0' || formatStr[i] == ' '))
|
||||
{
|
||||
if (formatStr[i] == '-') hasMinus = true;
|
||||
if (formatStr[i] == '+') hasPlus = true;
|
||||
if (formatStr[i] == '0') hasZero = true;
|
||||
i++;
|
||||
}
|
||||
|
||||
// Parse width: digits
|
||||
int width = 0;
|
||||
int widthStart = i;
|
||||
while (i < formatStr.Length && char.IsDigit(formatStr[i]))
|
||||
{
|
||||
i++;
|
||||
}
|
||||
if (i > widthStart)
|
||||
{
|
||||
int.TryParse(formatStr.Substring(widthStart, i - widthStart), out width);
|
||||
}
|
||||
|
||||
// Skip precision: .digits
|
||||
if (i < formatStr.Length && formatStr[i] == '.')
|
||||
{
|
||||
i++;
|
||||
while (i < formatStr.Length && char.IsDigit(formatStr[i]))
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// Skip length modifier: h, l, L, etc.
|
||||
while (i < formatStr.Length && (formatStr[i] == 'h' || formatStr[i] == 'l' || formatStr[i] == 'L'))
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
// Get type specifier
|
||||
if (i < formatStr.Length)
|
||||
{
|
||||
char typeChar = formatStr[i];
|
||||
// Common types: d, i, u, o, x, X, f, e, E, g, G, c, s, p, n
|
||||
if ("diouxXeEfFgGaAcspn".IndexOf(typeChar) >= 0)
|
||||
{
|
||||
// Extract the full format specifier for special handling
|
||||
string fullSpec = formatStr.Substring(startPos, i - startPos + 1);
|
||||
|
||||
// Check for special formats
|
||||
string csharpFormatSpec = "";
|
||||
|
||||
// Handle %-10d, %-5d, etc. (left-aligned with width) - check this FIRST
|
||||
// Also handle %-d (left-aligned without explicit width, but width might be 0)
|
||||
if (hasMinus && (typeChar == 'd' || typeChar == 'i' || typeChar == 'u' || typeChar == 's' || typeChar == 'c'))
|
||||
{
|
||||
if (width > 0)
|
||||
{
|
||||
// C# left alignment with width: {0,-10} (comma for alignment, negative for left-align)
|
||||
csharpFormatSpec = $",-{width}";
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just left alignment flag, no width specified - use default
|
||||
csharpFormatSpec = "";
|
||||
}
|
||||
}
|
||||
// Handle %02d, %03d, etc. (zero-padded integers) - check before regular width
|
||||
else if (hasZero && width > 0 && (typeChar == 'd' || typeChar == 'i' || typeChar == 'u'))
|
||||
{
|
||||
csharpFormatSpec = $":D{width}";
|
||||
}
|
||||
// Handle %10d, %5d, etc. (right-aligned with width, no zero-padding)
|
||||
else if (width > 0 && (typeChar == 'd' || typeChar == 'i' || typeChar == 'u' || typeChar == 's' || typeChar == 'c'))
|
||||
{
|
||||
// C# right alignment: {0,10} (comma for alignment)
|
||||
csharpFormatSpec = $",{width}";
|
||||
}
|
||||
// Handle %+d (signed format)
|
||||
else if (hasPlus && (typeChar == 'd' || typeChar == 'i'))
|
||||
{
|
||||
csharpFormatSpec = ":+0;-0";
|
||||
}
|
||||
// Handle %.2f, %.3f, etc. (float precision)
|
||||
else if (fullSpec.Contains(".") && (typeChar == 'f' || typeChar == 'F' || typeChar == 'e' || typeChar == 'E' || typeChar == 'g' || typeChar == 'G'))
|
||||
{
|
||||
int dotPos = fullSpec.IndexOf('.');
|
||||
if (dotPos >= 0 && dotPos + 1 < fullSpec.Length)
|
||||
{
|
||||
int precStart = dotPos + 1;
|
||||
int precEnd = precStart;
|
||||
while (precEnd < fullSpec.Length - 1 && char.IsDigit(fullSpec[precEnd]))
|
||||
{
|
||||
precEnd++;
|
||||
}
|
||||
if (precEnd > precStart && int.TryParse(fullSpec.Substring(precStart, precEnd - precStart), out int precNum))
|
||||
{
|
||||
if (typeChar == 'f' || typeChar == 'F')
|
||||
{
|
||||
csharpFormatSpec = $":F{precNum}";
|
||||
}
|
||||
else if (typeChar == 'e' || typeChar == 'E')
|
||||
{
|
||||
csharpFormatSpec = $":E{precNum}";
|
||||
}
|
||||
else if (typeChar == 'g' || typeChar == 'G')
|
||||
{
|
||||
csharpFormatSpec = $":G{precNum}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Build replacement - always replace recognized format specifiers
|
||||
// C# format: {index,alignment} for width, {index:format} for format specifiers
|
||||
if (csharpFormatSpec.Length > 0)
|
||||
{
|
||||
// If format spec starts with comma (alignment) or colon (format), use it directly
|
||||
// Otherwise, assume it's a format specifier and add colon
|
||||
if (csharpFormatSpec.StartsWith(",") || csharpFormatSpec.StartsWith(":"))
|
||||
{
|
||||
sb.Append($"{{{paramIndex}{csharpFormatSpec}}}");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append($"{{{paramIndex}:{csharpFormatSpec}}}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append($"{{{paramIndex}}}");
|
||||
}
|
||||
|
||||
paramIndex++;
|
||||
// Note: i currently points to the type character (e.g., 'd' in "%-10d")
|
||||
// The for loop will increment i, so we've consumed the entire format specifier
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not a recognized format specifier, keep as-is
|
||||
sb.Append(formatStr[startPos]);
|
||||
i = startPos; // Reset to process next character
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Incomplete format specifier, keep the %
|
||||
sb.Append('%');
|
||||
i = startPos; // Reset to process next character
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
newStr += formatStr[i];
|
||||
sb.Append(formatStr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return newStr;
|
||||
// Use C#'s string.Format (equivalent to original vsprintf)
|
||||
// Handle case where we might have more format specifiers than arguments
|
||||
try
|
||||
{
|
||||
return string.Format(sb.ToString(), args);
|
||||
}
|
||||
catch (System.FormatException)
|
||||
{
|
||||
// If format fails (e.g., not enough arguments), return the original format string
|
||||
// This can happen if GetStringFromTable returns an unexpected format
|
||||
BMLogger.LogWarning($"Format failed for string: {formatStr}, expected {paramIndex} args, got {args.Length}");
|
||||
return formatStr;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -5,6 +5,8 @@ namespace BrewMonster.Scripts.UI
|
||||
{
|
||||
public class CECUIHelper
|
||||
{
|
||||
public static string DlgTaskName = "Win_Quest";
|
||||
|
||||
public static A3DVECTOR3 GetTaskObjectCoordinates(int id, ref bool in_table)
|
||||
{
|
||||
in_table = false;
|
||||
|
||||
@@ -8,6 +8,7 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using BrewMonster.Scripts.Task;
|
||||
using BrewMonster.Scripts.Task.UI;
|
||||
using BrewMonster.Scripts.UI;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BrewMonster.UI
|
||||
@@ -117,7 +118,7 @@ namespace BrewMonster.UI
|
||||
{
|
||||
base.Init();
|
||||
|
||||
m_pDlgTask = GetDialog("Win_Task").GetComponent<DlgTask>();
|
||||
m_pDlgTask = GetDialog(CECUIHelper.DlgTaskName).GetComponent<DlgTask>();
|
||||
m_pDlgTask.Show(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
using BrewMonster.Network;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace BrewMonster.UI
|
||||
{
|
||||
public class JumpBtn : MonoBehaviour
|
||||
{
|
||||
Button jumpBtn;
|
||||
|
||||
// Start is called once before the first execution of Update after the MonoBehaviour is created
|
||||
void Start()
|
||||
{
|
||||
if(jumpBtn == null)
|
||||
{
|
||||
jumpBtn = GetComponent<Button>();
|
||||
jumpBtn.onClick.AddListener(OnClickBtnJump);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnClickBtnJump()
|
||||
{
|
||||
if(EC_Game.GetGameRun()?.GetHostPlayer() != null)
|
||||
{
|
||||
EC_Game.GetGameRun()?.GetHostPlayer().OnClickBtnJump();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a6149141837cadc4baae427c4864833e
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8e7328e7267d4c744bffdd93781ac215
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 57 KiB |
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -0,0 +1,21 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f6437c7f6dfb42144a799984e8b18fc6
|
||||
IHVImageFormatImporter:
|
||||
externalObjects: {}
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 0
|
||||
wrapV: 0
|
||||
wrapW: 0
|
||||
isReadable: 1
|
||||
sRGBTexture: 1
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
ignoreMipmapLimit: 0
|
||||
mipmapLimitGroupName:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,59 @@
|
||||
32
|
||||
32
|
||||
7
|
||||
8
|
||||
unknown.dds
|
||||
一键拾取.dds
|
||||
交易命令.dds
|
||||
亲亲密密的动作.dds
|
||||
亲吻.dds
|
||||
伸懒腰.dds
|
||||
倒地.dds
|
||||
冲锋.dds
|
||||
加速飞行.dds
|
||||
协助攻击.dds
|
||||
坐下.dds
|
||||
坐下站起.dds
|
||||
大笑.dds
|
||||
定点传送.dds
|
||||
害羞.dds
|
||||
寻找目标.dds
|
||||
寻找队伍.dds
|
||||
张望.dds
|
||||
思考.dds
|
||||
战斗.dds
|
||||
打坐.dds
|
||||
抱拳.dds
|
||||
招手.dds
|
||||
拾取.dds
|
||||
挑衅.dds
|
||||
挖掘.dds
|
||||
摆摊买.dds
|
||||
摆摊卖.dds
|
||||
摇头.dds
|
||||
摔倒.dds
|
||||
攻击1.dds
|
||||
攻击2.dds
|
||||
攻击3.dds
|
||||
攻击4.dds
|
||||
晕倒.dds
|
||||
普通攻击.dds
|
||||
沮丧.dds
|
||||
滚开.dds
|
||||
点头.dds
|
||||
生气.dds
|
||||
相依相偎的动作.dds
|
||||
耸肩膀.dds
|
||||
胜利.dds
|
||||
脱离队伍.dds
|
||||
舞蹈1.dds
|
||||
舞蹈2.dds
|
||||
走跑转换.dds
|
||||
跳跃.dds
|
||||
跳跃的动作1.dds
|
||||
跳跃的动作2.dds
|
||||
踢出队伍.dds
|
||||
邀请加入.dds
|
||||
防御.dds
|
||||
飞吻.dds
|
||||
飞行.dds
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4a842797640137d4a92a75f0c0007a46
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:7828b12fbfdfde737297134cda6d57b867012039352583752e99f3768aa64e48
|
||||
size 200521545
|
||||
oid sha256:e4b6387464cc1416f14012251c47b22f28e699e88848f49f62116f827959e1b8
|
||||
size 200544838
|
||||
|
||||
+116
-22
@@ -63,36 +63,114 @@ public class CECUIManager : MonoSingleton<CECUIManager>
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lấy hoặc spawn UI mới nếu chưa có
|
||||
/// Show UI by name of component ("DlgTask", "EC_InventoryUI")
|
||||
/// </summary>
|
||||
public T ShowUI<T>() where T : Component
|
||||
/// <param name="componentName">name of component ("DlgTask", "EC_InventoryUI")</param>
|
||||
public void ShowUI(string componentName)
|
||||
{
|
||||
var type = typeof(T);
|
||||
if (string.IsNullOrEmpty(componentName) || canvasDlg == null)
|
||||
{
|
||||
if (canvasDlg == null) Debug.LogError("canvasDlg chưa được gán");
|
||||
return;
|
||||
}
|
||||
|
||||
// Nếu đã spawn rồi thì bật lại
|
||||
if (_spawnedUIs.TryGetValue(type, out var uiGo))
|
||||
var type = FindTypeByName(componentName);
|
||||
|
||||
if (TryShowCachedUI(type)) return;
|
||||
if (FindUIByName(componentName, type)) return;
|
||||
if (FindUIByType(type)) return;
|
||||
|
||||
Debug.LogWarning($"Không tìm thấy UI {componentName} đã spawn trong canvasDlg. Type found: {(type != null ? type.FullName : "null")}");
|
||||
}
|
||||
|
||||
private System.Type FindTypeByName(string componentName)
|
||||
{
|
||||
string[] namespacePrefixes = {
|
||||
"", // No namespace
|
||||
"BrewMonster.Scripts.Task.UI.",
|
||||
"BrewMonster.UI.",
|
||||
"BrewMonster.Scripts.UI.",
|
||||
"BrewMonster."
|
||||
};
|
||||
|
||||
// Try with common namespace prefixes
|
||||
foreach (var prefix in namespacePrefixes)
|
||||
{
|
||||
string fullTypeName = string.IsNullOrEmpty(prefix) ? componentName : prefix + componentName;
|
||||
var type = System.Type.GetType(fullTypeName);
|
||||
if (type != null) return type;
|
||||
}
|
||||
|
||||
// Search in all assemblies
|
||||
foreach (var assembly in System.AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
var type = assembly.GetType(componentName);
|
||||
if (type != null) return type;
|
||||
|
||||
foreach (var prefix in namespacePrefixes)
|
||||
{
|
||||
if (string.IsNullOrEmpty(prefix)) continue;
|
||||
type = assembly.GetType(prefix + componentName);
|
||||
if (type != null) return type;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool TryShowCachedUI(System.Type type)
|
||||
{
|
||||
if (type != null && _spawnedUIs.TryGetValue(type, out var uiGo))
|
||||
{
|
||||
uiGo.SetActive(true);
|
||||
return uiGo.GetComponent<T>();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Tìm prefab phù hợp
|
||||
var prefab = uiPrefabs.Find(p => p.GetComponent<T>() != null);
|
||||
if (prefab == null)
|
||||
{
|
||||
Debug.LogError($"Không tìm thấy prefab chứa component {type.Name}");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Spawn mới
|
||||
var instance = Instantiate(prefab, uiRoot ? uiRoot : transform);
|
||||
instance.name = $"{type.Name}_UI";
|
||||
_spawnedUIs[type] = instance;
|
||||
instance.SetActive(true);
|
||||
|
||||
return instance.GetComponent<T>();
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool FindUIByName(string componentName, System.Type type)
|
||||
{
|
||||
for (int i = 0; i < canvasDlg.transform.childCount; i++)
|
||||
{
|
||||
var child = canvasDlg.transform.GetChild(i);
|
||||
if (!child.name.Contains(componentName) && child.name != componentName) continue;
|
||||
|
||||
if (type != null)
|
||||
{
|
||||
var foundComponent = child.GetComponentInChildren(type, true);
|
||||
if (foundComponent != null)
|
||||
{
|
||||
ActivateAndCacheUI(foundComponent.gameObject, type);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
ActivateAndCacheUI(child.gameObject, type);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool FindUIByType(System.Type type)
|
||||
{
|
||||
if (type == null) return false;
|
||||
|
||||
var foundComponent = canvasDlg.GetComponentInChildren(type, true);
|
||||
if (foundComponent != null)
|
||||
{
|
||||
ActivateAndCacheUI(foundComponent.gameObject, type);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void ActivateAndCacheUI(GameObject uiGameObject, System.Type type)
|
||||
{
|
||||
uiGameObject.SetActive(true);
|
||||
if (type != null) _spawnedUIs[type] = uiGameObject;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Ẩn UI (disable thay vì destroy)
|
||||
/// </summary>
|
||||
@@ -143,4 +221,20 @@ public class CECUIManager : MonoSingleton<CECUIManager>
|
||||
{
|
||||
return currentTargetNPCID;
|
||||
}
|
||||
|
||||
//todo: change this code to other place
|
||||
private int slot = 0;
|
||||
public void OnClickedWaveHand()
|
||||
{
|
||||
if (EC_Game.GetGameRun().GetPoseCmdShortcuts() == null)
|
||||
{
|
||||
EC_Game.GetGameRun().StartGame(0, Vector3.zero);
|
||||
}
|
||||
CECShortcut pSC = EC_Game.GetGameRun().GetPoseCmdShortcuts().GetShortcut(slot);
|
||||
if (pSC != null) // && pObjSrc->GetDataPtr("ptr_CECShortcut") == pSC
|
||||
{
|
||||
// a_LogOutput(1, "[Dat Emote] ptr_CECShortcut");
|
||||
pSC.Execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using Animancer;
|
||||
using BrewMonster;
|
||||
using System.Collections.Generic;
|
||||
@@ -150,6 +151,7 @@ namespace BrewMonster
|
||||
return namedAnimancer.States.TryGet("ActionName", out var existingState) ? true : false;
|
||||
}
|
||||
|
||||
private string _currentAnimationName;
|
||||
/// <summary>
|
||||
/// play an animation with name
|
||||
/// </summary>
|
||||
@@ -159,6 +161,7 @@ namespace BrewMonster
|
||||
private void InternalPlayAnimation(string animationName, float duration = FadeTime, FadeMode fadeMode = FadeMode)
|
||||
{
|
||||
_currentState = namedAnimancer.TryPlay(animationName, duration, fadeMode);
|
||||
_currentAnimationName = animationName;
|
||||
if (_currentState == null)
|
||||
{
|
||||
BMLogger.LogError($"Null animation with name: {animationName}");
|
||||
|
||||
Reference in New Issue
Block a user