From 2b1aee3e03f53865ca9a8df2ea1b5d97653e3fd1 Mon Sep 17 00:00:00 2001 From: Matt F Date: Tue, 4 Aug 2026 22:50:33 -0700 Subject: [PATCH] Major pipeline changes to map building, introducing 3player map, and adding Shared build mode to level authoring options --- Assets/_Project/Levels/LevelAuthoring.cs | 10 + Assets/_Project/Levels/LevelData.cs | 11 + Assets/_Project/Prefabs/MatchCore.meta | 8 + .../Prefabs/MatchCore/MatchNetwork.prefab | 483 +++++ .../MatchCore/MatchNetwork.prefab.meta | 7 + .../Prefabs/MatchCore/MatchServices.prefab | 921 +++++++++ .../MatchCore/MatchServices.prefab.meta | 7 + Assets/_Project/Scenes/Levels/3Player.asset | 327 ++++ .../_Project/Scenes/Levels/3Player.asset.meta | 8 + Assets/_Project/Scenes/Levels/3Player.unity | 1682 +++++++++++++++++ .../_Project/Scenes/Levels/3Player.unity.meta | 7 + .../Scenes/Levels/3Player_TerrainData.asset | Bin 0 -> 1950772 bytes .../Levels/3Player_TerrainData.asset.meta | 8 + .../Scenes/Levels/3Player_Thumbnail.png | 3 + .../Scenes/Levels/3Player_Thumbnail.png.meta | 117 ++ .../Scenes/{UI.meta => UI_Scenes.meta} | 0 .../Scenes/{UI => UI_Scenes}/Lobby.unity | 0 .../Scenes/{UI => UI_Scenes}/Lobby.unity.meta | 0 .../Scenes/{UI => UI_Scenes}/MainMenu.unity | 1 + .../{UI => UI_Scenes}/MainMenu.unity.meta | 0 Assets/_Project/Scripts/Core/Enums.cs | 25 + .../Editor/Levels/LevelBakePipeline.cs | 41 +- .../Scripts/Editor/Levels/MapCoreExtractor.cs | 356 ++++ .../Editor/Levels/MapCoreExtractor.cs.meta | 2 + .../Scripts/Editor/Levels/MapTemplate.cs | 292 +++ .../Scripts/Editor/Levels/MapTemplate.cs.meta | 2 + .../Scripts/Editor/Levels/NewMapBuilder.cs | 578 ++++++ .../Editor/Levels/NewMapBuilder.cs.meta | 2 + .../Scripts/Editor/Levels/NewMapWindow.cs | 205 ++ .../Editor/Levels/NewMapWindow.cs.meta | 2 + .../_Project/Scripts/Gameplay/LevelLoader.cs | 33 + .../Gameplay/TowerPlacementController.cs | 2 +- .../Scripts/Gameplay/TowerPlacementManager.cs | 66 +- Assets/_Project/Settings/MapTemplate.asset | 39 + .../_Project/Settings/MapTemplate.asset.meta | 8 + Docs/Map_Pipeline.md | 188 ++ ProjectSettings/EditorBuildSettings.asset | 7 +- 37 files changed, 5418 insertions(+), 30 deletions(-) create mode 100644 Assets/_Project/Prefabs/MatchCore.meta create mode 100644 Assets/_Project/Prefabs/MatchCore/MatchNetwork.prefab create mode 100644 Assets/_Project/Prefabs/MatchCore/MatchNetwork.prefab.meta create mode 100644 Assets/_Project/Prefabs/MatchCore/MatchServices.prefab create mode 100644 Assets/_Project/Prefabs/MatchCore/MatchServices.prefab.meta create mode 100644 Assets/_Project/Scenes/Levels/3Player.asset create mode 100644 Assets/_Project/Scenes/Levels/3Player.asset.meta create mode 100644 Assets/_Project/Scenes/Levels/3Player.unity create mode 100644 Assets/_Project/Scenes/Levels/3Player.unity.meta create mode 100644 Assets/_Project/Scenes/Levels/3Player_TerrainData.asset create mode 100644 Assets/_Project/Scenes/Levels/3Player_TerrainData.asset.meta create mode 100644 Assets/_Project/Scenes/Levels/3Player_Thumbnail.png create mode 100644 Assets/_Project/Scenes/Levels/3Player_Thumbnail.png.meta rename Assets/_Project/Scenes/{UI.meta => UI_Scenes.meta} (100%) rename Assets/_Project/Scenes/{UI => UI_Scenes}/Lobby.unity (100%) rename Assets/_Project/Scenes/{UI => UI_Scenes}/Lobby.unity.meta (100%) rename Assets/_Project/Scenes/{UI => UI_Scenes}/MainMenu.unity (99%) rename Assets/_Project/Scenes/{UI => UI_Scenes}/MainMenu.unity.meta (100%) create mode 100644 Assets/_Project/Scripts/Editor/Levels/MapCoreExtractor.cs create mode 100644 Assets/_Project/Scripts/Editor/Levels/MapCoreExtractor.cs.meta create mode 100644 Assets/_Project/Scripts/Editor/Levels/MapTemplate.cs create mode 100644 Assets/_Project/Scripts/Editor/Levels/MapTemplate.cs.meta create mode 100644 Assets/_Project/Scripts/Editor/Levels/NewMapBuilder.cs create mode 100644 Assets/_Project/Scripts/Editor/Levels/NewMapBuilder.cs.meta create mode 100644 Assets/_Project/Scripts/Editor/Levels/NewMapWindow.cs create mode 100644 Assets/_Project/Scripts/Editor/Levels/NewMapWindow.cs.meta create mode 100644 Assets/_Project/Settings/MapTemplate.asset create mode 100644 Assets/_Project/Settings/MapTemplate.asset.meta create mode 100644 Docs/Map_Pipeline.md diff --git a/Assets/_Project/Levels/LevelAuthoring.cs b/Assets/_Project/Levels/LevelAuthoring.cs index 5bd8ba5..792cc5d 100644 --- a/Assets/_Project/Levels/LevelAuthoring.cs +++ b/Assets/_Project/Levels/LevelAuthoring.cs @@ -51,6 +51,16 @@ namespace TD.Levels [Tooltip("Optional author/credit text. Empty triggers a soft warning at bake time.")] public string author = ""; + [Header("Rules")] + [Tooltip("OwnerOnly: players can only build inside their own PlayerZoneVolume — the classic " + + "one-maze-each layout.\n\n" + + "Shared: any player can build on any Buildable tile, so the whole map is one " + + "cooperative maze. Zones still define territory for leak attribution, camera " + + "start, builder spawn and minimap tinting — only the build restriction lifts.\n\n" + + "Towers always belong to whoever paid for them; sell and upgrade stay owner-gated " + + "under both modes.")] + public BuildAccess buildAccess = BuildAccess.OwnerOnly; + // ------------------------------------------------------------------- // Gizmo visibility toggles. Each volume type reads its own toggle to decide whether to // draw always-on or only-when-selected. diff --git a/Assets/_Project/Levels/LevelData.cs b/Assets/_Project/Levels/LevelData.cs index faba95b..288b056 100644 --- a/Assets/_Project/Levels/LevelData.cs +++ b/Assets/_Project/Levels/LevelData.cs @@ -63,6 +63,17 @@ namespace TD.Levels public BakeOutcome LastBakeOutcome; public int LastBakeWarningCount; + // ------------------------------------------------------------------- + // Match rules. + // ------------------------------------------------------------------- + + [Header("Rules")] + [Tooltip("Whether players are restricted to building in their own zone (OwnerOnly) or can " + + "build anywhere on the map's buildable area (Shared). Affects placement permission " + + "only — OwnerGrid still drives leak attribution, camera start, builder spawn and " + + "minimap tinting under both modes.")] + public BuildAccess BuildAccess; + // ------------------------------------------------------------------- // Grid metadata. // ------------------------------------------------------------------- diff --git a/Assets/_Project/Prefabs/MatchCore.meta b/Assets/_Project/Prefabs/MatchCore.meta new file mode 100644 index 0000000..3efebf9 --- /dev/null +++ b/Assets/_Project/Prefabs/MatchCore.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cf34e1b2cedcd9a4fa7f938f8f0bf3c2 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_Project/Prefabs/MatchCore/MatchNetwork.prefab b/Assets/_Project/Prefabs/MatchCore/MatchNetwork.prefab new file mode 100644 index 0000000..e8eb442 --- /dev/null +++ b/Assets/_Project/Prefabs/MatchCore/MatchNetwork.prefab @@ -0,0 +1,483 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &1348868032911320215 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2098889495380348335} + - component: {fileID: 8734966915826773517} + - component: {fileID: 6131651964009722688} + m_Layer: 0 + m_Name: TowerPlacementManager + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &2098889495380348335 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1348868032911320215} + serializedVersion: 2 + 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: 5251454257324784754} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &8734966915826773517 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1348868032911320215} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject + GlobalObjectIdHash: 3734927306 + InScenePlacedSourceGlobalObjectIdHash: 0 + DeferredDespawnTick: 0 + Ownership: 1 + AlwaysReplicateAsRoot: 0 + SynchronizeTransform: 1 + ActiveSceneSynchronization: 0 + SceneMigrationSynchronization: 0 + SpawnWithObservers: 1 + DontDestroyWithOwner: 0 + AutoObjectParentSync: 1 + SyncOwnerTransformWhenParented: 1 + AllowOwnerToParent: 0 +--- !u!114 &6131651964009722688 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1348868032911320215} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d369496ba7887b844b1c220b524a507d, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.TowerPlacementManager + ShowTopMostFoldoutHeaderGroup: 1 + requestsPerFrame: 3 + towerDefinitions: + - {fileID: 0} + - {fileID: 11400000, guid: d5b2e8fa3c7e9b5f4a1d0c2e7f6b3a91, type: 2} + - {fileID: 11400000, guid: 0f693e29ca953e1439e10cb8f12e4b30, type: 2} + - {fileID: 11400000, guid: 86d4c3ab00d4c654eb4c255280ee5701, type: 2} + - {fileID: 11400000, guid: 04219895bbea4fb9a94fd62fef35bf2a, type: 2} + - {fileID: 11400000, guid: e3f1a9c2b5d84e76a0c3f1e8d27b4905, type: 2} + startingDeck: + - {fileID: 11400000, guid: d5b2e8fa3c7e9b5f4a1d0c2e7f6b3a91, type: 2} + - {fileID: 11400000, guid: 0f693e29ca953e1439e10cb8f12e4b30, type: 2} +--- !u!1 &5626802001211498962 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3648445760525794609} + - component: {fileID: 4563436515829454556} + - component: {fileID: 8936124320851695101} + m_Layer: 0 + m_Name: WaveManager + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &3648445760525794609 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5626802001211498962} + serializedVersion: 2 + 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: 5251454257324784754} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &4563436515829454556 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5626802001211498962} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject + GlobalObjectIdHash: 3957247190 + InScenePlacedSourceGlobalObjectIdHash: 0 + DeferredDespawnTick: 0 + Ownership: 1 + AlwaysReplicateAsRoot: 0 + SynchronizeTransform: 1 + ActiveSceneSynchronization: 0 + SceneMigrationSynchronization: 0 + SpawnWithObservers: 1 + DontDestroyWithOwner: 0 + AutoObjectParentSync: 1 + SyncOwnerTransformWhenParented: 1 + AllowOwnerToParent: 0 +--- !u!114 &8936124320851695101 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5626802001211498962} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 81d8e215d8419404ea4d959196cd9cc3, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.WaveManager + ShowTopMostFoldoutHeaderGroup: 1 + startingLives: 40 + draftTimeSeconds: 30 + voteTimeSeconds: 25 + goldConfig: {fileID: 11400000, guid: d5e01c919f14a1e4888ad494a159241b, type: 2} + enemyScalingConfig: {fileID: 11400000, guid: ae9fde0b564e20440ac2e20861fa1ca6, type: 2} +--- !u!1 &6226139915412633039 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8547990667945757531} + - component: {fileID: 4703036714451320211} + - component: {fileID: 2895480021437825520} + m_Layer: 0 + m_Name: MatchState + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &8547990667945757531 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6226139915412633039} + serializedVersion: 2 + 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: 5251454257324784754} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &4703036714451320211 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6226139915412633039} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject + GlobalObjectIdHash: 1618207171 + InScenePlacedSourceGlobalObjectIdHash: 0 + DeferredDespawnTick: 0 + Ownership: 1 + AlwaysReplicateAsRoot: 0 + SynchronizeTransform: 1 + ActiveSceneSynchronization: 0 + SceneMigrationSynchronization: 0 + SpawnWithObservers: 1 + DontDestroyWithOwner: 0 + AutoObjectParentSync: 1 + SyncOwnerTransformWhenParented: 1 + AllowOwnerToParent: 0 +--- !u!114 &2895480021437825520 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6226139915412633039} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a34585be59d49e94b811d96be51c5088, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.MatchState + ShowTopMostFoldoutHeaderGroup: 1 +--- !u!1 &8213601217886697539 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1789974153803072425} + - component: {fileID: 5759999417597858157} + - component: {fileID: 8805989965283647635} + m_Layer: 0 + m_Name: RunState + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1789974153803072425 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8213601217886697539} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 38.30481, y: 0.5, z: 155.93135} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 5251454257324784754} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &5759999417597858157 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8213601217886697539} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject + GlobalObjectIdHash: 3660389945 + InScenePlacedSourceGlobalObjectIdHash: 0 + DeferredDespawnTick: 0 + Ownership: 1 + AlwaysReplicateAsRoot: 0 + SynchronizeTransform: 1 + ActiveSceneSynchronization: 0 + SceneMigrationSynchronization: 0 + SpawnWithObservers: 1 + DontDestroyWithOwner: 0 + AutoObjectParentSync: 1 + SyncOwnerTransformWhenParented: 1 + AllowOwnerToParent: 0 +--- !u!114 &8805989965283647635 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8213601217886697539} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a293cf6dca91dd2478c9f4e799cf9e0d, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.Waves.RunState + ShowTopMostFoldoutHeaderGroup: 1 + runDefinition: {fileID: 11400000, guid: 1bb81a966192c344d94cce2628c1832b, type: 2} +--- !u!1 &8429081419068942390 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5251454257324784754} + m_Layer: 0 + m_Name: MatchNetwork + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &5251454257324784754 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8429081419068942390} + serializedVersion: 2 + 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: 2182889149551291466} + - {fileID: 8547990667945757531} + - {fileID: 1789974153803072425} + - {fileID: 2098889495380348335} + - {fileID: 3648445760525794609} + - {fileID: 2625678984567986094} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &9094815948999422851 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2182889149551291466} + - component: {fileID: 8307773927879075679} + - component: {fileID: 3604854611554599773} + m_Layer: 0 + m_Name: ChatService + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &2182889149551291466 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9094815948999422851} + serializedVersion: 2 + 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: 5251454257324784754} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &8307773927879075679 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9094815948999422851} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject + GlobalObjectIdHash: 1681065116 + InScenePlacedSourceGlobalObjectIdHash: 0 + DeferredDespawnTick: 0 + Ownership: 1 + AlwaysReplicateAsRoot: 0 + SynchronizeTransform: 1 + ActiveSceneSynchronization: 0 + SceneMigrationSynchronization: 0 + SpawnWithObservers: 1 + DontDestroyWithOwner: 0 + AutoObjectParentSync: 1 + SyncOwnerTransformWhenParented: 1 + AllowOwnerToParent: 0 +--- !u!114 &3604854611554599773 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9094815948999422851} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 816890bb20c416b419e38d3d4b91ffca, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.ChatService + ShowTopMostFoldoutHeaderGroup: 1 +--- !u!1 &9150709944481815107 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2625678984567986094} + - component: {fileID: 1287556557852043940} + - component: {fileID: 4386956365137913543} + m_Layer: 0 + m_Name: WaveVote + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &2625678984567986094 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9150709944481815107} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 38.30481, y: 0.5, z: 155.93135} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 5251454257324784754} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1287556557852043940 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9150709944481815107} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject + GlobalObjectIdHash: 3520766009 + InScenePlacedSourceGlobalObjectIdHash: 0 + DeferredDespawnTick: 0 + Ownership: 1 + AlwaysReplicateAsRoot: 0 + SynchronizeTransform: 1 + ActiveSceneSynchronization: 0 + SceneMigrationSynchronization: 0 + SpawnWithObservers: 1 + DontDestroyWithOwner: 0 + AutoObjectParentSync: 1 + SyncOwnerTransformWhenParented: 1 + AllowOwnerToParent: 0 +--- !u!114 &4386956365137913543 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9150709944481815107} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a18321dc2d138034fbdb5f705f19f893, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.EnemyUpgrades.WaveVote + ShowTopMostFoldoutHeaderGroup: 1 + optionsPerVote: 3 diff --git a/Assets/_Project/Prefabs/MatchCore/MatchNetwork.prefab.meta b/Assets/_Project/Prefabs/MatchCore/MatchNetwork.prefab.meta new file mode 100644 index 0000000..707a454 --- /dev/null +++ b/Assets/_Project/Prefabs/MatchCore/MatchNetwork.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 7116de1968afffb4990ee24f709612fb +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_Project/Prefabs/MatchCore/MatchServices.prefab b/Assets/_Project/Prefabs/MatchCore/MatchServices.prefab new file mode 100644 index 0000000..edfdc8b --- /dev/null +++ b/Assets/_Project/Prefabs/MatchCore/MatchServices.prefab @@ -0,0 +1,921 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &216401704418653358 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2369632775351055227} + - component: {fileID: 5469845921758518005} + - component: {fileID: 1431563384465486267} + m_Layer: 0 + m_Name: HUD + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &2369632775351055227 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 216401704418653358} + serializedVersion: 2 + 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: 3833381251955063088} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &5469845921758518005 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 216401704418653358} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 19102, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: UnityEngine.dll::UnityEngine.UIElements.UIDocument + m_PanelSettings: {fileID: 11400000, guid: 6aa0af71585acea4db4995c3931dc946, type: 2} + m_ParentUI: {fileID: 0} + sourceAsset: {fileID: 9197481963319205126, guid: eba711c1def2b194584102ceb5517c48, type: 3} + m_SortingOrder: 0 + m_Position: 0 + m_WorldSpaceSizeMode: 1 + m_WorldSpaceWidth: 1920 + m_WorldSpaceHeight: 1080 + m_PivotReferenceSize: 0 + m_Pivot: 0 + m_WorldSpaceCollider: {fileID: 0} +--- !u!114 &1431563384465486267 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 216401704418653358} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1c69cd177f09f0c419288f73b49df886, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.UI.HUDController + placementController: {fileID: 7706260725108150093} + paintController: {fileID: 559798155559411408} + placementManager: {fileID: 0} + cameraController: {fileID: 5042310339586537117} + rejectionMessageDuration: 2.5 + menuButtonIcon: {fileID: 0} + chatMaxHeight: 280 + chatMaxMessages: 2147483647 + chatSystemColor: {r: 1, g: 0.7, b: 0.2, a: 1} + chatPlayerColor: {r: 0.92, g: 0.92, b: 0.92, a: 1} +--- !u!1 &1445952844252628864 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3833381251955063088} + - component: {fileID: 6850685008819507485} + - component: {fileID: 3524271020287320838} + - component: {fileID: 6600478213912852129} + - component: {fileID: 191939159250915621} + - component: {fileID: 7706260725108150093} + - component: {fileID: 559798155559411408} + - component: {fileID: 1988948222073846279} + - component: {fileID: 2077830364583566817} + - component: {fileID: 8797807118405570736} + - component: {fileID: 3273128039403554245} + - component: {fileID: 1661838386639436151} + - component: {fileID: 8864891455444378183} + - component: {fileID: 7594921744928559756} + - component: {fileID: 1678455881203478607} + - component: {fileID: 8637796564860235120} + - component: {fileID: 4396752746502665908} + - component: {fileID: 9162204174128098398} + - component: {fileID: 4044629536480845444} + - component: {fileID: 1951038390230828916} + m_Layer: 0 + m_Name: MatchServices + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &3833381251955063088 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1445952844252628864} + serializedVersion: 2 + 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: 2369632775351055227} + - {fileID: 2545698982756849348} + - {fileID: 9174177271844320236} + - {fileID: 7648787753941018277} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &6850685008819507485 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1445952844252628864} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a303b690faebb0e4e930d1714afa424e, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.LevelLoader + level: {fileID: 0} + buildablePlaneLayerName: BuildablePlane + drawGridBounds: 1 + drawWalkability: 1 + drawBuildablePlane: 1 + drawOwnerBorders: 1 +--- !u!114 &3524271020287320838 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1445952844252628864} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: de7d013503af0f74c950f215f8dae1c0, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.PathfindingService + recomputeBudgetMs: 1.5 +--- !u!114 &6600478213912852129 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1445952844252628864} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dc307e7e94967894584e8e6050fc38cf, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.SelectionState +--- !u!114 &191939159250915621 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1445952844252628864} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e28d10549c8d2ac4585eded3ad8d2198, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.SelectionVisualizer + selectionRingPrefab: {fileID: 8648063358813763958, guid: 74757e379bac0e444aabab5e388e17c6, type: 3} + yOffset: 0.02 + projectionLayerMask: + serializedVersion: 2 + m_Bits: 960 +--- !u!114 &7706260725108150093 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1445952844252628864} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 124253f2cbc2d9f46befb6e1763cd6b9, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.TowerPlacementController + settings: {fileID: 11400000, guid: 18f99b4b94d13eb429d4dfb9b0b37b4b, type: 2} + buildablePlaneLayerMask: + serializedVersion: 2 + m_Bits: 64 + raycastMaxDistance: 500 +--- !u!114 &559798155559411408 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1445952844252628864} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 6b81770471b644b3aa0e58d4a108dddd, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.TowerPaintController + raycastMaxDistance: 500 + cursorSize: 28 +--- !u!114 &1988948222073846279 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1445952844252628864} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: cc99a2b3d3e8d8178a74e1d68a34553c, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.BuilderSpellCastController + groundLayerMask: + serializedVersion: 2 + m_Bits: 128 + raycastMaxDistance: 500 + aimDecal: {fileID: 0} + pointReticleDiameter: 1.5 + projectionDepth: 50 +--- !u!114 &2077830364583566817 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1445952844252628864} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a31401869def6d64c87e645f1da1aa2a, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.UI.FloatingTextSpawner + prefab: {fileID: 4844901775730304629, guid: e5002bdc91043d24994f0b1cb578de56, type: 3} + goldColor: {r: 1, g: 0.84, b: 0.2, a: 1} + livesColor: {r: 0.95, g: 0.25, b: 0.25, a: 1} + verticalOffset: 2 + positionJitter: 0.4 + verticalJitter: 0.2 +--- !u!114 &8797807118405570736 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1445952844252628864} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e2708c6bac8136f45b48c899d3d40630, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.VFX.SellEffectSpawner + coinBurstPrefab: {fileID: 2313150535691989867, guid: 31f8d8c320b42c54d886d610fb13a1e7, type: 3} + sellSound: + clip: {fileID: 8300000, guid: 778b3d5981f4c3045a475794435f43cc, type: 3} + volume: 1 + minPitch: 0.95 + maxPitch: 1.05 + verticalOffset: 0.75 +--- !u!114 &3273128039403554245 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1445952844252628864} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9ec21c01769ef58d1ac26ba89668eeaa, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Audio.AudioManager + categories: + - category: 0 + maxVoices: 6 + volume: 0.5 + - category: 1 + maxVoices: 4 + volume: 0.5 + - category: 2 + maxVoices: 4 + volume: 0.5 +--- !u!82 &1661838386639436151 +AudioSource: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1445952844252628864} + m_Enabled: 1 + serializedVersion: 4 + OutputAudioMixerGroup: {fileID: 0} + m_audioClip: {fileID: 0} + m_Resource: {fileID: 0} + m_PlayOnAwake: 1 + m_Volume: 1 + m_Pitch: 1 + Loop: 0 + Mute: 0 + Spatialize: 0 + SpatializePostEffects: 0 + Priority: 128 + DopplerLevel: 1 + MinDistance: 1 + MaxDistance: 500 + Pan2D: 0 + rolloffMode: 0 + BypassEffects: 0 + BypassListenerEffects: 0 + BypassReverbZones: 0 + rolloffCustomCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + - serializedVersion: 3 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + panLevelCustomCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + spreadCustomCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + reverbZoneMixCustomCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 +--- !u!114 &8864891455444378183 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1445952844252628864} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 292ad37b9e4d1d7c28e59cf4dc1e99fa, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Audio.MusicPlayer + clip: {fileID: 8300000, guid: d4626563ad3c90179b247207e7b9f0be, type: 3} + volume: 0.632 +--- !u!114 &7594921744928559756 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1445952844252628864} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 6226c6e672c5b358a9cdc2a1bee47daf, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.BuilderEffects.BuilderEffectPool + effects: + - {fileID: 11400000, guid: 419fac0976a3e0a20827beff81826161, type: 2} +--- !u!114 &1678455881203478607 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1445952844252628864} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 36a7be1b3824682b8a183fbcf8564652, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.BuilderSpells.BuilderSpellPool + spells: + - {fileID: 11400000, guid: 051c48f416e5366b59d49b0e062333ac, type: 2} + - {fileID: 11400000, guid: d893f46b037536b4ba91307e184cecfe, type: 2} + - {fileID: 11400000, guid: 364edf6abc3c31e33b53d0a01142b8ab, type: 2} +--- !u!114 &8637796564860235120 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1445952844252628864} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4409eb25a8be555de8dc3a73d4ed95db, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.EnemyAbilities.EnemyAbilityPool + abilities: + - {fileID: 11400000, guid: 0305468bc8f912d429a8b20bf23f947c, type: 2} + - {fileID: 11400000, guid: 030f10c9a264e544ea3e0f4fdb4171bd, type: 2} + - {fileID: 11400000, guid: cb2ec6bb70f57d0429b99b7cd4c7db73, type: 2} + - {fileID: 11400000, guid: a18691a20d75f17479a83b3e171759e7, type: 2} + - {fileID: 11400000, guid: c64c7121b0456bb4a873acec9e0abf91, type: 2} +--- !u!114 &4396752746502665908 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1445952844252628864} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: c4d98a01d9b9a7b438a6f91b0b7f498f, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.EnemyUpgrades.EnemyUpgradePool + options: + - {fileID: 11400000, guid: eef28ca7b8844504e9d75ff903a3bb61, type: 2} + - {fileID: 11400000, guid: 46e2a6a59c0a3034f9fa44681d9ba422, type: 2} + - {fileID: 11400000, guid: 80fb851b702ff304183cb6e89c4aa245, type: 2} + - {fileID: 11400000, guid: a67aa3644d2ad4847a47040f53fea26f, type: 2} + - {fileID: 11400000, guid: 37d761966a349ba4cb4141f913224d5c, type: 2} + - {fileID: 11400000, guid: f6bfb033a15b6d0419587b80a8286bd1, type: 2} +--- !u!114 &9162204174128098398 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1445952844252628864} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5a7e1f3c9d2b4867a1c0e4f8b3d6792a, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.Draft.DraftPool + options: + - {fileID: 11400000, guid: 6b1d3f8a2c5e4097b8a1d0c3e6f9b240, type: 2} + - {fileID: 11400000, guid: f4a2b8d1c6e93f05a7b2d4c8e1f6a930, type: 2} + - {fileID: 11400000, guid: 0b9f4905752751f44b9959b84b620266, type: 2} + - {fileID: 11400000, guid: 65ff25c1c8a89f7df8e88f71968c1c98, type: 2} + - {fileID: 11400000, guid: 5f390de69ba43b2a6a0d89cf09580320, type: 2} + - {fileID: 11400000, guid: 29b35841f7e5db454903798cb5d83434, type: 2} + - {fileID: 11400000, guid: d180030b68a9a5e1da497bf6f83451d4, type: 2} +--- !u!114 &4044629536480845444 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1445952844252628864} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9d3a7c5e1b8f42606a2d4e9f1c7b3850, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.Draft.DraftService + optionsPerDraft: 3 + rerollCost: 50 +--- !u!114 &1951038390230828916 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1445952844252628864} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 468de2ce61e73ce4595ba4792874b076, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Dev.DevWaveControls + hotkey: 94 + grantTowerHotkey: 101 + skipToBossHotkey: 100 +--- !u!1 &2434986514412567376 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 9174177271844320236} + - component: {fileID: 5042310339586537117} + m_Layer: 0 + m_Name: CameraRig + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &9174177271844320236 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2434986514412567376} + serializedVersion: 2 + 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: 7042465335914098461} + m_Father: {fileID: 3833381251955063088} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &5042310339586537117 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2434986514412567376} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1e670a36689801e428873c5712ea3679, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.CameraController + cameraChild: {fileID: 5566698628747533439} + basePanSpeed: 12 + edgePanMarginPixels: 16 + edgePanEnabled: 1 + minDollyDistance: 5 + maxDollyDistance: 50 + startDollyDistance: 25 + zoomSpeed: 3 + cursorAnchoredZoom: 1 + minPitchDegrees: 30 + maxPitchDegrees: 75 + startPitchDegrees: 50 + pitchSpeed: 4 +--- !u!1 &2936049029850371745 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7042465335914098461} + - component: {fileID: 5566698628747533439} + - component: {fileID: 9062733689301865828} + - component: {fileID: 7984992879034746998} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &7042465335914098461 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2936049029850371745} + serializedVersion: 2 + 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: 9174177271844320236} + m_LocalEulerAnglesHint: {x: 45, y: -90, z: 0} +--- !u!20 &5566698628747533439 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2936049029850371745} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_projectionMatrixMode: 1 + m_GateFitMode: 2 + m_FOVAxisMode: 0 + m_Iso: 200 + m_ShutterSpeed: 0.005 + m_Aperture: 16 + m_FocusDistance: 10 + m_FocalLength: 50 + m_BladeCount: 5 + m_Curvature: {x: 2, y: 11} + m_BarrelClipping: 0.25 + m_Anamorphism: 0 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!81 &9062733689301865828 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2936049029850371745} + m_Enabled: 1 +--- !u!114 &7984992879034746998 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2936049029850371745} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a79441f348de89743a2939f4d699eac1, type: 3} + m_Name: + m_EditorClassIdentifier: + m_RenderShadows: 1 + m_RequiresDepthTextureOption: 2 + m_RequiresOpaqueTextureOption: 2 + m_CameraType: 0 + m_Cameras: [] + m_RendererIndex: -1 + m_VolumeLayerMask: + serializedVersion: 2 + m_Bits: 1 + m_VolumeTrigger: {fileID: 0} + m_VolumeFrameworkUpdateModeOption: 2 + m_RenderPostProcessing: 1 + m_Antialiasing: 0 + m_AntialiasingQuality: 2 + m_StopNaN: 0 + m_Dithering: 0 + m_ClearDepth: 1 + m_AllowXRRendering: 1 + m_AllowHDROutput: 1 + m_UseScreenCoordOverride: 0 + m_ScreenSizeOverride: {x: 0, y: 0, z: 0, w: 0} + m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0} + m_RequiresDepthTexture: 0 + m_RequiresColorTexture: 0 + m_TaaSettings: + m_Quality: 3 + m_FrameInfluence: 0.1 + m_JitterScale: 1 + m_MipBias: 0 + m_VarianceClampScale: 0.9 + m_ContrastAdaptiveSharpening: 0 + m_Version: 2 +--- !u!1 &3584612494616813666 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2545698982756849348} + - component: {fileID: 9037991996416952042} + - component: {fileID: 6848311735055501230} + m_Layer: 0 + m_Name: DebugConsole + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &2545698982756849348 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3584612494616813666} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: -52.51635, y: 0, z: -27.6311} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 3833381251955063088} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &9037991996416952042 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3584612494616813666} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 19102, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: UnityEngine.dll::UnityEngine.UIElements.UIDocument + m_PanelSettings: {fileID: 11400000, guid: 6aa0af71585acea4db4995c3931dc946, type: 2} + m_ParentUI: {fileID: 0} + sourceAsset: {fileID: 0} + m_SortingOrder: 1 + m_Position: 0 + m_WorldSpaceSizeMode: 1 + m_WorldSpaceWidth: 1920 + m_WorldSpaceHeight: 1080 + m_PivotReferenceSize: 0 + m_Pivot: 0 + m_WorldSpaceCollider: {fileID: 0} +--- !u!114 &6848311735055501230 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3584612494616813666} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 7c6a808e8291552d0b64e36a210879c4, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Dev.DebugConsole + toggleKey: 4 +--- !u!1 &5697898299420166755 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7648787753941018277} + - component: {fileID: 4271007794402033964} + - component: {fileID: 1710569614611447900} + m_Layer: 0 + m_Name: Directional Light + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &7648787753941018277 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5697898299420166755} + serializedVersion: 2 + m_LocalRotation: {x: 0.0000014901161, y: 0.9063078, z: -0.42261824, w: 0.00000295043} + m_LocalPosition: {x: -17, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 3833381251955063088} + m_LocalEulerAnglesHint: {x: 50, y: 180, z: 0} +--- !u!108 &4271007794402033964 +Light: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5697898299420166755} + m_Enabled: 1 + serializedVersion: 13 + m_Type: 1 + m_Color: {r: 0.8156863, g: 0.9098039, b: 1, a: 1} + m_Intensity: 0.65 + m_Range: 10 + m_SpotAngle: 30 + m_InnerSpotAngle: 21.80208 + m_CookieSize2D: {x: 10, y: 10} + m_Shadows: + m_Type: 2 + m_Resolution: -1 + m_CustomResolution: -1 + m_Strength: 1 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_CullingMatrixOverride: + e00: 1 + e01: 0 + e02: 0 + e03: 0 + e10: 0 + e11: 1 + e12: 0 + e13: 0 + e20: 0 + e21: 0 + e22: 1 + e23: 0 + e30: 0 + e31: 0 + e32: 0 + e33: 1 + m_UseCullingMatrixOverride: 0 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingLayerMask: 1 + m_Lightmapping: 4 + m_LightShadowCasterMode: 0 + m_AreaSize: {x: 1, y: 1} + m_BounceIntensity: 1 + m_ColorTemperature: 7191 + m_UseColorTemperature: 1 + m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} + m_UseBoundingSphereOverride: 0 + m_UseViewFrustumForShadowCasterCull: 1 + m_ForceVisible: 0 + m_ShapeRadius: 0 + m_ShadowAngle: 0 + m_LightUnit: 1 + m_LuxAtDistance: 1 + m_EnableSpotReflector: 1 +--- !u!114 &1710569614611447900 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5697898299420166755} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 474bcb49853aa07438625e644c072ee6, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UsePipelineSettings: 1 + m_AdditionalLightsShadowResolutionTier: 2 + m_CustomShadowLayers: 0 + m_LightCookieSize: {x: 1, y: 1} + m_LightCookieOffset: {x: 0, y: 0} + m_SoftShadowQuality: 1 + m_RenderingLayersMask: + serializedVersion: 0 + m_Bits: 1 + m_ShadowRenderingLayersMask: + serializedVersion: 0 + m_Bits: 1 + m_Version: 4 + m_LightLayerMask: 1 + m_ShadowLayerMask: 1 + m_RenderingLayers: 1 + m_ShadowRenderingLayers: 1 diff --git a/Assets/_Project/Prefabs/MatchCore/MatchServices.prefab.meta b/Assets/_Project/Prefabs/MatchCore/MatchServices.prefab.meta new file mode 100644 index 0000000..0ec6795 --- /dev/null +++ b/Assets/_Project/Prefabs/MatchCore/MatchServices.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 13be8328f6275e14da787f25c94683ee +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_Project/Scenes/Levels/3Player.asset b/Assets/_Project/Scenes/Levels/3Player.asset new file mode 100644 index 0000000..e991500 --- /dev/null +++ b/Assets/_Project/Scenes/Levels/3Player.asset @@ -0,0 +1,327 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 6d4e9c37b9205f3408a8225823f7a4da, type: 3} + m_Name: 3Player + m_EditorClassIdentifier: Assembly-CSharp::TD.Levels.LevelData + MapName: 3Player + PlayerCount: 3 + MapDescription: 3 Player new design map + Author: BigBoysFellowship + MapThumbnail: {fileID: 21300000, guid: 7e33bd8556d93f04eb4f5c38006a7880, type: 3} + ScenePath: Assets/_Project/Scenes/Levels/3Player.unity + AuthoringHash: bb69927c7e56c27f8073227f6af654d08b2b8a72ed8439ac4fb5392cb4132b67 + LastBakeTimestamp: 2026-08-05T05:39:40.7353238Z + LastBakeOutcome: 1 + LastBakeWarningCount: 3 + BuildAccess: 1 + GridOriginTile: {x: 0, y: 0} + GridSize: {x: 100, y: 100} + PlacementGrid: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020202020202020202000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020202020202020202020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000202020202020202020200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020202020202020202000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020202020202020202020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010202020202020202010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000002020202020101010101010101010101010101010101010101010101010101010101010101010101010101010102020202020202020202010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000020202020201010101010101010101010101010101010101010101010101010101010101010101010101010101020202020202020202020101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000202020202010101010101010101010101010101010101010101010101010101010101010101010101010101010202020202020202020201010101010101010101010101010101010101010101010101010101010101010101010101010101000000000002020202020101010101010101010101010101010101010101010101010101010101010101010101010101010102020202020202020202010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000020202020201010101010101010101010101010101010101010101010101010101010101010101010101010101020202020202020202020101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000202020202010101010101010101010101010101010101010101010101010101010101010101010101010101010202020202020202020201010101010101010101010101010101010101010101010101010101010101010101010101010101000000000002020202020101010101010101010101010101010101010101010101010101010101010101010101010101010102020202020202020202010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000020202020201010101010101010101010101010101010101010101010101010101010101010101010101010101020202020202020202020101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000202020202010101010101010101010101010101010101010101010101010101010101010101010101010101010202020202020202020201010101010101010101010101010101010101010101010101010101010101010101010101010101000000000002020202020101010101010101010101010101010101010101010101010101010101010101010101010101010102020202020202020202010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101020202020202020201010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000202020202020202020200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020202020202020202000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020202020202020202020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000202020202020202020200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020202020202020202000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + WalkabilityGrid: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001010101010101010101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101010101010101010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001010101010101010101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101010101010101010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001010101010101010101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101010101010101010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001010101010101010101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + OwnerGrid: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000202020202020202020202020202020202020202020202020202020202020202020202020202020200000000000000000000020202020202020202020202020202020202020202020202020202020202020202020202020202020000000000000000000002020202020202020202020202020202020202020202020202020202020202020202020202020202000000000000000000000202020202020202020202020202020202020202020202020202020202020202020202020202020200000000000000000000020202020202020202020202020202020202020202020202020202020202020202020202020202020000000000000000000002020202020202020202020202020202020202020202020202020202020202020202020202020202000000000000000000000202020202020202020202020202020202020202020202020202020202020202020202020202020200000000000000000000020202020202020202020202020202020202020202020202020202020202020202020202020202020000000000000000000002020202020202020202020202020202020202020202020202020202020202020202020202020202000000000000000000000202020202020202020202020202020202020202020202020202020202020202020202020202020200000000000000000000020202020202020202020202020202020202020202020202020202020202020202020202020202020000000000000000000002020202020202020202020202020202020202020202020202020202020202020202020202020202000000000000000000000202020202020202020202020202020202020202020202020202020202020202020202020202020200000000000000000000020202020202020202020202020202020202020202020202020202020202020202020202020202020000000000000000000002020202020202020202020202020202020202020202020202020202020202020202020202020202000000000000000000000202020202020202020202020202020202020202020202020202020202020202020202020202020200000000000000000000020202020202020202020202020202020202020202020202020202020202020202020202020202020000000000000000000002020202020202020202020202020202020202020202020202020202020202020202020202020202000000000000000000000202020202020202020202020202020202020202020202020202020202020202020202020202020200000000000000000000020202020202020202020202020202020202020202020202020202020202020202020202020202020000000000000000000003030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303000000000000000000000303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030000000000000000000003030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303000000000000000000000303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030000000000000000000003030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303000000000000000000000303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030000000000000000000003030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303000000000000000000000303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030000000000000000000003030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303000000000000000000000303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030000000000000000000003030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303000000000000000000000303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030000000000000000000003030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303000000000000000000000303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030000000000000000000003030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303000000000000000000000303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030000000000000000000003030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303000000000000000000000303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030000000000000000000003030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303000000000000000000000303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030000000000000000000003030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303000000000000000000000303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030000000000000000000003030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303000000000000000000000303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030000000000000000000003030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303000000000000000000000303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030000000000000000000003030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + MapAreaGrid: 01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101 + PlayerZones: + - Owner: 1 + Spawners: + - SpawnerIdInZone: 0 + TilePosition: {x: 50, y: 3} + TileArea: + - {x: 45, y: 0} + - {x: 46, y: 0} + - {x: 47, y: 0} + - {x: 48, y: 0} + - {x: 49, y: 0} + - {x: 50, y: 0} + - {x: 51, y: 0} + - {x: 52, y: 0} + - {x: 53, y: 0} + - {x: 54, y: 0} + - {x: 45, y: 1} + - {x: 46, y: 1} + - {x: 47, y: 1} + - {x: 48, y: 1} + - {x: 49, y: 1} + - {x: 50, y: 1} + - {x: 51, y: 1} + - {x: 52, y: 1} + - {x: 53, y: 1} + - {x: 54, y: 1} + - {x: 45, y: 2} + - {x: 46, y: 2} + - {x: 47, y: 2} + - {x: 48, y: 2} + - {x: 49, y: 2} + - {x: 50, y: 2} + - {x: 51, y: 2} + - {x: 52, y: 2} + - {x: 53, y: 2} + - {x: 54, y: 2} + - {x: 45, y: 3} + - {x: 46, y: 3} + - {x: 47, y: 3} + - {x: 48, y: 3} + - {x: 49, y: 3} + - {x: 50, y: 3} + - {x: 51, y: 3} + - {x: 52, y: 3} + - {x: 53, y: 3} + - {x: 54, y: 3} + - {x: 45, y: 4} + - {x: 46, y: 4} + - {x: 47, y: 4} + - {x: 48, y: 4} + - {x: 49, y: 4} + - {x: 50, y: 4} + - {x: 51, y: 4} + - {x: 52, y: 4} + - {x: 53, y: 4} + - {x: 54, y: 4} + Facing: 0 + LeakExits: + - Target: 2 + TileArea: + - {x: 36, y: 44} + - {x: 37, y: 44} + - {x: 38, y: 44} + - {x: 39, y: 44} + - {x: 40, y: 44} + - {x: 41, y: 44} + - {x: 42, y: 44} + - {x: 43, y: 44} + NormalizedWeight: 1 + - Owner: 2 + Spawners: + - SpawnerIdInZone: 0 + TilePosition: {x: 2, y: 50} + TileArea: + - {x: 0, y: 45} + - {x: 1, y: 45} + - {x: 2, y: 45} + - {x: 3, y: 45} + - {x: 4, y: 45} + - {x: 0, y: 46} + - {x: 1, y: 46} + - {x: 2, y: 46} + - {x: 3, y: 46} + - {x: 4, y: 46} + - {x: 0, y: 47} + - {x: 1, y: 47} + - {x: 2, y: 47} + - {x: 3, y: 47} + - {x: 4, y: 47} + - {x: 0, y: 48} + - {x: 1, y: 48} + - {x: 2, y: 48} + - {x: 3, y: 48} + - {x: 4, y: 48} + - {x: 0, y: 49} + - {x: 1, y: 49} + - {x: 2, y: 49} + - {x: 3, y: 49} + - {x: 4, y: 49} + - {x: 0, y: 50} + - {x: 1, y: 50} + - {x: 2, y: 50} + - {x: 3, y: 50} + - {x: 4, y: 50} + - {x: 0, y: 51} + - {x: 1, y: 51} + - {x: 2, y: 51} + - {x: 3, y: 51} + - {x: 4, y: 51} + - {x: 0, y: 52} + - {x: 1, y: 52} + - {x: 2, y: 52} + - {x: 3, y: 52} + - {x: 4, y: 52} + - {x: 0, y: 53} + - {x: 1, y: 53} + - {x: 2, y: 53} + - {x: 3, y: 53} + - {x: 4, y: 53} + - {x: 0, y: 54} + - {x: 1, y: 54} + - {x: 2, y: 54} + - {x: 3, y: 54} + - {x: 4, y: 54} + Facing: 0 + LeakExits: + - Target: 3 + TileArea: + - {x: 36, y: 55} + - {x: 37, y: 55} + - {x: 38, y: 55} + - {x: 39, y: 55} + - {x: 40, y: 55} + - {x: 41, y: 55} + - {x: 42, y: 55} + - {x: 43, y: 55} + NormalizedWeight: 1 + - Owner: 3 + Spawners: + - SpawnerIdInZone: 0 + TilePosition: {x: 50, y: 97} + TileArea: + - {x: 45, y: 95} + - {x: 46, y: 95} + - {x: 47, y: 95} + - {x: 48, y: 95} + - {x: 49, y: 95} + - {x: 50, y: 95} + - {x: 51, y: 95} + - {x: 52, y: 95} + - {x: 53, y: 95} + - {x: 54, y: 95} + - {x: 45, y: 96} + - {x: 46, y: 96} + - {x: 47, y: 96} + - {x: 48, y: 96} + - {x: 49, y: 96} + - {x: 50, y: 96} + - {x: 51, y: 96} + - {x: 52, y: 96} + - {x: 53, y: 96} + - {x: 54, y: 96} + - {x: 45, y: 97} + - {x: 46, y: 97} + - {x: 47, y: 97} + - {x: 48, y: 97} + - {x: 49, y: 97} + - {x: 50, y: 97} + - {x: 51, y: 97} + - {x: 52, y: 97} + - {x: 53, y: 97} + - {x: 54, y: 97} + - {x: 45, y: 98} + - {x: 46, y: 98} + - {x: 47, y: 98} + - {x: 48, y: 98} + - {x: 49, y: 98} + - {x: 50, y: 98} + - {x: 51, y: 98} + - {x: 52, y: 98} + - {x: 53, y: 98} + - {x: 54, y: 98} + - {x: 45, y: 99} + - {x: 46, y: 99} + - {x: 47, y: 99} + - {x: 48, y: 99} + - {x: 49, y: 99} + - {x: 50, y: 99} + - {x: 51, y: 99} + - {x: 52, y: 99} + - {x: 53, y: 99} + - {x: 54, y: 99} + Facing: 0 + LeakExits: [] + Goals: + - TileArea: + - {x: 45, y: 45} + - {x: 46, y: 45} + - {x: 47, y: 45} + - {x: 48, y: 45} + - {x: 49, y: 45} + - {x: 50, y: 45} + - {x: 51, y: 45} + - {x: 52, y: 45} + - {x: 53, y: 45} + - {x: 54, y: 45} + - {x: 45, y: 46} + - {x: 46, y: 46} + - {x: 47, y: 46} + - {x: 48, y: 46} + - {x: 49, y: 46} + - {x: 50, y: 46} + - {x: 51, y: 46} + - {x: 52, y: 46} + - {x: 53, y: 46} + - {x: 54, y: 46} + - {x: 45, y: 47} + - {x: 46, y: 47} + - {x: 47, y: 47} + - {x: 48, y: 47} + - {x: 49, y: 47} + - {x: 50, y: 47} + - {x: 51, y: 47} + - {x: 52, y: 47} + - {x: 53, y: 47} + - {x: 54, y: 47} + - {x: 45, y: 48} + - {x: 46, y: 48} + - {x: 47, y: 48} + - {x: 48, y: 48} + - {x: 49, y: 48} + - {x: 50, y: 48} + - {x: 51, y: 48} + - {x: 52, y: 48} + - {x: 53, y: 48} + - {x: 54, y: 48} + - {x: 45, y: 49} + - {x: 46, y: 49} + - {x: 47, y: 49} + - {x: 48, y: 49} + - {x: 49, y: 49} + - {x: 50, y: 49} + - {x: 51, y: 49} + - {x: 52, y: 49} + - {x: 53, y: 49} + - {x: 54, y: 49} + - {x: 45, y: 50} + - {x: 46, y: 50} + - {x: 47, y: 50} + - {x: 48, y: 50} + - {x: 49, y: 50} + - {x: 50, y: 50} + - {x: 51, y: 50} + - {x: 52, y: 50} + - {x: 53, y: 50} + - {x: 54, y: 50} + - {x: 45, y: 51} + - {x: 46, y: 51} + - {x: 47, y: 51} + - {x: 48, y: 51} + - {x: 49, y: 51} + - {x: 50, y: 51} + - {x: 51, y: 51} + - {x: 52, y: 51} + - {x: 53, y: 51} + - {x: 54, y: 51} + - {x: 45, y: 52} + - {x: 46, y: 52} + - {x: 47, y: 52} + - {x: 48, y: 52} + - {x: 49, y: 52} + - {x: 50, y: 52} + - {x: 51, y: 52} + - {x: 52, y: 52} + - {x: 53, y: 52} + - {x: 54, y: 52} + - {x: 45, y: 53} + - {x: 46, y: 53} + - {x: 47, y: 53} + - {x: 48, y: 53} + - {x: 49, y: 53} + - {x: 50, y: 53} + - {x: 51, y: 53} + - {x: 52, y: 53} + - {x: 53, y: 53} + - {x: 54, y: 53} + - {x: 45, y: 54} + - {x: 46, y: 54} + - {x: 47, y: 54} + - {x: 48, y: 54} + - {x: 49, y: 54} + - {x: 50, y: 54} + - {x: 51, y: 54} + - {x: 52, y: 54} + - {x: 53, y: 54} + - {x: 54, y: 54} diff --git a/Assets/_Project/Scenes/Levels/3Player.asset.meta b/Assets/_Project/Scenes/Levels/3Player.asset.meta new file mode 100644 index 0000000..165c532 --- /dev/null +++ b/Assets/_Project/Scenes/Levels/3Player.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4ca1d0054e9d3744e8802817bf0b69e2 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_Project/Scenes/Levels/3Player.unity b/Assets/_Project/Scenes/Levels/3Player.unity new file mode 100644 index 0000000..f76a371 --- /dev/null +++ b/Assets/_Project/Scenes/Levels/3Player.unity @@ -0,0 +1,1682 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 10 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 13 + m_BakeOnSceneLoad: 0 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 12 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 2 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 512 + m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 256 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 1 + m_PVRDenoiserTypeDirect: 1 + m_PVRDenoiserTypeIndirect: 1 + m_PVRDenoiserTypeAO: 1 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVREnvironmentMIS: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 1 + m_PVRFilteringGaussRadiusAO: 1 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 + m_LightingDataAsset: {fileID: 20201, guid: 0000000000000000f000000000000000, type: 0} + m_LightingSettings: {fileID: 0} +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 3 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + buildHeightMesh: 0 + maxJobWorkers: 0 + preserveTilesOutsideBounds: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &33702846 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 33702847} + - component: {fileID: 33702849} + - component: {fileID: 33702848} + m_Layer: 0 + m_Name: Player2Zone + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &33702847 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 33702846} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 25, y: 0, z: 50} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1254053184} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &33702848 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 33702846} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5e8ab74b9038bd64782043bfc21f4cd7, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Levels.PlayerZoneVolume + owner: 2 + placementValidity: 1 +--- !u!65 &33702849 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 33702846} + 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: 40, y: 1, z: 10} + m_Center: {x: 0, y: 0, z: 0} +--- !u!1 &134093951 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 134093952} + - component: {fileID: 134093954} + - component: {fileID: 134093953} + m_Layer: 0 + m_Name: Player1Zone + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &134093952 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 134093951} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 50, y: 0, z: 25} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 928556819} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &134093953 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 134093951} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5e8ab74b9038bd64782043bfc21f4cd7, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Levels.PlayerZoneVolume + owner: 1 + placementValidity: 1 +--- !u!65 &134093954 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 134093951} + 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: 90, y: 1, z: 40} + m_Center: {x: 0, y: 0, z: 0} +--- !u!1 &266460570 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 266460571} + - component: {fileID: 266460573} + - component: {fileID: 266460572} + m_Layer: 0 + m_Name: Player2Leak + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &266460571 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 266460570} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 40.07, y: 0, z: 55.86} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1254053184} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &266460572 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 266460570} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d4da5d6673a12f546ac47563abc49d5a, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Levels.LeakExitVolume + sourceZone: 2 + target: 3 + weight: 1 + placementValidity: 0 +--- !u!65 &266460573 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 266460570} + 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: 8, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!1 &401715852 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 401715853} + - component: {fileID: 401715855} + - component: {fileID: 401715854} + m_Layer: 0 + m_Name: Player1Spawn + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &401715853 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 401715852} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 50, y: 0, z: 3} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 928556819} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &401715854 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 401715852} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a756762f899008f45b2986bdcb11c819, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Levels.SpawnerVolume + owner: 1 + spawnerIdInZone: 0 + spawnFacing: 0 + placementValidity: 0 +--- !u!65 &401715855 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 401715852} + 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: 10, y: 1, z: 5} + m_Center: {x: 0, y: 0, z: 0} +--- !u!1 &459910557 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 459910558} + - component: {fileID: 459910560} + - component: {fileID: 459910559} + m_Layer: 0 + m_Name: Player3Zone + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &459910558 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 459910557} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 50, y: 0, z: 74.8} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 795669283} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &459910559 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 459910557} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5e8ab74b9038bd64782043bfc21f4cd7, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Levels.PlayerZoneVolume + owner: 3 + placementValidity: 1 +--- !u!65 &459910560 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 459910557} + 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: 90, y: 1, z: 40} + m_Center: {x: 0, y: 0, z: 0} +--- !u!1 &795669282 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 795669283} + m_Layer: 0 + m_Name: Player 3 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &795669283 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 795669282} + serializedVersion: 2 + 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: 459910558} + - {fileID: 798920373} + m_Father: {fileID: 2019237589} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &798920372 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 798920373} + - component: {fileID: 798920375} + - component: {fileID: 798920374} + m_Layer: 0 + m_Name: Player3Spawn + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &798920373 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 798920372} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 50, y: 0, z: 97.35} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 795669283} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &798920374 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 798920372} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a756762f899008f45b2986bdcb11c819, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Levels.SpawnerVolume + owner: 3 + spawnerIdInZone: 0 + spawnFacing: 0 + placementValidity: 0 +--- !u!65 &798920375 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 798920372} + 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: 10, y: 1, z: 5} + m_Center: {x: 0, y: 0, z: 0} +--- !u!1 &818973742 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 818973745} + - component: {fileID: 818973744} + - component: {fileID: 818973743} + m_Layer: 7 + m_Name: Terrain + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 2147483647 + m_IsActive: 1 +--- !u!154 &818973743 +TerrainCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 818973742} + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ProvidesContacts: 0 + m_Enabled: 1 + serializedVersion: 2 + m_TerrainData: {fileID: 15600000, guid: ee9f119ba54c4b14d83c6818dc2f0ef8, type: 2} + m_EnableTreeColliders: 1 +--- !u!218 &818973744 +Terrain: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 818973742} + m_Enabled: 1 + serializedVersion: 6 + m_TerrainData: {fileID: 15600000, guid: ee9f119ba54c4b14d83c6818dc2f0ef8, type: 2} + m_TreeDistance: 5000 + m_TreeBillboardDistance: 50 + m_TreeCrossFadeLength: 5 + m_TreeMaximumFullLODCount: 50 + m_DetailObjectDistance: 80 + m_DetailObjectDensity: 1 + m_HeightmapPixelError: 5 + m_SplatMapDistance: 1000 + m_HeightmapMinimumLODSimplification: 0 + m_HeightmapMaximumLOD: 0 + m_ShadowCastingMode: 2 + m_DrawHeightmap: 1 + m_DrawInstanced: 0 + m_DrawTreesAndFoliage: 1 + m_StaticShadowCaster: 0 + m_IgnoreQualitySettings: 0 + m_ReflectionProbeUsage: 1 + m_MaterialTemplate: {fileID: 2100000, guid: 594ea882c5a793440b60ff72d896021e, type: 2} + m_BakeLightProbesForTrees: 1 + m_PreserveTreePrototypeLayers: 0 + m_DeringLightProbesForTrees: 1 + m_ReceiveGI: 1 + m_ScaleInLightmap: 0.18285714 + m_LightmapParameters: {fileID: 15203, guid: 0000000000000000f000000000000000, type: 0} + m_GroupingID: 0 + m_RenderingLayerMask: 1 + m_AllowAutoConnect: 1 + m_EnableHeightmapRayTracing: 1 + m_EnableTreesAndDetailsRayTracing: 0 + m_TreeMotionVectorModeOverride: 3 +--- !u!4 &818973745 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 818973742} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: -20, y: -5, z: -20} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &928556818 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 928556819} + m_Layer: 0 + m_Name: Player 1 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &928556819 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 928556818} + serializedVersion: 2 + 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: 134093952} + - {fileID: 401715853} + - {fileID: 1270045952} + m_Father: {fileID: 2019237589} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1001 &1085185471 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + serializedVersion: 3 + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 1445952844252628864, guid: 13be8328f6275e14da787f25c94683ee, type: 3} + propertyPath: m_Name + value: _MatchServices + objectReference: {fileID: 0} + - target: {fileID: 3833381251955063088, guid: 13be8328f6275e14da787f25c94683ee, type: 3} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3833381251955063088, guid: 13be8328f6275e14da787f25c94683ee, type: 3} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3833381251955063088, guid: 13be8328f6275e14da787f25c94683ee, type: 3} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3833381251955063088, guid: 13be8328f6275e14da787f25c94683ee, type: 3} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 3833381251955063088, guid: 13be8328f6275e14da787f25c94683ee, type: 3} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3833381251955063088, guid: 13be8328f6275e14da787f25c94683ee, type: 3} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3833381251955063088, guid: 13be8328f6275e14da787f25c94683ee, type: 3} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3833381251955063088, guid: 13be8328f6275e14da787f25c94683ee, type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3833381251955063088, guid: 13be8328f6275e14da787f25c94683ee, type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3833381251955063088, guid: 13be8328f6275e14da787f25c94683ee, type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6850685008819507485, guid: 13be8328f6275e14da787f25c94683ee, type: 3} + propertyPath: level + value: + objectReference: {fileID: 11400000, guid: 4ca1d0054e9d3744e8802817bf0b69e2, type: 2} + m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] + m_SourcePrefab: {fileID: 100100000, guid: 13be8328f6275e14da787f25c94683ee, type: 3} +--- !u!1 &1254053183 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1254053184} + m_Layer: 0 + m_Name: Player 2 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1254053184 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1254053183} + serializedVersion: 2 + 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: 33702847} + - {fileID: 1980551240} + - {fileID: 1422989821} + - {fileID: 266460571} + m_Father: {fileID: 2019237589} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1270045951 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1270045952} + - component: {fileID: 1270045954} + - component: {fileID: 1270045953} + m_Layer: 0 + m_Name: Player1Leak + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1270045952 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1270045951} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 40.49, y: 0, z: 44.4} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 928556819} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1270045953 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1270045951} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d4da5d6673a12f546ac47563abc49d5a, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Levels.LeakExitVolume + sourceZone: 1 + target: 2 + weight: 1 + placementValidity: 0 +--- !u!65 &1270045954 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1270045951} + 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: 8, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!1 &1422989820 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1422989821} + - component: {fileID: 1422989823} + - component: {fileID: 1422989822} + m_Layer: 0 + m_Name: Player2Spawn + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1422989821 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1422989820} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 2.72, y: 0, z: 50} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1254053184} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1422989822 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1422989820} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a756762f899008f45b2986bdcb11c819, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Levels.SpawnerVolume + owner: 2 + spawnerIdInZone: 0 + spawnFacing: 0 + placementValidity: 0 +--- !u!65 &1422989823 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1422989820} + 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: 5, y: 1, z: 10} + m_Center: {x: 0, y: 0, z: 0} +--- !u!1 &1725776290 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1725776291} + - component: {fileID: 1725776293} + - component: {fileID: 1725776292} + m_Layer: 0 + m_Name: Goal + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1725776291 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1725776290} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 50, y: 0, z: 50} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2019237589} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1725776292 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1725776290} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 755948f0244afea4da6ed2e4e3d27579, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Levels.GoalVolume + placementValidity: 0 +--- !u!65 &1725776293 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1725776290} + 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: 10, y: 1, z: 10} + m_Center: {x: 0, y: 0, z: 0} +--- !u!1 &1980551239 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1980551240} + - component: {fileID: 1980551242} + - component: {fileID: 1980551241} + m_Layer: 0 + m_Name: Player2Zone (1) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1980551240 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1980551239} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 75.5, y: 0, z: 50} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1254053184} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1980551241 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1980551239} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5e8ab74b9038bd64782043bfc21f4cd7, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Levels.PlayerZoneVolume + owner: 2 + placementValidity: 1 +--- !u!65 &1980551242 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1980551239} + 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: 40, y: 1, z: 10} + m_Center: {x: 0, y: 0, z: 0} +--- !u!1 &2019237587 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2019237589} + - component: {fileID: 2019237588} + m_Layer: 0 + m_Name: _LevelAuthoring + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &2019237588 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2019237587} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 37de128911d7bbc4299ea87cdb520ed7, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Levels.LevelAuthoring + targetAsset: {fileID: 11400000, guid: 4ca1d0054e9d3744e8802817bf0b69e2, type: 2} + mapName: 3Player + playerCount: 3 + expectedGoalCount: 1 + mapDescription: 3 Player new design map + author: BigBoysFellowship + buildAccess: 1 + alwaysShowPlayerZones: 1 + alwaysShowSpawners: 1 + alwaysShowLeakExits: 1 + alwaysShowGoals: 1 + alwaysShowMapArea: 1 +--- !u!4 &2019237589 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2019237587} + serializedVersion: 2 + 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: 2082667048} + - {fileID: 1725776291} + - {fileID: 928556819} + - {fileID: 1254053184} + - {fileID: 795669283} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &2082667047 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2082667048} + - component: {fileID: 2082667050} + - component: {fileID: 2082667049} + m_Layer: 0 + m_Name: MapArea + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &2082667048 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2082667047} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 50, y: 0, z: 50} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2019237589} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &2082667049 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2082667047} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: bacb3662546735544bc6c56b5bf5830a, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Levels.MapAreaVolume +--- !u!65 &2082667050 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2082667047} + 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: 100, y: 1, z: 100} + m_Center: {x: 0, y: 0, z: 0} +--- !u!1 &3017635515177826 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8988393256734803841} + - component: {fileID: 8162852702969474156} + - component: {fileID: 3611798548410183501} + m_Layer: 0 + m_Name: WaveManager + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &140582381973810141 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4602750115185197811} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject + GlobalObjectIdHash: 2907458687 + InScenePlacedSourceGlobalObjectIdHash: 0 + DeferredDespawnTick: 0 + Ownership: 1 + AlwaysReplicateAsRoot: 0 + SynchronizeTransform: 1 + ActiveSceneSynchronization: 0 + SceneMigrationSynchronization: 0 + SpawnWithObservers: 1 + DontDestroyWithOwner: 0 + AutoObjectParentSync: 1 + SyncOwnerTransformWhenParented: 1 + AllowOwnerToParent: 0 +--- !u!4 &503343020638521026 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4244307270187979398} + serializedVersion: 2 + 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: 5789372923279415034} + - {fileID: 4088215286431904235} + - {fileID: 6254257571613030681} + - {fileID: 5997689683896399647} + - {fileID: 8988393256734803841} + - {fileID: 7668674954522045726} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1105731448975329059 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1764112936023248767} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject + GlobalObjectIdHash: 33007430 + InScenePlacedSourceGlobalObjectIdHash: 0 + DeferredDespawnTick: 0 + Ownership: 1 + AlwaysReplicateAsRoot: 0 + SynchronizeTransform: 1 + ActiveSceneSynchronization: 0 + SceneMigrationSynchronization: 0 + SpawnWithObservers: 1 + DontDestroyWithOwner: 0 + AutoObjectParentSync: 1 + SyncOwnerTransformWhenParented: 1 + AllowOwnerToParent: 0 +--- !u!1 &1764112936023248767 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4088215286431904235} + - component: {fileID: 1105731448975329059} + - component: {fileID: 7363980916811660096} + m_Layer: 0 + m_Name: MatchState + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1946912819156519408 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6675731345053163047} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d369496ba7887b844b1c220b524a507d, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.TowerPlacementManager + ShowTopMostFoldoutHeaderGroup: 1 + requestsPerFrame: 3 + towerDefinitions: + - {fileID: 0} + - {fileID: 11400000, guid: d5b2e8fa3c7e9b5f4a1d0c2e7f6b3a91, type: 2} + - {fileID: 11400000, guid: 0f693e29ca953e1439e10cb8f12e4b30, type: 2} + - {fileID: 11400000, guid: 86d4c3ab00d4c654eb4c255280ee5701, type: 2} + - {fileID: 11400000, guid: 04219895bbea4fb9a94fd62fef35bf2a, type: 2} + - {fileID: 11400000, guid: e3f1a9c2b5d84e76a0c3f1e8d27b4905, type: 2} + startingDeck: + - {fileID: 11400000, guid: d5b2e8fa3c7e9b5f4a1d0c2e7f6b3a91, type: 2} + - {fileID: 11400000, guid: 0f693e29ca953e1439e10cb8f12e4b30, type: 2} +--- !u!1 &3471031726177798451 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5789372923279415034} + - component: {fileID: 4420272328355700207} + - component: {fileID: 8942977016248842733} + m_Layer: 0 + m_Name: ChatService + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &3522105368117485811 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7668674954522045726} + - component: {fileID: 6900222455741435924} + - component: {fileID: 8285861969374059639} + m_Layer: 0 + m_Name: WaveVote + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &3611798548410183501 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3017635515177826} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 81d8e215d8419404ea4d959196cd9cc3, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.WaveManager + ShowTopMostFoldoutHeaderGroup: 1 + startingLives: 40 + draftTimeSeconds: 30 + voteTimeSeconds: 25 + goldConfig: {fileID: 11400000, guid: d5e01c919f14a1e4888ad494a159241b, type: 2} + enemyScalingConfig: {fileID: 11400000, guid: ae9fde0b564e20440ac2e20861fa1ca6, type: 2} +--- !u!114 &3758811521878612515 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4602750115185197811} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a293cf6dca91dd2478c9f4e799cf9e0d, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.Waves.RunState + ShowTopMostFoldoutHeaderGroup: 1 + runDefinition: {fileID: 11400000, guid: 1bb81a966192c344d94cce2628c1832b, type: 2} +--- !u!114 &3973305430985036989 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6675731345053163047} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject + GlobalObjectIdHash: 2279944997 + InScenePlacedSourceGlobalObjectIdHash: 0 + DeferredDespawnTick: 0 + Ownership: 1 + AlwaysReplicateAsRoot: 0 + SynchronizeTransform: 1 + ActiveSceneSynchronization: 0 + SceneMigrationSynchronization: 0 + SpawnWithObservers: 1 + DontDestroyWithOwner: 0 + AutoObjectParentSync: 1 + SyncOwnerTransformWhenParented: 1 + AllowOwnerToParent: 0 +--- !u!4 &4088215286431904235 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1764112936023248767} + serializedVersion: 2 + 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: 503343020638521026} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &4244307270187979398 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 503343020638521026} + m_Layer: 0 + m_Name: _MatchNetwork + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &4420272328355700207 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3471031726177798451} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject + GlobalObjectIdHash: 3614769064 + InScenePlacedSourceGlobalObjectIdHash: 0 + DeferredDespawnTick: 0 + Ownership: 1 + AlwaysReplicateAsRoot: 0 + SynchronizeTransform: 1 + ActiveSceneSynchronization: 0 + SceneMigrationSynchronization: 0 + SpawnWithObservers: 1 + DontDestroyWithOwner: 0 + AutoObjectParentSync: 1 + SyncOwnerTransformWhenParented: 1 + AllowOwnerToParent: 0 +--- !u!1 &4602750115185197811 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6254257571613030681} + - component: {fileID: 140582381973810141} + - component: {fileID: 3758811521878612515} + m_Layer: 0 + m_Name: RunState + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &5789372923279415034 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3471031726177798451} + serializedVersion: 2 + 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: 503343020638521026} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &5997689683896399647 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6675731345053163047} + serializedVersion: 2 + 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: 503343020638521026} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &6254257571613030681 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4602750115185197811} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 38.30481, y: 0.5, z: 155.93135} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 503343020638521026} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &6675731345053163047 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5997689683896399647} + - component: {fileID: 3973305430985036989} + - component: {fileID: 1946912819156519408} + m_Layer: 0 + m_Name: TowerPlacementManager + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &6900222455741435924 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3522105368117485811} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject + GlobalObjectIdHash: 1445073833 + InScenePlacedSourceGlobalObjectIdHash: 0 + DeferredDespawnTick: 0 + Ownership: 1 + AlwaysReplicateAsRoot: 0 + SynchronizeTransform: 1 + ActiveSceneSynchronization: 0 + SceneMigrationSynchronization: 0 + SpawnWithObservers: 1 + DontDestroyWithOwner: 0 + AutoObjectParentSync: 1 + SyncOwnerTransformWhenParented: 1 + AllowOwnerToParent: 0 +--- !u!114 &7363980916811660096 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1764112936023248767} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a34585be59d49e94b811d96be51c5088, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.MatchState + ShowTopMostFoldoutHeaderGroup: 1 +--- !u!4 &7668674954522045726 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3522105368117485811} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 38.30481, y: 0.5, z: 155.93135} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 503343020638521026} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &8162852702969474156 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3017635515177826} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject + GlobalObjectIdHash: 1797533733 + InScenePlacedSourceGlobalObjectIdHash: 0 + DeferredDespawnTick: 0 + Ownership: 1 + AlwaysReplicateAsRoot: 0 + SynchronizeTransform: 1 + ActiveSceneSynchronization: 0 + SceneMigrationSynchronization: 0 + SpawnWithObservers: 1 + DontDestroyWithOwner: 0 + AutoObjectParentSync: 1 + SyncOwnerTransformWhenParented: 1 + AllowOwnerToParent: 0 +--- !u!114 &8285861969374059639 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3522105368117485811} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a18321dc2d138034fbdb5f705f19f893, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.EnemyUpgrades.WaveVote + ShowTopMostFoldoutHeaderGroup: 1 + optionsPerVote: 3 +--- !u!114 &8942977016248842733 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3471031726177798451} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 816890bb20c416b419e38d3d4b91ffca, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.ChatService + ShowTopMostFoldoutHeaderGroup: 1 +--- !u!4 &8988393256734803841 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3017635515177826} + serializedVersion: 2 + 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: 503343020638521026} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1660057539 &9223372036854775807 +SceneRoots: + m_ObjectHideFlags: 0 + m_Roots: + - {fileID: 1085185471} + - {fileID: 503343020638521026} + - {fileID: 2019237589} + - {fileID: 818973745} diff --git a/Assets/_Project/Scenes/Levels/3Player.unity.meta b/Assets/_Project/Scenes/Levels/3Player.unity.meta new file mode 100644 index 0000000..757486c --- /dev/null +++ b/Assets/_Project/Scenes/Levels/3Player.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 128de09101c3e3240b094d29d1eb9d22 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_Project/Scenes/Levels/3Player_TerrainData.asset b/Assets/_Project/Scenes/Levels/3Player_TerrainData.asset new file mode 100644 index 0000000000000000000000000000000000000000..f27ca6b44d46d3260332f368fad5f6f0e0493e13 GIT binary patch literal 1950772 zcmeI)eT<|BUBK~Y_x30hgknWSpd6)@f>3*0DWIiXdw1K}kFV9KW_H;nmt1o3r59g% zWP9=O>C>m@=40^G9G*UX?#egEm)-cb%P0SQ#V>#1^ta%#muGXuT=B7(e{!yvp_&25i9`IGZ(IJa|p zzNPH-l$XFki0c=WZ}RQP00?gZb_C{7Dts^iD$kn7 zcXxTYD88qhOv>{-Yv%Wqmy6Xk9pqjS*!P~F68}l{@Qw;?=^Y5=G4rO*YjuRU}rPU z+g7jdx5YePzt73hWP09yeg8m==5|ic+pq8E=KRb!F1KIb&zqT7`~RVO|1Qq^?##35 z)bxq>pCX^XA8ZCw^L+eYsPBJCxqPyEtLE|laXpXsso4MaJfFV@>-9fB=4<=s{NL*N zj=X>TG^hEvwsk&Um+_OYz4|k)8OOBx{CIZEbN^qkI;k!+^ULb_W$VoEi|t=g&*O8h zb!zUvx1PVKHO+mkwtt|Wzj%ZBE9?0W&CILU&l~Fb4{tDkb3MO&o%x@~>*w~Er>}e; z-^|w)Ip3LQ)hYdC|K{`KrOjY!{*hRJ^ZBuJW%nx zP0lB0ZWMi5pTB!!)P8&mt$zD*e&+6Rd7<_Bd+nO}fdk{=<$IQTJ9o= z6vuD5y0_fjw>vHz=!}oWh4OX>hTS8b!~6Q9ai_o7&718z-Z|RcHR#7Z$D_TS(Xrz2 zsd0DonoC|+U)bJUcz$zXM|0uQ=E4h_3zsz)Uf5iCQFGzN&4uk}R=v9J?W-%_zPk49 ztE=B0>yJGhUAeq+th4J_r{C``U%xVr2ijSV!Ogv;@v->5x7#~o6*y)c}I>T;%F_+fQQ?-lr-tX=mub%JXn*H^n zgWd5swwT+RT@ob5-QjhErQEwK`@PX1e#g#T)$8OPZXR}4ZmfUbRR6v?e(%q$@c>t2 z?HVi(h6h(Vi@BZy%boF&$avNA;Be7PP1}|_<4&>q==b%HXh#gc?6N4toaU+w`tGk%1@O?I)Z4{ztIsyv;MQzS^u|k1ktR2qa%oB z{b#SU{{QPEh|k0kQoi%$^OQ#r?Y`9~K=b(W(|_%J`uWKti0OHL0^AbIj>k`a!sQXf z+$7HGQ$D}>3HW1iJ?D7@(Vn;8!Se`Wvv=@3f>`?w{_a?opMd%J@(7|m-&%eGG>}{(fos%fDjU^J@P;63cV{^9W+I{m&za&GtW!Alm!4P~`K|?0+8cx99Ese_A=8 z#CdgEyZ`6K;9x&8}tKAFD%*3#D# z;x;+YBZ&6=QLVoa@(7}Rgnm|Q`xmX*{#o1@@f|%aF?4Q1$T5tb3kFfpf2x5Bw z+uMKc%=+8guZ|$5?_c@MBd~n@c?8jZe%k%>2x2pzc?1!wT0Ld|7sZ0?KaQp45ya{= zZ@aa)H2m(3+vMvnk07S+KUX}e_4=!hASSD8$ocg9OCCYA{cbH^A2-zN&m)M<)}KcZ z?fbXapGOew`PSmTcx;QY(tLg75k!0a)qJ_0=Mltu^Aq(vk092YzqOv{5yaYg`hRCV z&m)Mn^ZR1{-g=%#5bMoht09dj5(H=KJdT4eQMF`O72heEtrW^KEfn zo$?4b_rLLVC>FP$pK9Ltx^aVf^ZdoO*1do8{M|e=pD(w6tls}umh(8PPx<+l`*(Xi ze^o4xr(*Tg%->VbU%k#eef(lQf6Y4c{QUT>nCJWVYjfWEd~3gdzb@xHr{DkEpP#QU z*WaFhG1i^$-}%{^f2*zi{CY69{}*waeE)t!Ilm~*t5fs({%XDdomgCbr{A9cT|Ga% z!Tj&*`QpsHdVhVeo-dX2>HV+f57qPT2J`=_=SSAe=i~L6{mj+j=lFuRgzb#clHWUzwS=Kfm8x&L?qRo$~Qde|`^R@p_-H z*T(wu^L13ttNZ48^Zs~aJ2pzAg6s&U*iUBQYIBK)k|Lr+1rtiN{YzyD{{KreAct+R>U?q=Kn>6~w}{hygx|3dls)@=Xo znR)g3{~xja+`peK=W$k_vQNIh&Brk3?}?xG>ubKq&zHx>FyCL^Th6z|d39<&|C`U3 z_r>D%KL4A~m-lZlZ$4i>Ff*SkkI&AH?dSW)2Xj7&v-%YK-#R}0P%NL@*-Ud^+TXz6 zlk+pRo7gvH^0AgsyiH2Uvp0{$}hRg zuT<;x_4r2fhVE#vd?LR{j)hmn>aS}p+ua>^ddpLro>>sztuG$yj*4nfUMrS! zNA~rXdhwlcu{gN3JB;r{WBv7QhJ*27d}`&)otg#3%Iu}4L41o`f6LuDSzqY&oA0|j zC+kc7L2uMO*p2V0t4k~K{qs_BY_Qxt)E$j)=q&Y4jEbfF$~eApKGy9lkB^-yzsoI# z#nIw$(J7XO&4O-!ss5_?#3;W2uXg&nZu|p5EU5nlA--wOYrCse9$f4!=aM)-+CMbN zufqFF#mXQy7lp6wjpNJbV%!-X?T&Yy$x=pZzI!jP9PH%R_oL$G&aJV!YlfZC=uofx zYJO@-ex2MuT7K_8we-s4^_Tcl%MPw&k*0s_WbQ}(CHSFXw|OkF!Rc$O`(2zYP8GKm zZ^?gT$Vb?Xa`}aLbveRxN=kdbm@>!!N%tuhRA+r0s^>i*$8BaWr}Vw?-wd>m)TPyPe=+EXsco9FLl+FWj~H}}c) zosKJhG+=-M1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|ZO|7@W6HcscpeRmvK?wsllZ#mQ*4m-X6?#{T=TH``on~R_S zeAQR~>7v2Ix6V&p-ZFJLZ`a%=Z=a_J?zrpxJ1*)yP~@HRXX>;qF7Mc}Mt z#r(-rbGf-*EsgWJg@xk&v;C)l0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC37vEl{kU=Hk+gTUW2Tpnw7jD4>7>3Mim}0tzUgfC36A zpnw7jDDW*5_{7;oasMYj@e)58Fu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 s00Rs#zyJdbFu(u<3^2d|0}T9c8 + /// Whether a map restricts tower placement to each player's own zone, or lets everyone build + /// anywhere on the map's buildable area. + /// + /// + /// This governs placement PERMISSION only. Zone ownership keeps doing everything else it + /// does today under both modes — leak attribution, camera start position, builder spawn point, + /// minimap tinting. A shared-build map still has distinct player territories; they are simply + /// all buildable by everyone. + /// + /// Backed by byte with OwnerOnly = 0 so LevelData assets baked before this + /// existed deserialize to the pre-existing behaviour without needing a re-bake. + /// + /// Tower OWNERSHIP is unaffected: a tower belongs to whoever paid for it, and sell / + /// upgrade stay owner-gated in both modes. + /// + public enum BuildAccess : byte + { + /// A player may only build on tiles covered by their own PlayerZoneVolume. + OwnerOnly = 0, + + /// Any player may build on any Buildable tile, whichever zone owns it. + Shared = 1, + } + /// /// Outcome of a bake operation, recorded on the baked asset. /// diff --git a/Assets/_Project/Scripts/Editor/Levels/LevelBakePipeline.cs b/Assets/_Project/Scripts/Editor/Levels/LevelBakePipeline.cs index dac565b..a759032 100644 --- a/Assets/_Project/Scripts/Editor/Levels/LevelBakePipeline.cs +++ b/Assets/_Project/Scripts/Editor/Levels/LevelBakePipeline.cs @@ -802,17 +802,33 @@ namespace TD.Levels.Editor } // P5-8: zones with neither outgoing leak nor goal adjacency. - var zonesWithLeaks = new HashSet(); - foreach (var l in ctx.LeakExitVolumes) zonesWithLeaks.Add(l.sourceZone); - - foreach (var owner in ctx.DeclaredOwners) + // + // OwnerOnly maps only. The rule asserts the lane-chain topology those maps are built + // around: each player's zone either hands off to the next or is the final defender. + // + // On a Shared map that assertion is wrong, not merely unnecessary. Zones there are + // typically directly adjacent with no gate between them, so most have no outgoing leak + // and are not goal-adjacent — and that is the intended shape, because the whole map is + // one contiguous maze. The property P5-8 actually protects ("enemies from this zone have + // somewhere to go") is enforced more strictly by P5-4 above, which runs a real BFS from + // every spawner to the exit set — and with no leak volumes present, that exit set is the + // goal tiles, which is exactly the right requirement. Zones with no spawners can't + // strand anything: WaveManager skips them. + if (ctx.Authoring.buildAccess == BuildAccess.OwnerOnly) { - bool hasLeak = zonesWithLeaks.Contains(owner); - bool isGoalAdj = goalAdjacentZones.Contains(owner); - if (!hasLeak && !isGoalAdj) + var zonesWithLeaks = new HashSet(); + foreach (var l in ctx.LeakExitVolumes) zonesWithLeaks.Add(l.sourceZone); + + foreach (var owner in ctx.DeclaredOwners) { - report.Error("P5-8", $"Player zone {owner} has no outgoing leak exit AND is not goal-adjacent. " + - "Every zone must either lead somewhere or be a final defender."); + bool hasLeak = zonesWithLeaks.Contains(owner); + bool isGoalAdj = goalAdjacentZones.Contains(owner); + if (!hasLeak && !isGoalAdj) + { + report.Error("P5-8", $"Player zone {owner} has no outgoing leak exit AND is not goal-adjacent. " + + "Every zone must either lead somewhere or be a final defender. " + + "(This rule is skipped on Shared-build maps.)"); + } } } @@ -919,6 +935,7 @@ namespace TD.Levels.Editor data.PlayerCount = ctx.Authoring.playerCount; data.MapDescription = ctx.Authoring.mapDescription; data.Author = ctx.Authoring.author; + data.BuildAccess = ctx.Authoring.buildAccess; data.GridOriginTile = ctx.GridOriginTile; data.GridSize = ctx.GridSize; @@ -1152,7 +1169,10 @@ namespace TD.Levels.Editor sb.Append("playerCount=").Append(ctx.Authoring.playerCount.ToString(inv)).Append('|'); sb.Append("expectedGoalCount=").Append(ctx.Authoring.expectedGoalCount.ToString(inv)).Append('|'); sb.Append("mapDescription=").Append(ctx.Authoring.mapDescription ?? "").Append('|'); - sb.Append("author=").Append(ctx.Authoring.author ?? "").Append('\n'); + sb.Append("author=").Append(ctx.Authoring.author ?? "").Append('|'); + // By NAME, matching the per-volume enum convention below — a future reordering of the + // enum must not silently produce a matching hash for different rules. + sb.Append("buildAccess=").Append(ctx.Authoring.buildAccess.ToString()).Append('\n'); // Volume blocks, ordered by canonical path. var rootTransform = ctx.Authoring.transform; @@ -1354,6 +1374,7 @@ namespace TD.Levels.Editor target.PlayerCount = src.PlayerCount; target.MapDescription = src.MapDescription; target.Author = src.Author; + target.BuildAccess = src.BuildAccess; target.ScenePath = src.ScenePath; target.AuthoringHash = src.AuthoringHash; target.LastBakeTimestamp = src.LastBakeTimestamp; diff --git a/Assets/_Project/Scripts/Editor/Levels/MapCoreExtractor.cs b/Assets/_Project/Scripts/Editor/Levels/MapCoreExtractor.cs new file mode 100644 index 0000000..43fc91c --- /dev/null +++ b/Assets/_Project/Scripts/Editor/Levels/MapCoreExtractor.cs @@ -0,0 +1,356 @@ +// Assets/_Project/Scripts/Editor/Levels/MapCoreExtractor.cs +using System.Collections.Generic; +using UnityEditor; +using UnityEditor.SceneManagement; +using UnityEditorInternal; +using UnityEngine; +using UnityEngine.SceneManagement; + +using TD.Audio; +using TD.Dev; +using TD.Gameplay; +using TD.Gameplay.BuilderEffects; +using TD.Gameplay.BuilderSpells; +using TD.Gameplay.Draft; +using TD.Gameplay.EnemyAbilities; +using TD.Gameplay.EnemyUpgrades; +using TD.Gameplay.Waves; +using TD.UI; +using TD.VFX; + +namespace TD.Levels.Editor +{ + /// + /// One-time (re-runnable) utility that lifts every map-independent scene object out of a + /// reference match scene and bakes it into the two prefabs TD/New Map… instantiates. + /// + /// + /// Why extract instead of generating from scratch? Several of these components hold + /// ORDER-SENSITIVE arrays that double as network identity — EnemyUpgradePool.options + /// indices are card network ids, and TowerPlacementManager.towerDefinitions indices are + /// TowerTypeId. Re-deriving those from an AssetDatabase scan would produce a different + /// order than the shipping map and desync peers. Copying the live components preserves them + /// exactly. + /// + /// Two prefabs, two lifetimes. MatchServices contains no NetworkObject, so + /// new maps keep it as a LINKED prefab instance and later edits propagate everywhere. + /// MatchNetwork holds the six scene-placed NetworkBehaviours and is UNPACKED on use, so + /// what NGO sees in a generated scene is indistinguishable from a hand-authored one. + /// + /// This does not modify the reference scene's contents — temporary objects are + /// created and destroyed — but Unity still marks the scene dirty. Don't save it afterwards. + /// + public static class MapCoreExtractor + { + private const string PrefabFolder = "Assets/_Project/Prefabs/MatchCore"; + private const string ServicesPrefabPath = PrefabFolder + "/MatchServices.prefab"; + private const string NetworkPrefabPath = PrefabFolder + "/MatchNetwork.prefab"; + + // Plain (non-networked, no UIDocument) singleton services, collapsed onto the + // _MatchServices ROOT GameObject in this order. + // + // Order matters in exactly one place: AudioSource must precede MusicPlayer, whose + // [RequireComponent(typeof(AudioSource))] would otherwise auto-add a second, default-valued + // AudioSource before we get a chance to copy the authored one. + private static readonly System.Type[] RootServiceTypes = + { + typeof(LevelLoader), + typeof(PathfindingService), + typeof(SelectionState), + typeof(SelectionVisualizer), + typeof(TowerPlacementController), + typeof(TowerPaintController), + typeof(BuilderSpellCastController), + typeof(FloatingTextSpawner), + typeof(SellEffectSpawner), + typeof(AudioManager), + typeof(AudioSource), // must come before MusicPlayer — see note above + typeof(MusicPlayer), + typeof(BuilderEffectPool), + typeof(BuilderSpellPool), + typeof(EnemyAbilityPool), + typeof(EnemyUpgradePool), + typeof(DraftPool), + typeof(DraftService), + typeof(DevWaveControls), + }; + + // Scene-placed NetworkBehaviours. Each keeps its own GameObject and its own NetworkObject — + // they are only re-parented under a shared root, so network topology is unchanged. + private static readonly System.Type[] NetworkServiceTypes = + { + typeof(ChatService), + typeof(MatchState), + typeof(RunState), + typeof(TowerPlacementManager), + typeof(WaveManager), + typeof(WaveVote), + }; + + // ------------------------------------------------------------------- + // Menu entry + // ------------------------------------------------------------------- + + [MenuItem("TD/Map Pipeline/Build Core Prefabs From Open Scene", false, 200)] + public static void BuildCorePrefabs() + { + Scene scene = EditorSceneManager.GetActiveScene(); + + if (!scene.IsValid() || string.IsNullOrEmpty(scene.path)) + { + EditorUtility.DisplayDialog( + "No saved scene open", + "Open a fully-wired match scene (9Player) before running this. The extractor " + + "reads its components to build the core prefabs.", + "OK"); + return; + } + + // Pre-scan so a missing service aborts before we create anything. + if (!TryResolveSources(scene, out var rootSources, out var missing)) + { + EditorUtility.DisplayDialog( + "Reference scene is incomplete", + $"'{scene.name}' is missing {missing.Count} component(s) the core prefabs need:\n\n" + + string.Join("\n", missing) + + "\n\nOpen a complete match scene (9Player) and try again.", + "OK"); + return; + } + + bool proceed = EditorUtility.DisplayDialog( + "Build core prefabs", + $"Read '{scene.name}' and (re)write:\n\n" + + $" {ServicesPrefabPath}\n" + + $" {NetworkPrefabPath}\n\n" + + "The scene's own contents are not changed, but Unity will mark it dirty. " + + "Don't save it afterwards.\n\nProceed?", + "Build Prefabs", + "Cancel"); + if (!proceed) return; + + MapTemplate.EnsureFolder(PrefabFolder); + + GameObject servicesPrefab = BuildServicesPrefab(scene, rootSources); + GameObject networkPrefab = BuildNetworkPrefab(scene); + + var template = MapTemplate.LoadOrCreate(); + template.matchServicesPrefab = servicesPrefab; + template.matchNetworkPrefab = networkPrefab; + CaptureTerrainDefaults(scene, template); + EditorUtility.SetDirty(template); + + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); + + Debug.Log( + $"[MapPipeline] Core prefabs built from '{scene.name}'.\n" + + $" MatchServices: {RootServiceTypes.Length} components on the root + HUD / DebugConsole / " + + $"CameraRig / lighting children.\n" + + $" MatchNetwork: {NetworkServiceTypes.Length} NetworkBehaviours under one root.\n" + + $" Template: {MapTemplate.AssetPath}\n" + + $" '{scene.name}' is now marked dirty by the temporary objects — do NOT save it."); + + EditorGUIUtility.PingObject(template); + } + + // ------------------------------------------------------------------- + // Source resolution + // ------------------------------------------------------------------- + + // Resolves every root-service component up front. Returns false (with a human-readable list) + // if anything is absent, so we never write a half-populated prefab. + private static bool TryResolveSources(Scene scene, out List rootSources, + out List missing) + { + rootSources = new List(RootServiceTypes.Length); + missing = new List(); + + // AudioSource is resolved from MusicPlayer's GameObject rather than "first in scene", + // so we copy the music source's authored volume rather than some unrelated emitter. + var musicPlayer = FindOne(scene, typeof(MusicPlayer)) as MusicPlayer; + + foreach (var type in RootServiceTypes) + { + Component found = type == typeof(AudioSource) + ? (musicPlayer != null ? musicPlayer.GetComponent() : null) + : FindOne(scene, type); + + if (found == null) missing.Add(" • " + type.Name); + rootSources.Add(found); + } + + foreach (var type in NetworkServiceTypes) + { + if (FindOne(scene, type) == null) missing.Add(" • " + type.Name); + } + + if (FindOne(scene, typeof(HUDController)) == null) missing.Add(" • HUDController"); + if (FindOne(scene, typeof(CameraController)) == null) missing.Add(" • CameraController"); + + return missing.Count == 0; + } + + // Scans the scene's root objects rather than Object.FindObjectsByType: the FindObjectsByType + // overload set has churned across Unity 6.x (FindObjectsSortMode deprecation), and walking + // roots is stable across all of them. + private static Component FindOne(Scene scene, System.Type type) + { + foreach (var root in scene.GetRootGameObjects()) + { + var found = root.GetComponentInChildren(type, true); + if (found != null) return found; + } + return null; + } + + private static Light FindDirectionalLight(Scene scene) + { + foreach (var root in scene.GetRootGameObjects()) + { + foreach (var light in root.GetComponentsInChildren(true)) + { + if (light.type == LightType.Directional) return light; + } + } + return null; + } + + // ------------------------------------------------------------------- + // MatchServices prefab + // ------------------------------------------------------------------- + + private static GameObject BuildServicesPrefab(Scene scene, List rootSources) + { + var root = new GameObject("_MatchServices"); + + // Flatten every plain service onto the root. CopyComponent/PasteComponentAsNew carries + // all serialized values, including the order-sensitive asset arrays. + for (int i = 0; i < rootSources.Count; i++) + { + var src = rootSources[i]; + if (src == null) continue; + ComponentUtility.CopyComponent(src); + ComponentUtility.PasteComponentAsNew(root); + } + + // Components that need their own GameObject: UIDocument is [DisallowMultipleComponent], + // so HUD and DebugConsole can't share one; CameraRig needs an independently-moving + // transform with the Camera as its child. + GameObject hud = CloneUnder(FindOne(scene, typeof(HUDController)), root, "HUD"); + CloneUnder(FindOne(scene, typeof(DebugConsole)), root, "DebugConsole"); + GameObject cameraRig = CloneUnder(FindOne(scene, typeof(CameraController)), root, "CameraRig"); + CloneUnder(FindDirectionalLight(scene), root, "Directional Light"); + + // Post-processing volume is optional — 9Player doesn't have one, Main does. + CloneUnder(FindOne(scene, typeof(UnityEngine.Rendering.Volume)), root, "Global Volume"); + + RewireHudReferences(hud, root, cameraRig); + ClearBakedLevelReference(root); + + var prefab = PrefabUtility.SaveAsPrefabAsset(root, ServicesPrefabPath); + Object.DestroyImmediate(root); + return prefab; + } + + // Instantiate() remaps references that point INSIDE the copied hierarchy but leaves + // references that point outside it aimed at the original scene objects. Saving a prefab + // silently nulls those, so re-aim them at the prefab-internal equivalents first. + private static void RewireHudReferences(GameObject hud, GameObject root, GameObject cameraRig) + { + if (hud == null) return; + var controller = hud.GetComponent(); + if (controller == null) return; + + var so = new SerializedObject(controller); + SetRef(so, "placementController", root.GetComponent()); + SetRef(so, "paintController", root.GetComponent()); + SetRef(so, "cameraController", + cameraRig != null ? cameraRig.GetComponent() : null); + + // TowerPlacementManager lives in the OTHER prefab (it's a NetworkBehaviour), so this + // reference cannot be satisfied here. HUDController already falls back to + // TowerPlacementManager.Instance and retries per-frame until the object spawns, so + // leaving it null is the correct wiring, not a gap. + SetRef(so, "placementManager", null); + + so.ApplyModifiedPropertiesWithoutUndo(); + } + + // The reference scene's LevelLoader points at that map's LevelData. The prefab is map- + // independent, so blank it — NewMapBuilder sets it per-instance as a prefab override. + private static void ClearBakedLevelReference(GameObject root) + { + var loader = root.GetComponent(); + if (loader == null) return; + + var so = new SerializedObject(loader); + SetRef(so, "level", null); + so.ApplyModifiedPropertiesWithoutUndo(); + } + + // ------------------------------------------------------------------- + // MatchNetwork prefab + // ------------------------------------------------------------------- + + private static GameObject BuildNetworkPrefab(Scene scene) + { + var root = new GameObject("_MatchNetwork"); + + foreach (var type in NetworkServiceTypes) + { + CloneUnder(FindOne(scene, type), root, type.Name); + } + + var prefab = PrefabUtility.SaveAsPrefabAsset(root, NetworkPrefabPath); + Object.DestroyImmediate(root); + return prefab; + } + + // ------------------------------------------------------------------- + // Terrain defaults + // ------------------------------------------------------------------- + + private static void CaptureTerrainDefaults(Scene scene, MapTemplate template) + { + var terrain = FindOne(scene, typeof(Terrain)) as Terrain; + if (terrain == null) return; + + if (terrain.materialTemplate != null) template.terrainMaterial = terrain.materialTemplate; + if (terrain.terrainData != null && terrain.terrainData.terrainLayers != null && + terrain.terrainData.terrainLayers.Length > 0) + { + template.terrainLayers = terrain.terrainData.terrainLayers; + } + } + + // ------------------------------------------------------------------- + // Helpers + // ------------------------------------------------------------------- + + // Clones the component's whole GameObject subtree and parents it under root. + // Returns null (silently) when source is null — callers treat those as optional. + private static GameObject CloneUnder(Component source, GameObject root, string name) + { + if (source == null) return null; + + var clone = Object.Instantiate(source.gameObject); + clone.name = name; + clone.transform.SetParent(root.transform, worldPositionStays: false); + return clone; + } + + private static void SetRef(SerializedObject so, string propertyPath, Object value) + { + var prop = so.FindProperty(propertyPath); + if (prop == null) + { + Debug.LogWarning($"[MapPipeline] Serialized field '{propertyPath}' not found on " + + $"{so.targetObject.GetType().Name}. It was probably renamed — " + + "update MapCoreExtractor."); + return; + } + prop.objectReferenceValue = value; + } + } +} diff --git a/Assets/_Project/Scripts/Editor/Levels/MapCoreExtractor.cs.meta b/Assets/_Project/Scripts/Editor/Levels/MapCoreExtractor.cs.meta new file mode 100644 index 0000000..7dfcd04 --- /dev/null +++ b/Assets/_Project/Scripts/Editor/Levels/MapCoreExtractor.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: d1b948bcbbe8d8b4788f2056372280b3 \ No newline at end of file diff --git a/Assets/_Project/Scripts/Editor/Levels/MapTemplate.cs b/Assets/_Project/Scripts/Editor/Levels/MapTemplate.cs new file mode 100644 index 0000000..0d112c0 --- /dev/null +++ b/Assets/_Project/Scripts/Editor/Levels/MapTemplate.cs @@ -0,0 +1,292 @@ +// Assets/_Project/Scripts/Editor/Levels/MapTemplate.cs +using UnityEditor; +using UnityEngine; + +namespace TD.Levels.Editor +{ + /// + /// Editor-only settings asset that drives TD/New Map…. Holds the two core prefabs + /// produced by plus every default the new-map generator needs, + /// so tuning the starter layout is an inspector edit rather than a code change. + /// + /// + /// Lives in the Editor assembly deliberately — nothing at runtime reads it, and keeping the + /// type editor-only stops it from being pulled into a player build. + /// + /// The asset is created on demand at . If it goes missing, both + /// TD/New Map… and the extractor recreate it with defaults; only the prefab references + /// and captured terrain settings are lost, and re-running the extractor restores those. + /// + public class MapTemplate : ScriptableObject + { + public const string AssetPath = "Assets/_Project/Settings/MapTemplate.asset"; + + // ------------------------------------------------------------------- + // Core prefabs. Populated by MapCoreExtractor; consumed by NewMapBuilder. + // ------------------------------------------------------------------- + + [Header("Core Prefabs (built by TD/Map Pipeline/Build Core Prefabs)")] + [Tooltip("Every map-independent, non-networked service collapsed onto one GameObject " + + "(plus HUD / DebugConsole / CameraRig / light children). Instantiated as a LINKED " + + "prefab instance so edits here propagate to every map.")] + public GameObject matchServicesPrefab; + + [Tooltip("The six scene-placed NetworkBehaviours, parented under one root. Instantiated " + + "and immediately UNPACKED so the scene contains plain GameObjects — network " + + "topology stays byte-identical to hand-authored maps.")] + public GameObject matchNetworkPrefab; + + // ------------------------------------------------------------------- + // Output locations. + // ------------------------------------------------------------------- + + [Header("Output Locations")] + [Tooltip("Folder new map scenes, their LevelData, and their TerrainData are written to. " + + "Drag the folder itself here — an asset reference follows renames and moves, " + + "which a path string does not.")] + public DefaultAsset sceneFolderAsset; + + [Tooltip("Scene holding the MapRegistry that the lobby's map browser reads. New maps are " + + "appended to its Maps array automatically.")] + public SceneAsset mainMenuScene; + + // Legacy path strings, superseded by the asset references above. Kept so an existing + // template migrates itself (see MigratePathsToAssets) and as a last resort if a reference + // is cleared. Hidden so there's exactly one obvious place to edit. + [HideInInspector] public string sceneFolder = "Assets/_Project/Scenes/Levels"; + [HideInInspector] public string mainMenuScenePath = "Assets/_Project/Scenes/UI/MainMenu.unity"; + + /// + /// Folder new maps are written to. Prefers ; falls back to the + /// legacy path string if the reference is unset or doesn't point at a folder. + /// + public string SceneFolderPath + { + get + { + if (sceneFolderAsset != null) + { + string path = AssetDatabase.GetAssetPath(sceneFolderAsset); + if (AssetDatabase.IsValidFolder(path)) return path; + + Debug.LogWarning($"[MapPipeline] MapTemplate's Scene Folder Asset points at " + + $"'{path}', which is not a folder. Falling back to '{sceneFolder}'."); + } + return sceneFolder; + } + } + + /// + /// Scene containing the MapRegistry. Prefers ; falls back to the + /// legacy path string. Returns empty if neither resolves. + /// + public string MainMenuScenePath + { + get + { + if (mainMenuScene != null) + { + string path = AssetDatabase.GetAssetPath(mainMenuScene); + if (!string.IsNullOrEmpty(path)) return path; + } + return mainMenuScenePath ?? string.Empty; + } + } + + // ------------------------------------------------------------------- + // Terrain defaults. Captured from the reference scene by the extractor. + // ------------------------------------------------------------------- + + [Header("Terrain Defaults")] + [Tooltip("Material applied to new terrain. Captured from the reference scene's Terrain.")] + public Material terrainMaterial; + + [Tooltip("Terrain layers (splat textures) applied to new terrain.")] + public TerrainLayer[] terrainLayers; + + [Tooltip("Heightmap resolution. Must be 2^n + 1 (129, 257, 513, 1025…).")] + public int terrainHeightmapResolution = 513; + + [Tooltip("Total vertical range of the terrain in world units.")] + public float terrainHeight = 60f; + + [Tooltip("How far the terrain extends past the map bounds on each side, in tiles. Gives " + + "the camera something to look at beyond the playable area.")] + public int terrainSkirtTiles = 20; + + [Tooltip("Terrain is created flattened to this height above its own base, and its transform " + + "is dropped by the same amount — so the flat surface lands exactly on the buildable " + + "plane (Y=0) while leaving headroom to carve DOWN as well as up. Set 0 to match the " + + "older 9Player setup (surface at the very bottom of the height range).")] + public float terrainCarveDepth = 5f; + + // ------------------------------------------------------------------- + // Starter layout. All values in tiles. + // ------------------------------------------------------------------- + + [Header("Starter Layout (tiles)")] + [Tooltip("Default map width for the New Map dialog.")] + public int defaultMapWidth = 60; + + [Tooltip("Default map height for the New Map dialog.")] + public int defaultMapHeight = 70; + + [Tooltip("Gap between the map edge (MapAreaVolume) and the gameplay volumes. The map area " + + "must fully contain every gameplay volume, and the buffer gives the camera room " + + "to pan past the playfield.")] + public int playAreaMargin = 4; + + [Tooltip("Depth (north-south) of the GoalVolume.")] + public int goalDepth = 5; + + [Tooltip("Width (east-west) of the GoalVolume.")] + public int goalWidth = 10; + + [Tooltip("Depth of each SpawnerVolume, measured from the south edge of its owner's band.")] + public int spawnerDepth = 3; + + [Tooltip("Width of each SpawnerVolume.")] + public int spawnerWidth = 10; + + [Tooltip("Width of the one-tile-deep LeakExitVolume gate between adjacent player bands.")] + public int leakGateWidth = 8; + + [Tooltip("Smallest acceptable north-south depth for a player band. The New Map dialog " + + "refuses to generate a layout thinner than this and tells you the map height needed.")] + public int minBandDepth = 8; + + // ------------------------------------------------------------------- + // Loading + // ------------------------------------------------------------------- + + /// + /// Returns the template asset, creating it with defaults if it doesn't exist yet. + /// Never returns null. + /// + public static MapTemplate LoadOrCreate() + { + var existing = AssetDatabase.LoadAssetAtPath(AssetPath); + if (existing != null) + { + existing.MigratePathsToAssets(); + return existing; + } + + EnsureFolder(System.IO.Path.GetDirectoryName(AssetPath).Replace("\\", "/")); + + var created = CreateInstance(); + AssetDatabase.CreateAsset(created, AssetPath); + created.MigratePathsToAssets(); + AssetDatabase.SaveAssets(); + Debug.Log($"[MapPipeline] Created default map template at '{AssetPath}'."); + return created; + } + + /// + /// Upgrades a template that still stores locations as path strings, resolving each to an + /// asset reference. Idempotent and cheap — safe to call on every load. + /// + /// + /// If the recorded path no longer resolves (the folder was renamed out from under it, which + /// is exactly the failure the asset references exist to prevent), falls back to searching + /// the project for a uniquely-named match. An ambiguous match is left unresolved on purpose: + /// guessing which of several same-named scenes holds the MapRegistry would be worse than + /// asking. + /// + private void MigratePathsToAssets() + { + bool changed = false; + + if (sceneFolderAsset == null && !string.IsNullOrEmpty(sceneFolder) + && AssetDatabase.IsValidFolder(sceneFolder)) + { + sceneFolderAsset = AssetDatabase.LoadAssetAtPath(sceneFolder); + changed |= sceneFolderAsset != null; + } + + if (mainMenuScene == null && !string.IsNullOrEmpty(mainMenuScenePath)) + { + var scene = AssetDatabase.LoadAssetAtPath(mainMenuScenePath); + + if (scene == null) + { + string wanted = System.IO.Path.GetFileNameWithoutExtension(mainMenuScenePath); + scene = FindUniqueSceneNamed(wanted); + if (scene != null) + { + Debug.Log($"[MapPipeline] MapTemplate's recorded Main Menu path " + + $"'{mainMenuScenePath}' no longer exists; relinked to " + + $"'{AssetDatabase.GetAssetPath(scene)}'."); + } + } + + if (scene != null) + { + mainMenuScene = scene; + changed = true; + } + } + + if (changed) + { + EditorUtility.SetDirty(this); + AssetDatabase.SaveAssets(); + } + } + + // Returns the one SceneAsset whose file name matches exactly, or null if there are zero or + // several. Name search only — the caller has already failed to resolve by path. + private static SceneAsset FindUniqueSceneNamed(string sceneName) + { + if (string.IsNullOrEmpty(sceneName)) return null; + + string[] guids = AssetDatabase.FindAssets($"{sceneName} t:SceneAsset"); + SceneAsset first = null; + int matches = 0; + + foreach (string guid in guids) + { + string path = AssetDatabase.GUIDToAssetPath(guid); + if (!string.Equals(System.IO.Path.GetFileNameWithoutExtension(path), sceneName, + System.StringComparison.OrdinalIgnoreCase)) + { + continue; // FindAssets does substring matching; we want an exact file name. + } + + matches++; + if (first == null) first = AssetDatabase.LoadAssetAtPath(path); + } + + if (matches > 1) + { + Debug.LogWarning($"[MapPipeline] Found {matches} scenes named '{sceneName}'. " + + "Assign Main Menu Scene on MapTemplate manually."); + return null; + } + + return first; + } + + /// + /// Creates and any missing ancestors. Path is asset-relative and + /// uses forward slashes ("Assets/_Project/Prefabs/MatchCore"). No-op if it already exists. + /// + public static void EnsureFolder(string folder) + { + if (string.IsNullOrEmpty(folder) || AssetDatabase.IsValidFolder(folder)) return; + + string[] parts = folder.Split('/'); + // parts[0] is always "Assets" for a valid asset path; walk down creating as needed. + string running = parts[0]; + for (int i = 1; i < parts.Length; i++) + { + string next = running + "/" + parts[i]; + if (!AssetDatabase.IsValidFolder(next)) + { + AssetDatabase.CreateFolder(running, parts[i]); + } + running = next; + } + } + } +} diff --git a/Assets/_Project/Scripts/Editor/Levels/MapTemplate.cs.meta b/Assets/_Project/Scripts/Editor/Levels/MapTemplate.cs.meta new file mode 100644 index 0000000..7fbc813 --- /dev/null +++ b/Assets/_Project/Scripts/Editor/Levels/MapTemplate.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: fb7355881928ea146a26471078f207c2 \ No newline at end of file diff --git a/Assets/_Project/Scripts/Editor/Levels/NewMapBuilder.cs b/Assets/_Project/Scripts/Editor/Levels/NewMapBuilder.cs new file mode 100644 index 0000000..737e97b --- /dev/null +++ b/Assets/_Project/Scripts/Editor/Levels/NewMapBuilder.cs @@ -0,0 +1,578 @@ +// Assets/_Project/Scripts/Editor/Levels/NewMapBuilder.cs +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEditor.SceneManagement; +using UnityEngine; +using UnityEngine.SceneManagement; + +using TD.Core; +using TD.Gameplay; + +namespace TD.Levels.Editor +{ + /// + /// Everything the TD/New Map… command does once the designer presses Create: build the + /// scene, generate a starter volume layout that bakes clean, create and wire the LevelData, and + /// perform the three registration steps that otherwise fail silently (Build Settings, the + /// LevelLoader reference, and the lobby's MapRegistry). + /// + /// + /// The generated scene has four roots — _LevelAuthoring, _MatchServices, + /// _MatchNetwork, Terrain — replacing the ~30 the hand-authored maps carry. + /// + public static class NewMapBuilder + { + // The physics layer terrain must sit on. Builder.SampleTerrainY and + // BuilderSpellCastController both raycast against it; terrain left on Default silently + // falls back to Y=0 and the builder walks through hills instead of over them. + private const string TerrainLayerName = "TerrainGeometry"; + + // Vertical size of every authoring volume's BoxCollider. Any value works so long as the + // bounds straddle Y=0 (bake rule P2-18); 1 unit centred on zero matches 9Player. + private const float VolumeHeight = 1f; + + private static readonly Regex ValidName = new Regex(@"^[A-Za-z0-9_]+$"); + + // ------------------------------------------------------------------- + // Request + // ------------------------------------------------------------------- + + public class Request + { + public string MapName = "NewMap"; + public int PlayerCount = 3; + public int MapWidth = 60; + public int MapHeight = 70; + public string Author = ""; + public string Description = ""; + public BuildAccess BuildAccess = BuildAccess.OwnerOnly; + public bool CreateTerrain = true; + public bool AddToBuildSettings = true; + public bool AddToMapRegistry = true; + public bool BakeImmediately = true; + } + + // ------------------------------------------------------------------- + // Starter layout + // ------------------------------------------------------------------- + + /// + /// Tile rectangles for a generated starter map. Zones are stacked south-to-north as + /// full-width bands; enemies spawn at the south edge of their owner's band and travel north + /// through a one-tile leak gate into the next player's band, with the goal north of the + /// final band. + /// + public struct Layout + { + public RectInt MapArea; + public RectInt[] Zones; // index 0 = Player1 + public RectInt[] Spawners; // parallel to Zones + public RectInt[] Leaks; // Zones.Length - 1 entries; Leaks[i] runs zone i -> zone i+1 + public RectInt Goal; + public int BandDepth; + } + + /// + /// Computes the starter layout, or explains why the requested dimensions can't hold one. + /// Pure — safe to call every OnGUI frame for live validation. + /// + public static bool TryComputeLayout(MapTemplate template, int mapWidth, int mapHeight, + int playerCount, BuildAccess buildAccess, + out Layout layout, out string error) + { + layout = default; + error = null; + + // OwnerOnly maps get a one-tile leak gate between bands: it is the only walkable + // connection, which is what forces enemies through a chokepoint and makes the handoff + // between lanes legible. Shared maps skip gates entirely and butt the bands together — + // the whole map is one maze, so a gate would just be an arbitrary pinch, and with no + // LeakExitVolume the gap row would not be walkable at all. + bool useLeakGates = buildAccess == BuildAccess.OwnerOnly; + int gapRows = useLeakGates ? playerCount - 1 : 0; + + int margin = Mathf.Max(0, template.playAreaMargin); + int playX0 = margin; + int playY0 = margin; + int playW = mapWidth - margin * 2; + int playH = mapHeight - margin * 2; + + int widestFeature = Mathf.Max(template.goalWidth, + Mathf.Max(template.spawnerWidth, template.leakGateWidth)); + if (playW < widestFeature) + { + error = $"Map is too narrow. The play area is {playW} tiles wide after the " + + $"{margin}-tile margin, but the widest starter feature needs {widestFeature}. " + + $"Use a width of at least {widestFeature + margin * 2}."; + return false; + } + + // Vertical budget: N bands + the gate rows (if any) + the goal. + int budget = playH - gapRows - template.goalDepth; + int bandDepth = playerCount > 0 ? budget / playerCount : 0; + + int minBand = Mathf.Max(template.minBandDepth, template.spawnerDepth + 1); + if (bandDepth < minBand) + { + int required = playerCount * minBand + gapRows + + template.goalDepth + margin * 2; + error = $"Map is too shallow for {playerCount} player band(s). Each band would be " + + $"{Mathf.Max(bandDepth, 0)} tiles deep; the minimum is {minBand}. " + + $"Use a height of at least {required}."; + return false; + } + + layout.MapArea = new RectInt(0, 0, mapWidth, mapHeight); + layout.BandDepth = bandDepth; + layout.Zones = new RectInt[playerCount]; + layout.Spawners = new RectInt[playerCount]; + layout.Leaks = new RectInt[useLeakGates ? Mathf.Max(0, playerCount - 1) : 0]; + + int y = playY0; + for (int i = 0; i < playerCount; i++) + { + layout.Zones[i] = new RectInt(playX0, y, playW, bandDepth); + + // Spawner sits at the south edge of its own band, so enemies always have the full + // band depth to walk through before reaching the exit (bake rule P5-5 wants it + // inside the owner's zone). + int spawnW = Mathf.Min(template.spawnerWidth, playW); + layout.Spawners[i] = new RectInt( + CenteredStart(playX0, playW, spawnW), y, spawnW, template.spawnerDepth); + + y += bandDepth; + + if (useLeakGates && i < playerCount - 1) + { + // One-tile gate wedged between two bands: its south neighbours are band i and + // its north neighbours are band i+1, satisfying both adjacency rules (P5-6/P5-7). + int gateW = Mathf.Min(template.leakGateWidth, playW); + layout.Leaks[i] = new RectInt( + CenteredStart(playX0, playW, gateW), y, gateW, 1); + y += 1; + } + } + + int goalW = Mathf.Min(template.goalWidth, playW); + layout.Goal = new RectInt( + CenteredStart(playX0, playW, goalW), y, goalW, template.goalDepth); + + return true; + } + + private static int CenteredStart(int areaStart, int areaWidth, int featureWidth) + { + return areaStart + (areaWidth - featureWidth) / 2; + } + + // ------------------------------------------------------------------- + // Creation + // ------------------------------------------------------------------- + + /// + /// Creates the map. Returns false with a human-readable reason on any precondition failure; + /// nothing is written to disk in that case. + /// + public static bool Create(Request request, out string error) + { + error = null; + var template = MapTemplate.LoadOrCreate(); + + if (!ValidatePreconditions(request, template, out error)) return false; + + if (!TryComputeLayout(template, request.MapWidth, request.MapHeight, + request.PlayerCount, request.BuildAccess, + out Layout layout, out error)) + { + return false; + } + + string folder = template.SceneFolderPath; + string scenePath = $"{folder}/{request.MapName}.unity"; + string dataPath = $"{folder}/{request.MapName}.asset"; + + // Give the designer a chance to save whatever they had open — NewScene(Single) would + // otherwise discard it. + if (!EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo()) + { + error = "Cancelled while saving the currently open scene."; + return false; + } + + MapTemplate.EnsureFolder(folder); + + Scene scene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single); + + // ---- Core objects ------------------------------------------- + var services = (GameObject)PrefabUtility.InstantiatePrefab(template.matchServicesPrefab); + services.name = "_MatchServices"; + + var network = (GameObject)PrefabUtility.InstantiatePrefab(template.matchNetworkPrefab); + network.name = "_MatchNetwork"; + // Unpack so the six NetworkObjects are plain scene objects. NGO treats in-scene placed + // NetworkObjects that are prefab instances differently from loose ones; unpacking keeps + // generated maps structurally identical to the hand-authored ones. + PrefabUtility.UnpackPrefabInstance( + network, PrefabUnpackMode.Completely, InteractionMode.AutomatedAction); + + // ---- LevelData ---------------------------------------------- + var levelData = ScriptableObject.CreateInstance(); + AssetDatabase.CreateAsset(levelData, dataPath); + + // ---- Authoring hierarchy ------------------------------------ + LevelAuthoring authoring = BuildAuthoring(request, layout, levelData); + + // ---- Terrain ------------------------------------------------- + if (request.CreateTerrain) + { + CreateTerrain(request, template); + } + + // ---- Wire the runtime loader --------------------------------- + // LevelLoader lives inside the linked MatchServices prefab; assigning here records a + // per-instance override, which is exactly the intent — the asset differs per map. + WireLevelLoader(services, levelData); + + // ---- Save + register ----------------------------------------- + EditorSceneManager.SaveScene(scene, scenePath); + + var notes = new List(); + + if (request.AddToBuildSettings) notes.Add(RegisterInBuildSettings(scenePath)); + if (request.AddToMapRegistry) notes.Add(RegisterInMapRegistry(template, levelData)); + + // Bake last: it stamps LevelData.ScenePath from the ACTIVE scene, so the scene has to + // be saved (and therefore have a path) before this runs. + if (request.BakeImmediately) + { + notes.Add(LevelBakePipeline.Bake(authoring) + ? "Baked LevelData (see console for the bake report)." + : "Bake FAILED — see console. The scene and assets were still created."); + } + + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); + + Selection.activeGameObject = authoring.gameObject; + if (SceneView.lastActiveSceneView != null) SceneView.lastActiveSceneView.FrameSelected(); + + Debug.Log( + $"[MapPipeline] Created map '{request.MapName}' " + + $"({request.PlayerCount} player(s), {request.MapWidth}×{request.MapHeight} tiles, " + + $"band depth {layout.BandDepth}).\n" + + $" Scene: {scenePath}\n" + + $" LevelData: {dataPath}\n" + + string.Join("\n", notes.Where(n => !string.IsNullOrEmpty(n)).Select(n => " " + n))); + + return true; + } + + private static bool ValidatePreconditions(Request request, MapTemplate template, + out string error) + { + error = null; + + if (string.IsNullOrWhiteSpace(request.MapName) || !ValidName.IsMatch(request.MapName)) + { + error = "Map name must be letters, digits and underscores only — it becomes the " + + "scene file name and the string NGO uses to load the scene."; + return false; + } + + if (template.matchServicesPrefab == null || template.matchNetworkPrefab == null) + { + error = "Core prefabs are missing. Open the 9Player scene and run " + + "TD → Map Pipeline → Build Core Prefabs From Open Scene first."; + return false; + } + + string folder = template.SceneFolderPath; + if (string.IsNullOrEmpty(folder)) + { + error = "MapTemplate has no output folder. Assign Scene Folder Asset on " + + MapTemplate.AssetPath + "."; + return false; + } + + string scenePath = $"{folder}/{request.MapName}.unity"; + if (System.IO.File.Exists(scenePath)) + { + error = $"A scene already exists at '{scenePath}'. Pick a different name."; + return false; + } + + string dataPath = $"{folder}/{request.MapName}.asset"; + if (System.IO.File.Exists(dataPath)) + { + error = $"A LevelData asset already exists at '{dataPath}'. Pick a different name."; + return false; + } + + return true; + } + + // ------------------------------------------------------------------- + // Authoring hierarchy + // ------------------------------------------------------------------- + + private static LevelAuthoring BuildAuthoring(Request request, Layout layout, + LevelData levelData) + { + var rootGO = new GameObject("_LevelAuthoring"); + var authoring = rootGO.AddComponent(); + + authoring.targetAsset = levelData; + authoring.mapName = request.MapName; + authoring.playerCount = request.PlayerCount; + authoring.expectedGoalCount = 1; + authoring.mapDescription = request.Description ?? ""; + authoring.author = request.Author ?? ""; + authoring.buildAccess = request.BuildAccess; + + // Default every gizmo category on. A designer opening a fresh map wants to SEE the + // starter layout without hunting for toggles; turning them off is the deliberate act. + authoring.alwaysShowPlayerZones = true; + authoring.alwaysShowSpawners = true; + authoring.alwaysShowLeakExits = true; + authoring.alwaysShowGoals = true; + authoring.alwaysShowMapArea = true; + + CreateVolume("MapArea", rootGO.transform, layout.MapArea); + + var goal = CreateVolume("Goal", rootGO.transform, layout.Goal); + goal.GetComponent().placementValidity = PlacementValidity.Invalid; + + for (int i = 0; i < request.PlayerCount; i++) + { + int playerNumber = i + 1; + var slot = (PlayerSlot)(byte)playerNumber; + + var group = new GameObject($"Player {playerNumber}"); + group.transform.SetParent(rootGO.transform, worldPositionStays: false); + + var zone = CreateVolume( + $"Player{playerNumber}Zone", group.transform, layout.Zones[i]); + var zoneVolume = zone.GetComponent(); + zoneVolume.owner = slot; + zoneVolume.placementValidity = PlacementValidity.Allowed; + + var spawn = CreateVolume( + $"Player{playerNumber}Spawn", group.transform, layout.Spawners[i]); + var spawnVolume = spawn.GetComponent(); + spawnVolume.owner = slot; + spawnVolume.spawnerIdInZone = 0; + spawnVolume.spawnFacing = Direction.North; // bands run south -> north + spawnVolume.placementValidity = PlacementValidity.Invalid; + + // The northernmost band has no leak — it's the final defender, and its zone is + // goal-adjacent instead (bake rule P5-8). + if (i < layout.Leaks.Length) + { + var leak = CreateVolume( + $"Player{playerNumber}Leak", group.transform, layout.Leaks[i]); + var leakVolume = leak.GetComponent(); + leakVolume.sourceZone = slot; + leakVolume.target = (PlayerSlot)(byte)(playerNumber + 1); + leakVolume.weight = 1f; + leakVolume.placementValidity = PlacementValidity.Invalid; + } + } + + return authoring; + } + + // Builds one authoring volume covering the given tile rectangle. Tiles are edge-aligned, so + // a rect spanning tiles [x0..x1] occupies world X [x0, x1+1] — which is exactly + // RectInt.xMin..RectInt.xMax. Geometry goes on the BoxCollider (centre zero, size = extent) + // with the transform at the volume's centre, matching the existing maps and keeping + // VolumeEditTool's edge-drag behaviour predictable. + private static GameObject CreateVolume(string name, Transform parent, RectInt tiles) + where T : VolumeBase + { + var go = new GameObject(name); + go.transform.SetParent(parent, worldPositionStays: false); + go.transform.localPosition = new Vector3( + (tiles.xMin + tiles.xMax) * 0.5f * GridCoordinates.TILE_SIZE, + 0f, + (tiles.yMin + tiles.yMax) * 0.5f * GridCoordinates.TILE_SIZE); + + // Added before the volume component so VolumeBase's [RequireComponent] doesn't add a + // second, default-sized collider. + var collider = go.AddComponent(); + collider.center = Vector3.zero; + collider.size = new Vector3( + tiles.width * GridCoordinates.TILE_SIZE, + VolumeHeight, + tiles.height * GridCoordinates.TILE_SIZE); + + go.AddComponent(); + return go; + } + + // ------------------------------------------------------------------- + // Terrain + // ------------------------------------------------------------------- + + private static void CreateTerrain(Request request, MapTemplate template) + { + int skirt = Mathf.Max(0, template.terrainSkirtTiles); + float carve = Mathf.Clamp(template.terrainCarveDepth, 0f, template.terrainHeight); + + var data = new TerrainData { name = request.MapName + "_TerrainData" }; + // Resolution before size: changing heightmapResolution resets size. + data.heightmapResolution = template.terrainHeightmapResolution; + data.size = new Vector3( + request.MapWidth + skirt * 2f, + Mathf.Max(1f, template.terrainHeight), + request.MapHeight + skirt * 2f); + + if (template.terrainLayers != null && template.terrainLayers.Length > 0) + { + data.terrainLayers = template.terrainLayers; + } + + // Start the surface partway up its own height range and drop the transform to match, so + // the flat ground lands on the buildable plane (Y=0) with room to carve downwards. + if (carve > 0f) + { + int res = data.heightmapResolution; + float normalized = carve / Mathf.Max(1f, template.terrainHeight); + var heights = new float[res, res]; + for (int y = 0; y < res; y++) + { + for (int x = 0; x < res; x++) heights[y, x] = normalized; + } + data.SetHeights(0, 0, heights); + } + + AssetDatabase.CreateAsset( + data, $"{template.SceneFolderPath}/{request.MapName}_TerrainData.asset"); + + var terrainGO = Terrain.CreateTerrainGameObject(data); + terrainGO.name = "Terrain"; + terrainGO.transform.position = new Vector3(-skirt, -carve, -skirt); + + int layer = LayerMask.NameToLayer(TerrainLayerName); + if (layer >= 0) + { + terrainGO.layer = layer; + } + else + { + Debug.LogWarning( + $"[MapPipeline] Layer '{TerrainLayerName}' does not exist, so the new terrain was " + + "left on Default. The builder's ground raycast and spell targeting both filter " + + "on that layer and will ignore this terrain until it's fixed."); + } + + if (template.terrainMaterial != null) + { + terrainGO.GetComponent().materialTemplate = template.terrainMaterial; + } + } + + // ------------------------------------------------------------------- + // Wiring and registration + // ------------------------------------------------------------------- + + private static void WireLevelLoader(GameObject services, LevelData levelData) + { + var loader = services.GetComponentInChildren(true); + if (loader == null) + { + Debug.LogError("[MapPipeline] MatchServices prefab has no LevelLoader — the map " + + "will not load at runtime. Re-run Build Core Prefabs."); + return; + } + + var so = new SerializedObject(loader); + var prop = so.FindProperty("level"); + if (prop == null) + { + Debug.LogError("[MapPipeline] LevelLoader has no serialized field 'level'. It was " + + "renamed — update NewMapBuilder."); + return; + } + prop.objectReferenceValue = levelData; + so.ApplyModifiedPropertiesWithoutUndo(); + } + + private static string RegisterInBuildSettings(string scenePath) + { + var scenes = EditorBuildSettings.scenes.ToList(); + if (scenes.Any(s => s.path == scenePath)) + { + return "Already in Build Settings."; + } + + scenes.Add(new EditorBuildSettingsScene(scenePath, true)); + EditorBuildSettings.scenes = scenes.ToArray(); + return $"Added to Build Settings (index {scenes.Count - 1})."; + } + + // MapRegistry lives in the MainMenu scene, not the map scene — the one registration step + // that isn't visible from where the designer is working, and therefore the one most often + // forgotten. Open it additively, append, save, close. + private static string RegisterInMapRegistry(MapTemplate template, LevelData levelData) + { + string path = template.MainMenuScenePath; + if (string.IsNullOrEmpty(path) || !System.IO.File.Exists(path)) + { + return $"SKIPPED MapRegistry — no scene at '{path}'. Assign Main Menu Scene on " + + $"{MapTemplate.AssetPath}, then add this LevelData to the registry by hand."; + } + + Scene menu = default; + bool opened = false; + try + { + menu = EditorSceneManager.OpenScene(path, OpenSceneMode.Additive); + opened = true; + + MapRegistry registry = null; + foreach (var root in menu.GetRootGameObjects()) + { + registry = root.GetComponentInChildren(true); + if (registry != null) break; + } + + if (registry == null) + { + return $"SKIPPED MapRegistry — none found in '{menu.name}'. Add the LevelData by hand."; + } + + var so = new SerializedObject(registry); + var maps = so.FindProperty("maps"); + if (maps == null) + { + return "SKIPPED MapRegistry — serialized field 'maps' not found (renamed?)."; + } + + for (int i = 0; i < maps.arraySize; i++) + { + if (maps.GetArrayElementAtIndex(i).objectReferenceValue == levelData) + { + return "Already in MapRegistry."; + } + } + + maps.InsertArrayElementAtIndex(maps.arraySize); + maps.GetArrayElementAtIndex(maps.arraySize - 1).objectReferenceValue = levelData; + so.ApplyModifiedPropertiesWithoutUndo(); + + EditorSceneManager.MarkSceneDirty(menu); + EditorSceneManager.SaveScene(menu); + return $"Added to MapRegistry in '{menu.name}' (slot {maps.arraySize - 1})."; + } + finally + { + if (opened && menu.IsValid()) + { + EditorSceneManager.CloseScene(menu, removeScene: true); + } + } + } + } +} diff --git a/Assets/_Project/Scripts/Editor/Levels/NewMapBuilder.cs.meta b/Assets/_Project/Scripts/Editor/Levels/NewMapBuilder.cs.meta new file mode 100644 index 0000000..e60c9fd --- /dev/null +++ b/Assets/_Project/Scripts/Editor/Levels/NewMapBuilder.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 5eda54745c5c78c489eb2cf9aa6265b7 \ No newline at end of file diff --git a/Assets/_Project/Scripts/Editor/Levels/NewMapWindow.cs b/Assets/_Project/Scripts/Editor/Levels/NewMapWindow.cs new file mode 100644 index 0000000..b1e07ba --- /dev/null +++ b/Assets/_Project/Scripts/Editor/Levels/NewMapWindow.cs @@ -0,0 +1,205 @@ +// Assets/_Project/Scripts/Editor/Levels/NewMapWindow.cs +using UnityEditor; +using UnityEngine; + +using TD.Core; + +namespace TD.Levels.Editor +{ + /// + /// The TD/New Map… dialog. Collects the handful of decisions only a designer can make, + /// validates the resulting layout live, and hands off to . + /// + public class NewMapWindow : EditorWindow + { + // Mirrors LevelBakePipeline's accepted set — anything else is a hard bake error (P2-15), + // so there's no point offering it here. + private static readonly int[] PlayerCountValues = { 1, 2, 3, 4, 5, 9 }; + private static readonly string[] PlayerCountLabels = + { "1 player", "2 players", "3 players", "4 players", "5 players", "9 players" }; + + private const string AuthorPrefKey = "TD.MapPipeline.LastAuthor"; + + private readonly NewMapBuilder.Request request = new NewMapBuilder.Request(); + private bool initialized; + private Vector2 scroll; + + [MenuItem("TD/New Map...", false, 100)] + public static void Open() + { + var window = GetWindow(utility: true, title: "New Map", focus: true); + window.minSize = new Vector2(420f, 460f); + window.Show(); + } + + private void Initialize() + { + if (initialized) return; + initialized = true; + + var template = MapTemplate.LoadOrCreate(); + request.MapWidth = template.defaultMapWidth; + request.MapHeight = template.defaultMapHeight; + request.Author = EditorPrefs.GetString(AuthorPrefKey, ""); + } + + private void OnGUI() + { + Initialize(); + var template = MapTemplate.LoadOrCreate(); + + scroll = EditorGUILayout.BeginScrollView(scroll); + + bool prefabsReady = template.matchServicesPrefab != null + && template.matchNetworkPrefab != null; + if (!prefabsReady) + { + EditorGUILayout.HelpBox( + "Core prefabs haven't been built yet.\n\n" + + "Open the 9Player scene, then run:\n" + + "TD → Map Pipeline → Build Core Prefabs From Open Scene", + MessageType.Error); + EditorGUILayout.Space(6); + } + + EditorGUILayout.LabelField("Identity", EditorStyles.boldLabel); + request.MapName = EditorGUILayout.TextField( + new GUIContent("Map Name", + "Becomes the scene file name, the LevelData asset name, and the string NGO " + + "uses to load the scene. Letters, digits and underscores only."), + request.MapName); + request.Author = EditorGUILayout.TextField("Author", request.Author); + + EditorGUILayout.LabelField(new GUIContent("Description", + "Shown in the lobby's map browser. Empty produces a bake warning.")); + request.Description = EditorGUILayout.TextArea( + request.Description, GUILayout.Height(38f)); + + EditorGUILayout.Space(8); + EditorGUILayout.LabelField("Shape", EditorStyles.boldLabel); + request.PlayerCount = EditorGUILayout.IntPopup( + "Players", request.PlayerCount, PlayerCountLabels, PlayerCountValues); + request.MapWidth = Mathf.Max(8, EditorGUILayout.IntField( + new GUIContent("Width (tiles)", "1 tile = 1 world unit."), request.MapWidth)); + request.MapHeight = Mathf.Max(8, EditorGUILayout.IntField( + new GUIContent("Height (tiles)", "1 tile = 1 world unit."), request.MapHeight)); + + request.BuildAccess = (BuildAccess)EditorGUILayout.EnumPopup( + new GUIContent("Build Access", + "OwnerOnly: each player builds only in their own zone.\n" + + "Shared: everyone builds anywhere on the map's buildable area.\n\n" + + "Changeable later on _LevelAuthoring — it just needs a re-bake."), + request.BuildAccess); + + if (request.BuildAccess == BuildAccess.Shared) + { + EditorGUILayout.HelpBox( + "Shared: every band forms one cooperative maze. Zones still define " + + "territory for leak attribution, camera start and builder spawn. Towers stay " + + "owned by whoever paid — only that player can sell or upgrade them.", + MessageType.None); + } + + EditorGUILayout.Space(8); + EditorGUILayout.LabelField("On Create", EditorStyles.boldLabel); + request.CreateTerrain = EditorGUILayout.Toggle( + new GUIContent("Create Terrain", + "Adds a Terrain sized to the map plus a skirt, on the TerrainGeometry layer, " + + "flattened onto the buildable plane."), + request.CreateTerrain); + request.AddToBuildSettings = EditorGUILayout.Toggle( + new GUIContent("Add to Build Settings", + "Required — NGO cannot load a scene that isn't in the build list."), + request.AddToBuildSettings); + request.AddToMapRegistry = EditorGUILayout.Toggle( + new GUIContent("Add to MapRegistry", + "Opens the MainMenu scene, appends the LevelData to the lobby's map browser, " + + "and saves it."), + request.AddToMapRegistry); + request.BakeImmediately = EditorGUILayout.Toggle( + new GUIContent("Bake immediately", + "Runs the bake on the generated starter layout so the map is valid and " + + "playable the moment it's created."), + request.BakeImmediately); + + // Registry wiring is the one step that reaches into a scene the designer isn't looking + // at, so a broken reference should be visible BEFORE Create, not in the summary after. + if (request.AddToMapRegistry && !System.IO.File.Exists(template.MainMenuScenePath)) + { + EditorGUILayout.HelpBox( + "Main Menu Scene isn't resolving, so the new map won't be added to the lobby's " + + "map browser. Assign it on MapTemplate, or add the LevelData to MapRegistry.Maps " + + "by hand afterwards.", + MessageType.Warning); + } + + EditorGUILayout.Space(8); + DrawLayoutPreview(template); + + EditorGUILayout.EndScrollView(); + + EditorGUILayout.Space(6); + bool canCreate = prefabsReady && + NewMapBuilder.TryComputeLayout( + template, request.MapWidth, request.MapHeight, + request.PlayerCount, request.BuildAccess, out _, out _); + + using (new EditorGUI.DisabledScope(!canCreate)) + { + if (GUILayout.Button("Create Map", GUILayout.Height(30f))) + { + CreateMap(); + } + } + } + + private void DrawLayoutPreview(MapTemplate template) + { + EditorGUILayout.LabelField("Starter Layout", EditorStyles.boldLabel); + + if (!NewMapBuilder.TryComputeLayout(template, request.MapWidth, request.MapHeight, + request.PlayerCount, request.BuildAccess, + out var layout, out string error)) + { + EditorGUILayout.HelpBox(error, MessageType.Error); + return; + } + + string routing = layout.Leaks.Length > 0 + ? $"through {layout.Leaks.Length} one-tile leak gate(s) " + + $"{Mathf.Min(template.leakGateWidth, layout.Zones[0].width)} tiles wide" + : "across directly-adjacent band borders (no leak gates)"; + + EditorGUILayout.HelpBox( + $"{request.PlayerCount} full-width band(s), {layout.BandDepth} tiles deep each, " + + $"stacked south to north.\n" + + $"Each band gets a spawner at its south edge; enemies travel north " + + $"{routing} to the goal.\n\n" + + $"Grid will bake to {layout.MapArea.width}×{layout.MapArea.height} with its " + + $"south-west corner at tile (0, 0).", + MessageType.Info); + + EditorGUILayout.LabelField( + "Tune the starter proportions on the MapTemplate asset:", + EditorStyles.miniLabel); + if (GUILayout.Button("Select MapTemplate", EditorStyles.miniButton)) + { + Selection.activeObject = template; + EditorGUIUtility.PingObject(template); + } + } + + private void CreateMap() + { + EditorPrefs.SetString(AuthorPrefKey, request.Author ?? ""); + + if (NewMapBuilder.Create(request, out string error)) + { + Close(); + return; + } + + EditorUtility.DisplayDialog("Could not create map", error, "OK"); + } + } +} diff --git a/Assets/_Project/Scripts/Editor/Levels/NewMapWindow.cs.meta b/Assets/_Project/Scripts/Editor/Levels/NewMapWindow.cs.meta new file mode 100644 index 0000000..850067e --- /dev/null +++ b/Assets/_Project/Scripts/Editor/Levels/NewMapWindow.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 50a9cf35b1b63204da8774b8afe7003e \ No newline at end of file diff --git a/Assets/_Project/Scripts/Gameplay/LevelLoader.cs b/Assets/_Project/Scripts/Gameplay/LevelLoader.cs index 3a29dfb..b93427f 100644 --- a/Assets/_Project/Scripts/Gameplay/LevelLoader.cs +++ b/Assets/_Project/Scripts/Gameplay/LevelLoader.cs @@ -355,6 +355,39 @@ namespace TD.Gameplay return level.OwnerGrid[idx]; } + /// + /// This map's build-permission rule. for an unloaded + /// or unbaked level, which is the safe default (it can only ever reject more). + /// + public BuildAccess BuildAccess => level != null ? level.BuildAccess : BuildAccess.OwnerOnly; + + /// + /// True if is permitted to build on under + /// this map's rule. + /// + /// + /// Permission ONLY — the caller still has to check and + /// . Keeping them separate is deliberate: each produces a different + /// PlacementRejectionReason, and collapsing them would cost the player a useful + /// message. + /// + /// Both the client's ghost preview and the server's authoritative check call this, so + /// they cannot drift apart and show a white ghost that then gets rejected. + /// + /// Under the tile must still belong to SOME player + /// zone. In practice every Buildable tile does, but stating it here keeps the method + /// meaningful on its own rather than relying on a caller's later check. + /// + public bool HasBuildPermission(Vector2Int tile, PlayerSlot slot) + { + if (slot == PlayerSlot.None) return false; + + PlayerSlot owner = GetOwner(tile); // PlayerSlot.None when out of bounds + return BuildAccess == BuildAccess.Shared + ? owner != PlayerSlot.None + : owner == slot; + } + /// /// True if is currently occupied by a placed tower footprint. /// Returns false for out-of-bounds tiles. Unlike , this grid diff --git a/Assets/_Project/Scripts/Gameplay/TowerPlacementController.cs b/Assets/_Project/Scripts/Gameplay/TowerPlacementController.cs index 9b1db7c..8800175 100644 --- a/Assets/_Project/Scripts/Gameplay/TowerPlacementController.cs +++ b/Assets/_Project/Scripts/Gameplay/TowerPlacementController.cs @@ -353,7 +353,7 @@ namespace TD.Gameplay foreach (var tile in GridCoordinates.GetFootprintTiles(anchor, def.FootprintSize)) { - if (loader.GetOwner(tile) != localSlot) return false; + if (!loader.HasBuildPermission(tile, localSlot)) return false; if (loader.GetPlacement(tile) != PlacementState.Buildable) return false; if (loader.IsOccupied(tile)) return false; } diff --git a/Assets/_Project/Scripts/Gameplay/TowerPlacementManager.cs b/Assets/_Project/Scripts/Gameplay/TowerPlacementManager.cs index 3706dfb..24dacba 100644 --- a/Assets/_Project/Scripts/Gameplay/TowerPlacementManager.cs +++ b/Assets/_Project/Scripts/Gameplay/TowerPlacementManager.cs @@ -217,8 +217,10 @@ namespace TD.Gameplay footprint.Add(tile); // ------------------------------------------------------------------ - // Check 1: Ownership - // Every footprint tile must be owned by the placing player's zone. + // Check 1: Build permission + // On an OwnerOnly map every footprint tile must be owned by the placing + // player's zone; on a Shared map any zone's tile will do. LevelLoader owns + // that rule so the client's ghost preview can't disagree with us. // ------------------------------------------------------------------ PlayerSlot placingSlot = ClientIdToPlayerSlot(req.SenderClientId); if (placingSlot == PlayerSlot.None) @@ -229,7 +231,7 @@ namespace TD.Gameplay foreach (var tile in footprint) { - if (loader.GetOwner(tile) != placingSlot) + if (!loader.HasBuildPermission(tile, placingSlot)) { Reject(req, PlacementRejectionReason.WrongOwner); return; @@ -533,37 +535,67 @@ namespace TD.Gameplay // ----- Path-validity BFS ------------------------------------------ /// - /// Returns true if every spawner in 's zone can still - /// reach an exit tile (any leak exit tile OR any goal tile) via walkable tiles, - /// given the current state of LevelLoader's runtime walkability grid. + /// Returns true if the map's mazes are still solvable with the candidate footprint in + /// place — every spawner can still reach an exit tile (any leak exit from its own zone, + /// OR any goal tile) via walkable tiles, given LevelLoader's runtime grid. /// /// - /// Mirrors bake-time P5-4. Runs a BFS per spawner against the runtime walkability - /// grid. Reuses and scratch - /// collections (cleared between BFS runs) to avoid GC allocation per call. + /// Mirrors bake-time P5-4. Reuses and + /// scratch collections (cleared between BFS runs) to avoid GC allocation per call. + /// + /// Scope depends on the map's build rule. Under + /// a player can only build inside their own zone, so + /// their footprint can only ever strand their OWN spawners — checking + /// 's zone alone is both sufficient and cheapest. Under + /// anyone can wall off anyone's lane, so every zone has to + /// be checked or a player could strand a teammate's spawner and leave its enemies with no + /// route at all. /// - private bool CheckPathValidity(LevelLoader loader, PlayerSlot slot, + private bool CheckPathValidity(LevelLoader loader, PlayerSlot placingSlot, HashSet virtualBlocked = null) { var levelData = loader.LevelData; + if (levelData?.PlayerZones == null) return true; + + if (loader.BuildAccess == BuildAccess.Shared) + { + foreach (var zone in levelData.PlayerZones) + { + if (!ZoneSpawnersCanReachExit(loader, levelData, zone, virtualBlocked)) + return false; + } + return true; + } - // Find the PlayerZoneData for this slot. - PlayerZoneData zoneData = null; foreach (var zone in levelData.PlayerZones) { - if (zone.Owner == slot) { zoneData = zone; break; } + if (zone.Owner == placingSlot) + return ZoneSpawnersCanReachExit(loader, levelData, zone, virtualBlocked); } - if (zoneData == null || zoneData.Spawners == null || zoneData.Spawners.Length == 0) + + // Placing player has no zone — nothing of theirs to strand. + return true; + } + + /// + /// Runs the reachability BFS for every spawner in one zone. Returns true if they can all + /// still reach an exit (or the zone has no spawners to strand). + /// + private bool ZoneSpawnersCanReachExit(LevelLoader loader, LevelData levelData, + PlayerZoneData zoneData, + HashSet virtualBlocked) + { + if (zoneData?.Spawners == null || zoneData.Spawners.Length == 0) { // No spawners means nothing to block — treat as valid. return true; } - // Build the exit tile set: union of all leak exit tiles and all goal tiles. - var exitTiles = BuildExitTileSet(levelData, slot); + // Build the exit tile set: this zone's leak exits, plus all goal tiles. + var exitTiles = BuildExitTileSet(levelData, zoneData.Owner); if (exitTiles.Count == 0) { - Debug.LogWarning($"[TowerPlacementManager] Zone {slot} has no exit tiles. " + + Debug.LogWarning($"[TowerPlacementManager] Zone {zoneData.Owner} has no exit tiles. " + $"This should have been caught at bake time (P5-8)."); return true; } diff --git a/Assets/_Project/Settings/MapTemplate.asset b/Assets/_Project/Settings/MapTemplate.asset new file mode 100644 index 0000000..a82dd59 --- /dev/null +++ b/Assets/_Project/Settings/MapTemplate.asset @@ -0,0 +1,39 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fb7355881928ea146a26471078f207c2, type: 3} + m_Name: MapTemplate + m_EditorClassIdentifier: Assembly-CSharp-Editor::TD.Levels.Editor.MapTemplate + matchServicesPrefab: {fileID: 1445952844252628864, guid: 13be8328f6275e14da787f25c94683ee, type: 3} + matchNetworkPrefab: {fileID: 8429081419068942390, guid: 7116de1968afffb4990ee24f709612fb, type: 3} + sceneFolderAsset: {fileID: 102900000, guid: 1ac41b242a484844a85bb02ca1ae9f1f, type: 3} + mainMenuScene: {fileID: 102900000, guid: 1f4cb4a6391f5e94285960890282b70e, type: 3} + sceneFolder: Assets/_Project/Scenes/Levels + mainMenuScenePath: Assets/_Project/Scenes/UI_Scenes/MainMenu.unity + terrainMaterial: {fileID: 2100000, guid: 594ea882c5a793440b60ff72d896021e, type: 2} + terrainLayers: + - {fileID: 8574412962073106934, guid: f72a840f9f0991747a2d10c3c220bd27, type: 2} + - {fileID: 8574412962073106934, guid: 445b935ebf050f74a96e491cb1596964, type: 2} + - {fileID: 8574412962073106934, guid: faa5ef4eade0336408d27e4e78ebf1a6, type: 2} + - {fileID: 8574412962073106934, guid: 79a46a4f0f2c8a04a9f50c26dc17dc48, type: 2} + terrainHeightmapResolution: 513 + terrainHeight: 60 + terrainSkirtTiles: 20 + terrainCarveDepth: 5 + defaultMapWidth: 100 + defaultMapHeight: 100 + playAreaMargin: 4 + goalDepth: 5 + goalWidth: 10 + spawnerDepth: 5 + spawnerWidth: 10 + leakGateWidth: 8 + minBandDepth: 8 diff --git a/Assets/_Project/Settings/MapTemplate.asset.meta b/Assets/_Project/Settings/MapTemplate.asset.meta new file mode 100644 index 0000000..f79b9ea --- /dev/null +++ b/Assets/_Project/Settings/MapTemplate.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ac495796f7ea6a9478aa5512f162d264 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Docs/Map_Pipeline.md b/Docs/Map_Pipeline.md new file mode 100644 index 0000000..c1e16ea --- /dev/null +++ b/Docs/Map_Pipeline.md @@ -0,0 +1,188 @@ +# Map Pipeline + +How to make a new map, and what the generator puts in the scene for you. + +--- + +## One-time setup + +Open **`9Player`** and run **`TD → Map Pipeline → Build Core Prefabs From Open Scene`**. + +This reads the fully-wired reference scene and writes: + +| Output | What it holds | +|---|---| +| `Assets/_Project/Prefabs/MatchCore/MatchServices.prefab` | Every map-independent, non-networked service | +| `Assets/_Project/Prefabs/MatchCore/MatchNetwork.prefab` | The six scene-placed `NetworkBehaviour`s | +| `Assets/_Project/Settings/MapTemplate.asset` | Prefab references, terrain defaults, starter-layout proportions | + +It **copies live components** rather than rebuilding them from an asset scan. `AssetDatabase.FindAssets` +order isn't guaranteed stable across machines or re-imports, and several of these arrays double as +network identity — `EnemyUpgradePool.options` indices *are* card network ids, and +`TowerPlacementManager.towerDefinitions` indices *are* `TowerTypeId`. Two people generating the same +map could commit different orders, and *that* desyncs a host from a client. Copying sidesteps it, and +gives each new map the same known-good content as the reference. + +> Maps having **different** catalogs from each other is fine and supported — every peer loads the same +> scene, and `PlayerTowerDeck.ServerInitialize` clears the deck at match start. Per-map enemy rosters +> are a matter of assigning a different `RunDefinition` on `_MatchNetwork/RunState`. + +> The reference scene's contents aren't modified, but Unity marks it dirty. **Don't save it.** + +Re-run this any time the shared boilerplate changes in a way the prefab should pick up. + +--- + +## Making a map + +**`TD → New Map...`** + +Fill in name, player count, and size. The dialog validates the starter layout live and tells you the +exact width or height to use if the shape can't hold one. + +On Create it does all of this: + +1. Creates and saves the scene in `Assets/_Project/Scenes/Levels/` +2. Instantiates `_MatchServices` (**linked** prefab instance) and `_MatchNetwork` (**unpacked**) +3. Creates the `LevelData` asset and assigns it to **both** `LevelAuthoring.targetAsset` *and* + `LevelLoader.level` +4. Generates a bakeable starter volume layout +5. Creates a `Terrain` on the `TerrainGeometry` layer, sized to the map plus a skirt +6. Registers the scene in **Build Settings** +7. Appends the `LevelData` to the **`MapRegistry`** in `MainMenu.unity` +8. Runs the bake + +Steps 3, 6 and 7 are the ones that used to fail silently — a map missing any of them looks fine in +the editor and breaks only at match start, or just never appears in the lobby. + +A generated map bakes with **zero warnings** as long as you filled in author and description. + +--- + +## What you get, and where to edit it + +Four roots instead of the ~30 the hand-authored maps carry: + +``` +_LevelAuthoring ← yours: shape the volumes here +_MatchServices ← shared prefab: don't edit per-map (except LevelLoader.level) +_MatchNetwork ← the six NetworkBehaviours, unpacked +Terrain ← yours: sculpt here +``` + +`_MatchServices` is a **linked prefab instance**, so fixing something in +`MatchServices.prefab` fixes it in every map at once. The one field that is legitimately a +per-instance override is `LevelLoader.level`. + +**Never press "Apply All" on the `_MatchServices` instance** — that would push this map's +`LevelData` into the shared prefab. + +`_MatchNetwork` is unpacked deliberately: NGO treats in-scene placed `NetworkObject`s that are prefab +instances differently from loose ones, and unpacking keeps generated scenes structurally identical to +hand-authored ones. The cost is that changes to `MatchNetwork.prefab` don't propagate to maps already +created — there are only three asset references in it (`RunDefinition`, `GoldConfig`, +`EnemyScalingConfig`), so fix those by hand if they ever change. + +--- + +## The starter layout + +Player bands stacked south → north, full map width: + +``` + ┌─────────── Goal ───────────┐ north + │ Player N band │ + │ ····· leak gate ····· │ + │ Player N-1 band │ + │ ····· leak gate ····· │ + │ Player 1 band │ + │ [Player 1 spawner] │ south + └── MapArea (margin border) ─┘ +``` + +Enemies spawn at the south edge of their owner's band and walk north. Each band leaks through a +one-tile gate into the next; the northernmost band is goal-adjacent instead of having a leak. + +Proportions (margin, band depth, gate width, goal size, terrain skirt and carve depth) all live on +**`MapTemplate.asset`** — tune them there, not in code. + +--- + +## Build Access: one maze each, or one maze together + +`_LevelAuthoring → Rules → Build Access` is a per-map choice. Also offered in the New Map dialog. + +| Mode | Meaning | +|---|---| +| `OwnerOnly` | Default. A player builds only inside their own `PlayerZoneVolume`. | +| `Shared` | Any player builds on any Buildable tile — the whole map is one cooperative maze. | + +**Ownership doesn't disappear in Shared mode.** `OwnerGrid` still drives leak attribution, camera +start position, builder spawn point, and minimap tinting; zones still own their spawners and leak +exits. The only thing that lifts is the placement restriction. That's why this is a per-map enum and +not a change to how maps are authored — a Shared map is authored exactly like an OwnerOnly one. + +**Towers still belong to whoever paid.** Sell, upgrade and paint stay owner-gated in both modes, so a +teammate can't sell your tower out of the lane you put it in. + +Both modes route through `LevelLoader.HasBuildPermission`, which the client's ghost preview and the +server's authoritative check both call — they can't drift apart and show a white ghost that then gets +rejected. + +> **Shared mode widens path validation.** Under `OwnerOnly` a player can only strand their own +> spawners, so `TowerPlacementManager.CheckPathValidity` checks one zone. Under `Shared` anyone can +> wall off anyone's lane, so it checks *every* zone's spawners — otherwise a player could leave a +> teammate's enemies with no route to any exit. Cost is one BFS per spawner per placement attempt +> rather than one per placement; placements are already throttled to `requestsPerFrame`. + +Changing the mode on an existing map just needs a re-bake. + +### Leak exits are optional on Shared maps + +Bake rule **P5-8** ("every zone must have an outgoing leak or be goal-adjacent") is **skipped on +Shared maps**, so you can delete the `LeakExitVolume`s entirely. Every other leak rule is conditional +on a leak existing, so they're vacuously satisfied at zero. + +That's safe because leak exits do almost nothing at runtime. `PathfindingService.ComputePath` takes no +destination — enemies always path to `LevelData.Goals`, and the route through a gate is *emergent* +from walkability, never directed. `LeakExitData.NormalizedWeight` is written by the bake and read +nowhere. Leak *attribution* runs off `OwnerGrid`, not leak volumes, so it keeps working. The safety +property P5-8 protected is enforced more strictly by **P5-4**, which BFSes every spawner to the exit +set — and with no leaks present that set is the goal tiles, which is exactly the right requirement. + +> **Zones must then be directly adjacent.** A `LeakExitVolume`'s tiles are walkable; a bare gap +> between two zones is not. Delete the leaks without closing the gap and the bands become +> disconnected — P5-4 hard-errors and P5-11 warns, so the bake catches it loudly rather than shipping +> a map whose enemies can't move. + +New Map handles this for you: choosing **Shared** generates bands butted directly together with no +gate rows and no leak volumes. Choosing **OwnerOnly** generates the one-tile gates. + +--- + +## Changing the Quick Play map + +Quick Start skips the lobby and loads **`MapRegistry.Default`**, which is the *first valid entry* in +the `Maps` array — not a separate setting. + +Open `MainMenu`, select the `MapRegistry` GameObject, and drag the map you want to element **0**. +Entries with an empty `MapName` or `ScenePath` are skipped, so "first" means first *usable*. + +New maps are **appended** to the array, so creating one never silently changes what Quick Play loads. +Reordering is deliberate. + +--- + +## Things worth knowing + +- **Walkability is the union of the gameplay volumes**, not something you paint. Walls are the + *absence* of a `PlayerZone` / `Spawner` / `LeakExit` / `Goal` volume. `MapAreaVolume` tiles are + deliberately **not** walkable — that volume only bounds camera pan and builder movement. +- **Terrain must stay on the `TerrainGeometry` layer.** The builder's ground raycast and spell + targeting both filter on it; on `Default` the builder silently walks at Y=0. +- **Terrain visuals have no relationship to the grid.** Nothing validates that the hills you sculpt + match the volumes you placed. That correspondence is yours to keep. +- **Volumes must be axis-aligned and unit-scaled.** Rotation is a hard bake error; non-unit + `Transform.Scale` is a warning. Size volumes with `BoxCollider.Size`, or use the + **Resize Volume Edge** scene tool. +- `MatchRules.MaxPlayers` is **3**. Larger player counts bake fine but no lobby can fill them yet. diff --git a/ProjectSettings/EditorBuildSettings.asset b/ProjectSettings/EditorBuildSettings.asset index 789ebb2..ebac9f7 100644 --- a/ProjectSettings/EditorBuildSettings.asset +++ b/ProjectSettings/EditorBuildSettings.asset @@ -6,10 +6,10 @@ EditorBuildSettings: serializedVersion: 2 m_Scenes: - enabled: 1 - path: Assets/_Project/Scenes/UI/MainMenu.unity + path: Assets/_Project/Scenes/UI_Scenes/MainMenu.unity guid: 1f4cb4a6391f5e94285960890282b70e - enabled: 1 - path: Assets/_Project/Scenes/UI/Lobby.unity + path: Assets/_Project/Scenes/UI_Scenes/Lobby.unity guid: 3a3639dca674a8049a570cb848bb69d2 - enabled: 1 path: Assets/_Project/Scenes/Levels/Main.unity @@ -17,5 +17,8 @@ EditorBuildSettings: - enabled: 1 path: Assets/_Project/Scenes/Levels/9Player.unity guid: 74fdeec477e257d4484b38108c283d84 + - enabled: 1 + path: Assets/_Project/Scenes/Levels/3Player.unity + guid: 128de09101c3e3240b094d29d1eb9d22 m_configObjects: com.unity.input.settings.actions: {fileID: -944628639613478452, guid: 052faaac586de48259a63d0c4782560b, type: 3}