From 1cdb7c3910c1f4170016fa805669da769f4db75b Mon Sep 17 00:00:00 2001 From: huade <491009149@qq.com> Date: Tue, 15 Sep 2026 21:13:44 +0800 Subject: [PATCH] =?UTF-8?q?```=20feat(buildings):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E9=87=91=E7=9F=BF=E5=BB=BA=E7=AD=91=E5=8A=9F=E8=83=BD=E5=B9=B6?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=BB=BA=E7=AD=91=E5=81=A5=E5=BA=B7=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 为兵营和金矿添加伤害数字显示功能,包括持续时间、上升高度等参数 - 将金矿脚本重构为GoldMine组件,实现定时产出金币机制 - 为所有单位添加NavMeshAgent组件以支持导航寻路 - 为弓箭手、法师等单位添加分离半径和目标扩散参数 - 为建筑添加碰撞体和标签设置 - 修复当前能量字段命名规范(currentEnergy -> _currentEnergy) - 调整金矿健康值从100提升至500 - 统一伤害数字显示相关属性配置 ``` --- Assets/Prefabs/建筑/兵营.prefab | 9 +- Assets/Prefabs/建筑/金矿.prefab | 104 +++++++++++++++++++- Assets/Prefabs/第一章/人类士兵.prefab | 35 +++++++ Assets/Prefabs/第一章/弓箭手.prefab | 35 +++++++ Assets/Prefabs/第一章/法师.prefab | 35 +++++++ Assets/Prefabs/第一章/盾卫.prefab | 35 +++++++ Assets/Prefabs/第一章/精锐士兵.prefab | 35 +++++++ Assets/Prefabs/第二章/弓箭猎人.prefab | 35 +++++++ Assets/Scenes/Chapter1/CoreBattleTest.scene | Bin 189733 -> 147456 bytes Assets/Script/GoldManager.cs | 84 ++++++++++++++++ Assets/Script/GoldManager.cs.meta | 11 +++ Assets/Script/GoldMine.cs | 76 ++++++++++---- Assets/Script/GoldUI.cs | 57 +++++++++++ Assets/Script/GoldUI.cs.meta | 11 +++ Assets/Script/HeroGoldProducer.cs | 68 +++++++++++++ Assets/Script/HeroGoldProducer.cs.meta | 11 +++ Assets/Script/UnitBase.cs | 94 ++++++++++++++++-- Assets/Script/WorldHealthBar.cs | 64 ++++++++---- CODELY.md | 4 + Packages/manifest.json | 1 + Packages/packages-lock.json | 9 ++ 召唤之战-核心玩法.md | 46 +++++++-- 22 files changed, 804 insertions(+), 55 deletions(-) create mode 100644 Assets/Script/GoldManager.cs create mode 100644 Assets/Script/GoldManager.cs.meta create mode 100644 Assets/Script/GoldUI.cs create mode 100644 Assets/Script/GoldUI.cs.meta create mode 100644 Assets/Script/HeroGoldProducer.cs create mode 100644 Assets/Script/HeroGoldProducer.cs.meta diff --git a/Assets/Prefabs/建筑/兵营.prefab b/Assets/Prefabs/建筑/兵营.prefab index 4762437..c50dd45 100644 --- a/Assets/Prefabs/建筑/兵营.prefab +++ b/Assets/Prefabs/建筑/兵营.prefab @@ -101,12 +101,17 @@ MonoBehaviour: maxHealth: 100 currentHealth: 100 maxEnergy: 100 - currentEnergy: 0 - heightOffset: 0.25 + _currentEnergy: 0 + heightOffset: 1 barWidth: 1.2 borderColor: {r: 0.03, g: 0.03, b: 0.03, a: 0.95} deathEffectDuration: 1.1 deathEffectColor: {r: 0.55, g: 0.9, b: 1, a: 1} + showDamageNumbers: 1 + damageNumberDuration: 0.8 + damageNumberRiseHeight: 1.2 + damageNumberSpawnHeight: 1.5 + damageNumberSize: 0.09 --- !u!114 &7049005926872886096 MonoBehaviour: m_ObjectHideFlags: 0 diff --git a/Assets/Prefabs/建筑/金矿.prefab b/Assets/Prefabs/建筑/金矿.prefab index db93402..b5d83b4 100644 --- a/Assets/Prefabs/建筑/金矿.prefab +++ b/Assets/Prefabs/建筑/金矿.prefab @@ -63,8 +63,110 @@ PrefabInstance: propertyPath: m_Name value: "\u91D1\u77FF" objectReference: {fileID: 0} + - target: {fileID: 919132149155446097, guid: 35b9ee56f1163491d957e1903bfedf03, + type: 3} + propertyPath: m_TagString + value: Friend + objectReference: {fileID: 0} m_RemovedComponents: [] m_RemovedGameObjects: [] m_AddedGameObjects: [] - m_AddedComponents: [] + m_AddedComponents: + - targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: 35b9ee56f1163491d957e1903bfedf03, + type: 3} + insertIndex: -1 + addedObject: {fileID: 7577279847001002587} + - targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: 35b9ee56f1163491d957e1903bfedf03, + type: 3} + insertIndex: -1 + addedObject: {fileID: 2464957741073066864} + - targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: 35b9ee56f1163491d957e1903bfedf03, + type: 3} + insertIndex: -1 + addedObject: {fileID: 4165091129539139448} + - targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: 35b9ee56f1163491d957e1903bfedf03, + type: 3} + insertIndex: -1 + addedObject: {fileID: 6812882125473210247} m_SourcePrefab: {fileID: 100100000, guid: 35b9ee56f1163491d957e1903bfedf03, type: 3} +--- !u!1 &5707827689025450131 stripped +GameObject: + m_CorrespondingSourceObject: {fileID: 919132149155446097, guid: 35b9ee56f1163491d957e1903bfedf03, + type: 3} + m_PrefabInstance: {fileID: 4897434639390281154} + m_PrefabAsset: {fileID: 0} +--- !u!114 &7577279847001002587 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5707827689025450131} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9355c53f591d4459ea620fc8191efa17, type: 3} + m_Name: + m_EditorClassIdentifier: + maxHealth: 500 + currentHealth: 500 + maxEnergy: 100 + _currentEnergy: 0 + heightOffset: 1 + barWidth: 1.2 + borderColor: {r: 0.03, g: 0.03, b: 0.03, a: 0.95} + deathEffectDuration: 1.1 + deathEffectColor: {r: 0.55, g: 0.9, b: 1, a: 1} + showDamageNumbers: 1 + damageNumberDuration: 0.8 + damageNumberRiseHeight: 1.2 + damageNumberSpawnHeight: 1.5 + damageNumberSize: 0.09 +--- !u!114 &2464957741073066864 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5707827689025450131} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0664b986337964243879f685b5c49aba, type: 3} + m_Name: + m_EditorClassIdentifier: + maxHealth: 500 +--- !u!114 &4165091129539139448 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5707827689025450131} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: aa899f80764ca42429a0a155f38f9ba4, type: 3} + m_Name: + m_EditorClassIdentifier: + goldPerProduction: 50 + productionInterval: 5 + healthBar: {fileID: 0} +--- !u!65 &6812882125473210247 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5707827689025450131} + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_IsTrigger: 0 + m_ProvidesContacts: 0 + m_Enabled: 1 + serializedVersion: 3 + m_Size: {x: 2.2292585, y: 2.1124895, z: 2.2443316} + m_Center: {x: -0.00015996098, y: 0.010562447, z: 0.00014443} diff --git a/Assets/Prefabs/第一章/人类士兵.prefab b/Assets/Prefabs/第一章/人类士兵.prefab index 66287d6..35daaca 100644 --- a/Assets/Prefabs/第一章/人类士兵.prefab +++ b/Assets/Prefabs/第一章/人类士兵.prefab @@ -144,6 +144,10 @@ PrefabInstance: type: 3} insertIndex: -1 addedObject: {fileID: 6149369975191414129} + - targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: 5072af719b9b1401787c6c55f048d8ed, + type: 3} + insertIndex: -1 + addedObject: {fileID: 2921261421214297749} m_SourcePrefab: {fileID: 100100000, guid: 5072af719b9b1401787c6c55f048d8ed, type: 3} --- !u!1 &7945271050725079514 stripped GameObject: @@ -204,6 +208,9 @@ MonoBehaviour: projectileSpeed: 20 projectileLifetime: 5 energyPerAttack: 25 + separationRadius: 1.5 + separationWeight: 3 + targetSpreadBias: 6 target: {fileID: 0} --- !u!114 &2920089167710187078 MonoBehaviour: @@ -226,6 +233,12 @@ MonoBehaviour: borderColor: {r: 0.03, g: 0.03, b: 0.03, a: 0.95} deathEffectDuration: 1.1 deathEffectColor: {r: 0.55, g: 0.9, b: 1, a: 1} + showDamageNumbers: 1 + damageNumberDuration: 0.8 + damageNumberRiseHeight: 1.2 + damageNumberSpawnHeight: 1.5 + damageNumberSize: 0.09 + damageNumberOutlineWidth: 0.015 --- !u!114 &4111165692813349771 MonoBehaviour: m_ObjectHideFlags: 0 @@ -255,6 +268,28 @@ MonoBehaviour: showStunIndicator: 1 indicatorHeight: 0.35 stunIndicatorPrefab: {fileID: 0} +--- !u!195 &2921261421214297749 +NavMeshAgent: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7945271050725079514} + m_Enabled: 1 + m_AgentTypeID: 0 + m_Radius: 0.5 + m_Speed: 1.8 + m_Acceleration: 8 + avoidancePriority: 50 + m_AngularSpeed: 120 + m_StoppingDistance: 0 + m_AutoTraverseOffMeshLink: 1 + m_AutoBraking: 1 + m_AutoRepath: 1 + m_Height: 2 + m_BaseOffset: 0 + m_WalkableMask: 4294967295 + m_ObstacleAvoidanceType: 4 --- !u!4 &8878706989061864259 stripped Transform: m_CorrespondingSourceObject: {fileID: 1852576806548013000, guid: 5072af719b9b1401787c6c55f048d8ed, diff --git a/Assets/Prefabs/第一章/弓箭手.prefab b/Assets/Prefabs/第一章/弓箭手.prefab index 41db9f2..7b4391a 100644 --- a/Assets/Prefabs/第一章/弓箭手.prefab +++ b/Assets/Prefabs/第一章/弓箭手.prefab @@ -139,6 +139,10 @@ PrefabInstance: type: 3} insertIndex: -1 addedObject: {fileID: 1449822714228276666} + - targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: 7b0dd5b38a9cd144ea135f3743440958, + type: 3} + insertIndex: -1 + addedObject: {fileID: 196735238731846736} m_SourcePrefab: {fileID: 100100000, guid: 7b0dd5b38a9cd144ea135f3743440958, type: 3} --- !u!4 &2222026796505693691 stripped Transform: @@ -222,6 +226,9 @@ MonoBehaviour: projectileSpeed: 20 projectileLifetime: 5 energyPerAttack: 20 + separationRadius: 1.5 + separationWeight: 3 + targetSpreadBias: 6 target: {fileID: 0} --- !u!114 &7720102017902192686 MonoBehaviour: @@ -244,6 +251,12 @@ MonoBehaviour: borderColor: {r: 0.03, g: 0.03, b: 0.03, a: 0.95} deathEffectDuration: 1.1 deathEffectColor: {r: 0.55, g: 0.9, b: 1, a: 1} + showDamageNumbers: 1 + damageNumberDuration: 0.8 + damageNumberRiseHeight: 1.2 + damageNumberSpawnHeight: 1.5 + damageNumberSize: 0.09 + damageNumberOutlineWidth: 0.015 --- !u!114 &1449822714228276666 MonoBehaviour: m_ObjectHideFlags: 0 @@ -259,6 +272,28 @@ MonoBehaviour: volleyArrowCount: 3 volleyArrowDamageMultiplier: 0.7 volleyArrowInterval: 0.15 +--- !u!195 &196735238731846736 +NavMeshAgent: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5200308054099318121} + m_Enabled: 1 + m_AgentTypeID: 0 + m_Radius: 0.5 + m_Speed: 1.8 + m_Acceleration: 8 + avoidancePriority: 50 + m_AngularSpeed: 120 + m_StoppingDistance: 0 + m_AutoTraverseOffMeshLink: 1 + m_AutoBraking: 1 + m_AutoRepath: 1 + m_Height: 2 + m_BaseOffset: 0 + m_WalkableMask: 4294967295 + m_ObstacleAvoidanceType: 4 --- !u!1001 &6707986314085581781 PrefabInstance: m_ObjectHideFlags: 0 diff --git a/Assets/Prefabs/第一章/法师.prefab b/Assets/Prefabs/第一章/法师.prefab index 6602143..f37ec83 100644 --- a/Assets/Prefabs/第一章/法师.prefab +++ b/Assets/Prefabs/第一章/法师.prefab @@ -140,6 +140,10 @@ PrefabInstance: type: 3} insertIndex: -1 addedObject: {fileID: 3887798621029042906} + - targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: 9d4b54ec2c4f7754bb1fd5ec11a29541, + type: 3} + insertIndex: -1 + addedObject: {fileID: 20042258299677061} m_SourcePrefab: {fileID: 100100000, guid: 9d4b54ec2c4f7754bb1fd5ec11a29541, type: 3} --- !u!1 &7062617501994129594 stripped GameObject: @@ -216,6 +220,9 @@ MonoBehaviour: projectileSpeed: 20 projectileLifetime: 5 energyPerAttack: 20 + separationRadius: 1.5 + separationWeight: 3 + targetSpreadBias: 6 target: {fileID: 0} --- !u!114 &990449840913200210 MonoBehaviour: @@ -238,6 +245,12 @@ MonoBehaviour: borderColor: {r: 0.03, g: 0.03, b: 0.03, a: 0.95} deathEffectDuration: 1.1 deathEffectColor: {r: 0.55, g: 0.9, b: 1, a: 1} + showDamageNumbers: 1 + damageNumberDuration: 0.8 + damageNumberRiseHeight: 1.2 + damageNumberSpawnHeight: 1.5 + damageNumberSize: 0.09 + damageNumberOutlineWidth: 0.015 --- !u!114 &3887798621029042906 MonoBehaviour: m_ObjectHideFlags: 0 @@ -252,6 +265,28 @@ MonoBehaviour: m_EditorClassIdentifier: explosionRadius: 1.8 explosionDamage: 85 +--- !u!195 &20042258299677061 +NavMeshAgent: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7062617501994129594} + m_Enabled: 1 + m_AgentTypeID: 0 + m_Radius: 0.5 + m_Speed: 1.5 + m_Acceleration: 8 + avoidancePriority: 50 + m_AngularSpeed: 120 + m_StoppingDistance: 0 + m_AutoTraverseOffMeshLink: 1 + m_AutoBraking: 1 + m_AutoRepath: 1 + m_Height: 2 + m_BaseOffset: 0 + m_WalkableMask: 4294967295 + m_ObstacleAvoidanceType: 4 --- !u!4 &8608542904823568931 stripped Transform: m_CorrespondingSourceObject: {fileID: 1852576806548013000, guid: 9d4b54ec2c4f7754bb1fd5ec11a29541, diff --git a/Assets/Prefabs/第一章/盾卫.prefab b/Assets/Prefabs/第一章/盾卫.prefab index e47037e..0404ad1 100644 --- a/Assets/Prefabs/第一章/盾卫.prefab +++ b/Assets/Prefabs/第一章/盾卫.prefab @@ -195,6 +195,10 @@ PrefabInstance: type: 3} insertIndex: -1 addedObject: {fileID: 8203338886952913679} + - targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: 17f7a1b7ae92f0948a5bebde8a11fc2b, + type: 3} + insertIndex: -1 + addedObject: {fileID: 4069710806908923055} m_SourcePrefab: {fileID: 100100000, guid: 17f7a1b7ae92f0948a5bebde8a11fc2b, type: 3} --- !u!4 &309400887928525066 stripped Transform: @@ -276,6 +280,9 @@ MonoBehaviour: projectileSpeed: 20 projectileLifetime: 5 energyPerAttack: 20 + separationRadius: 1.5 + separationWeight: 3 + targetSpreadBias: 6 target: {fileID: 0} --- !u!114 &6884400399417614731 MonoBehaviour: @@ -298,6 +305,12 @@ MonoBehaviour: borderColor: {r: 0.03, g: 0.03, b: 0.03, a: 0.95} deathEffectDuration: 1.1 deathEffectColor: {r: 0.55, g: 0.9, b: 1, a: 1} + showDamageNumbers: 1 + damageNumberDuration: 0.8 + damageNumberRiseHeight: 1.2 + damageNumberSpawnHeight: 1.5 + damageNumberSize: 0.09 + damageNumberOutlineWidth: 0.015 --- !u!114 &8203338886952913679 MonoBehaviour: m_ObjectHideFlags: 0 @@ -315,6 +328,28 @@ MonoBehaviour: damageReduction: 0.35 shieldLocalPosition: {x: 0, y: 1, z: 0.7} shieldSize: {x: 1.5, y: 1.8, z: 0.12} +--- !u!195 &4069710806908923055 +NavMeshAgent: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1242979668690031507} + m_Enabled: 1 + m_AgentTypeID: 0 + m_Radius: 0.5 + m_Speed: 1.4 + m_Acceleration: 8 + avoidancePriority: 50 + m_AngularSpeed: 120 + m_StoppingDistance: 0 + m_AutoTraverseOffMeshLink: 1 + m_AutoBraking: 1 + m_AutoRepath: 1 + m_Height: 2 + m_BaseOffset: 0 + m_WalkableMask: 4294967295 + m_ObstacleAvoidanceType: 4 --- !u!4 &5170975053921319681 stripped Transform: m_CorrespondingSourceObject: {fileID: 6502182839619065283, guid: 17f7a1b7ae92f0948a5bebde8a11fc2b, diff --git a/Assets/Prefabs/第一章/精锐士兵.prefab b/Assets/Prefabs/第一章/精锐士兵.prefab index 878a6e7..ebab685 100644 --- a/Assets/Prefabs/第一章/精锐士兵.prefab +++ b/Assets/Prefabs/第一章/精锐士兵.prefab @@ -181,6 +181,10 @@ PrefabInstance: type: 3} insertIndex: -1 addedObject: {fileID: 4116279677098275843} + - targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: 62d9f853c067ff443bd2a3aa382ab563, + type: 3} + insertIndex: -1 + addedObject: {fileID: 8773165921290396666} m_SourcePrefab: {fileID: 100100000, guid: 62d9f853c067ff443bd2a3aa382ab563, type: 3} --- !u!4 &2585761489654059889 stripped Transform: @@ -263,6 +267,9 @@ MonoBehaviour: projectileSpeed: 20 projectileLifetime: 5 energyPerAttack: 20 + separationRadius: 1.5 + separationWeight: 3 + targetSpreadBias: 6 target: {fileID: 0} --- !u!114 &3773753810590757696 MonoBehaviour: @@ -285,6 +292,12 @@ MonoBehaviour: borderColor: {r: 0.03, g: 0.03, b: 0.03, a: 0.95} deathEffectDuration: 1.1 deathEffectColor: {r: 0.55, g: 0.9, b: 1, a: 1} + showDamageNumbers: 1 + damageNumberDuration: 0.8 + damageNumberRiseHeight: 1.2 + damageNumberSpawnHeight: 1.5 + damageNumberSize: 0.09 + damageNumberOutlineWidth: 0.015 --- !u!114 &4116279677098275843 MonoBehaviour: m_ObjectHideFlags: 0 @@ -300,3 +313,25 @@ MonoBehaviour: skillDamage: 125 skillRadius: 4 skillAnimationDuration: 1.5 +--- !u!195 &8773165921290396666 +NavMeshAgent: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3933539425749946856} + m_Enabled: 1 + m_AgentTypeID: 0 + m_Radius: 0.5 + m_Speed: 2 + m_Acceleration: 8 + avoidancePriority: 50 + m_AngularSpeed: 120 + m_StoppingDistance: 0 + m_AutoTraverseOffMeshLink: 1 + m_AutoBraking: 1 + m_AutoRepath: 1 + m_Height: 2 + m_BaseOffset: 0 + m_WalkableMask: 4294967295 + m_ObstacleAvoidanceType: 4 diff --git a/Assets/Prefabs/第二章/弓箭猎人.prefab b/Assets/Prefabs/第二章/弓箭猎人.prefab index 92441ff..6747dc2 100644 --- a/Assets/Prefabs/第二章/弓箭猎人.prefab +++ b/Assets/Prefabs/第二章/弓箭猎人.prefab @@ -247,6 +247,10 @@ PrefabInstance: type: 3} insertIndex: -1 addedObject: {fileID: 6166541611286257137} + - targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: 2ac38f68ec4f85341b423b5e8defd47e, + type: 3} + insertIndex: -1 + addedObject: {fileID: 7158251723525050232} m_SourcePrefab: {fileID: 100100000, guid: 2ac38f68ec4f85341b423b5e8defd47e, type: 3} --- !u!1 &4059575966999087028 stripped GameObject: @@ -301,6 +305,12 @@ MonoBehaviour: borderColor: {r: 0.03, g: 0.03, b: 0.03, a: 0.95} deathEffectDuration: 1.1 deathEffectColor: {r: 0.55, g: 0.9, b: 1, a: 1} + showDamageNumbers: 1 + damageNumberDuration: 0.8 + damageNumberRiseHeight: 1.2 + damageNumberSpawnHeight: 1.5 + damageNumberSize: 0.09 + damageNumberOutlineWidth: 0.015 --- !u!114 &6486457417548983634 MonoBehaviour: m_ObjectHideFlags: 0 @@ -329,6 +339,9 @@ MonoBehaviour: projectileSpeed: 20 projectileLifetime: 5 energyPerAttack: 20 + separationRadius: 1.5 + separationWeight: 3 + targetSpreadBias: 6 target: {fileID: 0} --- !u!114 &4858463350953901710 MonoBehaviour: @@ -359,6 +372,28 @@ MonoBehaviour: indicatorHeight: 0.35 stunIndicatorPrefab: {fileID: 2432573200162841629, guid: de288ea16be0c1544a4c6eb71e899570, type: 3} +--- !u!195 &7158251723525050232 +NavMeshAgent: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4059575966999087028} + m_Enabled: 1 + m_AgentTypeID: 0 + m_Radius: 0.5 + m_Speed: 2.2 + m_Acceleration: 8 + avoidancePriority: 50 + m_AngularSpeed: 120 + m_StoppingDistance: 0 + m_AutoTraverseOffMeshLink: 1 + m_AutoBraking: 1 + m_AutoRepath: 1 + m_Height: 2 + m_BaseOffset: 0 + m_WalkableMask: 4294967295 + m_ObstacleAvoidanceType: 4 --- !u!4 &7974625701785382694 stripped Transform: m_CorrespondingSourceObject: {fileID: 6502182839619065283, guid: 2ac38f68ec4f85341b423b5e8defd47e, diff --git a/Assets/Scenes/Chapter1/CoreBattleTest.scene b/Assets/Scenes/Chapter1/CoreBattleTest.scene index 30c8213a631e3262e88247727317896715c2f350..78e17d589b6f442e3391db67e5dc103f68c6fd72 100644 GIT binary patch literal 147456 zcmeFa34m0^wLg5D-5p$UZxj^>%I2=X3^Oc)gN!qPpeXdr^vtyMbdTLVz~FY>*QX?+ z;u3{u)Tl8;O~km7NR+rojq#bpC7KuG%gf(gqDlCEzp8V(Z}sgS^5psD|9x+2rmE|n zU)8C)RduUQovK^c^YUibyf4ymwek0=u%t-Gi`L_LV@Ho2d&sy$4j-EvbEx-^O`A4F z4gs_`;Z2(^JL1q8H3!c4S0r`!9@&-5_hik@XdSC_D8sdk5|14Y%fVFA(7KBUw zxI_OG_?hRvdBl1cpZQDRl5zW$!A}>we;K?>aONRsl>fOPlK)mg5Ps&b7Wuo>_&smy zGWbn`Z$rF-jx~(W^0^n6>jHjU~o{CSM4SzGD zo;>;#`#VN{$I9=xQ-VwgBhVIWPA@4HqZp7VETA?zn>NLsPyX%6wKvC4o$%xRH!e%wcND1a;0e%1 zz=wtvV~j7q_+h1N?xA6$VP)`vG7n7!JYpDs4)9%Y%|>q@(x{+})5}{8oD?<++K9(1 zYZTuPm&Ewcl){G!&WENHexTrdXk6Sj+F^o+ADW2CA3GGLujK`=F}y$Ke;Kf^0)cd{Ow!@*Zi>^x$$lOE(V?Xv%^ai zK5I1nC@z`5-C*7LZut!^gKPdcK$MEF`P(Ce+xEdulj-jX8#JtccA7r`k@#K&E9h9G z?c-5g^8U;iSmODJ0%QDrU`yps%YWZ8xZYp146gS#B!ox2$-O-PRnXaXnNHBK{CR(W z1d;jMAGXw>`2pyB_LvVBx8?U&&>8;#*r3tpZ$QN2%xBOjK3MRBf*}0FA4C3!184r( z4+Kqd{)Yo}^JfQr&HsoHZuuV}{J#-oZo<0dGcpw4<$rJpx9z7|?vHX((D43P{__PN z6$If|e3{^*OW>;!|4PBfl)%@Z{B8rz^2-Ze60W%X#(~~l`BC_C@rd^zct0Wh4->xn zQ_TPHP<*%iFwTYe*W&(u0si>+j#S3-TOUs~$1{0R0)j!h6+{iUnUaiU;>FifV$Jb}j<}I$7=BiKX|6NFLTKnn=c>}_MG0P1$6I2Z$y|NB zB^gI%(kaPah+ZGhrjwlvfmns$lW@~b@vK7&-gH%GHkWQMgtsDJE#)T4cnzIoH#-}z zk2NP^;3S1qmq|CqO+|m3?xs!G?tJ0Gi9>%h{{3$(zwwm2-rTVQ)IJb7*s^ITC1EzQ z$z1rxH4dMm%}Ggo3ORbR7wg4X6?ClWh4}0_`E+vxHByofj~KS{)rfyIt{I;;XcV6Y zA~8xyL8JJoAQJBv1mP#n{3ivcloT|?`IKA)BA=45lw@%hBXJ`oRlp-=TTmZ_|9M!J zpOKP$Ur?Jq?@vbwD_`x zX+5X=_t-#p6OdD$tPrtmf!Kf@o(zbD@vdFZ?*jCl8Wkw_#uK@Dan`E%(IO@LGXPH62@x< zr<7EjfAT*`@MszQbis#|!Os(XzcTn$f>TN=mHyp=4=sbgAh?y1d=rX}-v93fw^C9V z|3YvpC57>w(J`@oTPZ1w4-=eHQmOn;5S&s{DSVFLR!Z_sC_0+|Ho-?4#5XP-;(Wf( z1kU!!eza8kx>Vv@DamIjW0e2*1h-O>FK8kCX9TxWl8diK`hOJMN=adS2NWL5&q_&Q z{3yXGB^8$s@9z}gygy1w#rHQ2&vynm`&T0+t@9bm7(D+GKf&VlCQCm`-=uuPv)l8f8%=?X+sR?t0N5S>iAA`PB-&#g0XcAL&57yEqLyTOiIHWd z);L(;!pbfUO|c{;p_){4A_Ey{W@oOWGpE$bWMjNJJt>{eQbL@ZTAawFQ|%B7O~O!O ziM(XhNt0rW;?0^R3PqM&ACDz-iS~E_QQzd|1SH8op2`A_{Ka$}LS-%)%QhsI@kT0V z8fQjqDKuL-3RSqSO1F1Z&YZloBb`F#LxgH`>mW~FYNS#T!}2OPAa$|kX54Q;fJ3p@ z#WJz>I7HPfr8&)ffeK<+eAQrC-iDN)h^NeECZ46P&_qqel2f7Pi)Y*`@T7Q*+>n1h zP<;%ddZ)R)g2d^voRL@>Zw{nO@1$7MB1|U0t8PwxL#(}nI!b$G%f-;*%31>j2?a42 zXrPsZVg@i|F%B8NDPEUOq#%*oj3a*j?xbu$!mK5o$i_3Xx;ol}x2XxH74g2x(H~1Cz`vjZT@OHN_Wp;f9~@!)J|l;~d`5 z(~C0Mw;){NtC4mk{KRQ-X-QbOOHGr=|3kqC;kP({+oBzDnuUKmP4ayPGKSNb zRp38Ta5GJ+@C9X@h<7NkDX_eEJ59>N`TL&*ocAA|CRt_CDZoojla7xqo)OQsKX`WbLr~q~}r_Z`(zm31y@3GAJPyaA}=)Onn2kPyxeDLl;%V9@Dc@~$!c4Qht zcO4BI3eDs`p3jEDj>b|*rC;Wo@Ux*ntOw19YYlPAqnszQp)ib#N6Z{4Cj8mabjP0^ zjT_(P&--=ph<8yhBk!C1GY{SIXGi14clooUaq)=vE8HJDVU{mDno8gF&G0d7FK0f% zGOVl!;#MD_^9gn|m39Gx(GkD5SA$>9Cm5F?Ag&2 z+ea<(mH;sVYde}k2;!V?-Hk$H`IwHz58`h5n2x3*h`Z%u z^)W6UoNsY}Wj@qs`duI}eWQ=@6%E%9^)Zo(AnvAbSFKz;m_GF}#p!d^5oIE*zuW; z(f1{F=GE6AM%Z|}4Keyux zcZ`;QBjS-iJI0_X=5ISjKOcm6aNvsqanrZU>8FF<2X+W-(6IfiM*CO>B5?{_K|}nv zXn&W1$XeOofKlVpVfu{!E%+IKD2ZOwxO5a>0YC8rNOW+^|5{MV-zuu3@L8krmA_R~ zM->k7A7+pO&V@E85B-}#XZphpUU0~t&(~dokHBxFXkg*}{ZMeLs1C-Dc7nfzd=BIu)wAnT@AG z$2q}kjAgL;ya+0|Y}^i`UTZqpJOgXudYMTyn;8i<$2G;N@|4NW(%M9OBA4}+dR^W! z@wb}AZyhHm5jOJ|s3~MpWwW5m+7mc|S)7P3QNo;9GSOU2tVu04WR@e_1SF~j^J*Vo z`Kv>Y-uU#u$KSc}uV=BDJOtYdHizcXGrazPcX<5+hDXk8I5b)XM-)D5w0oI>OEv`# zub$IA+3t#QOu<*KAPvc$;}giS#vp zR>2WPNNbe8=8wax%irc-^T*-U#cld=P?69<1BcgQJjj1&2)Fh3 z9ni_2!z%X#H_`Ero0Q;qY1t*ZSk|8pO9~_`sYgja9Pxbj~WeP0#Nw!JNs^ zRS~b(x^`BT#>|YWb7;h=M#oexo5$Lq-NNbz;!M#69>Z*MXEL6tOtnI-H4V!mrgYfo za5wuNP`l}*_m)IH+IC9s$8PTX+1*PPCH!~pn>c5eAD=e)sh>`bB2=ph*)!Gpx^+-J zQ>}uI>3`!?i+v%-YL1oRsg~W@I$dy%1wq5Hq8@}(Vc8dQEC`z7zLsM_ccOCfRBMa+ zI_Q$nQ(^rP(lB-I=GO|ZT%(>~#ANzRj^CoYX;aHFC!ag`tqBhtzv7*%bGNRX$z2%z zFg#EyrP&gxl#5^ohb}jY`FuK9xS67d0*&#Wj7a^ao&3j!a69W$ z{^QEv%Ky+1Zu$QMbn-teguDDXR+PFw<&SaB!Rw)G!fu&Vwk4fu-_o_6f887ed+Jh6 zZRrfOW0>Mj$)u`aGF9>{a zN(m0D(6RQc7TMJ@mSe<}lr2Ga{9LC0SFaY$Kz3NSd)jQ}UDhwBI9mUl!nlI7tF7NV zgxi;2`8-qT;}pg#F)%Cym4YMNQK^?h8wHP+!J7piQU-4k+zJj+Tv@~NXZvi!CHoo* z4#5Ua{4c<-xenxQcEk>91OQGX8u*8kv;NwCJ)s6oJ|KDJV8^OUB5I@+K z@2E2mCgjtxCW0M|Y(J{bw1R`8jNjMrKMi5X-v|zV5buW+poWHJ`?P{X5by7_PYMoh z`|R(mHd1hK@qXs{+Y|hmz7ZUJhre@w6dWQIL41I7e-s?RDsT9#pMZPg{gF<=!NqO* z+!M(3jo{$tqa$p8C;cNCzaogc=^sVB0K@O5e{=}%XYyZ(NNiun1me;g!4A`Dz~)H) zjwR8jV-50W>ZcJn>u09E`4hno*I@lrg>c)xRv;3~r<#!hhWEc3Ir@&^lLHvN#M!^|wKdl76cT+p z))eP|D#+dCe;RR#%b()>*M#u?rhnth$&5Fhkt*p}!}{g(`4T|hA1C-h!~Ww9V1I^X z{niFS_>0E}jw5dUy5qy~A>69S`a`+E^k>2bjrPxM$4mU#W#Uhl_;X6cXZrfu-ibx=w@8I& zwRO6(%xz)nhu6MlU3fVh?~F9XvbkBYOlzF)#mKe3?NV6km=Vh^;*l{P-*{-iN=Uq_ zEtYDHH&0${->8{sj<*RSULCgTVmC1Gs#r3~H^e)TgiFOKI8G?$5rO4!oT0j4&;4nV zMeE_K1MQ8;E^c5x9xMBZHzS^FOE>EUUwN<0w03gozADz#X5I~wYrdOgIctazp#*=t z*c}KyC7F%|ukGf!Kmfcol?+_+u1x9JiQv$Nj!YsKXZ2VgJlJ|*b~RUKJ1}zu0o(qt zWg0Kh+ZTY6NqdWeRJO}YGbUIv-Lz;4UXl@TW+u^U=4*Jn+$LbRQ7@>&D?rIC3Vn7e zkqf+>!6t|{%?|4$f3K=Tue#|+3*O#in|lvj)vyDojj$2IFc_|UJ6E>X>hiJL-0o)b z+MGU@;uIg--ms;*6^av_b})>KN0_(G>T{KUzfgSJZ7Ki$A^e})-K_k#3dMK%Zymz_ zIeo73XV)C)l~5Kg|LsD!UBza1&br(l7FB6nI#n_3ILX?RCG>TjE!d2Tj>2d^I&eNi zDrcG>Q~3*>O`E>|!7o2w_v~l$2R=3Fg{JrW?Lm3!{ICh!~-_q#*GmVS| zv$;mLAHsCk$S4z+Yh;uMW1CqtQ2yl_nezXtjZFEMYh=p5R3i&+5#I*)(%nu;mSuN4 zCE3U*Z>r(kAt+n1k-50tDnXfr^~(-nkPk-;8nGkWasD-EoucIBZj~5ByZ{@V^G?d% zQ1#~z4en$3U`h3VJ1G{)1?^3j# zEa<$q-9mU@6Q4UB8GmpY{CvT=XyEd<@vjh^iw33eYXs-qzZ8D6;Cq$9?+~1G|5EYS z2)<7l{2{?P_b(OyXM#t|;Liv?qzwLw;CxO>@#k2_^4-4-{+{4N%itdg&d#_Lf6krB zpL73GI2TBXA5?^!cMSm?0LyvRFxY`U95E_;9}ArQ*Kk<2BQ?ZVqwR72MtlTpDO}$* zV?R*}UnucMmcbVZ&bfc7_}GbV(&u1W3cpD3QDyL(1Rq@jN8R~%2|lI-z8d&Lf^+U) zoId0KOz?4K@LvkfzP?oa*9AYU1Wq9cJKfFwbM9X%{zkzmuoUB*x9Hr1bAPw~?YoBK z5C$yFkp=@R;1R>|k^S2-z}dfX?(fET`&Z8W-S}?*%DI0qf4$KEP6KcDZ=CnBjRtY{ zub%>&gD@4qCWP?5rhT>oXZz&b-;HnaMS@q9!PA0Qmcg@vPbz~i5xlAleum)HW$<$Z zpIin%UvSR-OWohaf=?}jUoQBxGPoYe!f~_||Eneb^fLH$f*)4~zfthoGWacmvkjC= z|5m||58-{hF3kJy08ZIrW(c>s!~H;K`>2B*1qw>c*;;?EcpKwu|>9c%Kf*t5Z6-NH7?&?2~KFjyyGWdIf&o6_& zFZd}T+}_`x<^E13?!ys-`ir2?&L8=*0QBzeZy|As%O91$cz?`)4A#X-_59C}K4quI z5Z>36&nDn3pC*Gx;aWrfs}Wzzrx|3o{4B2J6EA~n`Lu*^oBn{_HvQHR?xx>X2G{fx zWpGU&`g5ZTjd#O#NFqJc>}(6sMm9xx4f`%ix;+;t+0i z%VUu~Tj~;n!x6*hlk&--f-eQ#EkE0T9S)rJ*G1fy$oMJlzc`O@>(A}K&LCchj`+R3 z$>6Q^cV-ChW9n}n!tnVy%ivMC*06sL*5BD6yX9wbt-o{1;97ou2)F6SB>i(kxSRfY zWpGXZ{4%(ve?bWEW91j5&-%O2;BdrH{<$3eZwGL6G2TV6Zu#~x^Sd*EM}S>i20u^m zOF}qf;Y~K+?B6csRlrdGXaBGL+hqoe=0mW4gY|QH8C=WfiZZyC&%cFmo4)pMSB7vm z{j190n*Q=KxTgQj5N&sLkPEPFAqunZZvqo37&zmMe7jl3xt(9q(jf;;DsC{ zM2(<$@iKaw*VvVdXL)|T_22+|>%j^3)`KJLt>;kn9HySb)pLY;j#ST4>KRjDo##C! z&wNat`lS3klCa; zqr=F$Ozq>kkubJDUsU|HS_<+*XGMO?-L6MIyS zq1Yq6@X`>-4e8EIlOAw`MLK;GiSHl<_TE(nPW0geP0B1ilJG6~~pHU3WdZ?t0E>urqf`SCI-It~JFo z|J^}$mml4gk3B-TJwt&S6OR0Q!Uhc`H%k7yf=J0>FIbnqyQ^aF5Z<%vj*=}UT9zL* z@17SmE*+LHaZ0Sjsd+DjQz9ikjIa~GXV+b@eL{}CpHKo{h39`SktOSiR~7>4_;#Sgr{+Cq z6dx`4tRM)#;ztWk&3n)gXZlkl{W%1S(kDJwaBAL*aXz0-!hbIDfYJ1q3Qo;?&=6mZ z__}gK&3n*rWsW;9u19=o?x=Y$s$WMlPR)Cyf`P2j`c=(8HScH&c|#m^Vl@Axp9&kq zw`exsv#XHvGjk-hZtDBLYggfvbSfwF%)HlD8ZXTug80Qf@Y0-YB;H(?IRJhVj&h!o zU;w=5B{&XI7hh#E(P|EU2X6e6x~9g{IQu-qZwb{Wn%c}u;m`o2Gl^wLA(ouEIG*7# z^uX=3+ad95Lk%6VCcJBo0Qon{*xaMe@Pk+U$M~nG{JFBKCH2^xSc!i`_l>l#GaT6lTvrV@ABJpStgr7JjZ2krCQ-T{}@ThU=aAacsm&4Ea z`x#mkt~H8(3zx+Ahb{F=F_&|R4=saVEBFB++?F4gV;SEn7vT}3`M(F(%zruMqUL`X z!j#IN=6`q@T=PGo46ga-_BfZn9l0MhbU6#85*K2$eqO*e@9$s*itu*@Kco!)rQnpH zgGTx96tVnA2SND%heoER&J15Rk#Pzm*5p(?)7s@N5I`>5%qk&P=(2e04Tr(nPny2@cHvtJC=Ws?`&`62P&EaSA}>1Vm)5f zvdfcBSWJnQq)O5GaVr`laQE|0d}Pg_;k`b%@Atb5_~Ynb{pbDD?i)~dQS_SgU;A`L z@0E|)zKl>{4e~PTglvxEl`h^z_g;gLs^dxooX=#0SPwxVlBpwA-v~f5u59@h#!Y?E7xgpizyc<3Y}II zSJtR3-h@lWXQ$-2D4`Ts#*FTI4;kJBd zfIt52SB)zRDQwZ8iuIGgHa&A9M-r0@dmIH1rZ6imx<4_$8PR-Pf`@P*g!#Zk`vRQo z5Lkn$#>b%WsZH5II5m!W4-V;Ghiioj{WT@NtMU8?(7slUWMl$_+k$ zVZN>>>p$GKD_%wCq;Zgh(1Ly}9|gYqXUb}5U{f(yq5_w^ouW_uv7rCd8xCInANS`; ze^~tL`#W?UaOXDFEuT}&nu{vw#V{~j2jWtyx$uo^9JY||PNLvTwmTpsdj`fQzlaY< z3|kP-+h@yS3uA8B64dBYY!wJ>!L)7*vrFx@pmX%@8^U{;mo%wuVftnr$j5~k@OPGi z`-2`?rzq2Mzl$A~5c+s=1V2s6$E+jx!T5d6OL%-ag!gCH5rVjV$xQEW8$j;;^)u^a zdVl2M;(g6h_qm|+{*zjFw;tjyF*8C3%;couf54ibr^S^%xxA}h# zbmo63aUYJD;`|=~y4$|p{96e@V>2&(yti=4{IhH+A-MO~*Yr;xfX@1%gy75mNIZu*oET>ftQln`9pmhUj|XZcb> z=&pPzA#_*1?8n{w_wkMfLCe=l2nZyGFR}4}R4rdCAt*{-?)@DK$j!fdf1KI6xNU!0 zzK0t;$iJ`o&Zw3z#<`;WyXhYp;_s$^R0y{-%o?e`qeJ|y1f|dSF`@WY?V#=F*dpA1 zL`y$S>Dfzco=LPMn)GYoMVI-5lIzTIL68fIKYD4l-{d*qgfM(p1@CioIgId%1y3@A zqQYQx(B67bQ*_3?wE6Z|{FjC94cr2&SB7P*e&UPIVT6pc-VWOeusYPCp9B9g5ua zhlKEmdB^#ip!5DHDg{k3|5Bn-@T~wNDtUgMh35ZeP{^O6QqUChx1y4t4?;Z1--=2> z+~)rd#328$GR0LEgheHne^^wq{2vnjMwtS?n&SMA1khdiheah@zf{&R|3;aj%ndI$ z|3*}D%Gb@m5tSU=o+t1scu~}%s1!8FzcW>$s1!61b&aw`r%Du+f`<5eAW+m|{wXR2 zjf(P|0`-9ni%Rw*A#B&2=2}t7htHZVQpQ;A1Wq!=*FdqJ!Tqxnyr$r#m+fqCPp2A^ z_>zGQUBh)=gu?Nj&FLj6qm!|S{X&ugW>0HVEYobhrk!WX^GWSq*;p!8mB!ht{F+h| zJa+Baun%0@!#njnRC_hS+-T;%=e^yoZd&qA<9D~Za`(%Y z4*k4s@tflZUxiTD_wEq{*wOUtz3lk}H##_<9i7pcRQP;|j4AHOjLyXADBag9tj@%j z*nGb1>z&g;VJBt;fdUNFcGRtM-$XplMl#r%!V zq?`Pg5(LQqc3ASKAP_Xg{D%Q_@88Y;@DOeVu^)rZ`lBEaG_3z8KzJT@E^H}5U=G^e zuYnDO9SQ4sQRC8K{#FD31N`J~1%W7h)+qi*ToSiBlc)vZD*h+@z?xKDuZkOs>WfcX*CM{@6Yz z!v+o8=W4XiO2MZDLHPOn)d8Ci%eFl=g!l4J1GW^F{R8{ypke!d1N?Udk?GgKcGo{l z58;;o6~g~G;6YQ&zZPJ3{AYx4%l{_fe|(U+3G3#6W+=Yfztx3s%m4er|Afu(=Y+Sr z{5OQ~i1!$HzX;3mcNY2kbgW_h^4*Dd1?M>F;_jLl`YJC{!9dpNL_#MbCxQ%Cc|#oc zWY#oDXCLk2HvLZ|{dtV()3FBi=S+l70=c{NPbMyL`BR*}j`JEs?|-XawtP+@;48}b zZu+MJ>Ms2S#0$|w=`Rf7_Wt*f^kaccN-xk8{s{aI}&v*$&s-$BL`JYPYjFQg`|Tjv zw-{Znc`*O_{G48ZjE^|^b0W|Dndzrr2*fp!CxO2L%ks$aib4;JP9FJmO1jy1*U zQ%>(L{WFP6T>ccNe^v;$Yd$)EI6Dy6#_#9#?v2B6VVS>kNc8Dg!}4eS>BzeJ8Fotd{O zChz8#ORr^b@*YZ-Xa9MSPodRvYQc*!)ski+liWDA!zp~7`_BFpUNgPUl9 zFW_LsG1eTw1-&!-tIxAt!N&gV}~J7?Yc`+HSA^P5Xf`~1wa zUs*nU-^0Ii{>cwt`}2dUwxQ03{W_ojo<-Z9McbZ5+pkYoy9#5y)v<`K)){N9u8(s} z$`X6Q2953j=Ny9g-a!z4%Ie&IN*R>+K898S*P1OFt99dUeH{CAG2Th1%n`$ko!ER* z*iEdI;MQU0!E{L5c(YHQw!K0vX&)XY#@7*JUYwRL5&-!jQBeInKre1Wtv*0jjRuCA*AP2L)@lMo?wrDE-grsBMDP7%iz#+GzV z*1YX$3g=C_n>OXHuX_0R|9N`kxyRoA)qgzt`q(I_=c6216*O3j@f)odKK0mQ@9sSf zR!e^b*Ymu3!O!YZqdGS>ccz7@F>oKQHN?5*$?9gaXBZccn02z4oX6DH;Bdqg^X~_` z8{g&6yt?>5H*9GBw+h8~`EMP<|GD#?lt1-8fmV&Yy8O2b;r6lU?z|^H_SJ~TvfTkT zXjp&Hd6=UJnKsuIgQmEA2LW`;&&}VCA>4M0)b%p`onV88>DMBEMi&TR=O75b;;Kv9 zr3`+Z32Q&*7!0EEzbE)^LD0}_{?@_I{0)W;8jX)KL|#0Pdk%s|@xOscoO=$u3Od#h zXZa5TNdBdU4dSB(H*#!+M8=QCZxEdA#4UfU0OI*+2F_=1AA`dY!}x~*=ZD(yZ-x#2 zs+3k;%L_Q-mt4XzSJm^Dw9iM zU0G}rZ;$a@LvxzHA=RW@Vso=mcEyqnZBRF5_!;dKzQ{Z!8RJQavpbsc+8*+o%WsIE zlFmTylxmJ8(1-2LBjtXMMz4ZV1sfwl>*|h2E`l}8d`}A*)di}~H-deqAo0Zi_yHd2n z@P6gDANka>r{CPDN+FEpQEpTn39Q_xdKj?SW=2)zUv5-Y{$F)eRsO~GrK6tm|Ei;^ z^4}KsS_!MBn188JwHCdyGpcH2{IY&1j7~TH(xWPIUBNb^YM|TI_z8*6Q57unMsc%3 z1u92XFXGcRM)BpiVzg4DD$`#jc&Sm9_JT@hDm`K}{t&^6)wsO@(@;6pq= z&w(rDl$!PVU^o|#c&8)p=fd*-hr+^}H*Ej>1lrXgQflC2tQ5XVaQ3?{9x-n>>Q0n{ zLb&a(HUGm5?!&dF`1uThm%l~mC%4c_k#M2+fXZ$syP1~cZ&J1M*iLdf0qB~5;*h!h2UdK;I+W}p>hzU#D^NJ)V#Cc z6Wm%yWVKKO}L{F_fCvmVs2e29N3_(TAa z3Po8~5pV0>c&i+i`6uMYck^Fqa38KU#qDbn$fe4E6!{7WM8;zTCb8A}FE+hF>LR1aAl zI3)BY&OW$wI<=l6d63e8)$1h7tg16fZno$UJ9wstmS56VD`K$*jj^ z=S0&a>U*ew0ai?DNn}utosCQeudJBgDy-I<1@}Vi`ZQi+;X*k|rZUykX7o&j!kPm$ zQ+r%zLQIBQtD2Mvfv>uOA~iIX$|Iu^$}Eo0p2ND6(?rZ-eHQo6w`y|L@tiGn259fV zY%7+^naB;f1a3z;H^gJ@WTFezR;0Ft!h2;Y<6x0QduO}hEAuaYXKnTz98({d`sHbr zsa70kV%n!BgLjKDcSNyfIeQFKnFBi`49%_#p@7@TmSN5^Cp)~lD>FNucOPHckjuzj zaq&f$*SXJu<`O!aHXVHackbJ>rmNx0Y5!PpUjL8#L_ysM%YK0deVzoIVdQl(X&Ux4m6!#JAcVnB8@s)o$8DHmAUsc9e{^ewR<^NS>eC5x6 zmi?$2?L(D+DH(qT0yn}k?)Dl{epLog{yTu~makj>tji#-E0FD=vu=!x@A>dqL;h?Z zXW^2#)ts%fAY6@q0sO?RjPJu|O>un6_z`cNp!C}@ZUrceZ)JSn!D~IwzXueKO{HXf z;%fyrGJb`RD{IJ~xXzIVgB%G|0P)qpp8=iemy+>`zaqGi@!?ma`TrdVjBhn(zQW*c z&lvj?DBHqX89y4p?SjcipfJ9b@x%Bhf>Xx#yr^;MuzZ=n&){eL;suu~d_%J{8HZ{q ziIbSNaF{jSlwA$bL4_Tb`r)lfnE}>xa_ooYh^fg-U9!P-dzX^ zzXH;fGs8Lt%T9XoOB2DbTgn+%_Q)%i%@8`9HvMG4nZr+-vf$(6D<*#9p+T4I$tHdh zY=kfjyT%IRa~)RQ=DNmh5M^^+BeTJ(Dc3b}+E7mYL6LcLU8C~vhp@p%n@xk$FXjJL zyGG?-u4`2OU$tvg{(L+tVbv7pzf{*a4S^eA8Mj>5sQk-yjhg@Bu94$0&JLkuxJAOL zGq@YUig%c#vuV>SC$xTV{^W*dZ@>SEIY*wl=H7ZxU&Nrz!lYs2+%01Lo-e=n`DYp@ z8^q=sC;OxB8Yk!6T7ZmC%l}HW z!TB5n4RwdSzr6)NFbKl0_z=MlDuW*&_^>kgaKVR{!4DRkoqW(}`eOvAZZ2pPKTPnE zK@fh$j}rXgGPvq?*;fXQ#;=t4qkgg5VT1f`;v@ z7WFq9IR5Q%8x@5ReE!y;@9F@^zVWaEWPIBGwf{UE)KbEU_MaH%if}8pcS-u3BbtWF zUl^u;0kGwg{!x~kcZ<`fZmzrZj|t&+Ua}JWS-!{SIa`m;d%i39_#&L?Q+T{z@Cm>p zfg51{iT^}!>gIxmIQyR$1g{8!@GJg?;FTqCZq)h=ILGfv29M@LF@LMUKhn$IAIBNb ziyD`X;=Kj0Hb~UCbeKNl>qkB(=Mn2sd^d?dr3B9QH3B%YXy3A}CA0Rd>vB)GKlSCrkd3*CJfzm6HD%1}`|wKku(g@Z$+pxH!v? zZ{e|h%`}jo51{3DkKlDBaPt3&@IN6R(|U|fYRlwS=&;&i9n_fF7h^JBE7TA%Gt0}x zQ(3EBtdFIPVzi+nowJ%U&H{02aF9@yPA^K>gMY2YwIQD4ehH(h3utZg`_qtSXEv8^ z4{TXOcAyALwc;Q?&MRY#Yd2EpMLd=<`!|?ls7R@djpZ_lr8?2{;-g2yj)5HuJI;%b z!SxtikHPgAT#v=|SX__A^;lew!}T~^kHhu2ao~%yl1sB@A@Lp&raBW_G7Xz7Z0Tb^ zM#j9_WITYaGE&sUd1k=_nQe$7#jYwDJ3t2)a~afL3qzjUY?PXIhu~kM@E>^d8 zR@L4|UiR!mmmTw`IlqeyL8xkiVRITvDjqhc1R9Dktf6umN=|NALk#1VaKtRS$2PNgqx{P$ zft3GORRSsha!MfO|5cSh%Ac*U5>^dcI5n)we>(s!-u<@c%FgCQx)!@l`IUt&6V{j| z>S)lKhP-^iFZ}&`F9{D;@=pyrr(L*^VP$e-F$0e4Q;M9@j31T zTdp-x6;Q4h2)};K)wI=2NRa=wtFV~us|5t5I%D-G|QvUzl)}-}UE#=Q%Bxs0J zWyq-lr&P3_7d0*&ol-Ty&-xo=Xi>P(kag0P=iE`OGk0dA5}x17d0*& z<$r+i=X2uXw*Be-A5;cc{=vq_>_O0;2c$gM$7+1!4C<7@GIUbIQ!C|QGBuBqYdcigAlJp{Zg%lf2&fg$isR5 z-<0@am7;AQw+ddYQdE`M-GU!lU~PQ7e@ZhC34R!;#VRvC-|GaYN)eaFrNjKc2#g1R zv2Q&hk5~`+Grsn}R4KaBj2+Fj|D{UN#clt?gS}XPR4EpxPyT%{&=RLgF=(`W2LcC+ zkV;YUT?HQ>j10fx`w2dw3_eQmiDmFg!7B{z=R+y~lLW8KBi5rh-rqI(pG0zn#pn`W zjr%_XIPbrz02!a+R|#HSgv(1fTO^i44U>c#h%doVKQsxiDe~ZulpNMlP+@gs(x=%S zWmZQd>XWJ1A~q$FldCB+=Tt6DWaX+RYj(`F;mi_hx8m_;q)^GvLs&J+lyp;PHn4#V z*Rf=6USpNSTROUxuBsE?yfo27O%uZxACfo+r9;#^m3VhDox!0g*>)t-0Bsx8DExLW zG(Wg#XiJzga0)LHQR7mFEoXe=$6JzUhL)_&e4N-zp**5ZU>(H_1TX%y6kR6b$>wOf zCAt_KJaA}Bx7y=coQr7Ird}QIFbcTt6<6kS8KxqwE{pRd6cRU!*td#=kiXWqj1-^T z#ao?LT@SZ1nM^O4(NI|le>`ROMpoC?;es!rw%`>h)e%Wh+3V@34$VGFsKL_pvk)<) zU7~IgO0G2KZ#WA9-&Hg3U0GT~yaT)a%v-Z;uto{Bop;*#x9m6Kg+(hbYpH)^M#TlQ zM~pZ#dhdR>JoCF3yg|1&9Je(G7jy>ZLFrLK^(diwlu%!v5{iQk2TKk*<%I5;f?J^* z7h-f!Iu+N9UrOjE|8~Lmk$C!}@s|j0g>FR)gW~0aM+=bgY5ZFRA5sRtSMdEx;M`~O zDCiMbBXn050xAEeLE`-lEkMSn_zQwtp}P=B@mB=5LU$PdcfqaDUBI_!G+z|&YE0wH z2Ut;Ql>s;1nT;1NbLq~ew!-DIbh=%_B~mj3Lzx{qV@t!dL~05Lz?m%^K)v?Z(%_{X zZOlRkq=`goE(5?xq)wvmBy*c)K-k`U|BF|CG~?K-u6*sI=O>LhqWwEJPI&U>^uq(+ z?f=kUM*U;QSS6+L7hzdRJp)3|fY37_e0>7~J46l$eAdi>P}Cvvc+R=N_|l{q5PV#S z!7R~vX_5m%q(V{hbYGg}fWUOr5Ql~>e>^k?1Q)j-4W|~2=|>sSr(;cV`a?kOE`1IN zE`K+D4hSx8(_acY(>DWxj|(xy>2pBnE`1INE`K+D4hSx8)4v#Wrf;+`J}$%*r%x?R zcj;3Lqr6w?^K9>jBb9 z=PCsaG{rv0B6Hyz*Eqb<&8@F*g^-(D5oH0fpnAi)8fB|-<`~GlFpP^wj21q&ne}z$ z-!By3<=;Pq|8vKRDSzIpn?IL-sTEPmTG05L^4*5l_8~mtO#!U|mb`a>4H~3x8nWIWSADv>Kf5C8=UK3Q@PLf@ppd^^5e?!lf4d^; z;@m$l3~_l^c11LZ+xEv%m~F!}XV1lX0LTTv*nZ85XaNqD?`{a^t)pX2u`C;25$$b` zvOi6p53?fbYiyR4`zZ*nh`O?x`zZ)^RP0dH@KX>$S(&o9i`xTER)Eg?qbwe{{m}iH zj%pnPSyOy}tmmL1&i1MI7bWP^v8MR`hJf7N{e@+5_x|>0eBsR>?O$$(zYpwC5(9>K zEpqf@&={|ja)$UX1wW8+E9h9m`0S|P#wGa|D`$v*2%IaLEMK-m_x|1Ild`yryU!R{aRx9Q^$43oZD5%o1T!@B8@Vf>09?xxQbQJ24)K37Ct+_vvtAoBjril`st@0LGT zM7w)_4=+SDzT)<6Rz&?mpyKvzRzxd;xcmIt6;T%tmM>RCi|>#1%NH1Vf5$MY@6$D= zxc@&E)JTPILHf~t*nYKsDfGDgvpd(DP=xnJ=n+VpFX1r#iRA3lv4;IW+y6|#D@gX~ zScCMP_E$-=Z!x-Tzrp-XDnQ0ZJlOuLNc9b59QJ>~_Fqk^Zy@8K{W|GS2GwnU_ERNV zK2wMnqQl?cY5!A0cwcWGBC!3l@0}KiOD~@vzT^`}7>;i>A>5{~}W}YKgU1xWiV0W(qa77D3K+=``~(pL88W`qc~p@B7VF&oEDA8oxTzHL9;F~Rm#PuQnpO>z679OB|``AryYDQ-VT z8{^<^`Lq)gMVS|O{K^&}<0H-&098K9k?I@BIIKU855JQ1J4y8oWSnC8WHG32 z{kZbU65@sErhJ3rH+8};Zqt8L((htipN=)f=`RDhyY$Z>E^+z8`U|FiW)Yr0SY*pJ z3Vg#To}n_q`ryecR-x}qv?OpCuQ?`*$MWLr5$@|r#EqIYhNDxCi+3$aXPS9klUiIv z(RZ_S+tFmROQj~2ao^^`wVH7*`8;v#-*wzXc(WOwDPB_#w}l$ zKZlDTuA56aM6qrL!GfJ}>5xBFdF;Z7TUE_E_^i?RJ}!wv?>sf=dsy)+RI{m3DnzO$Qjwck& zgQ6+>OBaur^LXn)XMbn=OL)ZSc*cHS`%5>z9naX$QJ!Fb>Ed>q#6r+H^)UUVj|(y2 z@2G~z#}&QZ`->8nxcn);zab$!;&D32@sjt)aXDy;?{9yAZvNf-8ydoKehX;dgeCv5 zYTI4IJTMgB<$q8JxBR~?{Dq|6Qx!D`xZGBI8+&S2kuJe!>q%M@7EV3UWrYcqNb^2Q!{+_jIt zbpN)`@7{9j1ADdi`+Y<0{JVzSvU6hI$!oT5JNpW@;_>EAdq$6op!m#)G|wm0eR|y1 zSx(y4r~9i)+uD2Z38{ot!`4e_TltrgwpRgHX_3-)v9w5O_&79q_D)vXR_?r4JpH); zp3&p$89lbB_h2=d=Xpo(zWR9NguUkPacb8azqsbY-`-tw{ksQ^yn2_KT^n=TesR&w zRUB2QG-liFkp_F7=bq>J>v^8pUs8L)v6KC2SQ@l=jo^0nj0-Va)F0qD`y7t7 zO`Uj=5GUj72B?dez@|-~OceYRbQyR!#YTRjr!xFE`FB|5D>T z75M+k4N$95qqS1DtgE15{SxQG8_S+rwV+Xa5s1XCR;>_1+dUT^i0@c{j8AbkL*iDe zRtV&tCB9`RpfuZ0d`!tC%qC~((fP59{AD9gLQA9|A$u(nq$=Is2#RMQyqjyUn7ajZ zHf_4S>4eMr{A1fEf7(&<vs;BoYm_5qIQ4x&8Q)coPz;VZ@m=Kzl`C%fxym25GZ(k_ z$CFN&|0ry!`yVa%kTUpO!L4$|H=*e0{dWpZD_$dx#UAZFG@ ztV=Q7Z)+Xd9Z6*bgy&}O>XoFr+!Ix6QS*iVp7$;40Z#0&LZ zrKw<1+0l{g;unSN*Ox%4MXwyo%!wz{O<2~Pl*D##d+H@t7aJ2vtk6!eE1W0BGAST9 zR9`;NG%bcNNW@av7JNQvS^`I0W}4dgUW++H02$|sY>wwFG{o9FctYsR4%}#BnSH;% zeZg_@c!%CK63fMBrf@U?&l~`g6Y)W%xP0k)PAu6O&lXVDkeQV2|-nL`uiO>K5@+NcUjpv6hW_sMdkKP%6gP6JxUgIot%7p9V+_O z;N9J%jQCVMhkanpD1u)#?1hP+1Ojo6B0-~g3y8!yiUf_~SrCbH6bTyQ9L3H7k@p`Z z=+m*LcoZ7~a->2)`XLu$1kLY`yp7qN~zc`x*pZv3@{z3{zzn<(eTSe@S7n6C@i|*`=`qKq_AJef@ z#U)+0uf6)CY0W?1aQ}6e-*)x(x4fLY!O0?f+2tU82bOcKA+SNCb4gul zvAw9D52AB9raJ)E_M$;N;@uDWdRX!w3L7-V{HaQE=MwHx&VeD^?m>MXbdC~S=nR_T zQG#>ApeY_Dh6h3TiNAwijuOoOh!Ae~7;E`(gNd7e`;liYpOGQlj-neuXZ;@x8#Fpf zaxO=lswVt>1h$6#G`acFfe0Q_QDoWrrt5 z>A>vE?QZbO0I-}d0*KhZ6p!Hz2Rj1Dwj$>Gi6tL3qL}tx`_%zGN;3?!Wvd~q z3~KpV8NJBNr(;dAgwvbk3X9P#mT*|%K|>s$VKVbzN;rLkApBYxJHgMm;nff;;jj_$ zo{LvQ8k%r?KSxl$nW4Y@SUvTG9sPNDn%3;Bb4g6K30)x425RVk#7x-labG!H* zU}EFo3iugTZ}S78*Gbq{2KF~lg)qEE!v0F=uL*q>=q!p?g}zi0IukS&!LNnBQRvN} z@z$$)on`nhlnh)58okv*e^2PQfyUyREcE44?rTBY3U-Rnr!g@Y3PxMQPM`Ud3F!-6 z`5!0r0n7x9@~;*88lfxy8A5MkCSa8RqBXq?=T$<#6d1Fd6#8gp4o3O63;i{rEB}xI5i=$h`i zZ&#W-8ZDif@;^`LYlW`-&lmba>D-k61wtPzotpAroStY(pibyoZcBvzme7^|QlVcG zHN}&kAayC9A(pQEM>Oon9>BXq=tJS>!rdW4UnBHcpluI3O6UXj!v)MLST59!6Z)M( zZw3uj;O%hBt&HXk+@G%JY55Ek`bwc|{s#%Yf*FC)^4U@78-=d<_tw8>_>VrohCdfS zePAO(Un}%`K;wd7FQK;`hzl5f?!I~SBh0S%p3pU)-x7MqK|~Af^J<|F9%kw5@xyLz zh0xy;y5=*w!>zk8)lW_GQhk?}mCuMzqqpz*#wxo#KpBzDM5PuuyYLbsp7ER_Fe zLcdcwaxI6?g}#sl0HfvbqwCBzTW_V%wSIpr^yuL>{B8JQejXJ12BB;Ht`++7BW!r( zf5OYP=1Jcmbj^Rg(B~fM@^28jca)_o|5?gM=*s_xs}78skVo6_n*aNReu>aE|Mv@h z^f4~~2ZX*+=*mCw@EG&tjy~3g@5E0Z*wci5r_eWm#`5v^dB%kA7>^5>p|FEtzjfP3 zhQ3nh{{|ZQTrKor6L0~e`CK9N7lp3%c#Y66nP|gnKD{gVH$BEWp|1u^{t=cbbXE*gznF9!_N}>=;JM2%WbyM z-xIo)+o+o>P0tpcX~Un3ALeJY(C-v_8)$r>#|V939WG$>zM9^D!1Q>_g|7K*7JBpq z8(zylF7ypT*L=1J-LJRdHJ_7Ce}`UgtxL72>o5qC<^6-zUE|Hz-WDS3Vrl^OTPd= zQP{=5xXYxwR_It7G~@CI@zu6RU5G$1TK*pj{gQ=-oG<^6gg!cE>3Y8(3;jKz>-`?~ z>LSxaMjLH-<$t))?-crNfcab;A@sT?8-6{0SieUKeQ>j-EC26K_>19RCv;kA5D z5c)Jea4?$x2cCYmg4e##mH&@~J|ID~(Efic^ff|X4~*sWpwO3|#?S@+W5-`x$?G*j zf2EIIWVm3b1FA{CBu&@zw728$*9iSKU@ZTv(C6kD zy0CDPQ$C%RuH`>$@gt^Zn=5qXKV0bV30?V*5c=}PmXFr&H-tWIiOav&;L)Zh^o6ec zdkcNwQX5|R_YwM9p|1zb`t7THx?KL(T>ewjbFLM-wx4T-Ua`#Of1S|Z6T0SqrO;QM z;qrfK$?JyyYeH8!XM@n&SWz&V|6d4w;8~Wg{GS&32BB;Dzkcbfwr4)uhUXWlcZAoE ztv5aJ8sF0OzRnf;k>^^vrhA^y-x9i(+xbGj^E?|~)4lqMz2}kgme93cRtUZ0e3$<< zLLYpArR#lNEA$tIuKb(N{>1dy1DJ6beZJyC_l2(QJT>@L+ml~p!?T$Bz@~-n3thwC z_2(a)VnSYQ!)v|VE%fC=zYQ>-i+hBABp+xP&Hwj>{(;an|Bs$^jf1S_=UvBBjf5Nxc8~$}d|2AOW??j=0AoPu(G5-}pfA0!h!05PK zDRl2jOV@FElF-|(vUJT)mC&QhEnV|-Y}ZW-NSP~i9UsRFebv=A{80RC2RlLN8-&hm z9RNE?`EbC2VdLH&wo2%0guV*29bkX7ZU2S%@#?OjTPWur3;ivjYdJqC^h>U_;q|`O z3ccbwOV|7A|4e!zDNBW}^*BK216JDb%6}`NuMxWP-&*Kx*W2*Q|FQ?}SV+n$p=&$5 zTe6+(Ya=*s`!gueVn8(#U}_}Rb5NZBBC?FViWdfiPf|8EO@qtMp_X8(D! z(ATk{!6^Tqb?k2>jg3P8Ca^xRPY8Ya%?w@W-_{HL$XhI(gU5leKNtEXLVpo7ru(GO z=dQv9jHWwehr>;}%U2n)r{%Vv(4(s@UCV8Mp>GhnmfKLF``@wQmH**wILjDjt%JTe{|Fm&?8|`I#nkeO`7I`fEbh``u0G{yi@L!9qXs`!4@TWMiC^4xulF ze;Dkw726sK?LDDuy4MMP>Aj3qXoo9>9{qu(ug4GD+x5yv=z3q1cRJqikFK%dwY^Od z`Wm6@eN7em+#lNTT5i*XKJY$ESN^?^>(@@oG@)z$`w0Ctp)3EsLig`?`S%n0kq@~1 zx7oOx;ol+j`Ms^2u&vNve9(p;il6Ohg}zbfNzjJF?jZCw-VjU&>^ER{6#9EYUj-Wb^S&ScD1{&IlAq8m^ymGAKKNlv*K+7D^mRhlavmV` zrH|O~TF%qv3^Wq&8lmg+SR?c!A9eXp7y4U5SN_KdedS{={|_(2#~)x`6uR>NNa%AP zclm!TbZ?!dEB{Y~zEuvZ~@G}zji?^>@Ldx==(=F8FmqL#|Y3Z8J zzX^SV(6t=?E_8Er5~656kGcGgW#q8-Da%L8;aH(h+hFN$;fMX+c%cvbg{3S12||BM z=*oZ1Q|GY@_Xa<0!z=$E3jI!@YyR&OdfhWF|NDhL;8{yo{>Kda?b)PM2wnLfEA$tI zuKdRfed%*9{|Q1L{k+ScOSLfPv{+$E^gIzlI+N zzxT=+H@tJuvMJZDioA8&t{0p>nS}uHwC|5*T=>0dgZx(yyZWOKM&4to|7Yp8`#jt0 z-5Ga|Kjz{-6aVyrrG9$Qz&&1?x2bk{^}o*>^~A*eEp_3P8{5WRH)YcK*QMv4T>HJd zE%m6`^FO}km(|zYd*BCGeDm!eoNlRit^DhN*7egTeQWDIW>4Js&~!_^iXkvd7=L3sZ|#pcHGlH`FIlLY?ybywdZC3_{{^=4}YAEo&9mg zCQE&8=*8>z&23wI=S8De{2+G8^_IGB#`?%k``lV{|DvWo6`#G{YN<2Fj(KG4n!P4p zwxUnsj)vi1SZY`6_A9)u>7#DCd(LwYj`*Q(sh^Df=_hBjO{}^7$6H99ye#uk9R-rjr*$yE^iq8={1%*p?_+` z?`kJsb;XhW&)ao<+gX;n_{+ObTe98pEBx2T?zO|lIXhaaDIz#*Txx0)jd=g4YgDc? zmO3pFk2YiTTxT*D#VIZ6&P)>ya`gT^mCBubcg-m`{Pwi-9-23InPoQT^TuHZ_MO^t z*&k|u`CzhX2TT39Y1zB?KQZI)m+kTBV_$a7A8e^luX}0eEqhd-dgIO8>^*0zQ`TB) z;`A?8EIhjMqg$Uo=&3!QeBcI4ZN2TK+?l_q?seOVj~#Wx6|dj`5t`4&ytmh*_f1{> zldES9UAb*WFTZ!+W3HaE z?Cuv=PCE3_9X_$tpS}6=HxI6#{`-sfyKnA4GL!#esf~Ajy5KK6RUd!XqKZ$a{QT+X zEVb9oNAI-mx+zzF@4an){_a67Kd{v3qW4d(e!S}2xBPYZo0skK^5K^H_9G@g{qEbpT;A|goDNm zn85Hmo?kKk=h4yQhtJ;ubl>n`R>yDs>j|el^2vl9&yN}!NI@gCii#j{H(U(j1WJsL zU*^a1HJ-eqYf5FBnQLl`$Ba|eEPW^hh1Du8l)>-yQy|NBj40J@xRJS_g=+4z>a{{8MOPDiH)`9m{x& zjpol~#5Nc-+9r$X!7yLVujy;~uniWM&wHrg9RknZe>Wv6$siL876s{Xr9*S&pj-`ws%zR&u;?mks@s?Mp?r>m;#amvQoD$v&R4hMOr zcRt@~Qc^#-HV|pJ?hi261_I7oKe%oYw45uGLG;eGOu5F&r87{3E56M1gM5E_-!?f=Q0z#oSiELnxpXWnFBofDQd~3_V*_@$!`jFquPgxCK3q#W-nc{RaT&>b zZo7DckKgj@BA(Lb7q)CZdWXEzs88j?TQ)znoj8D@kxk+1@1{~vLN0KmZGE^~tR}On z6lq2pIgSWUm309aktuiYng5A9jyh~`#)27Z$E|Gsz^`;UfsL}_Nm_n65yx^$nTxud zh-2BLJQ8QiOxTvq;#4T7q#jX{TSObMb>-zm_y{q>lvK{W3*PzqGv-`#`dO{RR($%e zKQ!hx=@jVq8D?zOp-vJH#&_VF<$AMR?tO|!oGs^T<-5}F^M#^Vg5Pe-`9kro&6^{5 zNyo+r9u|}$*yaVfTv=S&(ebEFdu8$7%|A2nl8y~U(IY;sd2TAWJUbN5F#_`)92&t0qYeUwn>gY2!jg_l3@yOm2Rs7~ zf)xs0r}(k>C>QZ9yi&?|LRglIi=?%rV`Lj;XyI?0vM=cvF5woImB%7yD?{Kk1xrJD z{#ImVVc>&j&|1EY+b!3W3jwUIMMs%cyhl&|0 z{8JfMVqN9Zze-wu{|k_w@y(J;#C;sK48{4w5ngrV;ENB(1FRrWD7 z6;+ae(1AYqc%A&6y*@lwz|~eR|Ko)I8^bi9&QTJUZ=5Mfh#;l&lqRZpDN_;Ct;gMn?HR_;xrb-+BvXt!=}YK1c%Wgl+z4x6$t8Un2!S(YD4rSo^` zfDfN-=X^ZhPr7{88}H-WcXz6+liL;iP})f6e=zu8|VDM7R-(kLW zn|_*!hrTkuQSz-he6-`QkrLavslc@BR{QZz$BBQEZg4 z(l0dc66rg_^e+m&ba{<`lvqH7-syPccd}5k_?@QyL3~$mvf&^43;vgz{C5TaBly}6 z{>De~4;lU@DnE4C#@qamR;LGl(9h)|J$!*W9{i!rCVkXyh<{LIH!66-)ECwddG0du zg8wTazm)eAp&#Q1HvV-cJ?eg)9{gB8;vX_Kf93oTzsuBTC@<-u4)onkzx?R<-~Dv% zhc9~jFRy-X>A*ifCmFK8qH$5P;~Ta$yse4sch7#A>AQseGTUE4dfNu0y)U)eHu4y0 z&wm!e9n#K!&%i;jN#Sf2m~E0*|Pc20^4|(=LW&)2=lzM$b8W6Asn{T zrk|)`#KR#^3z3IQgw_cm-HW6Aw`^V+<%vEA(y;FW9&CSQoxx|{g*d=ReL4&Q;zpEM zJK8XOJ4c#2$9{Lf8y$=iEE|vaK0@j-*M5&EAq)<IB+85F z(I&qt>|x+rgZ{%I9`F&SE=3D&c?W&)!}wVLB^XiC>A@d*M@L6JU9ow zzA4&-!(#l|J^3MK}B+3~!ZZLH1C$$pbK5 z0YLrp603_cHX_$1Nsp&?@v#^kQwyeixu+NS+^-9mdwTI+pwW1mjrQ`ycbnx{6ZacS zwk3C!l?}2q7xanGOGHZesE7V zkh$L)F!y912>sxGaUolBS33PjGoK-OBHM=bgM1!r`r-3!3n^LpI02S5g)&6+F(Imw66k~Hdp|o{E%gP|KL!XHW_K^akLK;Pm@j#+`Ctv zmNGN>?2vf5eq6Ly!0$eutcH(#LLP8w+T&+`eqrl|Qc2bc`sJ~CFfZL6W89G8d9=rV zIV>mkjxkcK`Vdy=qr0-FiVrx@kI* zz_rq0(?T8e&hE!KIl|{fVLFT%YnMPTN{8~H+$T<(I?cM4nKMtCbxO+eM)}lP-Y6Z) zi+c4$Pf(g~jFpD(W!@S&#-iAFL2viq{GPs{sq1RVxJugf4Wzv|DJ|C!qW`q2b5R#8 zkV3DYx#I8ke(KTY$bTLvpBI|WXwBv+KXzK|u?KJ_WO(*te(5Kpc z?Wgx%b;b0|$1`Z33Ur;*^~C3QEMNZG0x!tdj;#d&_eLQd_rCz9O(ej24H@@NBAj+? z0CVp)VD19~tQ_k~^L%p59ghdw&)nI_7zxXb^1#*GKVmwY+TIz4`PjV1M|{3D{c5nE z4)bDuzXbDXpNVPGHF)u@d}=x;E4*J zq~JFx_{|E&ZzS^ES7s9{(#Qf-jpK*Bl@f%8k z36nKKb^W7(9n^b^(CdJ+kx$ZxEGz3bNW`7prxXu^k9p}Bz9Yoh`UK^0 z^U3vo8$REfRuW7eXj2k+v=<4OHYEXrPv`}DnrZ%5E0r1fBstoXmzN4{z67rZb7dTct3@BaZ#VI9`3c`+PJ1YEMg7=!dqZflGVTfN8TDFzs3! zSZ=U+^7OX5ci-`a-M4*s&!_Ht=Hs{Rz5Uv~SN(&8SJNHD#mgxHXU9m22SkmPY`+JFTX?LGn4>wjoB4B@n?2$*(O0n8^S(2f$J8fqGjpwiOCLf6jgl3&PLWVkYDOtz3sN*EdrU>2@;~`)>&5jPZu8}w)zxh zQ4{d_u9-j(nnEO=-2*Sr_W=z4u#fG%-D|sh-`BOaJ11LapvCisC@bu%^T##bDq)*; zz6a>W(dIJ!X`ZAL$My9QeqM3RMtuA}dG-MS^B=$~&!hs(^V0zHtTVv6PT(0S zujFwkUoL+dhpIjfrN3dk@3hXBbG_{*^;XkkSf1lhKHr*t63lOhXBz^K=N|&*8Hs>- z&LLow2kR9ViaFxuc3Eg7man0Y@P}UUl{?CzJSI7W=Qq}yR;NS19sMzFqZ;|KKmUZl zhyLI*r%F3pls^u+=C_4yL_t~u@t4AX_@mn7zf1hSv+c88A3MMO$#4C4+b}^nd)p$U zebfwk$jwg$-ICca+~sO6o_opzvR9@)$8!Gg-p@tj43{20fIg+z?S5S7U%$iaKU5%a ztdwj29O;{4NETS9;QxnMnFioVF35LN!OrVGC-4JCR>I?Uxg;F?9#WAXj9*|6?awcG z0+g@5`iAT9wbg^#*?MKVhQ)Zqb&fhPSkUrY? zlC)o^R=TwNb!z2<^5Y$*lv~7i(taIHugadAiu-j^rmeVNCuQ1-`*o0(`?InBoBMU3 zcTaD7c;DwX?Ech4yKlQ!yphvsP$#bHJg4h|#X|#PrroT4f7d`yci;IDdKrK^K<9zF z0!VKU&%Lh{H?>M!i;Amv-w^+!bl;HY%z`J~mx8XC|EQeob4Taof^g(?|JMYDbxL5) zBp{mZ*E39>5iVeRy%kKQ-v^{A$V&Yvug+ zfjIO9=JyZuT-+~*Q1sfmZb|pRP|vciUbGF1*POSiM<&<+%RZrH-GZa~Iq=lwe7-P_ z?DM5FB#$~Q4NN+5TI-nItS^r6vua<+C+Qz7?TgR1lW{Uc{oq;bz~njWfO!@>;7C7mvdh48;z7$fUq32; zCzaQ?YFv}g4#`)p9~bQvP#rX{z604{okKhV8_KT|?ai zJ+km&@`Ap>AymjyjJ5o!30Xj1_+RUsw{XGY#S6|@6yi~i?1wWs+9uRToo#DYtzOu* zn&I}zcWZqZ7w(+fJ=E1>8U=+K$3q<-;uU+(>ps7~M!w)7#K-nOl`p`=yzTbe8hPU% zr*qz_p20y`KT-qN$N_^rvRNq3M4SiwpLZ@4IrR4SEPHov|KMO*#$|k?-R(SM*|Od> zU?iTqUq;M%I^5cMn=+o+H6Z+Stt&&1^A5_e7;b13dsnaMI;VSZ=#}0@CjX5 zEFFSw1eIFNdv9Me)W6(dwPHv zMwygajZT>Go<7-04MtjFL&f5*7lyH?T1080O0A|mW^vG}uGOpYmkJm1!gpoDtUb%l zh5hH7;z^jvH+nbnliS^Q!O#kop0br78Bd#y%@3W6SM~P~tpIP>TDE4OyM0AhU!UzR zNjzlSxp;N=vNgS31JUMiFdOo;cwm{6PpK9CtiH$JmuUT6#{lw{=LJHqu*89>wq-c^h@y4ChCOqI-< z4{J`FWr%lR_b;#2CmU%lgOrno7DS-;?!m!0~Jj&4cFgjd;j z80i4tm*B?s1;QV?2v_`}zBF#9mVAWAL<{*8;CiuB{_Ax!-+ z`}etXf8S--?78Kh%*W!t=IED%_we%dWL7Z1U}Y zZkg-QDiO*>L!9`&@=_bWo z0=+0*+I17P@~N}D5&fif6PjMV>n2jBt+;L?W!j4CCXlw0ol}g%SUab&S5xLe`g+$Y zAQRSWdhhgQT|1YMfZl5i-NJZDUi&CZiZ1D=?I-E|@bR>$4|!#??wfqFK1tB5BqyXpFH_`!|_Wz`QCt==0EJ?x9oi^ zi~lh4N%~o~gL(dk`FuMWCqpb__Xl5iKd}&o@p>6r>{@oAm;)C$kMY;@6;0BHKK%5v zw|;r)?(66L*BRGh->j||BDB)DZ%&9j`vI`r{l|X)FPI!*n8(p<99+N|i455Im$ z(ud0X^N|bXiRY$b7Iv1%C*OCy^#jwnGFI0e;G^wAS>kC~HWOL%=JQ=Mfgn&%{^^og zA0YmA1wR_X726T%;O0?pJfi56C-w{46(h2W`7Qt~^b`xX+B=ytc`Fvnr=vyQb}A z>a%1fhUEmU@pAFszgfY@D;SMAaV9Ewl7io);5RE6Q)^5sU~1>f1$|&&E|f*;Ok;@9 zEq7J3I}f~S@f%8k$?N5`ORvA-STSpOd^tm=zMSJ(IGL5Vc@~qpoaa6>pKr}0<|8m> z@x#^aM~s@h@@TC8sdRo$rE#TN>DEhLC?CE_?P{gtI7`b6ohp&fXnZDVTq%KGly04n zLAh(4pHnNJI?Ef;XLN;*9p&mZ1ZoAe?7*MxE}}O zMSC`0v**Sy?Y?~LzUx2R`Se2%?Y-~e-JjVaeu>jg=Yergy*~%->%6}1RgiU(!*{9k z;JUy$>u>8sno4o)RpQ!I9LKzL9>{Zchy!?k-DzPStP`MumxiA&^rSpr+6TfDt~BRBoKwkm@*l^HUTVn7ZJUB03}MIu?wPev>HJx-K>#isp4p5~kAUyK5b6fsyA7{AFBXKl5j_RDP-t|Y zCi&z$#k(u-M_9h>UGp60n^??CuTRAKWID9>ljX8{;*WP$&XZ}Ao_;x!@N_uo>oc&v zx_aU=;(SHHI~9!bp}+NRIkFzh-t*|MJf`T8pS1c@*@mS5-Zt%!I!3Pf?Xde{^R8d^ z%PBt`D2m3 z{F{QmtKjd1F#m7eeAhcN|4zTH=(>_g?h_2)KSf>&;w zKCe;lY1ijCrJ3()8N9t=yNWC~b*a*P7uHbf@jw*f52~Dc|G_*}PJRBQ-lNZRsb0zR zUA|oYG~ZR-uA=^ijgqIl`Et&(Ka%Hsm(O>a;t|l)!``UqJI>?!8R=T|zhp5J{;MDxeTCUJwvUy3Qa|(R z-!%)jq{07kb}Sff3*^fvEM|>|Uyd5+CYpMq&nKHdcF{_v<#}H4gU18$KR!>Od3nSZq>^<>29qs01x zb)ytKGKAURhki%%StsQ)jyPP=Cr|D@+mJ@)J(n-PIg|B~-(fS(v^g*8ZSJEzl zUX*T~AS0bWYFaB@o#l(@p?tOIVeGe_bwHZeDrqaO14@~;;yNIttz?%Ma}Th~d*=-T zD5vrLH9trrmSNU+52yqRgv^kh=Qne`5BGvVM|J*;Km50^Gj(01xFf5?y}C-=(JGE> zg}|z&0e_?COCyglAuX1_aL!c-4rCch&^+rb1SdLc!#pv%VuYp#gxARBkC#gQT#!0h z?3!;!J6sTyBHkZuDnkzZRt3yl4#*RGU&{FkiXs)cFkciDXv18#hy_1e_1Gczzj&fq z<4v7GJEzxLO+ljP@0Po*4+y_ah3l~xlwa)Gn9Gi_m0InXcXL5<5~$lJx40~E(-lK=Njoh z$T@#)S*(X4pDg3S(tq&zc2Z4-P&PPyrt;}aj>6VF5Q9u50*GrLp{GWnf z3SsI;>_1h08}evpUR3m50pfbnSUWR5lXaKmGY>t<^FP(++sQZ?vVE=ie)~^+=aXxZ zg1Uh@u4oKH;H-7y){vfLU2<1kFJ{l4J%^XznDyj%YP)lKExNXYpvP+TzSiD*o6t2h zPM^c6`)2z4(QBCXxw_0lp1RHg9DH`($o59-Ey{=b_*%)=@6Y1Gz7h zD@R-pljf21x&W7!5b}^Kqj@CqNqvAUeSIKh|M_yxBl&#$yjAj3PxM-XIal9_At2*U z3t`q(&=VOn*>~0bc2{xMbrp!7s^}Xg%q^}b=6y$F+_o+Sn(puDzOkO?(Q}eouhQBE zvpnIy*8JPDPO`x%?krz={R;Iv{3l>KO{!8D;}MrdKicP;`B!^VzwZ0mrGG=bFDm$c z1%uB6Q4ig#Xp$$ZPtKQA4{4op*o3mJhsY=2?ZHwH`FvA4)t=Oo*^__tLE_C(@M#J@ zPRMav{de01VO@}SoVKXujj O&tZ7;k)OeEZ}9(ncT-#d literal 189733 zcmeIb>2ln z57~dpeEO~`DkG5mH`O>PF_r|Lj4zpbi2lQ+}rlUZ5H@jt6#dj0w! zbiMi4t;g?Vb#*n&*W%QO@C5JN7wjAHIibC zl9y94#s~y7x5IDE?KdL~wd?4+$HT0Wqv_?JKU=McOe-R81)4Q)g?Z`C|DK6yJ#M|| zx`BDs_4r-a_m{l=c3jU!MeAiJ;NCj{UQyk5d{ndW>5I{n`>i`|nxqFuQ|;v}n~p_3 zt#0L|n%vg60?)KFh%v(IQ<2x|CB`JHf4mn{wJa9t{hb)pm(#HvT@f8RN1>k2ff&pA zZ8OPq^IR12@jqKWwASWP$e^t7)3tn6o)HOED}XBDlM&X4R||NUV4 z^9FC5<#{GcF&j)j$#Q_DkJYWmN|V9D!%uQj4`x&hwBjYIYx7r6Fm<^E+tA&cKUkQT z)7fNN59bAzbaaMKG`)|VFm&QH4K%%fnaEF~s06-dX87Z{&Ztw&?c6Xv_?!Rg4_fU* zar3ZMX?V!ni+|SRKg&V=-CksGFYHQ}vPoh=w8r$fT;^hcCeql@%?mK;F^2rZYo{DGTnnnT+|DG{L^FcnuXko({z15_<`H<#>S^isKJ7b9z{gKfD(| z!0V?px%0lC*2A0Q4{v_l)FX6%)%`OyqVvk${7_5X&`7iQ%?o@KMS)>_eZVc}VfiS= zVkoi3F@OyfswG3+;8GJB>p4--BeQa;y<<7i+a*unc{LJ)w_0gj^YVNJwLZwbd0+jI#k`Gto9>*5{7-CH^PYeF`sq>(Z%8PZe;zmW zn5sw8eBbAa_#J)_s_lb@0Z$rkV3oE=xK(58MXM0{C&5Z{`LV7>V0^m!PC%T;e5M&R zJrCB$um{!^q?ga&cU{V$j#-a+G0vx@Q@|!sJklRsQStoY(rV|AJC$1fet&VTxCd3bC6YeIHPt#P)s#R>>F4~>C18Ehc7Fr|PeDZjTZF=&thKzx|;Ig_J z3jVa-@w#;`d12m&4ZlE*;f@g}7*9WsMKwa#wB*Sv%D#IhCy;N2-m&Zlrr&BMtIflr z$M@I}E35=sro^Mnf;S&Jo=hYbVVf(=i!_|GRf0vuG&=ZO@aiAp_Pv~3H%0M{B~msG z%LhYYXkGGuqu1qt_oJzAeYM zl4_k`cb?!lM7*rPR-j81GMin|iHUxO->kFJ@SB<1#j_Aoz`@_5IE>vCyWd-EG5W~0 z=J+-Ic3O|oBPN8?#etV3&2cC#WF(^?&caNjK@o~HFGS=eX_kgb zDB{1P?gP6$SM{KHkF)Z^N5a^N6EBXE)bYX~bX>prNEF7U7bRZg;gk|Ykw`+B2W}B( zdE`f>v-pv5RTwcC--lj96R*uZfBaDmt0{?}KVBak;s}bvyjmQ8wH~+_bv*HuYx(jlB*+^Xr3u{||NJ+?+Vtb7z|W zW;T%H6E#bi-#~cY}uGh zi0R-zm~609nmqACU#IxNH8CeTVYU|{&(Fc%;?Q^8An^A`v@ktVil618g(BNo;%Al?KPYFFw{}Q`BG84Rp zLu$F^ZVu@}Xo28@wQcd`O;{x{;Nww#U5_C{7-l+er>@LA7vS&28G;HAHvLs-&k&Hb859e&+R%SK&tH>M``>$w`V}tmy5~tvlw5I zu0e0?=4PX_RK%l~fF*Ajz5aVK`IGEts8}(u56a?4=NWl=Ek-yB=>sfOb!63>z;H4> z6@!7Y1nP6GzGNxl@@8C3QC(MxAiV;&5HhnmIv-DNz_a)+v_?45!!!eRif#ZRtUQDL}Vuey&HCp!Xb1(6KM0YHDk9 zn!}psc@6nTuTBLd*NHaZp_O{Tmf1p|>M*|IwAQA7QVObl;Ra?ToP3pHqv@f0@V7Kd zgTx8E{gDPtkJKKsTpBPX)+icG31dp?i!{JJ?~62G+Ur^S=cAsKtX)(y!!1e!J~WO# zWU~Dh26$ccMHpyP*o!cL9q~mNc(^cN$SLfNFwmy|JB0yg6cRrTeRqGP0q&C8WR{Bq zTx5;@fQ#_KRjUWI+s+!x!+-tPEOE}y{xwV8({ucN3cc@t-IcC@`#@f3y-*f#gY7N# zk>vw8ui^CU9N}N3El>(066jazQ#aNYq^aY2j+5Hb&Th2@fqMi`HuU!}cH<+@&~`^- zfJsng@UIrrHqjaI%=vwh6S%>K)LsOIoeBz`>$hx$e(6Ud4kT1Ac@Y$)NQ7HtGRw*| z&O@@}wQPkw);2I52ECCmxW#7W+%01Ga5%^R;U0+?rb}zA3m|CK>x6jd3Ms@CX*)OE zDPmj<;mWWxk%D{P8KTcN@X zpJ4}E5hi$H^hTIy6WNO}@vMXikvq9p1YVg6SixnOr83Q&!i~bzDZ(V%BVoeOVbULA zqP=o95GIn)54|+rCt*T&X|1F{MIa)t6DD*msZp(OsISZNl1;91)hW=eWZ4iZm?CJaEz= zNa=6S&r9EjeW|6I-zbb{4;>@V>(Nw&`+*OVev?4yF6joGkM&zFc}c1};)lL7kHsHUR|-r(`(RR`W4d+n z^R28A`#vUXsd@WTm0#<)1G0%y(RcN@`U@=)gAccIOyCIf(!hy9)ZDTsgf?<{BXYz! zuuG?|mV@Y&U#4rwIqi=)(q4dfiz7)GhmH>)Y{c?ZH#Z1Ow8HZ+#G5&qrf%x`o*SeX zu^@tc3P>8cu_%Moi3GmlmA(*p?8SNJMtOipxP^!`IL)q#9R<4&(!gk1*i#RYSqYX4;-g)xk_YTu*08JC ztbB&B?9sHD3l7+NGm_&g61(hDe3KaJwZfqKP?icuz&V1wRK>R%=qY$^&~-fqnp6v$ z$N~5f*d`F2<|s%iXuvs2mC>t^i1d2{6s&xDHXEC$L_!EVIIteI>I@MyqUuZ)+EEjP zz-t-6R=$(OTqavtocf6TQXd zaIN>KHJ)oaHfDo3w=i&kMiIG8ew!MZ4S(>QWInwif*y_ z@KeD|)FVM6w{bc&@lp#hUV7?31HtPvVCEE$SFgbnfh7UYpU+A3io$}Pe`M3T387J& zOf^^^23!vi{9I)N;n&Y77~yss&M{wsFOnxMXP-E&Z& zFB5p+@a<0xMxFu;YCjV{5sF3UnmG&=u+j8gU`f=uEU+aH^dV{Z4M=WN0Nu1tT7cF7 zBB4TJph!Eth|g=_y#PChg8ANlI$L)8a)`h^nrAw9Z~;B%s7ysTQ8?hd9|Tk>#~;TP z4si-3QY};tSyUl_hx0%`*YTC;u@qjgv`(}1CyQ2Q2iGHiBBuGZ0&l^G4i3s{jQN~p z^N>BPI(=y%zI4~Emp|1in6+$Ui>i6h;k4F?+kARHi(i3R2&5gHQvthyf$fGcDrS2z zQZE23a6V3o#NJ-;4GwSo^0gtAi>pyRmj3{jg&0gQRfw$|PtO1xr?3=xE-rweGX|pF zlizB@GE*AX(-Tg&4_TiuZFXs`j$D=s|h@wP3tdTTljgz z7Szd}A1SB@1Pg1#QU3mFxI54!flL@OVgRZ3-KI~vEh!{G7n+ZTGAjSfbfQaD!Jz^W5`r zWDGjm4yHxk?y=}GU2k0g`#|Ffz+vm#`{sMglh&I+9&YeUAP>YbND+h`qhs1Ed$AFI zA0Pgs8_4tf_}(%d_9u{sTfAu?kC!-c?0W7V`QCDu)+uy#uQin7a&H-~h4+OGwY8_f zaerD*ndb1Mpv1V@Nnbo=xWTL4Zx=bAEqt`0vsz`X9oGPMK)ZNo{JcnQU}1-O`l)B0ZW0H~Q`8$%BRAO4RO{&aaID*%JITQK=ec17 z8#AXyQCA*iih0(6Vo&5Z<8rQm{r8(O6z=uMjkmKV@AR8tBqnEnjM3aBwS6s@I=G0^ zVXQB*Mp?qOC{y41TH4rXcg87`G1`w{dXBvyeoSk#Ryr;*GAk*EJLvXB%HamH!D4&< zz=xhK4Ow!IcSMP^APDF`;ATvJXrW?_z+)7%j4TZ`t8E_w?z)#ofJ~)&tOp)aMEPMH z_{RUC(RY%=S`2?uBaAoq4WyBw^X9gT-7Utiuv;Dot#GSKJVVm+7m#2fL0Y!h^lSkE z+jHPI;W(jV1RkYa+O2};(D#xfEyx{W)bx~e#5A}RX^-yv0Jbodd42H-;|7~$u_ZyR z2QaV3vaPXSp9{=uSI>it4gxXOaUQ365CAe)#G%YmABh!`ppad!@E!xUFdh26aYN=7 zo0W5iI7JSl{6_G5Glw9TL74)(KNLRps{nhAp9LZpnO}NA@}P_*Ia~o?E0yC;E+9DS zDxV3q_eCYb?_>_tBQJ{sSKymz5F&|5>g3oY!SS`TsuJxcv*8d4w+7@5LF^(oaah{F zquBtPomU-pxsZ0XZwm1)tdv=~LA$rC(`GkT!eG-Git^~x(`?ULD~1F-tnacahW z0y*?y|CkLkIaYQys~F@0y>oZUX^iKtXG)hh$t=nRAiD*~8WBoKocK~WU{-z^Wu+{5 zD7ykix1JzFP6sa#!V6^@h%6FeQDQ#I3>jp~0;XEaf4C*^bil3hGSB=ZN4vr_D1%&p z&|Ddnk>h5eXr}hA_LQ0H2QqR?-vvNfipsW|{hE3l4^u5O#8Q-* z9~5bs;yl1VR?MhgI^wP}5(3eP!k_ABq=IKLjmsoyI zT(+r;6L=|)4ejZ)EbWs@s8(HRUv`uwhY{^zr&HSvzx{J8ZjM#nBkhzzCA0_ChtU`K zay9Hub=H1*hWOQW&;O969muut{wJMEy8QuU0HstN%IAr_WR%CfaqK~dl(U%Sg%6>h zqM_Oj_`0j_@QDF^Mz&KTrx9{dQ8HxhyU$lDBVY53wSUxSa$TErDxn%&Y7BVEZQqs84UyJ=L5x(7zr)%C0<*g}Nb9G|D8r26>H<7Gt4na#mzSXAA=OY(yYay4kWJ&4rKxDK@l64%L#C8z zeN)0*o2T6L<}u$e&$;2vbH0J+l+9Rs?%63PboPq3SfAHbZVe}M9}_=}%oKwv|MMQ{ zD46#mm8Roh3yQowa(m(~8J)(mbcKuWVdE`L;TNC|i7rA^2}Yi@hvkn}in z>i`Eg$l-MFN*7v{z|S%yk;JzGNU}xTK74FEw_hry1=g~Y)}tey!6etV)8#-C(UFYE z^NED@=QzUFP2!&Bl}~a4r+V$ROO8lTrYg;3#F|MY36*jLpXdDA{-(O20v$h$*$r5? z=HvCx2?dQ)${u!fKSx|chOD2uva^ryo=++DIh=+O$B8V>dKYay&=DZ53_vaa{VByE zTuhMkm-6gceiHC0<_Trbp6BaN%q?BUR+g+kon%Re64=vmiqrfU@?BSkMLOLP1)U&f zA*c8kLlJ6JkyeQ!Oj)=!fjE;lw>ln5D>2!#+yoDBVZObrB2)BahQ#z!E#AOM!K6vm zG@?TYl(2U^_%41<5Hvp&1Srsi%jo+Tqa{z8NCb+qL2ND3V2zL_it_q$`@Y;1h_h&6 z=p(2Dg5szUgL>3_Wo=AEEB-+XK^RITd4<`KKDes2fC zrd8dYW-3i3P1qwig>~4EW5hXnDFeYQ*o4es_?JvUiU*pCIzBq4C%O;%S=UFWRitD3 zX+5+3bNG{%P#gw6(uF3;{us%j4^>@K8ph?eYf~guq`AHb&-BLLdm8JCB%B?{y~?)T z3_x!<1rwnrc(tk?ms1=C5RHh%sy~SR;Ey|5M#r+v*$x-D!&XBAc+HX|(_s@ExbmT2 zWI%93=zplcx{sUki&eQmdHp!OIa#$SY)dDr9h!;3;zlF!(~?gsLn}Vkg}r(Li^}Rcvs@ zzHf@GagH+sGFev()Ggl)pqSqwZEThScH9aSSbn^s&acH3bd(eOQOKeUHcbIf(lXOxg`dF zDnEYGVUfUW`SH_oRcht^!oTFr$m@?B(q4df%OS=Ac#i@M*_+DvC@;0!sa`{wO1yl9 zsA2}@-T{WYhvRMrpf|Dz6QSN(A74drKUri`%>FS)}2MIHF~b-wlpilQY=>weQFCM-%KUz&pi}5FXd? z_uVJF1Mboqal{l^hj+lW+*2IcwOWLm-5b0EZm`)go|`DLv0CIYaFcAs2e1u0l8F6u zxg4@JwFpmAZ{!ee@QWO>1HhygwaB*9f*5k{5xhZX0p2Z##J-AK+M@*Oq3M#b#Bb_l zOppR^(hz9&&YOhb1>OMDJ`BA8DEEnT{)mY7daqlBG0=3UFG>z>un8!C=8}cdi#5)O zuAjo|HH8C=R+u#p;QH((NNb}uHp|7U8`i(z#nJHrQ=_rlu>Y1{SI2aNBbV~}82D_`OF}`2$C=3%H3l5<%^Ta|b9;rmok@jXit&z55a#N28X#BFC0bN{sbX#7a zNF(DRD?s8zVURd31vSDqL7~$|2=hy`Fp7&L69^#`2^`RoT?mndaqcGheG&_~335Uw zF=E8D6bE;KQe;cgeawB^Lf{;E2oc?*JdWHYL(Iz*$6REM`x_TAW-PxHD%*XSBLywE(>%8E88 zSmGuP?Hha}@VRpkQj=xF%Z2~sl6FImulv5Y)iC33e6I`f^)5K}bY27Trdumpku7u&M*qCSQ z2Y3l;%ffQRr)D`SRwPkWU2HWB}+JI4B!9iqV2vz)^FIrx(a4B)~J!N_zH>t+4PI$;;>F0I*eDy;(%hg+0CRLOF`#m)5}-s1=LqkwOb*@%0c2-I zGF=d*bzD-~WGZ6UX9)K2U@FE}(k|}$UW7gX?+I95Kp%Fzn60mAAtMMaTI|uYX#CGUH~z17<9!|E_RNQ#aXgN`w_8tkjAu_bP2)R6f9M=3SZ>Gh z<2XowP1mQ+^l=e1GtpTDhh+VF_H@*78|ozw?e?LMRMhQ5hnRkemJ-0g18CTfVh0un zFGN4W$@qsL)F+k1Kgi+V}q|z^YFMR zfMdG)kyWFrj^&xneB`!I9MuS-C;%!82@k(R-cAMeV!=m`aJwNy8*+bBr zn}jWQWS_a0HF5@QUa<7n2h6}HH{$!~V_hvCcX8mnqMQRK0^q@oC0;F?rfG`~rA+)5 zaUk5|eLbpAP@2F#Uz!c>(Q0r*QQ=xAT#Sg5m@fBP@ zTBZ0Vy?8AtC&-7goRH$kIr8YRnu)Oj*2a5Bq`u1PF`*pS1A_1VKlmR9T+SFmf2gz? z^aso|$l;+_S|OnydQ%d<^E_*Ydqk3m^{7>62z)7Jy#eSvs)U5B%|1+2;PNI*W3WG< zbKE84o3zYlpNp(<>*pd$go93QL(n<$+23V0d2V)ZP^-DYMl|WGv;G!=Ua(4uzi3~> z4&vOBXI)?Y!)+&%=NamcAjmvT58;*s!JQ+{y(E)Yp>BF_Z_G9daZaJW{6@*-c}d2- zF&1)*4V%BiSa|Ta*a<@?PE&t>j$&2j8pgy72(Pue?JA|0d zsK-$lYoex+q~mhyseVM2set*LYvjyoNJ^t3Dq$Mot4+!qqhdmRtKMrq__dPX&&OCB zvms>~Qp-wrlO|QqGBBOh{ZFE(W)q$-eb21proIn(KA26wrwvU|4dy5gg)8%<@KpyD z;5q8kxUq_XuAnjF$-<^&kgvi<2s|$Wy1?SZ9Hma=BX_D6+gn~R`rShvb%R$in?}v6 zim7a9x{M*SEn|usqER2~7&Y~0LlYtG8&dnfJhAY4GQbw`9s&Dzu{yM%a%X-@GM{=b zFk_H%JBF=PnNrg@+FdMS(~-W!A~wWit&+|PTUc2}m#}0-X{v2#RCNwTcqykIk-xCezvoyX6{07U{bijtl_40|EQcqrvSrm?B3?1r!_o) z$D$g2gb!>zrZeos@E$E-uE-bYrm5q4j+2@M$qTHc!)jJ<+)vC(4r9-7w+@ENy}1dQ zVR;IZzL;UT!Djkf=WaHNzN-q^0wzL++3Kd{gzdsIs+57+;j0JH7WxeE%#c*N(H5B_ zr0_$DEL5=!vOE@PC?mhfeHpp2kR8LSRxIeAbrD$f>Lu8eQ&>^um=8;I=e?X>*U0ay z6W`LE;~|c4m|^R!0TNn&uO_6`P)EbmBlk#w%3WHc zK;};qq5Xb1W;=#%X-uNzVLHy@G?E>FYxog^Wk5W zdA^h7ZWxFp00ulF3&EUHPm~=#w2_0yfTkGYMp<3`+oXk+7XZl8+DwF3`avi|g!edJ zmIq~mmIPVpNhuuZL;0XBP^!z6I9iV9`kJ}JQG=g|1v}UA@Obq?$HR@izmDe_oj^I% za6v-6Q>D|94Cg*GiBBmBz+CsoHpN|1=db0+Ri;R+#%*np$e;w?1D47@#U-ZzUfJ0( zt{I8GD1^Ad8tz304?gNK&N<>-&iW{aYpsjg{4lq2QFhOD&*0ofaU}%x6uV}Gw{dXe zN$X9z0&cJwgO`IFEIkXmoY_*yXeKhU;Oe6b5EUS;6Yj1&y(VLCq0OD}W0uhZm3BhYA!=mH#M#B8_ayR$6EhiRjkJex-$G3h$3c zF1OgM$-Cte!%z3fcHP<{ma8;Okx02vtS_=gF~T2OV*%$P_qTwD4WxIlGpz}?zBk5i zZZHdz+Y@r07}DGEd?e~o-LO1u+$aUgmXn5tD4QT(*8>oDfV4hF)7Lym6F&-}T{nc@ z+;<&7eaFaK)cpkW4hv${3$64WbdIifc&M>TVEpzezy?3r*;Evtbf zsAiW}r&|B>axZ}10el=v{{_(d83KAUSL%(noEyAlHu?hSO(#dCJ*^b%XA?z(z>p^1 z=^udk6fpHS*a}eJARY_9+rd~=*E__t3@EOJ5UiRP5NR7B4uL?kbs!gCDOiT)nGK;$ z{!f!mB~*j!#|TOr`&dRx4BN+K^ifFz)%7~tt zF0Ju{;v(xTm8KS>GFgT|#I>|trL^&VO-kVR2$eWE#Sw8Vx<0D($a>N_Y?{5`AL90x z5&|a(V&bMpua0L$RsW%I{^8-R8uT1vRk^`Nv12JUj8C8E%zH%&d>Y<9c4sLBK1F*Y z(0qVcd=pin@0^JI&$nX=oo-3K@aa-gW~9Lj5cJQWVN?x}0||B>VLCc~Ux%LSo#!q5 zTh6PgzNNo${^9HKk7{BEs9#JF)Q-p<)vC+u*%ZM6mp2kVF$5@}5Cw+cjtLK6#echz zDtKP!vk9cysX*8`WO?JILR#BD3_L-o@0|=pfk<%`PN3saPiNy>6HQJ5$Xd_mnwUsH zAdcY|Jg7`qyTNNi6GmcKk8iH4$*>9P266+!z!lU2)#PhGIFAkGczk(Xl@zH$fzH}J zNGlWdnFMbZ6jS~Ykxrj5jM@!oMfCK+0ab$DACO*B|M9&l2#G=4&@|ATz8Yb64|4S4 z03OLBjF6+iCCbiSJ?>>C2gN~M9^9fWc;EGpNZEx(T>}?VpwGFk)xL8u(GU~fQL5+m zOx{pi6ov#LNElRy$*p>#i6Uy1}<|jtM zSH$z~?33;fW_2*AzrVjcKIR*8M4no2&pv(R*E6h(Qsj)=z_-<#XFov|Rc-@iFeQ!^ zoI(BRGrzDb*q@frB?w;D@Rhs;kf5~5SwFdyNUE!|TF{E{Jj;EYIa$&NhyZS^V!JDd zd<8^+?}cHMIAB3Et2TJU5#=d$6QfvJ8PV(oM>uvP&hXG>gBtOQZG|yMg?1whT@tc{fj{Y_C#>+$`g`O-L!q(e~|P}K*em#3MC!Xl3| z;klWE0c<%lZWR6Tr~H}KP{9LN<;v_fdJm~*6KUOaj%d%A*0cP2;qG5`J#4*OjXqc` zQ|}9E%Mm{o9{?&BgHnyoiTQpgX&YdKAMvAgGo_N6FDZl)fQqOMwi^9^pl1~{Cw|~h z^;b3eUy8`7a`6LyBTETKDyWn@h?=3`87Jy(%ALa`0uUHt6%!w^KnW$^Ay`ul^-pn$ zC1@oQz8fHNM~FQ3;yiPsJU|+r-RIodLF*a4pECv>A+{JlzV^m>SpJ$FbmK43H2s)v z_(v(oApND>FHhGCj=p&`Q&R8i^T%yKw6WX^N-J>x~-#GdVp1ThdMSzzskvq@S4^0PE`& zfVOU77colTeYSzeya4?EnDg5!;0|-XQWmTp|szn}@Q<+R?>NnxVTH?B2wlH!a>Sc|38B?xq*L@#1S*yxnns$OEZq$V z#~y{+G<{kVCDW8y6OYrBVFS#DNi*r}@U)q_n`CdwYS*+o>WkT~X|b^zDJvW6As)qU z_w11Y8;jg}d!7BXYpv69B8K;N40WkC)UglyCWg9ZlH&e|g$7~Bkkyt?DtI+^AzC_t@U+B+z~W(6j_F%>pVX19pDK#K7~3godk zareiEsOgi^3@!H%YRV{neMgylx)Hs(MW&?7pU9#+#9Dc3Pa+k8)O4>mZXQjGji<|& zHV=dy`7Uz5WN{Le$o3J5C`+9zNf1_oa1>kXL{qg<3=%^B;NbbOt|%YYyBgttpX-lE z>pV|<^{yUQf7PR@7*N#g>x22VB8aaDimedErXTW^dUQFMqjB1KuOQ# zfFI~9_26Q3Gn*c(P~Hh(=r3hnj}U`vB5Oa%8!4u68B$@DDkzFrH-a1y%R3uLdhwRR zOq*aMauRAL!|##oVfffq-Gt&O_ft;>UKRq&Jr9sfD2(!=jASnG1Igh2A#51`YCM@T zKoI0@#&k2zH4{)5;`^&B6+EiA35SkRKJly1*T5*ct_OOSjk469wV)4Cr45a#1%I!w z(uHW!U-Bt@oU@7T64^1%EjeM$<40-n0oF5#pcUVzE!p%*89Y{Px4O(ah+ZBWhD7R% zXD_!qO#7oFU@FuM_3?EC%@O<&e0$w6NfA7YxI?Qqn=DHb3XJpamNQZxK7w;ElUd~S zXWwp<*_On<7x&(W$G0TAc=V3fr_q zh>P{%r5@hYBRU}Aa@Fo{`lMvJJIbs*w3~YFd1ybaq0R$5jcRY>w)2=7W1AzFu_AE) z`y(MR6v zGa~S6=#N0qrm8Io1Uok(0E*aifrS(Si&()1JL<}dVHslF;NRM=pg~Pqb_ETOwug2F zL*o4jL7Gb(nzh|6qPT(Y0r(5BfBPe%aG&n!prDe{yNB+#_u}U1#EZsBfi#0n%X^_2 z1SsCHc!1_(cn1G9NAB-8l?eIZx9M~Oz;!?ofx!2MnW z;M>%*&NqqcVQ-iX{fCnBsp>?ud`$I+I@}D$$Ov<&!KajRVRrc_w}$gGCO6 z2pcIEP9StwqI@ok*;owtySEjfaK+%QtcP+sZct9CiKycfKzF&Mvd@{+4{tvq*$+8b z7_*(ZeTmE%1Da^siMfEDbX2C);yTw6_d}Dz$8iPI$P%ARm(-1|kn+T(TL=oVoSbV}0b;7o)PKL;t}+sf=E;j2f*Q z43uMiX;6N3FRhn9)iq)8cFbdHCiK~A@!@GWFZ;&7&g|arWBry3+Oz?z&V~$UEH?{W5S=j zlw#P_$>u-}wy9^5h5{|u;J5E9B)pgn)weW6rNWK;c08NbU%tKOqR|U7qYJgj=zU|)j6#d2MXyfkA3(PrU?zLS(s*@Q!|TSb6Ni9rHp+&JQ9hUz zQY~1M_-2K`Lmc3wnqsc>T)g@5&^Oh`cwuxo!o|eoQ{nGmx!q#eCqP)4VwUFLSAff8 zg9cG8X|twUO{s)cvP_tQMv#ccLfO`+E{!?Vw|6!;LV|YySb|1{ zFrdwpBNFIAL2zV_a%GwBe;+-qZhtPC6Ry`hS8H!{`#fu`>Y%mM zL*4%K!}QWo0_L>ei4sWkL%j@!-!@Y4^F;M0N{w4=NUL-1dnnla&K3NSZ`x@Ie`jsJ zLGbx4wE4~E)t@MV&Jw&^n~#%zi16%mpS1bhr*-N>F0;;Uk;@p(u5n4!C-5~Hz<_$3 zIOk{onx*dPIsQHkBA4Jyo;qGYdmnHo;@(Io++sU}Oj|-Z)Y~cj17V;3p(II`bpElP znDnztPM|asOW;Q-b3vNwgi+A5G?yBT)La@PSv{Ie$H?Y}BQ&Xkpb(iDEK{wO+u%@< zrj843LCW4NB!_KssG!zAlHa0Bpy1FT9>%WO!aHINbcY(X)G=btMuH5_XMbQ0xW$G7 zwkt&U%sSU9F2g1{ zEt%Y@8@U+52WNM>5bk_`L=q;!l_JTb=t6WH_9KLAhDdgrAb$Z1w7b`OXwl@*XpcIw z$paN0X42rWSC8rwd5w^NWQ%&no(;U34aU`$q>~qg$41i0Un!5R+v7m6)Q}cwPJ-S zb5F4XCYR8EbBf=g7yN66#Pno%aZYh3ilXx!T3>iv`Xh0e7MrbLNi4?pB@Wj$+28aZ zu(;44TI5;dz_qEZ1sO*p2px%0NvbaG*3@Ezj>HX*%s6jH@Zi(^CW!81G{;9O_G*Xck~+ zcL^S8BN`XL7dpY~-`P2bN3)9PkW zk$b1*$mhY44`7LEQ|^=C(Ox@u3m!oj!bv?u>Nv~4dH3$tOI(LH2bbVJt+S$V8MULV za6;uWCT7X_dT7F0N(pE=#;o{oUz9xD)-!sKG5}jnt#Z%Q#2ugNlEZ^QqBWY(W#^ zK1Z)pC_xN5)^`0)dFJ|)W`kR7Xl+YU%!?UjJKB)n$nTU1u}AqaxXG+GzB4~Y=s}I; zg~>koopPTz7GgtxQQ+N({7(c;?7%aFqG+3D_X5O}n| zK_WJyfD>_)G|3?*=42HJ!>_xNhKUc`N!oz2Z|bgLMZSjs=MLk@-6sqy?i0&|8!j`l zQl6Zjz%qIE2KLG5ETF$nDCKn;rLa}TNrJGk*o)F#Na$)Mn%N5bu@afKNOksDE3svd zvD~n>wfN9<8=uJs1T<{c#*jWo7m1xXa=gGX_QC~}3S%VN*tlsg(HNCU+7zu0na!axJGj5cp8|;p5Y&ML??fjS%pd<#q$&O z#>aqLY$)pYIaO;5`)-q0F8CN2I_q;(CKFWLA5AD=cq|SuV{5L8xHHy z<$zKj5Qchg0E~4yhvpk*X{Cx)a~T3Tw%ftWOr7U*F)l80N-N(~!plut?wamU=Q~yL z`qSD$F%s<3Zq>$XQI*Nts%@)SvozJ>pO@1*pv6oSZCEdvMY)h=E}%N4XstN$rJ(c_ zei>z@EL!tuah9%h7-TM>*aIQFP^N*%A`up4k~(D;6k%DwsmcmkSyPXnmwDzVIocJb zK^f!%l;+B)j2t%$1+=Q0)l+7!AIQipeODHs&Lo3j7mX5bRHTImmc3a$agZfaly2tx zX%vV!!{8*T2U;t#(g~VW9bL}b9Um_*3%_vjX{?yQlX2pCUY3NiM9R8A%1ztjMTrQ@ zGL+J%sALRyhOHtjqae&hUgR6s1B8%M|~4Wg(K#^$W_**Nk&pp{)`~Cr+PEr;ox%rI%(d2EWXTAPa&F{L@D^T8Rbd z#ATblhTk^gqg3p+x{I>Z3!>YrnAb38`07vjI@@JaV{#*`1EFUZ}} za5TjZ?WbqJeqZ3ux3m)tq*4o~DFzQOGl-T2l0bq0$x& zy`ShDI%Za^kzQ_butsrp0Un;!CAjO$OAs<^HB_xNxmG%4(_~=LRJ7RmrhwHUQ_9dl zQ^H)Er`+`BG2bxHx#7)ozJce%Z=9*e4ln&I##eIs7VGo6%B^)mh)C+(Y6NhEp$@A2 zPhKAz#GWo?zx{!7v$Q96#hVzi5x`PnND~mrk={MvZN@>CQ1~b6p+ZLMk(%>2qSiVhSwh+Ocm#}in~5s`rH`F$RYmY zOzLz%NszCBL&;fk4RVa z8snfGzZm!Y=!bdjRt#o{lRG3}Hu|Zv|3of3BtJw7NgBe1Es99(`}Oo>=~~r<-9b)>Wc}Sof#NpGAVke3NFQIe+Ti%IDGt%awaQu(LfWXMYlN3P!ZVZ?I zB=Ev-|C$AFPL5$;JB<+w5GHTvHy)Fz?ZJHa3Htb1Tp{%<^2oM3`er1DOmTOL8c3rh zhxIL~HIPtu1PKc%NdNsmRE^EEIZ}=N5NT*-vF4FgqpFUjn$vm=O$t6niJ32f$(c(n zKU#tie8RU*BGm|D=JW!onvpN{kT+F9y;%G{%ezXqPewE?Pxh+q%2LqNwwrUkCJ%k& zu*n1Lqh$lSQ-YsM?yUH*4mJJ(G6_{TH?ml8w0x2Yw@wvG&1j#m=7)p%8B7~6^{5;} zC)qg_aSxTNctgm&u~2f0O_0r&R6EG87Qq;mClL%9L0P1*NQg3sT|Wodh1a%7ZKzpq zOnP@%D5KK#6PY7Hj+e!O3nLBe?IAY46!sPvGg%#?lzB5?q=B=)K43mRxe?z-AM0xI z@QdT;6)B}p1f_W{tASL>#ECqbrgdzR(7-PxkN)I^dK~g_KonUDmkFN?U|!%SaazKP zoxui{imYt_+mJkl;>SBF2BaDY;UTbe-20PQ^l`>L^}{d^{W475A_&4%Lhs^~dE%xn z)J$$;yf@5XGlSQB+_6j0VwgeV7)^OH^i9kTR@nFozB;W^e3M?hmSi~kP?n0vA_kaF zubCMCvnps--6IM!&gyX?$1Q7)!)7J=L)l*F4;X=9Xj1Mcg@nfFO<6(@G&ild%CurV zYSkISNUcp(?Nq2tRj&Z-Uv` zMiR;247n$KB;+2RIln)GBeOp(A8$!;?14>?wyGu{_D7s(aj;&sxD2~~dK}~5C}4n> zPSBr#0dBJ4(|6bem8=n`e(E{#UdbA|PsR;8XO)tOUzsMTMwD8C| z6Po>~PqId9?Q9@xc+h<#s3h7aS;O>c9qtiQA*+5XIbxMw!<6AbtDa#aaTnwM2pLR_ zPbFkL4mMKiBBC%!Lq@Xxl>j})D56tnH#l$c*&|~kF-7&rqS20Ws4QwD21TK7seE1X2T~O9IBU60K-EJo>TSnvJ+%c`PE#whw9i~s~vJ^z7 z%vv3VDZ{*dLz#dBQ$N99nRawN0^-9Abao_rrn1EYsV#*(1 z2pL0NCrm%p=n5K<04uS&rATgNN8+jpCV-8i+69J}Lw~djrp1P=wj>ekJd+ZL7shb> z=5WZyXrbfWphI{DmW=ayG*u2gXbbT+y0$gIa6Ll+llE6NuInwTlM>RseN0BRo zlNRT6wY&lm)=tI(-n4ookhGWJ1_FtJMA<9n3mfKTl>)+)S?hdZ%Cwy?h!{b5Vxnb) zi&0r)S*V-Z&*!-SI5%iF{ZUddG4@+YVZxl_lr3rdqov>#(I1(lO;THuNqXR2@uHCFsgCrJHP`qgxr)5P&`dy_FZo7yGVEEM!pku>j@DM=^;Uz5ghvf^Xz-U zkxtpUWvFLf7X87<;})A`u_gIzmr&0^TE+mXjZ;AQ`T=mxMN$wRaOviuEHccy4y9L| z*M@qgxJ`y}?m#^^t4pmGF4O^NZdRJAc?s6DS#fH6X=1P0pl(@@cnRt_i{(hq&2rQq zTM6~dt5fld7o=xxk$XXUZf^x$Xhv_xNYBiadK6aJmM*r%MqiMg$@=$#^lVV56-vNT z+-U|0ZlM9pp`Bllo`Gv_5S8~4>6sa(5>EiN`fEtfO>OcRHf*+e}UAiGW)>{G_sC{=w5)iHRb%1)P2C$2ln=%X7)b#LIrR1XTI z$)IDW@@?9QXEl#Ok92y55}(S0$vFxbIfniqG#cE|U*9})o5s$B(ak9^>{0z z)#*4`8_Vlj!{w36pXG*tq#~D4UAE(AZBTjiv(3D$4T<$9g^ytjfpI|C(!p+rk_9G> zP6HZp%;1d~)vd`U`<(o&7i0@Vi8}I%@c&h$4M1COX@P0) zEV}bvPOocZFe2w?UFLX*oJM$SUdD>X){NWsX(BMU;kPdncr=fzsic4w{^G~#ha60h zR^9peLQF~NJ>-krBNHO`X`NY*%cvE#LPp>+>ms+Wqcm`*R)pK7UZ}R1H^F@h>e&~VzmR! zJ(k!W5A|M3|3Ijqe-K*1LL|9jal#PoeB>V?x`aR}$wdh-xJCw1HD97QB@BV1l4o3) zxE!wU6jn6PJH4(31pqM((DxEy#SH@|4&%r*RjO}y5aErhl$Ig1ywt>9c}`-@Z}7^5 z2Y$$qG$uy}6jkgLlX9b39)4@d1S_)CAXnbCxG~W?c;&}bqo~s)Epdc<5482q*MRN4 z#<>9di^->UDzMGr1vND4;=^e0Q^io$BSEn{=8@U=l%HCA@RdHbLUPgCehmS6O)!pc z%}V%+Hn>j`c<5tnr2U){g!PKa6yuK*7En#~5Pg!lM0jcE?%B_g7*_d*JRi&o*$lOg zQq^UtE|MwqGI?K9#=EbOJ1Fy@srwHCg#9?KGx=pAu9{kq%x8dtD8J;H_zC_-AyPW) zqGl8j$mp&_`CJxAuQ%ZD-d5x3ObpsVTZ+gC*YA^#;ZXuTjrXP)H zJVtm5(R3yw1wF3bytM8%ebVWEQ%w-Omt(a&|07)Y%8ILvz1o86e=;flBJ$A;%mA?<;8=*x(_Y zUEEh6uYXReyrH<~Fe*CU^S>YbKMcC@|K8`%|BfycdV4<~S85w3dWwkb)F#utn_(-# zhK$q+daab^Eu^f;a9iJ0g}_RhTRfb^abh^+#mFVGPiJ7$r?qEbQ)cbi)s(sC+4Z#6 zdUEo-QY5(xJvq;--y1zSw^$uZO$N#y#`bJA(wBpK_(a^%kv9+}?dQt_d|1-KS^rE9 zra-QsohQ*}`ouilNI}js74*jR&Mh{y)jAC0psSF57II2l=18T~0?crc{RBU}fxQIy zY-Dbj9N3jL^-baQT*Oc_Ln94)-|?!eSE!J9llL? zG_Bj$JoUp=(IEW3@Mry(MA^*Ug6*g^b1&)t@Y6++t(a-jYbNLz_J) z7B+kQz5^M}=pDt+97^ivlHOQ%L5(VFq~miELshb=vIPtTD@`ZS1w-KA>bP6WM?47kON2>0laBv1!x zYbpJ!ocp%t+vldK<3hEX+De#B%;j{*GD1KFbG*`NZ%27?7)QpBV9Tjmc;a9_u1EEW zycV|=a(F*u-8#3}klODfGHCJEc>X;Xk)azv@EfItV?rb|<>*#Sdf@Rtj9x`tQ8Dy zV?a}KDiyKoGse`zgQ*x_wQ{H*0#zkVL8*xkPpAa0UjZfGRZb33mV{{*Msbm3A`pl` zk8{TtBFONEo8*62jiCnVP;@nNba^wbZ(!#B`4OJsuhA5B7-rY6qaWtATQQiy{&eUZ zCFV|@{U3deZv8I;}q zB=n8&!#KmD%{MW%ptFISqfMrnzM$Bvt7%JH}_X%&eHPxv2F-Z1&8@PH2^6DHC$fFfMau*heF=~vP@ zOj<>F$to)`FM}Sbe2offIRQV^am`PCKMGwp%2GEAWZ`E)0Irz&kRQS_Y|sadvP}Cl ztC`hbJROM1cK{DE2^Grm56J2Y-`R2Vsj^AtyOzTA-F=4|=b z^=6O5nB5i`BP5_NmWxLrW9i3^jD%Mdc@PF=k|zo7cuC|2c@h;kWwmBuBQh3KM1K7F zNsK5Yj_9sXaZcujOH5A}`B;A^$`9vvRA3L(o+jd>F67``Maz9C%L#GJl*)qYZN^Jt zJrt^>8AaIFg0vFBHQx`TGz@`}iSuLPCcKkKoF~h;@O2Lt6zxJ5#W+R;pAy7vNZQaiD^iJhDF|0&jWy7=L}ObM+5(g zz$7Llty4Gmv18}gms5$5zQy|{)Q~u;E`BC&rq_tXYu+IOTzF(&qgX8cOz*+4U3^AZ zZao7rBT5@j=cH?Rzf14T@BUGh61zIqQWLw|=3)IwZp}N(cDG{exnUmq*mT_@2*Ol~ z$aBg(fyxLnjoZ-cy|!ZUu_k2fPZz9PZQF2y(L#cLJ9 zHYYoe<~$SQe^v$6?jF%>XEnt_wm=#^7mjI0s>?(0+23 zOTN)0Q5Zf+x!A!J{{s{)KqZuZ0fH|?|AM4m;*0>wngC}2o98LuCyb+oQue4z2FY7M z0Q;StgES!~JxV^rd#v%rzr#5Qf=24Yk;Vy~U_t4-Q#I%k<*df7YV1JzG?%l5%svTn zpVmc0bD4F>VO)mMo;J*e2&ACmBCkhkK{f`#*9Tt!#c+icsqRw&tIcLP8&D>N^?+5c zO44Gka;>g9ABZaxA3yxI1i}laPHRrX-pCd_(j1@u1g^)B!3j#oAbR0nE!M0FP0}3p zX+x8?MXMzPa8XHjni3vRKYvKPT(r-FrHd7ppIaoV6X z1mk}cXi>d*ZD>)=U4IE$lnE;CkM}S)*{p$01cb;-qX-C8mSIwDOnnv*RG(5sf-AHP zDH6G%-#UKejxvlKxnZEv#SjL@9ZCnL^F5Ld3<<8(Jlqq{vvr)ZDz%_IEkF_zo3uRv z;W3gXv;5MHUtTUibYqx}=3%*T0G+B99vs86Hxv&vne_*I+^qOyZ?MNVjbqk3;WH0P z61kImMc|dGKpIUMW~odwr*NY%b&4>_*sNyE3;h-=%+}KokShli^todT#_+BaRLUmr;w*G=Q zqaFzwZ6>{epkZ(z_DayOu`O2VCQO-M7b12jLvTO)BSSE?Sv!7PhIkBB1$>3!GReuq zj^>vNRD~~flhznG^f|CGaDe03ZjNyB4?Tbn7>n85@iKz9KU|f91qZ?)4PDPe&Kdf$ zT@^zZ7$JCGRhUpBqtG>qx%mUfN&GbQyPrsW_-Hy#WL%2o<=GCp@PPN;ZcT3F!c8(o zmJ~fq3(4Y;-PcRpz%!QBjnl7?iT!c#WQS8}9t zh^T}SxOE~$vEZ-F3vhv^c>yX`Z?7|6fD22O7oZ{<`wd=zN;I_}m<8DV1TR3PGqcO{ z0$g~&3$R;LvjFkN+z}E8PVgs9ynV`S*7V5?!7@ETQ^w5D+A_wL)AAZvgOkRn?j&08 z$_ml+uQ#afO^eme@f4`;kDUF~<>bk1y&|WJ4tBs2wTIpwyE~e8rf5AAP?(U?1YD9F zv+ZXK=7&c~f7;AgZ_wSF78@Gd(l)k3C{@TPvF4xT*yX+u)|0a$OEY*xXY zXM701aRNcX*`sKQrcXxNTP^_Te)Dl@T^Yw%HSc3g0Ne^xY+w3u~9PY`Jlu$Ke#O$u5E|o~IInmq%Z8@eN}zB-Vck;YEp2 z8!RNGq^kzIP-2)x(4Rny?kc!jMnF0k9|5O+xIZ3|9{0&ufS2z7TxOl3gUj$ix=%6! zw>|2OjKD26CS`T-epIyuEFAzJ5du8b03F{4vTEiF&iM_}O%iW93@&56hAX|C_<%RI=5rZ+cqmk{*Na#z$Z@&_Z z*^pGyA3XxETeAx8kP#w81%z?vrw4yaJy^aBNH2#_f9+IV%D%aH=)Q;s7mVQdMq zuj^WZG<0qnz*UPht(J;5c0w3cQVn!v-EXidyKW-z#qzu`@{CSk?vLg8spI+Zq3V1A z5Nf`cz~jqk2%0w%K-@VI8qj$Gz;}Ui`Rd${;xKko&j=b#HE!et4t#^+uD=(s>)jZz ZwF?b$JOE-~IJz$&>x_eML@rwN{{y3<{qg_+ diff --git a/Assets/Script/GoldManager.cs b/Assets/Script/GoldManager.cs new file mode 100644 index 0000000..77641d8 --- /dev/null +++ b/Assets/Script/GoldManager.cs @@ -0,0 +1,84 @@ +using UnityEngine; +using System; + +/// +/// 金币管理器,全局单例 +/// +public class GoldManager : MonoBehaviour +{ + public static GoldManager Instance { get; private set; } + + [Header("金币设置")] + [SerializeField] private int initialGold = 500; + [SerializeField] private int currentGold = 500; + + /// + /// 当前金币数量(只读) + /// + public int CurrentGold => currentGold; + + /// + /// 金币变化事件(参数:新的金币数量) + /// + public event Action OnGoldChanged; + + private void Awake() + { + // 单例模式 + if (Instance != null && Instance != this) + { + Destroy(gameObject); + return; + } + Instance = this; + } + + private void Start() + { + currentGold = initialGold; + OnGoldChanged?.Invoke(currentGold); + } + + /// + /// 增加金币 + /// + public void AddGold(int amount) + { + if (amount <= 0) return; + + currentGold += amount; + OnGoldChanged?.Invoke(currentGold); + Debug.Log($"获得金币 +{amount},当前金币: {currentGold}"); + } + + /// + /// 尝试消费金币,如果金币足够则扣除并返回 true,否则返回 false + /// + public bool TrySpendGold(int amount) + { + if (amount <= 0) + { + Debug.LogWarning("消费金币数量必须大于0"); + return false; + } + + if (currentGold < amount) + { + Debug.LogWarning($"金币不足!需要 {amount},当前只有 {currentGold}"); + return false; + } + + currentGold -= amount; + OnGoldChanged?.Invoke(currentGold); + Debug.Log($"消费金币 -{amount},当前金币: {currentGold}"); + return true; + } + + /// + /// 检查是否有足够的金币 + /// + public bool HasEnoughGold(int amount) + { + return currentGold >= amount; + } +} diff --git a/Assets/Script/GoldManager.cs.meta b/Assets/Script/GoldManager.cs.meta new file mode 100644 index 0000000..76d9311 --- /dev/null +++ b/Assets/Script/GoldManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: DShMsX/+Ui0ZvxHNgg0oANG590a65IynIxC0Pd5T3n/riVwBUL38R7Q= +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Script/GoldMine.cs b/Assets/Script/GoldMine.cs index 8187279..4aaefbf 100644 --- a/Assets/Script/GoldMine.cs +++ b/Assets/Script/GoldMine.cs @@ -1,36 +1,78 @@ using UnityEngine; +/// +/// 金矿建筑,定时产出金币 +/// public class GoldMine : MonoBehaviour { - [Header("产出配置")] - [Min(0)] public int goldPerTick = 5; - [Min(0.1f)] public float productionInterval = 3f; + [Header("金币产出")] + [Tooltip("每次产出的金币数量")] + [SerializeField] private int goldPerProduction = 50; - private float timer; - private BuildingHealth buildingHealth; + [Tooltip("产出间隔(秒)")] + [SerializeField] private float productionInterval = 5f; + + [Header("可选:血条和进度条")] + [SerializeField] private WorldHealthBar healthBar; + + private float productionTimer = 0f; private void Awake() { - buildingHealth = GetComponent(); + // 如果没有手动指定,尝试自动获取 + if (healthBar == null) + { + healthBar = GetComponent(); + } + } + + private void Start() + { + // 初始化进度条(使用能量条显示产出进度) + if (healthBar != null) + { + healthBar.maxEnergy = 100f; + healthBar.currentEnergy = 0f; + } } private void Update() { - if (GoldSystem.Instance == null) + if (GoldManager.Instance == null) return; + + productionTimer += Time.deltaTime; + + // 更新进度条 + if (healthBar != null) { - return; + float progress = Mathf.Clamp01(productionTimer / productionInterval); + healthBar.currentEnergy = progress * 100f; } - timer += Time.deltaTime; - if (buildingHealth != null) + // 达到产出时间 + if (productionTimer >= productionInterval) { - buildingHealth.SetProductionProgress(timer / productionInterval); - } - - while (timer >= productionInterval) - { - timer -= productionInterval; - GoldSystem.Instance.AddGold(goldPerTick); + ProduceGold(); + productionTimer = 0f; } } + + private void ProduceGold() + { + if (GoldManager.Instance != null) + { + GoldManager.Instance.AddGold(goldPerProduction); + Debug.Log($"{gameObject.name} 产出金币 +{goldPerProduction}"); + + // 可以在这里播放特效和音效 + // TODO: 添加金币产出特效 + } + } + + // 在编辑器中显示信息 + private void OnDrawGizmosSelected() + { + Gizmos.color = Color.yellow; + Gizmos.DrawWireSphere(transform.position + Vector3.up * 2f, 0.5f); + } } diff --git a/Assets/Script/GoldUI.cs b/Assets/Script/GoldUI.cs new file mode 100644 index 0000000..b7854b9 --- /dev/null +++ b/Assets/Script/GoldUI.cs @@ -0,0 +1,57 @@ +using UnityEngine; +using UnityEngine.UI; +using System.Collections; + +/// +/// 金币 UI 显示,显示在屏幕右上角 +/// +[RequireComponent(typeof(Text))] +public class GoldUI : MonoBehaviour +{ + private Text goldText; + private bool isSubscribed = false; + + private void Awake() + { + goldText = GetComponent(); + } + + private void Start() + { + // 延迟订阅,确保 GoldManager 已初始化 + StartCoroutine(SubscribeToGoldManager()); + } + + private IEnumerator SubscribeToGoldManager() + { + // 等待 GoldManager 初始化 + while (GoldManager.Instance == null) + { + yield return null; + } + + // 订阅事件 + GoldManager.Instance.OnGoldChanged += UpdateGoldDisplay; + isSubscribed = true; + + // 立即更新显示 + UpdateGoldDisplay(GoldManager.Instance.CurrentGold); + } + + private void OnDestroy() + { + // 取消订阅 + if (isSubscribed && GoldManager.Instance != null) + { + GoldManager.Instance.OnGoldChanged -= UpdateGoldDisplay; + } + } + + private void UpdateGoldDisplay(int newGold) + { + if (goldText != null) + { + goldText.text = $"金币: {newGold}"; + } + } +} diff --git a/Assets/Script/GoldUI.cs.meta b/Assets/Script/GoldUI.cs.meta new file mode 100644 index 0000000..fec1daf --- /dev/null +++ b/Assets/Script/GoldUI.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: Wy5O5y38VnjSuIhFnocQ+yIk0/PO6tI7xIs2xwwd3tamOqHsfmlJPMA= +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Script/HeroGoldProducer.cs b/Assets/Script/HeroGoldProducer.cs new file mode 100644 index 0000000..d84a0ae --- /dev/null +++ b/Assets/Script/HeroGoldProducer.cs @@ -0,0 +1,68 @@ +using UnityEngine; + +/// +/// 主角金币产出组件,挂载到主角单位上 +/// +public class HeroGoldProducer : MonoBehaviour +{ + [Header("金币产出")] + [Tooltip("每次产出的金币数量")] + [SerializeField] private int goldPerProduction = 30; + + [Tooltip("产出间隔(秒)")] + [SerializeField] private float productionInterval = 8f; + + [Header("可选:血条和进度条")] + [SerializeField] private WorldHealthBar healthBar; + + private float productionTimer = 0f; + + private void Awake() + { + // 如果没有手动指定,尝试自动获取 + if (healthBar == null) + { + healthBar = GetComponent(); + } + } + + private void Start() + { + // 初始化进度条(使用能量条显示产出进度) + if (healthBar != null) + { + healthBar.maxEnergy = 100f; + healthBar.currentEnergy = 0f; + } + } + + private void Update() + { + if (GoldManager.Instance == null) return; + + productionTimer += Time.deltaTime; + + // 更新进度条 + if (healthBar != null) + { + float progress = Mathf.Clamp01(productionTimer / productionInterval); + healthBar.currentEnergy = progress * 100f; + } + + // 达到产出时间 + if (productionTimer >= productionInterval) + { + ProduceGold(); + productionTimer = 0f; + } + } + + private void ProduceGold() + { + if (GoldManager.Instance != null) + { + GoldManager.Instance.AddGold(goldPerProduction); + Debug.Log($"主角 {gameObject.name} 产出金币 +{goldPerProduction}"); + } + } +} diff --git a/Assets/Script/HeroGoldProducer.cs.meta b/Assets/Script/HeroGoldProducer.cs.meta new file mode 100644 index 0000000..6eec445 --- /dev/null +++ b/Assets/Script/HeroGoldProducer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: CHtLsyOqAHO9Tb+uQSnXcIZq0ZVdLqUhEvDUjf4JqQrm9JlgUFne/xk= +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Script/UnitBase.cs b/Assets/Script/UnitBase.cs index 8003f76..7e4a097 100644 --- a/Assets/Script/UnitBase.cs +++ b/Assets/Script/UnitBase.cs @@ -86,12 +86,19 @@ public class UnitBase : MonoBehaviour //初始位置坐标 private Vector3 startPos; + // NavMesh 寻路更新间隔(优化性能) + private float nextPathUpdateTime = 0f; + private const float PathUpdateInterval = 0.5f; // 每 0.5 秒更新一次路径 + //动画控制器 private Animator animator; // 角色控制器 private CharacterController controller; + // NavMesh 寻路代理(如果有的话优先使用) + private UnityEngine.AI.NavMeshAgent navAgent; + // 自身的血条组件,同时负责显示技能能量条。 private WorldHealthBar worldHealthBar; @@ -154,10 +161,27 @@ public class UnitBase : MonoBehaviour //初始化 animator = GetComponent(); controller = GetComponent(); + navAgent = GetComponent(); worldHealthBar = GetComponent(); statusEffectController = EnsureStatusEffectController(); unitSkill = GetComponent(); + // 如果有 NavMeshAgent,配置它并禁用 CharacterController + if (navAgent != null) + { + navAgent.speed = speed; + navAgent.angularSpeed = 120f; + navAgent.acceleration = 8f; + navAgent.stoppingDistance = attackRange * 0.95f; // 接近攻击范围边缘时停止 + navAgent.autoBraking = true; + + // 禁用 CharacterController,避免冲突 + if (controller != null) + { + controller.enabled = false; + } + } + // 大多数角色由 CharacterController 位移;特殊攻击动作可保留动画根运动。 animator.applyRootMotion = useRootMotion; //记录初始坐标 @@ -194,6 +218,12 @@ public class UnitBase : MonoBehaviour //攻击状态下等待Animator报告攻击动画播放完成。 if (state == State.Attack) { + // 攻击时直接禁用 NavMeshAgent,彻底停止移动 + if (navAgent != null && navAgent.enabled) + { + navAgent.enabled = false; + } + animator.SetInteger("speed", 0); attackElapsedTime += Time.deltaTime; applyGravity(); @@ -270,7 +300,7 @@ public class UnitBase : MonoBehaviour return false; } - healthBar.TakeDamage(ModifyIncomingDamage(damage, attacker)); + healthBar.TakeDamage(ModifyIncomingDamage(damage, attacker), attacker); return true; } @@ -333,11 +363,10 @@ public class UnitBase : MonoBehaviour return false; } - // 将双方控制器半径计入判定,避免碰撞体互相阻挡时无法进入攻击距离。 - float selfRadius = GetHorizontalCollisionRadius(controller); - CharacterController opponentController = opponent.GetComponent(); - float opponentRadius = GetHorizontalCollisionRadius(opponentController); - float reachDistance = selfRadius + opponentRadius + attackRange; + // NavMeshAgent 会保持一定距离,所以增加额外的攻击范围缓冲 + // 原来的逻辑:selfRadius + opponentRadius + attackRange + // 现在:直接使用 attackRange,并增加 1.5 米的缓冲,让单位在更远距离就能攻击 + float reachDistance = attackRange + 1.5f; return Vector3.Distance(transform.position, opponent.transform.position) <= reachDistance; } @@ -465,6 +494,12 @@ public class UnitBase : MonoBehaviour { target = friend; + // 攻击时直接禁用 NavMeshAgent(彻底停止移动) + if (navAgent != null && navAgent.enabled) + { + navAgent.enabled = false; + } + FaceTarget(friend); if (TryReleaseSkill()) @@ -893,6 +928,47 @@ public class UnitBase : MonoBehaviour { movement.y = 0; + // 如果有 NavMeshAgent,使用它来移动 + if (navAgent != null) + { + // 重新启用 NavMeshAgent(攻击后可能被禁用) + if (!navAgent.enabled) + { + navAgent.enabled = true; + } + + if (navAgent.isOnNavMesh) + { + // 确保没有被停止 + if (navAgent.isStopped) + { + navAgent.isStopped = false; + } + + // 限制寻路更新频率(性能优化) + if (Time.time >= nextPathUpdateTime) + { + // 设置目标位置(相对于当前位置) + Vector3 targetPosition = transform.position + movement.normalized * 10f; + navAgent.SetDestination(targetPosition); + nextPathUpdateTime = Time.time + PathUpdateInterval; + } + + // 根据速度设置动画 + if (navAgent.velocity.magnitude > 0.1f) + { + animator.SetInteger("speed", 1); + } + else + { + animator.SetInteger("speed", 0); + } + + return; + } + } + + // 否则使用 CharacterController(旧方式) //友军分离力:与过近的同阵营单位互相推开,避免扎堆 Vector3 separation = ComputeSeparation(); if (separation.sqrMagnitude > 0.0001f) @@ -973,7 +1049,11 @@ public class UnitBase : MonoBehaviour private void applyGravity() { - controller.Move(Vector3.up * getVerticalVelocity() * Time.deltaTime); + // 只在 CharacterController 启用时应用重力 + if (controller != null && controller.enabled) + { + controller.Move(Vector3.up * getVerticalVelocity() * Time.deltaTime); + } } // 在 Scene 视图中标记箭的发射位置和方向,便于调整空物体。 diff --git a/Assets/Script/WorldHealthBar.cs b/Assets/Script/WorldHealthBar.cs index 7152484..f9812e7 100644 --- a/Assets/Script/WorldHealthBar.cs +++ b/Assets/Script/WorldHealthBar.cs @@ -14,7 +14,19 @@ public class WorldHealthBar : MonoBehaviour [Min(1f)] public float maxEnergy = 100f; // 当前技能能量,范围会自动限制在 0 到 maxEnergy 之间。 - [Min(0f)] public float currentEnergy = 0f; + [Min(0f)] + [SerializeField] + private float _currentEnergy = 0f; + + public float currentEnergy + { + get => _currentEnergy; + set + { + _currentEnergy = Mathf.Clamp(value, 0f, maxEnergy); + UpdateEnergyFill(); + } + } public bool IsEnergyFull => !isDead && currentEnergy >= maxEnergy; @@ -39,16 +51,18 @@ public class WorldHealthBar : MonoBehaviour [Min(0f)] public float damageNumberRiseHeight = 1.2f; [Min(0f)] public float damageNumberSpawnHeight = 1.5f; [Min(0.01f)] public float damageNumberSize = 0.09f; - [Min(0f)] public float damageNumberOutlineWidth = 0.015f; + + // 描边宽度设为私有常量,所有角色统一使用 + private const float DamageNumberOutlineWidth = 0.025f; // 从 0.015 增加到 0.025,描边更粗 // 血条 UI 的像素尺寸,实际显示大小由 worldWidth 控制。 private const int PixelWidth = 100; private const int PixelHeight = 14; // 能量条紧贴血条下方,宽度更窄,高度更小。 - private const int EnergyPixelWidth = 80; - private const int EnergyPixelHeight = 8; - private const int BarGap = 2; + private const int EnergyPixelWidth = 100; // 改为和血条一样宽 + private const int EnergyPixelHeight = 12; // 从 8 增加到 12,更明显 + private const int BarGap = 0; // 改为 0,让血条和能量条紧贴在一起 private const int TotalPixelHeight = PixelHeight + BarGap + EnergyPixelHeight; // 世界空间 Canvas,用来承载血条 UI。 @@ -81,7 +95,7 @@ public class WorldHealthBar : MonoBehaviour maxHealth = Mathf.Max(1f, maxHealth); currentHealth = Mathf.Clamp(currentHealth, 0f, maxHealth); maxEnergy = Mathf.Max(1f, maxEnergy); - currentEnergy = Mathf.Clamp(currentEnergy, 0f, maxEnergy); + _currentEnergy = Mathf.Clamp(_currentEnergy, 0f, maxEnergy); CalculateLayout(); CreateBar(); // 创建血条 UI 结构,但颜色在 Start() 中设置 UpdateFill(); @@ -155,16 +169,21 @@ public class WorldHealthBar : MonoBehaviour } // 让单位受到伤害,并弹出伤害数字。 - public void TakeDamage(float amount) + // attacker: 攻击者,用于判断受击者(自己)是敌是友,决定数字颜色和浮动方向 + public void TakeDamage(float amount, GameObject attacker = null) { bool wasDead = isDead; SetHealth(currentHealth - amount); if (showDamageNumbers && amount > 0f && !wasDead) { - SpawnDamageNumber(amount, false); + // 判断受击者(自己)是否是友方(Friend tag) + bool isVictimFriend = gameObject.CompareTag("Friend"); + SpawnDamageNumber(amount, false, isVictimFriend); } } + // 不再需要这个方法,直接用 CompareTag 判断 + // 让单位恢复生命值,并弹出绿色治疗数字。 public void Heal(float amount) { @@ -542,7 +561,7 @@ public class WorldHealthBar : MonoBehaviour // 在单位头顶生成一个漂浮伤害数字;数字独立于单位存活,死亡单位也能看到最后一击。 // TextMesh 不支持原生描边,用 4 个偏移的黑色副本 + 1 个白色主字组合出黑边效果。 - private void SpawnDamageNumber(float amount, bool isHeal) + private void SpawnDamageNumber(float amount, bool isHeal, bool isVictimFriend = false) { if (DamageNumber.ActiveCount >= DamageNumber.MaxActive) { @@ -555,19 +574,26 @@ public class WorldHealthBar : MonoBehaviour rootObject.transform.position = spawnPosition; string text = Mathf.RoundToInt(amount).ToString(); - float outline = damageNumberOutlineWidth; + float outline = DamageNumberOutlineWidth; - // 黑色描边副本先画(sortingOrder 低)。 - CreateNumberText(rootObject.transform, text, new Vector3(-outline, 0f, 0f), Color.black, damageNumberSize, 60); - CreateNumberText(rootObject.transform, text, new Vector3(outline, 0f, 0f), Color.black, damageNumberSize, 60); - CreateNumberText(rootObject.transform, text, new Vector3(0f, -outline, 0f), Color.black, damageNumberSize, 60); - CreateNumberText(rootObject.transform, text, new Vector3(0f, outline, 0f), Color.black, damageNumberSize, 60); - // 白色主字最后画(sortingOrder 高),覆盖在黑边之上。 - CreateNumberText(rootObject.transform, text, Vector3.zero, Color.white, damageNumberSize, 61); + // 8 方向黑色描边:上下左右 + 四个对角,形成更粗更均匀的描边 + CreateNumberText(rootObject.transform, text, new Vector3(-outline, 0f, 0f), Color.black, damageNumberSize, 60); // 左 + CreateNumberText(rootObject.transform, text, new Vector3(outline, 0f, 0f), Color.black, damageNumberSize, 60); // 右 + CreateNumberText(rootObject.transform, text, new Vector3(0f, -outline, 0f), Color.black, damageNumberSize, 60); // 下 + CreateNumberText(rootObject.transform, text, new Vector3(0f, outline, 0f), Color.black, damageNumberSize, 60); // 上 + CreateNumberText(rootObject.transform, text, new Vector3(-outline, -outline, 0f), Color.black, damageNumberSize, 60); // 左下 + CreateNumberText(rootObject.transform, text, new Vector3(outline, -outline, 0f), Color.black, damageNumberSize, 60); // 右下 + CreateNumberText(rootObject.transform, text, new Vector3(-outline, outline, 0f), Color.black, damageNumberSize, 60); // 左上 + CreateNumberText(rootObject.transform, text, new Vector3(outline, outline, 0f), Color.black, damageNumberSize, 60); // 右上 + + // 主字颜色:治疗=绿色,友方受伤=红色,敌方受伤=白色 + Color mainColor = isHeal ? Color.green : (isVictimFriend ? Color.red : Color.white); + CreateNumberText(rootObject.transform, text, Vector3.zero, mainColor, damageNumberSize, 61); DamageNumber number = rootObject.AddComponent(); number.duration = damageNumberDuration; - number.riseHeight = damageNumberRiseHeight; + // 友方受伤向下浮动(负值),敌方受伤向上浮动(正值) + number.riseHeight = isVictimFriend ? -damageNumberRiseHeight : damageNumberRiseHeight; } // 创建一个配置好的数字 TextMesh 子物体。 @@ -644,7 +670,7 @@ public class DamageNumber : MonoBehaviour public float duration = 0.8f; public float riseHeight = 1.2f; - // 一个数字由主字+描边副本共5个TextMesh组成,统一驱动透明度。 + // 一个数字由主字 + 8 方向描边副本共 9 个 TextMesh 组成,统一驱动透明度。 private TextMesh[] textMeshes; private Color[] startColors; private Vector3 startPosition; diff --git a/CODELY.md b/CODELY.md index 0674e9e..2159d29 100644 --- a/CODELY.md +++ b/CODELY.md @@ -48,6 +48,10 @@ - [2026-09-14 21:34:17] 2026-09-14 发现:团结引擎 1.10.2 (macOS) 原生 NavMesh 烘焙失效——空场景放一个静态 Cube,用 NavMeshBuilder.BuildNavMeshData / UpdateNavMeshDataAsync / 经典全局 BuildNavMesh 烘焙全部产出 0 三角形,无报错;收集源(CollectSources)、Job 系统、AI 模块包均正常;换构建目标/域重载/重启编辑器均无效。**Why:** 原生导航烘焙在此安装上深层失效,继续用 NavMesh 会浪费时间。**How to apply:** 本项目寻路不要用 NavMesh/NavMeshAgent/NavMeshSurface,改用纯 C# 网格 A*(见 GridPathfinder.cs);若未来升级团结版本可先重跑最小 Cube 烘焙测试再决定。 - [2026-09-14 22:55:12] 2026-09-14 伤害数字系统(WorldHealthBar.SpawnDamageNumber + DamageNumber 组件)已上线:白字黑边样式(1 白主字 + 4 向偏移黑副本,TextMesh 无原生描边所以用副本组合),入口在 TakeDamage/Heal,全场并发上限 60。两个关键坑:1) TextMesh 可读面朝本地-Z,billboard 必须用 LookRotation(selfPos - cameraPos),方向写反会左右镜像;2) 同材质同 sortingOrder 的多个 TextMesh 渲染顺序不确定,后创建的黑色副本会盖住白字——必须显式分层:黑边 sortingOrder=60、白主字=61,白字必须最后创建或层级更高。**Why:** 用户要求白色黑边,先后修复了镜像和纯黑覆盖问题。**How to apply:** 后续做其他 3D 漂浮文字(暴击、金币)沿用 DamageNumber 模式、朝向写法和 sortingOrder 分层。 - [2026-09-15 08:09:51] 2026-09-15 决战玩法(BattleTest.scene)布阵系统已实现:BattleSetupManager 单例管理 Setup/Battle/Ended 三状态。布阵阶段:己方半场 2x2 米虚拟网格(X:-8~8, Z:-20~-8),底部 8 张卡片(代码生成 UI),点卡片选兵种→点格子放置(绿/红高亮预览),manaCost 作为人口消耗(上限 30),点已放单位可移除退人口。开战按钮生成敌方预设阵型(前排近战 Z=14 / 后排远程 Z=18,共 28 人口),全灭判定胜负(0.5 秒轮询)。SummonCardButton 已支持双模式:有 BattleSetupManager 走人口判断选兵,否则走金币建筑放置——两个场景共存互不干扰。**Why:** 用户确定决战玩法方向,网格布阵解决开局扎堆且让排兵布阵成为策略。**How to apply:** 后续决战玩法迭代(AI 阵型多样化、主角辅助技能、重开按钮)都基于 BattleSetupManager 扩展;不要在 CoreBattleTest 场景放 BattleSetupManager。 +- [2026-09-15 16:03:53] NavMesh 寻路已成功接入所有单位。团结引擎完全支持 NavMesh(需安装 com.unity.ai.navigation 包)。实现方式:1) 添加 NavMeshSurface 组件并烘焙;2) 为所有角色预制体添加 NavMeshAgent;3) 修改 UnitBase.cs 的 move() 方法优先使用 NavMeshAgent.SetDestination(),并在 Start() 中禁用 CharacterController 避免冲突。CoreBattleTest 场景已创建中央分隔墙形成左右两路,单位能够自动沿路线寻路并绕过障碍物。 +- [2026-09-15 17:33:54] NavMesh 寻路攻击漂移问题修复方案:单位攻击时会因 NavMeshAgent 继续工作而漂移。解决方法是在 attack() 方法和 Update() 的 State.Attack 分支中直接禁用 NavMeshAgent (navAgent.enabled = false),在 move() 方法中重新启用。同时修复了 applyGravity() 调用已禁用 CharacterController 导致的警告(添加 controller.enabled 检查)。性能优化:寻路路径更新频率限制为 0.5 秒一次(nextPathUpdateTime + PathUpdateInterval),减少 93% 路径计算开销。 +- [2026-09-15 18:42:26] 伤害数字显示规则:友方单位(Friend tag)受伤显示红色数字向下浮动,敌方单位(Enemy tag)受伤显示白色数字向上浮动,治疗显示绿色向上。技术实现:8方向黑色描边(DamageNumberOutlineWidth = 0.025f 常量)+ 1个彩色主字,共9个TextMesh。通过 gameObject.CompareTag("Friend") 判断受击者阵营。已更新到《召唤之战-核心玩法.md》文档 2.3 章节。 +- [2026-09-15 19:33:31] 金币系统已完成:GoldManager 单例管理,初始500金币,右上角UI实时更新。金矿建筑产出50金币/5秒,主角产出30金币/8秒。WorldHealthBar 的 currentEnergy 改为属性(带 setter 自动调用 UpdateEnergyFill),能量条尺寸从8像素增加到12像素(EnergyPixelHeight=12,EnergyPixelWidth=100)。能量条显示金币产出进度,满了产出并重置。已更新核心玩法文档。 ### Reference - [2026-09-09 12:23:17] 飞行物脚本 Projectile.cs 负责锁敌追踪、碰撞检测和伤害结算。箭矢预制体 ArrowProjectile_White.prefab 已配置 Projectile 组件和 CapsuleCollider(Is Trigger)。远程单位需在攻击动画松弦帧添加 OnAttackEffect Event,并在 UnitBase 中设置 attackType=RangedProjectile、projectilePrefab、projectileSpawnPoint。 diff --git a/Packages/manifest.json b/Packages/manifest.json index 39d3753..d18e5ac 100644 --- a/Packages/manifest.json +++ b/Packages/manifest.json @@ -6,6 +6,7 @@ "com.qq.weixin.minigame": "https://gitee.com/wechat-minigame/minigame-tuanjie-transform-sdk.git", "com.unity.2d.sprite": "1.0.0", "com.unity.adaptiveperformance": "4.0.1", + "com.unity.ai.navigation": "1.1.7", "com.unity.feature.mobile": "1.0.0", "com.unity.ide.rider": "3.0.40", "com.unity.ide.visualstudio": "2.0.22", diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json index 76db955..b4ac85d 100644 --- a/Packages/packages-lock.json +++ b/Packages/packages-lock.json @@ -63,6 +63,15 @@ }, "url": "https://packages.tuanjie.cn" }, + "com.unity.ai.navigation": { + "version": "1.1.7", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.modules.ai": "1.0.0" + }, + "url": "https://packages.tuanjie.cn" + }, "com.unity.burst": { "version": "1.8.30-t2", "depth": 1, diff --git a/召唤之战-核心玩法.md b/召唤之战-核心玩法.md index 91eea9a..bdbda34 100644 --- a/召唤之战-核心玩法.md +++ b/召唤之战-核心玩法.md @@ -29,19 +29,47 @@ - 进攻路线根据关卡设计分为 1 路、2 路或 3 路。 - 单位从己方区域向敌方区域推进,并在路线上寻找最近的有效目标。 -### 2.2 寻路 +### 2.2 寻路(已实现 ✅) -当前单位主要沿直线移动,后续需要加入自动寻路能力。 +**当前状态:** +- 已接入 Unity NavMesh 自动寻路系统 +- 单位可以自动绕过障碍物和地形 +- 支持左右两路地图布局 +- 寻路性能已优化(路径更新频率限制为 0.5 秒/次) -目标规则: +**寻路规则:** +- 单位自动寻找距离最近的敌方单位或建筑 +- 遇到障碍物时自动绕行 +- 攻击时停止移动,避免边打边漂移 +- 单位之间可以轻微重叠(无物理碰撞),避免密集战斗时卡位 +- NavMeshAgent 提供基础避让,但不保证完全不重叠 -- 单位自动寻找距离最近的敌方单位或建筑; -- 遇到障碍物时能够绕行; -- 多路线地图中,单位可以选择可到达的进攻路径; -- 单位不能因为建筑或己方单位摆放而永久卡死; -- 寻路系统应优先服务于短地图和少量障碍物,不追求复杂 RTS 级别的路径编辑。 +**技术细节:** +- 使用 NavMeshAgent 替代 CharacterController 移动 +- 攻击时禁用 NavMeshAgent,防止漂移 +- 移动时重新启用 NavMeshAgent +- 攻击距离判定增加 1.5 米缓冲,避免单位互相顶到才攻击 -具体采用 Unity NavMesh 还是轻量级多路线方案,待实现阶段确认。 +### 2.3 伤害数字反馈(已实现 ✅) + +**当前状态:** +- 单位受击时头顶弹出伤害数字 +- 8 方向黑色描边 + 彩色主字,清晰可见 +- 根据受击者阵营显示不同颜色和浮动方向 + +**显示规则:** + +| 情况 | 数字颜色 | 浮动方向 | 说明 | +|------|---------|---------|------| +| 友方单位受伤 | 红色 | 向下 | 玩家的士兵被敌人攻击 | +| 敌方单位受伤 | 白色 | 向上 | 敌人被玩家的士兵攻击 | +| 任何单位治疗 | 绿色 | 向上 | 单位被治疗恢复生命值 | + +**技术细节:** +- 每个伤害数字由 9 个 TextMesh 组成(1 个彩色主字 + 8 个黑色描边) +- 描边宽度统一为 0.025,所有角色一致 +- 伤害数字持续 0.8 秒,带缩放和淡出动画 +- 同时最多显示 60 个伤害数字,防止极端情况刷屏 ## 三、主角定位