From 9374d29fa465940ac181a8ffffcfd1342f5f2f65 Mon Sep 17 00:00:00 2001 From: stilnat Date: Fri, 6 Oct 2023 12:22:06 +0200 Subject: [PATCH 01/52] readd some tilehelper methods --- .../Systems/Tile/PlacedObjects/PlacedTileObject.cs | 4 +++- Assets/Scripts/SS3D/Systems/Tile/TileHelper.cs | 13 ++++++++++++- Assets/Scripts/SS3D/Systems/Tile/TileMap.cs | 4 ++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs b/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs index 1ae71aff26..a89f7b3e4b 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs @@ -1,4 +1,4 @@ -using FishNet; +using FishNet; using FishNet.Object; using SS3D.Core; using SS3D.Logging; @@ -71,6 +71,8 @@ public static PlacedTileObject Create(Vector3 worldPosition, Vector2Int origin, public TileObjectSpecificType SpecificType => _tileObjectSo.specificType; + public Direction Direction => _dir; + public string NameString => _tileObjectSo.nameString; public bool HasAdjacencyConnector => _connector != null; diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileHelper.cs b/Assets/Scripts/SS3D/Systems/Tile/TileHelper.cs index 5b8c62de96..c9635ec820 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/TileHelper.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/TileHelper.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using UnityEngine; @@ -51,6 +51,17 @@ public static Vector3 GetClosestPosition(Vector3 worldPosition) return new Vector3(Mathf.Round(worldPosition.x), 0, Mathf.Round(worldPosition.z)); } + public static Direction GetRelativeDirection(Direction to, Direction from) + { + return (Direction)((((int)to - (int)from) + 8) % 8); + } + + public static int GetDirectionIndex(Direction dir) + { + return (int)dir / 2; + } + + public static List CardinalDirections() { return new List { Direction.North, Direction.East, Direction.South, Direction.West }; diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs b/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs index c6f81f9ee2..619fd8e8a7 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs @@ -1,4 +1,4 @@ -using FishNet; +using FishNet; using FishNet.Object; using JetBrains.Annotations; using SS3D.Core; @@ -123,7 +123,7 @@ private TileObject[] GetTileObjects(Vector3 worldPosition) return tileObjects; } - private PlacedTileObject[] GetNeighbourPlacedObjects(TileLayer layer, Vector3 worldPosition) + public PlacedTileObject[] GetNeighbourPlacedObjects(TileLayer layer, Vector3 worldPosition) { PlacedTileObject[] adjacentObjects = new PlacedTileObject[8]; From a2ed930a004d03d7721523ba6a8bd9500e385059 Mon Sep 17 00:00:00 2001 From: stilnat Date: Fri, 6 Oct 2023 12:22:26 +0200 Subject: [PATCH 02/52] readd door --- .../SS3D/Systems/Tile/Connections/Door.cs | 215 ++++++++++++++++++ .../Systems/Tile/Connections/Door.cs.meta | 11 + 2 files changed, 226 insertions(+) create mode 100644 Assets/Scripts/SS3D/Systems/Tile/Connections/Door.cs create mode 100644 Assets/Scripts/SS3D/Systems/Tile/Connections/Door.cs.meta diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/Door.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/Door.cs new file mode 100644 index 0000000000..4390909335 --- /dev/null +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/Door.cs @@ -0,0 +1,215 @@ + +using UnityEngine; +using SS3D.Systems.Tile.Connections.AdjacencyTypes; +using Coimbra; + +namespace SS3D.Systems.Tile.Connections +{ + public class Door : MonoBehaviour, IAdjacencyConnector + { + public enum DoorType + { + Single, + Double + }; + + /** Based on peculiarities of the model, the appropriate position of the wall cap */ + private const float WALL_CAP_DISTANCE_FROM_CENTRE = 0f; + + // As is the standard in the rest of the code, wallCap should face east. + [SerializeField] + private GameObject wallCapPrefab = null; + + [SerializeField] + private DoorType doorType; + + private TileMap map; + private PlacedTileObject placedTileObject; + + public void CleanAdjacencies() + { + if (!map) + { + map = GetComponentInParent(); + } + + SetPerpendicularBlocked(false); + + var neighbourObjects = map.GetNeighbourPlacedObjects(TileLayer.Turf, transform.position); + for (int i = 0; i < neighbourObjects.Length; i++) + { + neighbourObjects[i]?.UpdateSingleAdjacency(placedTileObject, + TileHelper.GetOpposite((Direction)i)); + } + } + + public bool UpdateSingle(Direction direction, PlacedTileObject placedObject, bool updateNeighbours) + { + + if (UpdateSingleConnection(direction, placedObject)) + UpdateWallCaps(); + + // TODO should check if connection was actually updated. + return true; + } + + public void UpdateAll(PlacedTileObject[] neighbourObjects) + { + // Because we are on a Furniture layer and walls are on the Turf. Discard furniture neighbours and get the turf neighbours. + if (!map) + map = GetComponentInParent(); + + neighbourObjects = map.GetNeighbourPlacedObjects(TileLayer.Turf, transform.position); + PlacedTileObject currentObject = GetComponent(); + + bool changed = false; + for (int i = 0; i < neighbourObjects.Length; i++) + { + bool updatedSingle = false; + updatedSingle = UpdateSingleConnection((Direction)i, neighbourObjects[i]); + if (updatedSingle && neighbourObjects[i]) + neighbourObjects[i].UpdateSingleAdjacency(currentObject, TileHelper.GetOpposite((Direction)i)); + + changed |= updatedSingle; + } + + if (changed) + { + UpdateWallCaps(); + } + } + + /** + * Adjusts the connections value based on the given new tile. + * Returns whether value changed. + */ + private bool UpdateSingleConnection(Direction direction, PlacedTileObject placedObject) + { + SetPerpendicularBlocked(true); + bool isConnected = (placedObject && placedObject.HasAdjacencyConnector && + placedObject.GenericType == TileObjectGenericType.Wall); + + return adjacencyMap.SetConnection(direction, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, isConnected)); + } + + /// + /// Walls will try to connect to us. Block or unblock that connects if we are not facing the wall + /// + private void SetPerpendicularBlocked(bool isBlocked) + { + // Door can have rotated in the time between + Direction doorDirection = GetDoorDirection(); + if (map == null) + return; + // map = GetComponentInParent(); + + var neighbourObjects = map.GetNeighbourPlacedObjects(TileLayer.Turf, transform.position); + Direction opposite = TileHelper.GetOpposite(doorDirection); + + MultiAdjacencyConnector wallConnector = null; + if (neighbourObjects[(int)doorDirection] != null) + wallConnector = neighbourObjects[(int)doorDirection].GetComponent(); + + if (wallConnector) + wallConnector.SetBlockedDirection(opposite, isBlocked); + + // Opposite side of door + wallConnector = null; + if (neighbourObjects[(int)opposite] != null) + wallConnector = neighbourObjects[(int)opposite].GetComponent(); + + if (wallConnector) + wallConnector.SetBlockedDirection(doorDirection, isBlocked); + } + + private void CreateWallCaps(bool isPresent, Direction direction) + { + int capIndex = TileHelper.GetDirectionIndex(direction); + if (isPresent && wallCaps[capIndex] == null) + { + + wallCaps[capIndex] = SpawnWallCap(direction); + wallCaps[capIndex].name = $"WallCap{capIndex}"; + } + else if (!isPresent && wallCaps[capIndex] != null) + { + wallCaps[capIndex].Dispose(true); + wallCaps[capIndex] = null; + } + } + + private void UpdateWallCaps() + { + if (wallCapPrefab == null) + return; + + // Door may have rotated in the editor + Direction outFacing = TileHelper.GetNextDir(GetDoorDirection()); + + bool isPresent = adjacencyMap.HasConnection(outFacing); + CreateWallCaps(isPresent, TileHelper.GetOpposite(outFacing)); + + isPresent = adjacencyMap.HasConnection(TileHelper.GetOpposite(outFacing)); + CreateWallCaps(isPresent, outFacing); + } + + private void ValidateChildren() + { + // Note: This only needs to run on the server, which loads from the scene. + // Anywhere else (including clients, mostly), doesn't really need this. + for (int i = transform.childCount - 1; i > 0; --i) + { + var child = transform.GetChild(i); + if (child.name.StartsWith("WallCap")) + { + bool success = int.TryParse(child.name.Substring(7), out int num); + + // Remove if no int, int out of bounds, or duplicate + if (!success || num > wallCaps.Length || num < 0 || (wallCaps[num] != null && !ReferenceEquals(wallCaps[num], child.gameObject))) + { + Debug.LogWarning($"Unusual child found whilst searching for wall caps: {child.name}, deleting"); + child.gameObject.Dispose(true); + continue; + } + + wallCaps[num] = child.gameObject; + } + } + } + + /** + * Spawns a wall cap facing a direction, with appropriate position & settings + * Direction from the centre of the door + */ + private GameObject SpawnWallCap(Direction direction) + { + var wallCap = Instantiate(wallCapPrefab, transform); + Direction doorDirection = GetDoorDirection(); + + Direction cardinalDirectionInput = TileHelper.GetRelativeDirection(direction, doorDirection); + var cardinal = TileHelper.ToCardinalVector(cardinalDirectionInput); + float rotation = TileHelper.AngleBetween(direction, doorDirection); + + + wallCap.transform.localRotation = Quaternion.Euler(0, rotation, 0); + wallCap.transform.localPosition = new Vector3(cardinal.Item1 * WALL_CAP_DISTANCE_FROM_CENTRE, 0, cardinal.Item2 * WALL_CAP_DISTANCE_FROM_CENTRE); + + return wallCap; + } + + private Direction GetDoorDirection() + { + if (placedTileObject == null) + { + placedTileObject = GetComponent(); + } + + return placedTileObject.Direction; + } + + // WallCap gameobjects, North, East, South, West. Null if not present. + private GameObject[] wallCaps = new GameObject[4]; + private AdjacencyMap adjacencyMap = new AdjacencyMap(); + } + +} diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/Door.cs.meta b/Assets/Scripts/SS3D/Systems/Tile/Connections/Door.cs.meta new file mode 100644 index 0000000000..668ebbf8da --- /dev/null +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/Door.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d00d6a1b2cb9fb54fbefde21a9eb88a4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 98f6d2fa1bd818d42b54507f025f1cacf36bdeeb Mon Sep 17 00:00:00 2001 From: stilnat Date: Fri, 6 Oct 2023 19:23:37 +0200 Subject: [PATCH 03/52] add simple adjacency --- .../Pipes/Disposals/DisposalPipes.prefab | 53 ++----- .../Connections/SimpleAdjacencyConnector.cs | 139 ++++++++++++++++++ .../SimpleAdjacencyConnector.cs.meta | 11 ++ 3 files changed, 164 insertions(+), 39 deletions(-) create mode 100644 Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs create mode 100644 Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs.meta diff --git a/Assets/Content/WorldObjects/Structures/Pipes/Disposals/DisposalPipes.prefab b/Assets/Content/WorldObjects/Structures/Pipes/Disposals/DisposalPipes.prefab index 883ac32b85..0a8443be41 100644 --- a/Assets/Content/WorldObjects/Structures/Pipes/Disposals/DisposalPipes.prefab +++ b/Assets/Content/WorldObjects/Structures/Pipes/Disposals/DisposalPipes.prefab @@ -12,7 +12,7 @@ GameObject: - component: {fileID: -7727686409064562107} - component: {fileID: -1074477776341974781} - component: {fileID: -4998431523760016775} - - component: {fileID: 31680455597932218} + - component: {fileID: 1729570281371340860} m_Layer: 0 m_Name: DisposalPipes m_TagString: Untagged @@ -49,19 +49,25 @@ MonoBehaviour: m_EditorClassIdentifier: k__BackingField: 0 k__BackingField: 0 + k__BackingField: {fileID: 0} _networkBehaviours: - - {fileID: 31680455597932218} + - {fileID: 1729570281371340860} k__BackingField: {fileID: 0} k__BackingField: [] + SerializedTransformProperties: + Position: {x: 0, y: 0, z: 0} + Rotation: {x: 0, y: 0, z: 0, w: 0} + LocalScale: {x: 0, y: 0, z: 0} _isNetworked: 1 _isGlobal: 0 + _initializeOrder: 0 _defaultDespawnType: 0 NetworkObserver: {fileID: 0} - k__BackingField: 107 + k__BackingField: 166 + k__BackingField: 0 _scenePathHash: 0 k__BackingField: 0 k__BackingField: 18330170179948219730 - _sceneNetworkObjects: [] --- !u!33 &-1074477776341974781 MeshFilter: m_ObjectHideFlags: 0 @@ -112,7 +118,7 @@ MeshRenderer: m_SortingLayer: 0 m_SortingOrder: 0 m_AdditionalVertexStreams: {fileID: 0} ---- !u!114 &31680455597932218 +--- !u!114 &1729570281371340860 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -121,13 +127,14 @@ MonoBehaviour: m_GameObject: {fileID: 2802364579275783218} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 53a5cd0d46abb6d4d8686d11153009c2, type: 3} + m_Script: {fileID: 11500000, guid: bc6615260753fbd48af09343d5d55332, type: 3} m_Name: m_EditorClassIdentifier: _componentIndexCache: 0 _addedNetworkObject: {fileID: -7727686409064562107} _networkObjectCache: {fileID: -7727686409064562107} - SelectedAdjacencyType: 0 + _genericType: 1 + _specificType: 0 _simpleAdjacency: o: {fileID: -6725049071555871357, guid: 8fa7941da6a6a8d4da717a97b11b2621, type: 3} u: {fileID: -6725049071555871357, guid: 8fa7941da6a6a8d4da717a97b11b2621, type: 3} @@ -135,36 +142,4 @@ MonoBehaviour: l: {fileID: -7002929985465626668, guid: 8fa7941da6a6a8d4da717a97b11b2621, type: 3} t: {fileID: 7767200051770316982, guid: 8fa7941da6a6a8d4da717a97b11b2621, type: 3} x: {fileID: -7993494061914831054, guid: 8fa7941da6a6a8d4da717a97b11b2621, type: 3} - _advancedAdjacency: - o: {fileID: 0} - u: {fileID: 0} - i: {fileID: 0} - lNone: {fileID: 0} - lSingle: {fileID: 0} - tNone: {fileID: 0} - tSingleRight: {fileID: 0} - tSingleLeft: {fileID: 0} - tDouble: {fileID: 0} - xNone: {fileID: 0} - xSingle: {fileID: 0} - xSide: {fileID: 0} - xOpposite: {fileID: 0} - xTriple: {fileID: 0} - xQuad: {fileID: 0} - viewObstacles: [] - opaque: 0 - _offsetAdjacency: - o: {fileID: 0} - uNorth: {fileID: 0} - uSouth: {fileID: 0} - i: {fileID: 0} - lNE: {fileID: 0} - lNW: {fileID: 0} - lSE: {fileID: 0} - lSW: {fileID: 0} - tNEW: {fileID: 0} - tNSW: {fileID: 0} - tNSE: {fileID: 0} - tSWE: {fileID: 0} - x: {fileID: 0} _syncedConnections: 0 diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs new file mode 100644 index 0000000000..73a8cec576 --- /dev/null +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs @@ -0,0 +1,139 @@ +using FishNet.Object; +using FishNet.Object.Synchronizing; +using SS3D.Logging; +using SS3D.Systems.Tile; +using SS3D.Systems.Tile.Connections; +using SS3D.Systems.Tile.Connections.AdjacencyTypes; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +/// +/// Good for stuff that connects on the same layer only, horizontally, of the same specific and generic type. +/// +public class SimpleAdjacencyConnector : NetworkBehaviour, IAdjacencyConnector +{ + /// + /// A type that specifies to which objects to connect to. Must be set if cross connect is used. + /// + [Tooltip("Generic ID that adjacent objects must be to count. If empty, any id is accepted.")] + [SerializeField] + private TileObjectGenericType _genericType; + + /// + /// Specific ID to differentiate objects when the generic is the same. + /// + [Tooltip("Specific ID to differentiate objects when the generic is the same.")] + [SerializeField] + private TileObjectSpecificType _specificType; + + [SerializeField] private SimpleConnector _simpleAdjacency; + + [SyncVar(OnChange = nameof(SyncAdjacencies))] + private byte _syncedConnections; + + private AdjacencyMap _adjacencyMap; + private MeshFilter _filter; + private bool _initialized; + private PlacedTileObject _placedObject; + + public override void OnStartClient() + { + base.OnStartClient(); + Setup(); + } + + private void Setup() + { + if (!_initialized) + { + _adjacencyMap = new AdjacencyMap(); + _filter = GetComponent(); + + _placedObject = GetComponent(); + if (_placedObject == null) + { + _genericType = TileObjectGenericType.None; + _specificType = TileObjectSpecificType.None; + } + else + { + _genericType = _placedObject.GenericType; + _specificType = _placedObject.SpecificType; + } + _initialized = true; + } + } + + private void SyncAdjacencies(byte oldValue, byte newValue, bool asServer) + { + if (!asServer) + { + Setup(); + + _adjacencyMap.DeserializeFromByte(newValue); + UpdateMeshAndDirection(); + } + } + + public bool UpdateSingle(Direction dir, PlacedTileObject neighbourObject, bool updateNeighbour) + { + bool isConnected = false; + + if (neighbourObject != null) + { + isConnected = (neighbourObject && neighbourObject.HasAdjacencyConnector); + isConnected &= neighbourObject.GenericType == _genericType || _genericType == TileObjectGenericType.None; + isConnected &= neighbourObject.SpecificType == _specificType || _specificType == TileObjectSpecificType.None; + + // Update our neighbour as well + if (isConnected && updateNeighbour) + neighbourObject.UpdateSingleAdjacency(_placedObject, TileHelper.GetOpposite(dir)); + } + + bool isUpdated = _adjacencyMap.SetConnection(dir, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, isConnected)); + + if (isUpdated) + { + _syncedConnections = _adjacencyMap.SerializeToByte(); + UpdateMeshAndDirection(); + } + + return isUpdated; + } + + private void UpdateMeshAndDirection() + { + MeshDirectionInfo info = new(); + info = _simpleAdjacency.GetMeshAndDirection(_adjacencyMap); + + if (_filter == null) + { + Log.Warning(this, "Missing mesh {meshDirectionInfo}", Logs.Generic, info); + } + + _filter.mesh = info.Mesh; + + Quaternion localRotation = transform.localRotation; + Vector3 eulerRotation = localRotation.eulerAngles; + localRotation = Quaternion.Euler(eulerRotation.x, info.Rotation, eulerRotation.z); + + transform.localRotation = localRotation; + } + + public void UpdateAll(PlacedTileObject[] neighbourObjects) + { + Setup(); + + bool changed = false; + for (int i = 0; i < neighbourObjects.Length; i++) + { + changed |= UpdateSingle((Direction)i, neighbourObjects[i], true); + } + + if (changed) + { + UpdateMeshAndDirection(); + } + } +} diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs.meta b/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs.meta new file mode 100644 index 0000000000..bb92f1ded0 --- /dev/null +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bc6615260753fbd48af09343d5d55332 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 373abd0a081ce88db349a4c029ee84ed0f2e0d0b Mon Sep 17 00:00:00 2001 From: stilnat Date: Fri, 6 Oct 2023 19:35:06 +0200 Subject: [PATCH 04/52] add advanced connector --- .../Floors/Tiles/Carpet/FancyCarpetRed.prefab | 43 ++-- .../Connections/AdvancedAdjacencyConnector.cs | 150 +++++++++++++ .../AdvancedAdjacencyConnector.cs.meta | 11 + .../Connections/SimpleAdjacencyConnector.cs | 199 +++++++++--------- 4 files changed, 277 insertions(+), 126 deletions(-) create mode 100644 Assets/Scripts/SS3D/Systems/Tile/Connections/AdvancedAdjacencyConnector.cs create mode 100644 Assets/Scripts/SS3D/Systems/Tile/Connections/AdvancedAdjacencyConnector.cs.meta diff --git a/Assets/Content/WorldObjects/Structures/Floors/Tiles/Carpet/FancyCarpetRed.prefab b/Assets/Content/WorldObjects/Structures/Floors/Tiles/Carpet/FancyCarpetRed.prefab index 44ff81eb00..56a86f96c9 100644 --- a/Assets/Content/WorldObjects/Structures/Floors/Tiles/Carpet/FancyCarpetRed.prefab +++ b/Assets/Content/WorldObjects/Structures/Floors/Tiles/Carpet/FancyCarpetRed.prefab @@ -13,7 +13,7 @@ GameObject: - component: {fileID: 6696866361892651655} - component: {fileID: 37166840573251760} - component: {fileID: 6999522401175031449} - - component: {fileID: -2329561759450310542} + - component: {fileID: 3040907911380660968} m_Layer: 0 m_Name: FancyCarpetRed m_TagString: Untagged @@ -113,19 +113,26 @@ MonoBehaviour: m_EditorClassIdentifier: k__BackingField: 0 k__BackingField: 0 - _networkBehaviours: [] + k__BackingField: {fileID: 0} + _networkBehaviours: + - {fileID: 0} k__BackingField: {fileID: 0} k__BackingField: [] + SerializedTransformProperties: + Position: {x: 0, y: 0, z: 0} + Rotation: {x: 0, y: 0, z: 0, w: 0} + LocalScale: {x: 0, y: 0, z: 0} _isNetworked: 1 _isGlobal: 0 + _initializeOrder: 0 _defaultDespawnType: 0 NetworkObserver: {fileID: 0} - k__BackingField: -1 + k__BackingField: 65535 + k__BackingField: 0 _scenePathHash: 0 k__BackingField: 0 k__BackingField: 4511097998240534661 - _sceneNetworkObjects: [] ---- !u!114 &-2329561759450310542 +--- !u!114 &3040907911380660968 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -134,20 +141,14 @@ MonoBehaviour: m_GameObject: {fileID: 3591147544166670882} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 53a5cd0d46abb6d4d8686d11153009c2, type: 3} + m_Script: {fileID: 11500000, guid: ef4340642b9b436498fe733f9329ac87, type: 3} m_Name: m_EditorClassIdentifier: _componentIndexCache: 255 _addedNetworkObject: {fileID: 6999522401175031449} _networkObjectCache: {fileID: 0} - SelectedAdjacencyType: 1 - _simpleAdjacency: - o: {fileID: 0} - u: {fileID: 0} - i: {fileID: 0} - l: {fileID: 0} - t: {fileID: 0} - x: {fileID: 0} + _genericType: 9 + _specificType: 5 _advancedAdjacency: o: {fileID: 6313828114514605112, guid: 672e6a3c2617a374084ca41ab0f3b39d, type: 3} u: {fileID: 1428770310312528737, guid: 672e6a3c2617a374084ca41ab0f3b39d, type: 3} @@ -166,18 +167,4 @@ MonoBehaviour: xQuad: {fileID: 9022132694264211953, guid: 672e6a3c2617a374084ca41ab0f3b39d, type: 3} viewObstacles: [] opaque: 0 - _offsetAdjacency: - o: {fileID: 0} - uNorth: {fileID: 0} - uSouth: {fileID: 0} - i: {fileID: 0} - lNE: {fileID: 0} - lNW: {fileID: 0} - lSE: {fileID: 0} - lSW: {fileID: 0} - tNEW: {fileID: 0} - tNSW: {fileID: 0} - tNSE: {fileID: 0} - tSWE: {fileID: 0} - x: {fileID: 0} _syncedConnections: 0 diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdvancedAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdvancedAdjacencyConnector.cs new file mode 100644 index 0000000000..8d22fa29b3 --- /dev/null +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdvancedAdjacencyConnector.cs @@ -0,0 +1,150 @@ +using FishNet.Object; +using FishNet.Object.Synchronizing; +using SS3D.Logging; +using SS3D.Systems.Tile.Connections.AdjacencyTypes; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Serialization; + +namespace SS3D.Systems.Tile.Connections +{ + public class AdvancedAdjacencyConnector : NetworkBehaviour, IAdjacencyConnector + { + /// + /// A type that specifies to which objects to connect to. Must be set if cross connect is used. + /// + [Tooltip("Generic ID that adjacent objects must be to count. If empty, any id is accepted.")] + [SerializeField] + private TileObjectGenericType _genericType; + + /// + /// Specific ID to differentiate objects when the generic is the same. + /// + [Tooltip("Specific ID to differentiate objects when the generic is the same.")] + [SerializeField] + private TileObjectSpecificType _specificType; + + [FormerlySerializedAs("advancedAdjacency")][SerializeField] private AdvancedConnector _advancedAdjacency; + + private AdjacencyMap _adjacencyMap; + + [SyncVar(OnChange = nameof(SyncAdjacencies))] + private byte _syncedConnections; + + private MeshFilter _filter; + private bool _initialized; + private PlacedTileObject _placedObject; + + public override void OnStartClient() + { + base.OnStartClient(); + Setup(); + } + + private void Setup() + { + if (!_initialized) + { + _adjacencyMap = new AdjacencyMap(); + _filter = GetComponent(); + + _placedObject = GetComponent(); + if (_placedObject == null) + { + _genericType = TileObjectGenericType.None; + _specificType = TileObjectSpecificType.None; + } + else + { + _genericType = _placedObject.GenericType; + _specificType = _placedObject.SpecificType; + } + _initialized = true; + } + } + + public bool UpdateSingle(Direction dir, PlacedTileObject neighbourObject, bool updateNeighbour) + { + bool isConnected = false; + bool isUpdated = false; + + if (neighbourObject) + { + isConnected = (neighbourObject && neighbourObject.HasAdjacencyConnector); + isConnected &= neighbourObject.GenericType == _genericType || _genericType == TileObjectGenericType.None; + isConnected &= neighbourObject.SpecificType == _specificType || _specificType == TileObjectSpecificType.None; + + // Update our neighbour as well + if (isConnected && updateNeighbour) + neighbourObject.UpdateSingleAdjacency(_placedObject, TileHelper.GetOpposite(dir)); + } + + isUpdated = _adjacencyMap.SetConnection(dir, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, isConnected)); + if (isUpdated) + { + _syncedConnections = _adjacencyMap.SerializeToByte(); + UpdateMeshAndDirection(); + } + + return isUpdated; + } + + public void UpdateAll(PlacedTileObject[] neighbourObjects) + { + Setup(); + + bool changed = false; + for (int i = 0; i < neighbourObjects.Length; i++) + { + changed |= UpdateSingle((Direction)i, neighbourObjects[i], true); + } + + if (changed) + { + UpdateMeshAndDirection(); + } + } + + private void UpdateMeshAndDirection() + { + MeshDirectionInfo info = new(); + info = _advancedAdjacency.GetMeshAndDirection(_adjacencyMap); + + if (_filter == null) + { + Log.Warning(this, "Missing mesh {meshDirectionInfo}", Logs.Generic, info); + } + + _filter.mesh = info.Mesh; + + Quaternion localRotation = transform.localRotation; + Vector3 eulerRotation = localRotation.eulerAngles; + localRotation = Quaternion.Euler(eulerRotation.x, info.Rotation, eulerRotation.z); + + transform.localRotation = localRotation; + } + + private void SyncAdjacencies(byte oldValue, byte newValue, bool asServer) + { + if (!asServer) + { + Setup(); + + _adjacencyMap.DeserializeFromByte(newValue); + UpdateMeshAndDirection(); + } + } + + /// + /// Sets a given direction blocked. This means that it will no longer be allowed to connect on that direction. + /// + /// + /// + public void SetBlockedDirection(Direction dir, bool value) + { + _adjacencyMap.SetConnection(dir, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, value)); + UpdateMeshAndDirection(); + } + } +} diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdvancedAdjacencyConnector.cs.meta b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdvancedAdjacencyConnector.cs.meta new file mode 100644 index 0000000000..4234aecc6d --- /dev/null +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdvancedAdjacencyConnector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ef4340642b9b436498fe733f9329ac87 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs index 73a8cec576..7695dc4438 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs @@ -8,132 +8,135 @@ using System.Collections.Generic; using UnityEngine; -/// -/// Good for stuff that connects on the same layer only, horizontally, of the same specific and generic type. -/// -public class SimpleAdjacencyConnector : NetworkBehaviour, IAdjacencyConnector +namespace SS3D.Systems.Tile.Connections { /// - /// A type that specifies to which objects to connect to. Must be set if cross connect is used. + /// Good for stuff that connects on the same layer only, horizontally, of the same specific and generic type. /// - [Tooltip("Generic ID that adjacent objects must be to count. If empty, any id is accepted.")] - [SerializeField] - private TileObjectGenericType _genericType; - - /// - /// Specific ID to differentiate objects when the generic is the same. - /// - [Tooltip("Specific ID to differentiate objects when the generic is the same.")] - [SerializeField] - private TileObjectSpecificType _specificType; - - [SerializeField] private SimpleConnector _simpleAdjacency; - - [SyncVar(OnChange = nameof(SyncAdjacencies))] - private byte _syncedConnections; - - private AdjacencyMap _adjacencyMap; - private MeshFilter _filter; - private bool _initialized; - private PlacedTileObject _placedObject; - - public override void OnStartClient() - { - base.OnStartClient(); - Setup(); - } - - private void Setup() + public class SimpleAdjacencyConnector : NetworkBehaviour, IAdjacencyConnector { - if (!_initialized) + /// + /// A type that specifies to which objects to connect to. Must be set if cross connect is used. + /// + [Tooltip("Generic ID that adjacent objects must be to count. If empty, any id is accepted.")] + [SerializeField] + private TileObjectGenericType _genericType; + + /// + /// Specific ID to differentiate objects when the generic is the same. + /// + [Tooltip("Specific ID to differentiate objects when the generic is the same.")] + [SerializeField] + private TileObjectSpecificType _specificType; + + [SerializeField] private SimpleConnector _simpleAdjacency; + + [SyncVar(OnChange = nameof(SyncAdjacencies))] + private byte _syncedConnections; + + private AdjacencyMap _adjacencyMap; + private MeshFilter _filter; + private bool _initialized; + private PlacedTileObject _placedObject; + + public override void OnStartClient() { - _adjacencyMap = new AdjacencyMap(); - _filter = GetComponent(); + base.OnStartClient(); + Setup(); + } - _placedObject = GetComponent(); - if (_placedObject == null) - { - _genericType = TileObjectGenericType.None; - _specificType = TileObjectSpecificType.None; - } - else + private void Setup() + { + if (!_initialized) { - _genericType = _placedObject.GenericType; - _specificType = _placedObject.SpecificType; + _adjacencyMap = new AdjacencyMap(); + _filter = GetComponent(); + + _placedObject = GetComponent(); + if (_placedObject == null) + { + _genericType = TileObjectGenericType.None; + _specificType = TileObjectSpecificType.None; + } + else + { + _genericType = _placedObject.GenericType; + _specificType = _placedObject.SpecificType; + } + _initialized = true; } - _initialized = true; } - } - private void SyncAdjacencies(byte oldValue, byte newValue, bool asServer) - { - if (!asServer) + private void SyncAdjacencies(byte oldValue, byte newValue, bool asServer) { - Setup(); + if (!asServer) + { + Setup(); - _adjacencyMap.DeserializeFromByte(newValue); - UpdateMeshAndDirection(); + _adjacencyMap.DeserializeFromByte(newValue); + UpdateMeshAndDirection(); + } } - } - - public bool UpdateSingle(Direction dir, PlacedTileObject neighbourObject, bool updateNeighbour) - { - bool isConnected = false; - if (neighbourObject != null) + public bool UpdateSingle(Direction dir, PlacedTileObject neighbourObject, bool updateNeighbour) { - isConnected = (neighbourObject && neighbourObject.HasAdjacencyConnector); - isConnected &= neighbourObject.GenericType == _genericType || _genericType == TileObjectGenericType.None; - isConnected &= neighbourObject.SpecificType == _specificType || _specificType == TileObjectSpecificType.None; + bool isConnected = false; - // Update our neighbour as well - if (isConnected && updateNeighbour) - neighbourObject.UpdateSingleAdjacency(_placedObject, TileHelper.GetOpposite(dir)); - } + if (neighbourObject != null) + { + isConnected = (neighbourObject && neighbourObject.HasAdjacencyConnector); + isConnected &= neighbourObject.GenericType == _genericType || _genericType == TileObjectGenericType.None; + isConnected &= neighbourObject.SpecificType == _specificType || _specificType == TileObjectSpecificType.None; - bool isUpdated = _adjacencyMap.SetConnection(dir, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, isConnected)); + // Update our neighbour as well + if (isConnected && updateNeighbour) + neighbourObject.UpdateSingleAdjacency(_placedObject, TileHelper.GetOpposite(dir)); + } - if (isUpdated) - { - _syncedConnections = _adjacencyMap.SerializeToByte(); - UpdateMeshAndDirection(); - } + bool isUpdated = _adjacencyMap.SetConnection(dir, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, isConnected)); - return isUpdated; - } + if (isUpdated) + { + _syncedConnections = _adjacencyMap.SerializeToByte(); + UpdateMeshAndDirection(); + } - private void UpdateMeshAndDirection() - { - MeshDirectionInfo info = new(); - info = _simpleAdjacency.GetMeshAndDirection(_adjacencyMap); - - if (_filter == null) - { - Log.Warning(this, "Missing mesh {meshDirectionInfo}", Logs.Generic, info); + return isUpdated; } - _filter.mesh = info.Mesh; + private void UpdateMeshAndDirection() + { + MeshDirectionInfo info = new(); + info = _simpleAdjacency.GetMeshAndDirection(_adjacencyMap); - Quaternion localRotation = transform.localRotation; - Vector3 eulerRotation = localRotation.eulerAngles; - localRotation = Quaternion.Euler(eulerRotation.x, info.Rotation, eulerRotation.z); + if (_filter == null) + { + Log.Warning(this, "Missing mesh {meshDirectionInfo}", Logs.Generic, info); + } - transform.localRotation = localRotation; - } + _filter.mesh = info.Mesh; - public void UpdateAll(PlacedTileObject[] neighbourObjects) - { - Setup(); + Quaternion localRotation = transform.localRotation; + Vector3 eulerRotation = localRotation.eulerAngles; + localRotation = Quaternion.Euler(eulerRotation.x, info.Rotation, eulerRotation.z); - bool changed = false; - for (int i = 0; i < neighbourObjects.Length; i++) - { - changed |= UpdateSingle((Direction)i, neighbourObjects[i], true); + transform.localRotation = localRotation; } - if (changed) + public void UpdateAll(PlacedTileObject[] neighbourObjects) { - UpdateMeshAndDirection(); + Setup(); + + bool changed = false; + for (int i = 0; i < neighbourObjects.Length; i++) + { + changed |= UpdateSingle((Direction)i, neighbourObjects[i], true); + } + + if (changed) + { + UpdateMeshAndDirection(); + } } } -} +} \ No newline at end of file From 501afeb0db2f5f79fb33f90547ca1fe7c26b8e27 Mon Sep 17 00:00:00 2001 From: stilnat Date: Fri, 6 Oct 2023 20:00:46 +0200 Subject: [PATCH 05/52] rename door script --- .../Tile/Connections/{Door.cs => DoorAdjacencyConnector.cs} | 3 ++- .../{Door.cs.meta => DoorAdjacencyConnector.cs.meta} | 0 2 files changed, 2 insertions(+), 1 deletion(-) rename Assets/Scripts/SS3D/Systems/Tile/Connections/{Door.cs => DoorAdjacencyConnector.cs} (98%) rename Assets/Scripts/SS3D/Systems/Tile/Connections/{Door.cs.meta => DoorAdjacencyConnector.cs.meta} (100%) diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/Door.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs similarity index 98% rename from Assets/Scripts/SS3D/Systems/Tile/Connections/Door.cs rename to Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs index 4390909335..b813095a64 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/Door.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs @@ -2,10 +2,11 @@ using UnityEngine; using SS3D.Systems.Tile.Connections.AdjacencyTypes; using Coimbra; +using FishNet.Object; namespace SS3D.Systems.Tile.Connections { - public class Door : MonoBehaviour, IAdjacencyConnector + public class DoorAdjacencyConnector : NetworkBehaviour, IAdjacencyConnector { public enum DoorType { diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/Door.cs.meta b/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs.meta similarity index 100% rename from Assets/Scripts/SS3D/Systems/Tile/Connections/Door.cs.meta rename to Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs.meta From 633cb530dd9f2353551b5ffcb8c16a00c10749b3 Mon Sep 17 00:00:00 2001 From: stilnat Date: Sat, 7 Oct 2023 11:56:15 +0200 Subject: [PATCH 06/52] making door connections work --- .../Structures/Walls/SteelWall.prefab | 40 ++++------ .../Connections/DoorAdjacencyConnector.cs | 73 ++----------------- .../Tile/PlacedObjects/PlacedTileObject.cs | 46 ++++++++++++ .../Scripts/SS3D/Systems/Tile/TileHelper.cs | 64 +++++++++++++++- Assets/Scripts/SS3D/Systems/Tile/TileMap.cs | 4 +- .../Scripts/SS3D/Systems/Tile/TileSystem.cs | 3 +- 6 files changed, 135 insertions(+), 95 deletions(-) diff --git a/Assets/Content/WorldObjects/Structures/Walls/SteelWall.prefab b/Assets/Content/WorldObjects/Structures/Walls/SteelWall.prefab index d8852af08a..b05da7136e 100644 --- a/Assets/Content/WorldObjects/Structures/Walls/SteelWall.prefab +++ b/Assets/Content/WorldObjects/Structures/Walls/SteelWall.prefab @@ -148,7 +148,7 @@ GameObject: - component: {fileID: 6696866361892651655} - component: {fileID: 7033236083530598125} - component: {fileID: -2900075557854325373} - - component: {fileID: 1492278076387892290} + - component: {fileID: 3395800597640737248} m_Layer: 0 m_Name: SteelWall m_TagString: Untagged @@ -253,19 +253,25 @@ MonoBehaviour: m_EditorClassIdentifier: k__BackingField: 0 k__BackingField: 0 + k__BackingField: {fileID: 0} _networkBehaviours: [] k__BackingField: {fileID: 0} k__BackingField: [] + SerializedTransformProperties: + Position: {x: 0, y: 0, z: 0} + Rotation: {x: 0, y: 0, z: 0, w: 0} + LocalScale: {x: 0, y: 0, z: 0} _isNetworked: 1 _isGlobal: 0 + _initializeOrder: 0 _defaultDespawnType: 0 NetworkObserver: {fileID: 0} - k__BackingField: -1 + k__BackingField: 65535 + k__BackingField: 0 _scenePathHash: 0 k__BackingField: 0 k__BackingField: 11535764229462028423 - _sceneNetworkObjects: [] ---- !u!114 &1492278076387892290 +--- !u!114 &3395800597640737248 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -274,20 +280,14 @@ MonoBehaviour: m_GameObject: {fileID: 3591147544166670882} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 53a5cd0d46abb6d4d8686d11153009c2, type: 3} + m_Script: {fileID: 11500000, guid: d3995769f8fecf9469d1783a30e75625, type: 3} m_Name: m_EditorClassIdentifier: _componentIndexCache: 255 _addedNetworkObject: {fileID: -2900075557854325373} _networkObjectCache: {fileID: 0} - SelectedAdjacencyType: 1 - _simpleAdjacency: - o: {fileID: 0} - u: {fileID: 0} - i: {fileID: 0} - l: {fileID: 0} - t: {fileID: 0} - x: {fileID: 0} + _genericType: 3 + _specificType: 3 _advancedAdjacency: o: {fileID: -6490088118889457342, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} u: {fileID: -6723024526652964136, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} @@ -306,20 +306,6 @@ MonoBehaviour: xQuad: {fileID: 4199670461815796357, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} viewObstacles: [] opaque: 0 - _offsetAdjacency: - o: {fileID: 0} - uNorth: {fileID: 0} - uSouth: {fileID: 0} - i: {fileID: 0} - lNE: {fileID: 0} - lNW: {fileID: 0} - lSE: {fileID: 0} - lSW: {fileID: 0} - tNEW: {fileID: 0} - tNSW: {fileID: 0} - tNSE: {fileID: 0} - tSWE: {fileID: 0} - x: {fileID: 0} _syncedConnections: 0 --- !u!1 &7790124558541205835 GameObject: diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs index b813095a64..e3e653c7e7 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs @@ -25,7 +25,7 @@ public enum DoorType private DoorType doorType; private TileMap map; - private PlacedTileObject placedTileObject; + public PlacedTileObject placedTileObject; public void CleanAdjacencies() { @@ -56,7 +56,6 @@ public bool UpdateSingle(Direction direction, PlacedTileObject placedObject, boo public void UpdateAll(PlacedTileObject[] neighbourObjects) { - // Because we are on a Furniture layer and walls are on the Turf. Discard furniture neighbours and get the turf neighbours. if (!map) map = GetComponentInParent(); @@ -80,49 +79,18 @@ public void UpdateAll(PlacedTileObject[] neighbourObjects) } } - /** - * Adjusts the connections value based on the given new tile. - * Returns whether value changed. - */ + /// + /// Adjusts the connections value based on the given new tile. + /// + /// Returns whether value changed. private bool UpdateSingleConnection(Direction direction, PlacedTileObject placedObject) { - SetPerpendicularBlocked(true); bool isConnected = (placedObject && placedObject.HasAdjacencyConnector && placedObject.GenericType == TileObjectGenericType.Wall); return adjacencyMap.SetConnection(direction, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, isConnected)); } - /// - /// Walls will try to connect to us. Block or unblock that connects if we are not facing the wall - /// - private void SetPerpendicularBlocked(bool isBlocked) - { - // Door can have rotated in the time between - Direction doorDirection = GetDoorDirection(); - if (map == null) - return; - // map = GetComponentInParent(); - - var neighbourObjects = map.GetNeighbourPlacedObjects(TileLayer.Turf, transform.position); - Direction opposite = TileHelper.GetOpposite(doorDirection); - - MultiAdjacencyConnector wallConnector = null; - if (neighbourObjects[(int)doorDirection] != null) - wallConnector = neighbourObjects[(int)doorDirection].GetComponent(); - - if (wallConnector) - wallConnector.SetBlockedDirection(opposite, isBlocked); - - // Opposite side of door - wallConnector = null; - if (neighbourObjects[(int)opposite] != null) - wallConnector = neighbourObjects[(int)opposite].GetComponent(); - - if (wallConnector) - wallConnector.SetBlockedDirection(doorDirection, isBlocked); - } - private void CreateWallCaps(bool isPresent, Direction direction) { int capIndex = TileHelper.GetDirectionIndex(direction); @@ -144,38 +112,13 @@ private void UpdateWallCaps() if (wallCapPrefab == null) return; - // Door may have rotated in the editor Direction outFacing = TileHelper.GetNextDir(GetDoorDirection()); bool isPresent = adjacencyMap.HasConnection(outFacing); - CreateWallCaps(isPresent, TileHelper.GetOpposite(outFacing)); - - isPresent = adjacencyMap.HasConnection(TileHelper.GetOpposite(outFacing)); CreateWallCaps(isPresent, outFacing); - } - private void ValidateChildren() - { - // Note: This only needs to run on the server, which loads from the scene. - // Anywhere else (including clients, mostly), doesn't really need this. - for (int i = transform.childCount - 1; i > 0; --i) - { - var child = transform.GetChild(i); - if (child.name.StartsWith("WallCap")) - { - bool success = int.TryParse(child.name.Substring(7), out int num); - - // Remove if no int, int out of bounds, or duplicate - if (!success || num > wallCaps.Length || num < 0 || (wallCaps[num] != null && !ReferenceEquals(wallCaps[num], child.gameObject))) - { - Debug.LogWarning($"Unusual child found whilst searching for wall caps: {child.name}, deleting"); - child.gameObject.Dispose(true); - continue; - } - - wallCaps[num] = child.gameObject; - } - } + isPresent = adjacencyMap.HasConnection(TileHelper.GetOpposite(outFacing)); + CreateWallCaps(isPresent, TileHelper.GetOpposite(outFacing)); } /** @@ -194,7 +137,7 @@ private GameObject SpawnWallCap(Direction direction) wallCap.transform.localRotation = Quaternion.Euler(0, rotation, 0); wallCap.transform.localPosition = new Vector3(cardinal.Item1 * WALL_CAP_DISTANCE_FROM_CENTRE, 0, cardinal.Item2 * WALL_CAP_DISTANCE_FROM_CENTRE); - + Spawn(wallCap); return wallCap; } diff --git a/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs b/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs index a89f7b3e4b..af2bfa6da0 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs @@ -119,5 +119,51 @@ public SavedPlacedTileObject Save() dir = _dir, }; } + + /// + /// Is this in front of the other object ? + /// + public bool IsInFront(PlacedTileObject other) + { + if(Origin == other.Origin + TileHelper.CoordinateDifferenceInFrontFacingDirection(other.Direction)) + return true; + + return false; + } + + /// + /// Is this behind the other object ? + /// + public bool IsBehind(PlacedTileObject other) + { + if (Origin == other.Origin - TileHelper.CoordinateDifferenceInFrontFacingDirection(other.Direction)) + return true; + + return false; + } + + /// + /// Is this on the right of the other object ? + /// + public bool IsOnRight(PlacedTileObject other) + { + Direction dirOnRight = TileHelper.GetNextCardinalDir(other.Direction); + if (Origin == other.Origin + TileHelper.CoordinateDifferenceInFrontFacingDirection(dirOnRight)) + return true; + + return false; + } + + /// + /// Is this on the left of the other object ? + /// + public bool IsOnLeft(PlacedTileObject other) + { + Direction dirOnLeft = TileHelper.GetNextCardinalDir(other.Direction); + if (Origin == other.Origin - TileHelper.CoordinateDifferenceInFrontFacingDirection(dirOnLeft)) + return true; + + return false; + } } } \ No newline at end of file diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileHelper.cs b/Assets/Scripts/SS3D/Systems/Tile/TileHelper.cs index c9635ec820..1cca7c76dc 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/TileHelper.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/TileHelper.cs @@ -1,6 +1,8 @@ -using System; +using SS3D.Logging; +using System; using System.Collections; using System.Collections.Generic; +using System.Runtime.CompilerServices; using UnityEngine; namespace SS3D.Systems.Tile @@ -24,6 +26,22 @@ public static Direction GetNextDir(Direction dir) } } + public static Direction GetNextCardinalDir(Direction dir) + { + switch (dir) + { + default: + case Direction.South: return Direction.West; + case Direction.SouthWest: return Direction.NorthWest; + case Direction.West: return Direction.North; + case Direction.NorthWest: return Direction.NorthEast; + case Direction.North: return Direction.East; + case Direction.NorthEast: return Direction.SouthEast; + case Direction.East: return Direction.South; + case Direction.SouthEast: return Direction.SouthWest; + } + } + public static int GetRotationAngle(Direction dir) { return (int)dir * 45; @@ -97,5 +115,49 @@ public static Direction GetOpposite(Direction direction) { return (Direction)(((int)direction + 4) % 8); } + + /// + /// Return the difference in coordinates for a neighbour tile in front of another one facing + /// a particular direction. + /// e.g If the original one is facing north, return (0,1), because, the tile in front of the original + /// one will be just north of the original one (hence plus one on the y axis). + /// + public static Vector2Int CoordinateDifferenceInFrontFacingDirection(Direction direction) + { + switch(direction) + { + case Direction.North: + return new Vector2Int(0, 1); + + case Direction.NorthEast: + return new Vector2Int(1, 1); + + case Direction.East: + return new Vector2Int(1, 0); + + case Direction.SouthEast: + return new Vector2Int(1, -1); + + case Direction.South: + return new Vector2Int(0, -1); + + case Direction.SouthWest: + return new Vector2Int(-1, -1); + + case Direction.West: + return new Vector2Int(-1, 0); + + case Direction.NorthWest: + return new Vector2Int(-1, 1); + + default: + Debug.LogError("direction not handled, returning (0,0)"); + return new Vector2Int(0, 0); + } + } + + + + } } \ No newline at end of file diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs b/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs index 619fd8e8a7..b28b5362c9 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs @@ -11,7 +11,9 @@ namespace SS3D.Systems.Tile { /// - /// Class used for storing and modifying a tile map. + /// Class used for storing and modifying a tile map. Coordinates on the tile map follows the following : + /// - South North is the Y axis with North going toward positives. + /// - East West is the X axis with east going toward positives. /// public class TileMap : NetworkBehaviour { diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileSystem.cs b/Assets/Scripts/SS3D/Systems/Tile/TileSystem.cs index 04ab4a4cf8..cc128e2510 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/TileSystem.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/TileSystem.cs @@ -1,4 +1,4 @@ -using Cysharp.Threading.Tasks; +using Cysharp.Threading.Tasks; using FishNet.Object; using SS3D.Core.Behaviours; using SS3D.Data.Management; @@ -24,6 +24,7 @@ public class TileSystem : NetworkSystem public TileResourceLoader Loader { get; private set; } private TileMap _currentMap; + public TileMap CurrentMap => _currentMap; [ServerOrClient] protected override void OnStart() From 03745812de36999c09113bfee32980677c1b6675 Mon Sep 17 00:00:00 2001 From: stilnat Date: Sat, 7 Oct 2023 12:11:36 +0200 Subject: [PATCH 07/52] remove wrong method --- .../SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs index e3e653c7e7..f76333856c 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs @@ -34,8 +34,6 @@ public void CleanAdjacencies() map = GetComponentInParent(); } - SetPerpendicularBlocked(false); - var neighbourObjects = map.GetNeighbourPlacedObjects(TileLayer.Turf, transform.position); for (int i = 0; i < neighbourObjects.Length; i++) { From 2318831bc26114c1a4d9047bf882de4488b36bf0 Mon Sep 17 00:00:00 2001 From: stilnat Date: Sat, 7 Oct 2023 17:08:15 +0200 Subject: [PATCH 08/52] change a bit setup of map --- .../Connections/AdvancedAdjacencyConnector.cs | 1 + .../Connections/DoorAdjacencyConnector.cs | 30 ++++++++++++--- .../Tile/Connections/TileObjectType.cs | 5 ++- .../Tile/PlacedObjects/PlacedTileObject.cs | 2 + Assets/Scripts/SS3D/Systems/Tile/TileChunk.cs | 21 ++++++++++- Assets/Scripts/SS3D/Systems/Tile/TileMap.cs | 37 ++++++++++++++++--- .../Scripts/SS3D/Systems/Tile/TileSystem.cs | 2 +- 7 files changed, 84 insertions(+), 14 deletions(-) diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdvancedAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdvancedAdjacencyConnector.cs index 8d22fa29b3..fa74ce242d 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdvancedAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdvancedAdjacencyConnector.cs @@ -66,6 +66,7 @@ private void Setup() public bool UpdateSingle(Direction dir, PlacedTileObject neighbourObject, bool updateNeighbour) { + Setup(); bool isConnected = false; bool isUpdated = false; diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs index f76333856c..05899e16b5 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs @@ -27,6 +27,29 @@ public enum DoorType private TileMap map; public PlacedTileObject placedTileObject; + private bool _initialized = false; + + // WallCap gameobjects, North, East, South, West. Null if not present. + private GameObject[] wallCaps = new GameObject[4]; + private AdjacencyMap adjacencyMap = new AdjacencyMap(); + + public override void OnStartClient() + { + base.OnStartClient(); + Setup(); + } + + private void Setup() + { + if (!_initialized) + { + adjacencyMap = new AdjacencyMap(); + + placedTileObject = GetComponent(); + _initialized = true; + } + } + public void CleanAdjacencies() { if (!map) @@ -44,7 +67,7 @@ public void CleanAdjacencies() public bool UpdateSingle(Direction direction, PlacedTileObject placedObject, bool updateNeighbours) { - + Setup(); if (UpdateSingleConnection(direction, placedObject)) UpdateWallCaps(); @@ -54,6 +77,7 @@ public bool UpdateSingle(Direction direction, PlacedTileObject placedObject, boo public void UpdateAll(PlacedTileObject[] neighbourObjects) { + Setup(); if (!map) map = GetComponentInParent(); @@ -148,10 +172,6 @@ private Direction GetDoorDirection() return placedTileObject.Direction; } - - // WallCap gameobjects, North, East, South, West. Null if not present. - private GameObject[] wallCaps = new GameObject[4]; - private AdjacencyMap adjacencyMap = new AdjacencyMap(); } } diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/TileObjectType.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/TileObjectType.cs index 4bf9adc324..9190133b2d 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/TileObjectType.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/TileObjectType.cs @@ -1,4 +1,4 @@ -using System.Collections; +using System.Collections; using System.Collections.Generic; using UnityEngine; @@ -21,7 +21,8 @@ public enum TileObjectGenericType Floor, Counter, Cable, - Wire + Wire, + Door } /// diff --git a/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs b/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs index af2bfa6da0..6b5c4435da 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs @@ -71,6 +71,8 @@ public static PlacedTileObject Create(Vector3 worldPosition, Vector2Int origin, public TileObjectSpecificType SpecificType => _tileObjectSo.specificType; + public TileLayer Layer => _tileObjectSo.layer; + public Direction Direction => _dir; public string NameString => _tileObjectSo.nameString; diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileChunk.cs b/Assets/Scripts/SS3D/Systems/Tile/TileChunk.cs index 3d5113f0cc..58bd4222c1 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/TileChunk.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/TileChunk.cs @@ -1,4 +1,4 @@ -using FishNet; +using FishNet; using FishNet.Object; using SS3D.Core; using SS3D.Logging; @@ -198,5 +198,24 @@ public SavedTileChunk Save() return saveObject; } + + /// + /// Get all placed tile objects on this chunk. + /// + public List GetAllTilePlacedObjects() + { + var list = new List(); + foreach(TileGrid grid in _tileGridList) + { + foreach(TileObject obj in grid.TileObjectsGrid) + { + if(obj.PlacedObject != null) + { + list.Add(obj.PlacedObject); + } + } + } + return list; + } } } \ No newline at end of file diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs b/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs index b28b5362c9..d4e8c1019b 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs @@ -23,6 +23,8 @@ public class TileMap : NetworkBehaviour public int ChunkCount => _chunks.Count; + public event EventHandler OnMapLoaded; + public static TileMap Create(string name) { GameObject mapObject = new GameObject(name); @@ -165,7 +167,8 @@ public bool CanBuild(TileObjectSo tileObjectSo, Vector3 placePosition, Direction return canBuild; } - public bool PlaceTileObject(TileObjectSo tileObjectSo, Vector3 placePosition, Direction dir, bool skipBuildCheck, bool replaceExisting) + public bool PlaceTileObject(TileObjectSo tileObjectSo, Vector3 placePosition, Direction dir, + bool skipBuildCheck, bool replaceExisting, bool skipAdjacency) { bool canBuild = CanBuild(tileObjectSo, placePosition, dir, replaceExisting); @@ -189,9 +192,12 @@ public bool PlaceTileObject(TileObjectSo tileObjectSo, Vector3 placePosition, Di chunk.GetTileObject(tileObjectSo.layer, gridPosition).PlacedObject = placedObject; } - // Handle Adjacency connectors - var neighbourTiles = GetNeighbourPlacedObjects(tileObjectSo.layer, placePosition); - placedObject.UpdateAdjacencies(neighbourTiles); + // Handle Adjacency connectors, can skip it particulary when loading the map. + if (!skipAdjacency){ + var neighbourTiles = GetNeighbourPlacedObjects(tileObjectSo.layer, placePosition); + placedObject.UpdateAdjacencies(neighbourTiles); + } + } return canBuild; @@ -314,7 +320,7 @@ public void Load([CanBeNull] SavedTileMap saveObject) Vector3 placePosition = chunk.GetWorldPosition(savedTile.x, savedTile.y); // Skipping build check here to allow loading tile objects in a non-valid order - PlaceTileObject(toBePlaced, placePosition, savedTile.placedSaveObject.dir, true, false); + PlaceTileObject(toBePlaced, placePosition, savedTile.placedSaveObject.dir, true, false, true); } } @@ -323,6 +329,27 @@ public void Load([CanBeNull] SavedTileMap saveObject) ItemObjectSo toBePlaced = (ItemObjectSo)tileSystem.GetAsset(savedItem.itemName); PlaceItemObject(savedItem.worldPosition, savedItem.rotation, toBePlaced); } + + OnMapLoaded?.Invoke(this, EventArgs.Empty); + UpdateAllAdjacencies(); + } + + /// + /// Update every adjacency of each placed tile object when the map is loaded. + /// + private void UpdateAllAdjacencies() + { + foreach(TileChunk chunk in _chunks.Values) + { + foreach(PlacedTileObject obj in chunk.GetAllTilePlacedObjects()) + { + if (obj.HasAdjacencyConnector) + { + var pos = chunk.GetWorldPosition(obj.Origin.x, obj.Origin.y); + obj.UpdateAdjacencies(GetNeighbourPlacedObjects(obj.Layer, pos)); + } + } + } } } } \ No newline at end of file diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileSystem.cs b/Assets/Scripts/SS3D/Systems/Tile/TileSystem.cs index cc128e2510..5913421cea 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/TileSystem.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/TileSystem.cs @@ -84,7 +84,7 @@ private bool PlaceObject(GenericObjectSo genericObjectSo, Vector3 placePosition, switch (genericObjectSo) { case TileObjectSo so: - return _currentMap.PlaceTileObject(so, placePosition, dir, false, replaceExisting); + return _currentMap.PlaceTileObject(so, placePosition, dir, false, replaceExisting, false); case ItemObjectSo so: _currentMap.PlaceItemObject(placePosition, Quaternion.Euler(0, TileHelper.GetRotationAngle(dir), 0), so); break; From 8e3e3e41a0aa1f2d1985f0cd6af681374207503b Mon Sep 17 00:00:00 2001 From: stilnat Date: Sat, 7 Oct 2023 17:08:47 +0200 Subject: [PATCH 09/52] add wall connector --- .../Connections/WallAdjacencyConnector.cs | 172 ++++++++++++++++++ .../WallAdjacencyConnector.cs.meta | 11 ++ 2 files changed, 183 insertions(+) create mode 100644 Assets/Scripts/SS3D/Systems/Tile/Connections/WallAdjacencyConnector.cs create mode 100644 Assets/Scripts/SS3D/Systems/Tile/Connections/WallAdjacencyConnector.cs.meta diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/WallAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/WallAdjacencyConnector.cs new file mode 100644 index 0000000000..b31e774f01 --- /dev/null +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/WallAdjacencyConnector.cs @@ -0,0 +1,172 @@ +using DG.Tweening; +using FishNet.Object; +using FishNet.Object.Synchronizing; +using SS3D.Logging; +using SS3D.Systems.Tile.Connections; +using SS3D.Systems.Tile.Connections.AdjacencyTypes; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace SS3D.Systems.Tile.Connections +{ + public class WallAdjacencyConnector : NetworkBehaviour, IAdjacencyConnector + { + /// + /// A type that specifies to which objects to connect to. Must be set if cross connect is used. + /// + [Tooltip("Generic ID that adjacent objects must be to count. If empty, any id is accepted.")] + [SerializeField] + private TileObjectGenericType _genericType; + + /// + /// Specific ID to differentiate objects when the generic is the same. + /// + [Tooltip("Specific ID to differentiate objects when the generic is the same.")] + [SerializeField] + private TileObjectSpecificType _specificType; + + [SerializeField] private AdvancedConnector _advancedAdjacency; + + private AdjacencyMap _adjacencyMap; + + [SyncVar(OnChange = nameof(SyncAdjacencies))] + private byte _syncedConnections; + + private MeshFilter _filter; + private bool _initialized; + private PlacedTileObject _placedObject; + + public override void OnStartClient() + { + base.OnStartClient(); + Setup(); + } + + private void Setup() + { + if (!_initialized) + { + _adjacencyMap = new AdjacencyMap(); + _filter = GetComponent(); + + _placedObject = GetComponent(); + if (_placedObject == null) + { + _genericType = TileObjectGenericType.None; + _specificType = TileObjectSpecificType.None; + } + else + { + _genericType = _placedObject.GenericType; + _specificType = _placedObject.SpecificType; + } + _initialized = true; + } + } + + public bool UpdateSingle(Direction dir, PlacedTileObject neighbourObject, bool updateNeighbour) + { + Setup(); + bool isConnected = false; + bool isUpdated = false; + + if (neighbourObject != null) + { + isConnected = (neighbourObject && neighbourObject.HasAdjacencyConnector); + + isConnected &= neighbourObject.GenericType == TileObjectGenericType.Wall || + neighbourObject.GenericType == TileObjectGenericType.Door; + + if (neighbourObject.GetComponent() != null) + { + isConnected &= IsConnectedToDoor(neighbourObject); + } + + // Update our neighbour as well + if (isConnected && updateNeighbour) + neighbourObject.UpdateSingleAdjacency(_placedObject, TileHelper.GetOpposite(dir)); + } + + isUpdated = _adjacencyMap.SetConnection(dir, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, isConnected)); + if (isUpdated) + { + _syncedConnections = _adjacencyMap.SerializeToByte(); + UpdateMeshAndDirection(); + } + + return isUpdated; + } + + public void UpdateAll(PlacedTileObject[] neighbourObjects) + { + Setup(); + + bool changed = false; + for (int i = 0; i < neighbourObjects.Length; i++) + { + changed |= UpdateSingle((Direction)i, neighbourObjects[i], true); + } + + if (changed) + { + UpdateMeshAndDirection(); + } + } + + private void UpdateMeshAndDirection() + { + MeshDirectionInfo info = new(); + info = _advancedAdjacency.GetMeshAndDirection(_adjacencyMap); + + if (_filter == null) + { + Log.Warning(this, "Missing mesh {meshDirectionInfo}", Logs.Generic, info); + } + + _filter.mesh = info.Mesh; + + Quaternion localRotation = transform.localRotation; + Vector3 eulerRotation = localRotation.eulerAngles; + localRotation = Quaternion.Euler(eulerRotation.x, info.Rotation, eulerRotation.z); + + transform.localRotation = localRotation; + } + + private void SyncAdjacencies(byte oldValue, byte newValue, bool asServer) + { + if (!asServer) + { + Setup(); + + _adjacencyMap.DeserializeFromByte(newValue); + UpdateMeshAndDirection(); + } + } + + /// + /// Sets a given direction blocked. This means that it will no longer be allowed to connect on that direction. + /// + /// + /// + public void SetBlockedDirection(Direction dir, bool value) + { + _adjacencyMap.SetConnection(dir, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, value)); + UpdateMeshAndDirection(); + } + + private bool IsConnectedToDoor(PlacedTileObject neighbourObject) + { + bool isConnected = false; + var doorConnector = neighbourObject.GetComponent(); + var door = doorConnector.placedTileObject; + if (door != null) + { + if (_placedObject.IsOnLeft(door) || _placedObject.IsOnRight(door)) + return true; + } + + return false; + } + } +} diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/WallAdjacencyConnector.cs.meta b/Assets/Scripts/SS3D/Systems/Tile/Connections/WallAdjacencyConnector.cs.meta new file mode 100644 index 0000000000..b459144e35 --- /dev/null +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/WallAdjacencyConnector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d3995769f8fecf9469d1783a30e75625 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From f19395b96ab34e3bc8dd4f7cf40abe8ba68f52ef Mon Sep 17 00:00:00 2001 From: stilnat Date: Sat, 7 Oct 2023 17:57:14 +0200 Subject: [PATCH 10/52] expand interface and implement --- .../Connections/AdvancedAdjacencyConnector.cs | 35 +++++++++++-------- .../Connections/DoorAdjacencyConnector.cs | 31 ++++++++-------- .../Tile/Connections/IAdjacencyConnector.cs | 5 +-- .../Connections/SimpleAdjacencyConnector.cs | 33 ++++++++++------- .../Connections/WallAdjacencyConnector.cs | 26 +++++++++++--- .../Tile/PlacedObjects/PlacedTileObject.cs | 4 +-- 6 files changed, 80 insertions(+), 54 deletions(-) diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdvancedAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdvancedAdjacencyConnector.cs index fa74ce242d..7af9443c62 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdvancedAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdvancedAdjacencyConnector.cs @@ -64,22 +64,15 @@ private void Setup() } } - public bool UpdateSingle(Direction dir, PlacedTileObject neighbourObject, bool updateNeighbour) + public bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObject, bool updateNeighbour) { Setup(); - bool isConnected = false; - bool isUpdated = false; + bool isConnected = IsConnected(dir, neighbourObject); + bool isUpdated; - if (neighbourObject) - { - isConnected = (neighbourObject && neighbourObject.HasAdjacencyConnector); - isConnected &= neighbourObject.GenericType == _genericType || _genericType == TileObjectGenericType.None; - isConnected &= neighbourObject.SpecificType == _specificType || _specificType == TileObjectSpecificType.None; - - // Update our neighbour as well - if (isConnected && updateNeighbour) - neighbourObject.UpdateSingleAdjacency(_placedObject, TileHelper.GetOpposite(dir)); - } + // Update our neighbour as well + if (isConnected && updateNeighbour) + neighbourObject.UpdateSingleAdjacency(_placedObject, TileHelper.GetOpposite(dir)); isUpdated = _adjacencyMap.SetConnection(dir, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, isConnected)); if (isUpdated) @@ -91,14 +84,26 @@ public bool UpdateSingle(Direction dir, PlacedTileObject neighbourObject, bool u return isUpdated; } - public void UpdateAll(PlacedTileObject[] neighbourObjects) + public bool IsConnected(Direction dir, PlacedTileObject neighbourObject) + { + bool isConnected = false; + if (neighbourObject) + { + isConnected = (neighbourObject && neighbourObject.HasAdjacencyConnector); + isConnected &= neighbourObject.GenericType == _genericType || _genericType == TileObjectGenericType.None; + isConnected &= neighbourObject.SpecificType == _specificType || _specificType == TileObjectSpecificType.None; + } + return isConnected; + } + + public void UpdateAllConnections(PlacedTileObject[] neighbourObjects) { Setup(); bool changed = false; for (int i = 0; i < neighbourObjects.Length; i++) { - changed |= UpdateSingle((Direction)i, neighbourObjects[i], true); + changed |= UpdateSingleConnection((Direction)i, neighbourObjects[i], true); } if (changed) diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs index 05899e16b5..540a0b2171 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs @@ -65,17 +65,20 @@ public void CleanAdjacencies() } } - public bool UpdateSingle(Direction direction, PlacedTileObject placedObject, bool updateNeighbours) + public bool UpdateSingleConnection(Direction direction, PlacedTileObject placedObject, bool updateNeighbours) { Setup(); - if (UpdateSingleConnection(direction, placedObject)) + + bool isConnected = IsConnected(direction, placedObject); + bool update = adjacencyMap.SetConnection(direction, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, isConnected)); + + if (update) UpdateWallCaps(); - // TODO should check if connection was actually updated. return true; } - public void UpdateAll(PlacedTileObject[] neighbourObjects) + public void UpdateAllConnections(PlacedTileObject[] neighbourObjects) { Setup(); if (!map) @@ -88,7 +91,7 @@ public void UpdateAll(PlacedTileObject[] neighbourObjects) for (int i = 0; i < neighbourObjects.Length; i++) { bool updatedSingle = false; - updatedSingle = UpdateSingleConnection((Direction)i, neighbourObjects[i]); + updatedSingle = UpdateSingleConnection((Direction)i, neighbourObjects[i], true); if (updatedSingle && neighbourObjects[i]) neighbourObjects[i].UpdateSingleAdjacency(currentObject, TileHelper.GetOpposite((Direction)i)); @@ -101,18 +104,6 @@ public void UpdateAll(PlacedTileObject[] neighbourObjects) } } - /// - /// Adjusts the connections value based on the given new tile. - /// - /// Returns whether value changed. - private bool UpdateSingleConnection(Direction direction, PlacedTileObject placedObject) - { - bool isConnected = (placedObject && placedObject.HasAdjacencyConnector && - placedObject.GenericType == TileObjectGenericType.Wall); - - return adjacencyMap.SetConnection(direction, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, isConnected)); - } - private void CreateWallCaps(bool isPresent, Direction direction) { int capIndex = TileHelper.GetDirectionIndex(direction); @@ -172,6 +163,12 @@ private Direction GetDoorDirection() return placedTileObject.Direction; } + + public bool IsConnected(Direction dir, PlacedTileObject neighbourObject) + { + return (neighbourObject && neighbourObject.HasAdjacencyConnector && + neighbourObject.GenericType == TileObjectGenericType.Wall); + } } } diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/IAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/IAdjacencyConnector.cs index 6087d291f4..2e98df709e 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/IAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/IAdjacencyConnector.cs @@ -5,7 +5,8 @@ /// public interface IAdjacencyConnector { - bool UpdateSingle(Direction direction, PlacedTileObject neighbourObject, bool updateNeighbour); - void UpdateAll(PlacedTileObject[] neighbourObjects); + bool UpdateSingleConnection(Direction direction, PlacedTileObject neighbourObject, bool updateNeighbour); + void UpdateAllConnections(PlacedTileObject[] neighbourObjects); + bool IsConnected(Direction dir, PlacedTileObject neighbourObject); } } \ No newline at end of file diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs index 7695dc4438..8e3fb31a6d 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs @@ -78,20 +78,15 @@ private void SyncAdjacencies(byte oldValue, byte newValue, bool asServer) } } - public bool UpdateSingle(Direction dir, PlacedTileObject neighbourObject, bool updateNeighbour) + public bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObject, bool updateNeighbour) { - bool isConnected = false; + Setup(); - if (neighbourObject != null) - { - isConnected = (neighbourObject && neighbourObject.HasAdjacencyConnector); - isConnected &= neighbourObject.GenericType == _genericType || _genericType == TileObjectGenericType.None; - isConnected &= neighbourObject.SpecificType == _specificType || _specificType == TileObjectSpecificType.None; + bool isConnected = IsConnected(dir, neighbourObject); - // Update our neighbour as well - if (isConnected && updateNeighbour) - neighbourObject.UpdateSingleAdjacency(_placedObject, TileHelper.GetOpposite(dir)); - } + // Update our neighbour as well + if (isConnected && updateNeighbour) + neighbourObject.UpdateSingleAdjacency(_placedObject, TileHelper.GetOpposite(dir)); bool isUpdated = _adjacencyMap.SetConnection(dir, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, isConnected)); @@ -123,14 +118,14 @@ private void UpdateMeshAndDirection() transform.localRotation = localRotation; } - public void UpdateAll(PlacedTileObject[] neighbourObjects) + public void UpdateAllConnections(PlacedTileObject[] neighbourObjects) { Setup(); bool changed = false; for (int i = 0; i < neighbourObjects.Length; i++) { - changed |= UpdateSingle((Direction)i, neighbourObjects[i], true); + changed |= UpdateSingleConnection((Direction)i, neighbourObjects[i], true); } if (changed) @@ -138,5 +133,17 @@ public void UpdateAll(PlacedTileObject[] neighbourObjects) UpdateMeshAndDirection(); } } + + public bool IsConnected(Direction dir, PlacedTileObject neighbourObject) + { + bool isConnected = false; + if (neighbourObject != null) + { + isConnected = (neighbourObject && neighbourObject.HasAdjacencyConnector); + isConnected &= neighbourObject.GenericType == _genericType || _genericType == TileObjectGenericType.None; + isConnected &= neighbourObject.SpecificType == _specificType || _specificType == TileObjectSpecificType.None; + } + return isConnected; + } } } \ No newline at end of file diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/WallAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/WallAdjacencyConnector.cs index b31e774f01..2801732ee1 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/WallAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/WallAdjacencyConnector.cs @@ -65,10 +65,10 @@ private void Setup() } } - public bool UpdateSingle(Direction dir, PlacedTileObject neighbourObject, bool updateNeighbour) + public bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObject, bool updateNeighbour) { Setup(); - bool isConnected = false; + bool isConnected = IsConnected(dir, neighbourObject); bool isUpdated = false; if (neighbourObject != null) @@ -98,14 +98,14 @@ public bool UpdateSingle(Direction dir, PlacedTileObject neighbourObject, bool u return isUpdated; } - public void UpdateAll(PlacedTileObject[] neighbourObjects) + public void UpdateAllConnections(PlacedTileObject[] neighbourObjects) { Setup(); bool changed = false; for (int i = 0; i < neighbourObjects.Length; i++) { - changed |= UpdateSingle((Direction)i, neighbourObjects[i], true); + changed |= UpdateSingleConnection((Direction)i, neighbourObjects[i], true); } if (changed) @@ -157,7 +157,6 @@ public void SetBlockedDirection(Direction dir, bool value) private bool IsConnectedToDoor(PlacedTileObject neighbourObject) { - bool isConnected = false; var doorConnector = neighbourObject.GetComponent(); var door = doorConnector.placedTileObject; if (door != null) @@ -168,5 +167,22 @@ private bool IsConnectedToDoor(PlacedTileObject neighbourObject) return false; } + + public bool IsConnected(Direction dir, PlacedTileObject neighbourObject) + { + if(neighbourObject == null) return false; + + bool isConnected = (neighbourObject.HasAdjacencyConnector); + + isConnected &= neighbourObject.GenericType == TileObjectGenericType.Wall || + neighbourObject.GenericType == TileObjectGenericType.Door; + + if (neighbourObject.GetComponent() != null) + { + isConnected &= IsConnectedToDoor(neighbourObject); + } + + return isConnected; + } } } diff --git a/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs b/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs index 6b5c4435da..3576e32f46 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs @@ -103,13 +103,13 @@ public void DestroySelf() public void UpdateAdjacencies(PlacedTileObject[] neighbourObjects) { if (HasAdjacencyConnector) - _connector.UpdateAll(neighbourObjects); + _connector.UpdateAllConnections(neighbourObjects); } public void UpdateSingleAdjacency(PlacedTileObject neighbourObject, Direction dir) { if (HasAdjacencyConnector) - _connector.UpdateSingle(dir, neighbourObject, false); + _connector.UpdateSingleConnection(dir, neighbourObject, false); } public SavedPlacedTileObject Save() From 554990bd6b767bac96112970f54cbe04d7148a9d Mon Sep 17 00:00:00 2001 From: stilnat Date: Sat, 7 Oct 2023 18:22:59 +0200 Subject: [PATCH 11/52] fixed advanced adjacency --- .../Connections/AdjacencyTypes/AdvancedAdjacency.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/AdvancedAdjacency.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/AdvancedAdjacency.cs index 62931299f8..731ed9c331 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/AdvancedAdjacency.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/AdvancedAdjacency.cs @@ -97,9 +97,9 @@ public MeshDirectionInfo GetMeshAndDirection(AdjacencyMap adjacencyMap) case AdjacencyShape.XSingle: mesh = xSingle; Direction connectingDiagonal = adjacencyMap.GetSingleConnection(false); - rotation = connectingDiagonal == Direction.SouthWest ? 0f : - connectingDiagonal == Direction.SouthWest ? 90f : - connectingDiagonal == Direction.SouthEast ? 180f : -90f; + rotation = connectingDiagonal == Direction.NorthEast ? 0f : + connectingDiagonal == Direction.SouthEast ? 90f : + connectingDiagonal == Direction.SouthWest ? 180f : -90f; break; case AdjacencyShape.XOpposite: mesh = xOpposite; @@ -112,9 +112,9 @@ public MeshDirectionInfo GetMeshAndDirection(AdjacencyMap adjacencyMap) case AdjacencyShape.XTriple: mesh = xTriple; Direction nonConnectingDiagonal = adjacencyMap.GetSingleNonConnection(false); - rotation = nonConnectingDiagonal == Direction.SouthWest ? -90f : - nonConnectingDiagonal == Direction.SouthWest ? 0f : - nonConnectingDiagonal == Direction.SouthEast ? 90f : 180f; + rotation = nonConnectingDiagonal == Direction.NorthEast ? 90f : + nonConnectingDiagonal == Direction.SouthEast ? 180f : + nonConnectingDiagonal == Direction.SouthWest ? -90f : 0f; break; case AdjacencyShape.XQuad: mesh = xQuad; From 7da9a5cd7d084f84a7a603910673e2c15eb1ba66 Mon Sep 17 00:00:00 2001 From: stilnat Date: Sun, 8 Oct 2023 16:51:38 +0200 Subject: [PATCH 12/52] fix multiadjcon --- .../Tile/Connections/MultiAdjacencyConnector.cs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/MultiAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/MultiAdjacencyConnector.cs index 41beaef1fb..ec62bafa42 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/MultiAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/MultiAdjacencyConnector.cs @@ -1,4 +1,4 @@ -using FishNet.Object; +using FishNet.Object; using FishNet.Object.Synchronizing; using SS3D.Logging; using SS3D.Systems.Tile.Connections.AdjacencyTypes; @@ -72,8 +72,9 @@ private void Setup() } } - public bool UpdateSingle(Direction dir, PlacedTileObject neighbourObject, bool updateNeighbour) + public bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObject, bool updateNeighbour) { + Setup(); bool isConnected = false; bool isUpdated = false; @@ -98,14 +99,14 @@ public bool UpdateSingle(Direction dir, PlacedTileObject neighbourObject, bool u return isUpdated; } - public void UpdateAll(PlacedTileObject[] neighbourObjects) + public void UpdateAllConnections(PlacedTileObject[] neighbourObjects) { Setup(); bool changed = false; for (int i = 0; i < neighbourObjects.Length; i++) { - changed |= UpdateSingle((Direction)i, neighbourObjects[i], true); + changed |= UpdateSingleConnection((Direction)i, neighbourObjects[i], true); } if (changed) @@ -154,5 +155,10 @@ private void SyncAdjacencies(byte oldValue, byte newValue, bool asServer) UpdateMeshAndDirection(); } } + + public bool IsConnected(Direction dir, PlacedTileObject neighbourObject) + { + throw new System.NotImplementedException(); + } } } \ No newline at end of file From 386696e4a6e5639f4531e731a007c3eb72ebbb25 Mon Sep 17 00:00:00 2001 From: stilnat Date: Sun, 8 Oct 2023 18:26:54 +0200 Subject: [PATCH 13/52] add abstract horizontal connector class --- .../Structures/Doors/CivillianAirlock.prefab | 34 +++- .../Floors/Tiles/Carpet/FancyCarpetRed.prefab | 10 +- .../AbstractHorizontalConnector.cs | 155 ++++++++++++++++++ .../AbstractHorizontalConnector.cs.meta | 11 ++ .../AdjacencyTypes/AdvancedAdjacency.cs | 2 +- .../AdjacencyTypes/OffsetAdjacency.cs | 2 +- .../AdjacencyTypes/SimpleAdjacency.cs | 2 +- .../Connections/AdvancedAdjacencyConnector.cs | 135 +-------------- .../Connections/DoorAdjacencyConnector.cs | 112 +++---------- .../Connections/IMeshAndDirectionResolver.cs | 11 ++ .../IMeshAndDirectionResolver.cs.meta | 11 ++ .../Connections/SimpleAdjacencyConnector.cs | 124 +------------- .../Connections/WallAdjacencyConnector.cs | 2 +- 13 files changed, 258 insertions(+), 353 deletions(-) create mode 100644 Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs create mode 100644 Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs.meta create mode 100644 Assets/Scripts/SS3D/Systems/Tile/Connections/IMeshAndDirectionResolver.cs create mode 100644 Assets/Scripts/SS3D/Systems/Tile/Connections/IMeshAndDirectionResolver.cs.meta diff --git a/Assets/Content/WorldObjects/Structures/Doors/CivillianAirlock.prefab b/Assets/Content/WorldObjects/Structures/Doors/CivillianAirlock.prefab index fd4201db84..4ed4b4f845 100644 --- a/Assets/Content/WorldObjects/Structures/Doors/CivillianAirlock.prefab +++ b/Assets/Content/WorldObjects/Structures/Doors/CivillianAirlock.prefab @@ -273,6 +273,7 @@ GameObject: - component: {fileID: 2079395355536659087} - component: {fileID: 7942135432533076774} - component: {fileID: -6616120420594439688} + - component: {fileID: -4703641988129057345} m_Layer: 0 m_Name: CivillianAirlock m_TagString: Untagged @@ -311,19 +312,26 @@ MonoBehaviour: m_EditorClassIdentifier: k__BackingField: 0 k__BackingField: 0 + k__BackingField: {fileID: 0} _networkBehaviours: - {fileID: -6616120420594439688} + - {fileID: -4703641988129057345} k__BackingField: {fileID: 0} k__BackingField: [] + SerializedTransformProperties: + Position: {x: 0, y: 0, z: 0} + Rotation: {x: 0, y: 0, z: 0, w: 0} + LocalScale: {x: 0, y: 0, z: 0} _isNetworked: 1 _isGlobal: 0 + _initializeOrder: 0 _defaultDespawnType: 0 NetworkObserver: {fileID: 0} - k__BackingField: -1 + k__BackingField: 66 + k__BackingField: 0 _scenePathHash: 0 k__BackingField: 0 k__BackingField: 7168612627150811407 - _sceneNetworkObjects: [] --- !u!114 &-6616120420594439688 MonoBehaviour: m_ObjectHideFlags: 0 @@ -345,6 +353,28 @@ MonoBehaviour: _interpolation: 2 _clientAuthoritative: 1 _sendToOwner: 0 +--- !u!114 &-4703641988129057345 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7133738675197207439} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d00d6a1b2cb9fb54fbefde21a9eb88a4, type: 3} + m_Name: + m_EditorClassIdentifier: + _componentIndexCache: 1 + _addedNetworkObject: {fileID: 7942135432533076774} + _networkObjectCache: {fileID: 7942135432533076774} + _genericType: 13 + _specificType: 3 + _syncedConnections: 0 + connector: + unique: {fileID: 0} + wallCapPrefab: {fileID: 3591147544166670882, guid: 9682b163cae64f74a93b6e84ce84ae5b, type: 3} + doorType: 0 --- !u!1001 &2157331936072973061 PrefabInstance: m_ObjectHideFlags: 0 diff --git a/Assets/Content/WorldObjects/Structures/Floors/Tiles/Carpet/FancyCarpetRed.prefab b/Assets/Content/WorldObjects/Structures/Floors/Tiles/Carpet/FancyCarpetRed.prefab index 56a86f96c9..6a193a8085 100644 --- a/Assets/Content/WorldObjects/Structures/Floors/Tiles/Carpet/FancyCarpetRed.prefab +++ b/Assets/Content/WorldObjects/Structures/Floors/Tiles/Carpet/FancyCarpetRed.prefab @@ -115,7 +115,7 @@ MonoBehaviour: k__BackingField: 0 k__BackingField: {fileID: 0} _networkBehaviours: - - {fileID: 0} + - {fileID: 3040907911380660968} k__BackingField: {fileID: 0} k__BackingField: [] SerializedTransformProperties: @@ -144,12 +144,13 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: ef4340642b9b436498fe733f9329ac87, type: 3} m_Name: m_EditorClassIdentifier: - _componentIndexCache: 255 + _componentIndexCache: 0 _addedNetworkObject: {fileID: 6999522401175031449} - _networkObjectCache: {fileID: 0} + _networkObjectCache: {fileID: 6999522401175031449} _genericType: 9 _specificType: 5 - _advancedAdjacency: + _syncedConnections: 0 + advancedAdjacency: o: {fileID: 6313828114514605112, guid: 672e6a3c2617a374084ca41ab0f3b39d, type: 3} u: {fileID: 1428770310312528737, guid: 672e6a3c2617a374084ca41ab0f3b39d, type: 3} i: {fileID: -1544124563803091405, guid: 672e6a3c2617a374084ca41ab0f3b39d, type: 3} @@ -167,4 +168,3 @@ MonoBehaviour: xQuad: {fileID: 9022132694264211953, guid: 672e6a3c2617a374084ca41ab0f3b39d, type: 3} viewObstacles: [] opaque: 0 - _syncedConnections: 0 diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs new file mode 100644 index 0000000000..ca03ae756c --- /dev/null +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs @@ -0,0 +1,155 @@ +using FishNet.Object.Synchronizing; +using JetBrains.Annotations; +using SS3D.Core.Behaviours; +using SS3D.Logging; +using SS3D.Systems.Tile.Connections.AdjacencyTypes; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace SS3D.Systems.Tile.Connections +{ + public abstract class AbstractHorizontalConnector : NetworkActor, IAdjacencyConnector + { + + /// + /// A type that specifies to which objects to connect to. + /// + [Tooltip("Generic ID that adjacent objects must be to count. If empty, any id is accepted.")] + [SerializeField] + protected TileObjectGenericType _genericType; + + /// + /// Specific ID to differentiate objects when the generic is the same. + /// + [Tooltip("Specific ID to differentiate objects when the generic is the same.")] + [SerializeField] + protected TileObjectSpecificType _specificType; + + protected abstract IMeshAndDirectionResolver AdjacencyResolver { get; } + + protected AdjacencyMap _adjacencyMap; + + protected MeshFilter _filter; + protected PlacedTileObject _placedObject; + + public PlacedTileObject PlacedObject => _placedObject; + + [SyncVar(OnChange = nameof(SyncAdjacencies))] + private byte _syncedConnections; + + private bool _initialized; + + public override void OnStartClient() + { + base.OnStartClient(); + Setup(); + } + + private void Setup() + { + if (!_initialized) + { + _adjacencyMap = new AdjacencyMap(); + _filter = GetComponent(); + + _placedObject = GetComponent(); + if (_placedObject == null) + { + _genericType = TileObjectGenericType.None; + _specificType = TileObjectSpecificType.None; + } + else + { + _genericType = _placedObject.GenericType; + _specificType = _placedObject.SpecificType; + } + _initialized = true; + } + } + + public abstract bool IsConnected(Direction dir, PlacedTileObject neighbourObject); + + public virtual void UpdateAllConnections(PlacedTileObject[] neighbourObjects) + { + Setup(); + + bool changed = false; + for (int i = 0; i < neighbourObjects.Length; i++) + { + changed |= UpdateSingleConnection((Direction)i, neighbourObjects[i], true); + } + + if (changed) + { + UpdateMeshAndDirection(); + } + } + + public virtual bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObject, bool updateNeighbour) + { + Setup(); + + bool isConnected = IsConnected(dir, neighbourObject); + + // Update our neighbour as well + if (isConnected && updateNeighbour) + neighbourObject.UpdateSingleAdjacency(_placedObject, TileHelper.GetOpposite(dir)); + + bool isUpdated = _adjacencyMap.SetConnection(dir, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, isConnected)); + + if (isUpdated) + { + _syncedConnections = _adjacencyMap.SerializeToByte(); + UpdateMeshAndDirection(); + } + + return isUpdated; + } + + private void SyncAdjacencies(byte oldValue, byte newValue, bool asServer) + { + if (!asServer) + { + Setup(); + + _adjacencyMap.DeserializeFromByte(newValue); + UpdateMeshAndDirection(); + } + } + + + protected void UpdateMeshAndDirection() + { + // Some connectors might not have to update mesh or direction at all. + if (AdjacencyResolver == null) return; + + MeshDirectionInfo info = new(); + info = AdjacencyResolver.GetMeshAndDirection(_adjacencyMap); + + if (_filter == null) + { + Log.Warning(this, "Missing mesh {meshDirectionInfo}", Logs.Generic, info); + } + + _filter.mesh = info.Mesh; + + Quaternion localRotation = transform.localRotation; + Vector3 eulerRotation = localRotation.eulerAngles; + localRotation = Quaternion.Euler(eulerRotation.x, info.Rotation, eulerRotation.z); + + transform.localRotation = localRotation; + } + + /// + /// Sets a given direction blocked. This means that it will no longer be allowed to connect on that direction. + /// + /// + /// + public void SetBlockedDirection(Direction dir, bool value) + { + _adjacencyMap.SetConnection(dir, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, value)); + UpdateMeshAndDirection(); + } + } +} diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs.meta b/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs.meta new file mode 100644 index 0000000000..81ce7eb850 --- /dev/null +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4c00cf67fec139940a34518bf88d6691 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/AdvancedAdjacency.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/AdvancedAdjacency.cs index 731ed9c331..89cbef84be 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/AdvancedAdjacency.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/AdvancedAdjacency.cs @@ -7,7 +7,7 @@ namespace SS3D.Systems.Tile.Connections.AdjacencyTypes /// Adjacency type used for objects that do require complex connections. /// [Serializable] - public struct AdvancedConnector + public struct AdvancedConnector : IMeshAndDirectionResolver { [Tooltip("A mesh where no edges are connected")] public Mesh o; diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/OffsetAdjacency.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/OffsetAdjacency.cs index f833b63c23..ed43ce6edf 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/OffsetAdjacency.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/OffsetAdjacency.cs @@ -7,7 +7,7 @@ namespace SS3D.Systems.Tile.Connections.AdjacencyTypes /// Adjacency type used for objects that are not centred on a tile. Examples that use this are pipes (not the middle layer) /// [Serializable] - public struct OffsetConnector + public struct OffsetConnector : IMeshAndDirectionResolver { public enum OffsetOrientation { diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/SimpleAdjacency.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/SimpleAdjacency.cs index d6e1a459c2..1273974f0a 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/SimpleAdjacency.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/SimpleAdjacency.cs @@ -7,7 +7,7 @@ namespace SS3D.Systems.Tile.Connections.AdjacencyTypes /// Adjacency type used for objects that do not require complex connections. /// [Serializable] - public struct SimpleConnector + public struct SimpleConnector : IMeshAndDirectionResolver { [Tooltip("A mesh where no edges are connected")] public Mesh o; diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdvancedAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdvancedAdjacencyConnector.cs index 7af9443c62..a85c3fa33e 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdvancedAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdvancedAdjacencyConnector.cs @@ -9,82 +9,12 @@ namespace SS3D.Systems.Tile.Connections { - public class AdvancedAdjacencyConnector : NetworkBehaviour, IAdjacencyConnector + public class AdvancedAdjacencyConnector : AbstractHorizontalConnector, IAdjacencyConnector { - /// - /// A type that specifies to which objects to connect to. Must be set if cross connect is used. - /// - [Tooltip("Generic ID that adjacent objects must be to count. If empty, any id is accepted.")] - [SerializeField] - private TileObjectGenericType _genericType; + [SerializeField] private AdvancedConnector advancedAdjacency; + protected override IMeshAndDirectionResolver AdjacencyResolver => advancedAdjacency; - /// - /// Specific ID to differentiate objects when the generic is the same. - /// - [Tooltip("Specific ID to differentiate objects when the generic is the same.")] - [SerializeField] - private TileObjectSpecificType _specificType; - - [FormerlySerializedAs("advancedAdjacency")][SerializeField] private AdvancedConnector _advancedAdjacency; - - private AdjacencyMap _adjacencyMap; - - [SyncVar(OnChange = nameof(SyncAdjacencies))] - private byte _syncedConnections; - - private MeshFilter _filter; - private bool _initialized; - private PlacedTileObject _placedObject; - - public override void OnStartClient() - { - base.OnStartClient(); - Setup(); - } - - private void Setup() - { - if (!_initialized) - { - _adjacencyMap = new AdjacencyMap(); - _filter = GetComponent(); - - _placedObject = GetComponent(); - if (_placedObject == null) - { - _genericType = TileObjectGenericType.None; - _specificType = TileObjectSpecificType.None; - } - else - { - _genericType = _placedObject.GenericType; - _specificType = _placedObject.SpecificType; - } - _initialized = true; - } - } - - public bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObject, bool updateNeighbour) - { - Setup(); - bool isConnected = IsConnected(dir, neighbourObject); - bool isUpdated; - - // Update our neighbour as well - if (isConnected && updateNeighbour) - neighbourObject.UpdateSingleAdjacency(_placedObject, TileHelper.GetOpposite(dir)); - - isUpdated = _adjacencyMap.SetConnection(dir, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, isConnected)); - if (isUpdated) - { - _syncedConnections = _adjacencyMap.SerializeToByte(); - UpdateMeshAndDirection(); - } - - return isUpdated; - } - - public bool IsConnected(Direction dir, PlacedTileObject neighbourObject) + public override bool IsConnected(Direction dir, PlacedTileObject neighbourObject) { bool isConnected = false; if (neighbourObject) @@ -95,62 +25,5 @@ public bool IsConnected(Direction dir, PlacedTileObject neighbourObject) } return isConnected; } - - public void UpdateAllConnections(PlacedTileObject[] neighbourObjects) - { - Setup(); - - bool changed = false; - for (int i = 0; i < neighbourObjects.Length; i++) - { - changed |= UpdateSingleConnection((Direction)i, neighbourObjects[i], true); - } - - if (changed) - { - UpdateMeshAndDirection(); - } - } - - private void UpdateMeshAndDirection() - { - MeshDirectionInfo info = new(); - info = _advancedAdjacency.GetMeshAndDirection(_adjacencyMap); - - if (_filter == null) - { - Log.Warning(this, "Missing mesh {meshDirectionInfo}", Logs.Generic, info); - } - - _filter.mesh = info.Mesh; - - Quaternion localRotation = transform.localRotation; - Vector3 eulerRotation = localRotation.eulerAngles; - localRotation = Quaternion.Euler(eulerRotation.x, info.Rotation, eulerRotation.z); - - transform.localRotation = localRotation; - } - - private void SyncAdjacencies(byte oldValue, byte newValue, bool asServer) - { - if (!asServer) - { - Setup(); - - _adjacencyMap.DeserializeFromByte(newValue); - UpdateMeshAndDirection(); - } - } - - /// - /// Sets a given direction blocked. This means that it will no longer be allowed to connect on that direction. - /// - /// - /// - public void SetBlockedDirection(Direction dir, bool value) - { - _adjacencyMap.SetConnection(dir, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, value)); - UpdateMeshAndDirection(); - } } } diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs index 540a0b2171..ff2a2b8efd 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs @@ -6,14 +6,18 @@ namespace SS3D.Systems.Tile.Connections { - public class DoorAdjacencyConnector : NetworkBehaviour, IAdjacencyConnector + public class DoorAdjacencyConnector : AbstractHorizontalConnector, IAdjacencyConnector { - public enum DoorType + private enum DoorType { Single, Double }; + public Direction DoorDirection => _placedObject.Direction; + + protected override IMeshAndDirectionResolver AdjacencyResolver => null; + /** Based on peculiarities of the model, the appropriate position of the wall cap */ private const float WALL_CAP_DISTANCE_FROM_CENTRE = 0f; @@ -24,84 +28,21 @@ public enum DoorType [SerializeField] private DoorType doorType; - private TileMap map; - public PlacedTileObject placedTileObject; - - private bool _initialized = false; - // WallCap gameobjects, North, East, South, West. Null if not present. private GameObject[] wallCaps = new GameObject[4]; - private AdjacencyMap adjacencyMap = new AdjacencyMap(); - - public override void OnStartClient() - { - base.OnStartClient(); - Setup(); - } - - private void Setup() - { - if (!_initialized) - { - adjacencyMap = new AdjacencyMap(); - placedTileObject = GetComponent(); - _initialized = true; - } - } - - public void CleanAdjacencies() + public override bool UpdateSingleConnection(Direction direction, PlacedTileObject placedObject, bool updateNeighbours) { - if (!map) - { - map = GetComponentInParent(); - } - - var neighbourObjects = map.GetNeighbourPlacedObjects(TileLayer.Turf, transform.position); - for (int i = 0; i < neighbourObjects.Length; i++) - { - neighbourObjects[i]?.UpdateSingleAdjacency(placedTileObject, - TileHelper.GetOpposite((Direction)i)); - } - } - - public bool UpdateSingleConnection(Direction direction, PlacedTileObject placedObject, bool updateNeighbours) - { - Setup(); - - bool isConnected = IsConnected(direction, placedObject); - bool update = adjacencyMap.SetConnection(direction, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, isConnected)); - + bool update = base.UpdateSingleConnection(direction, placedObject, updateNeighbours); if (update) UpdateWallCaps(); - - return true; + return update; } - public void UpdateAllConnections(PlacedTileObject[] neighbourObjects) + public override void UpdateAllConnections(PlacedTileObject[] neighbourObjects) { - Setup(); - if (!map) - map = GetComponentInParent(); - - neighbourObjects = map.GetNeighbourPlacedObjects(TileLayer.Turf, transform.position); - PlacedTileObject currentObject = GetComponent(); - - bool changed = false; - for (int i = 0; i < neighbourObjects.Length; i++) - { - bool updatedSingle = false; - updatedSingle = UpdateSingleConnection((Direction)i, neighbourObjects[i], true); - if (updatedSingle && neighbourObjects[i]) - neighbourObjects[i].UpdateSingleAdjacency(currentObject, TileHelper.GetOpposite((Direction)i)); - - changed |= updatedSingle; - } - - if (changed) - { - UpdateWallCaps(); - } + base.UpdateAllConnections(neighbourObjects); + UpdateWallCaps(); } private void CreateWallCaps(bool isPresent, Direction direction) @@ -125,27 +66,26 @@ private void UpdateWallCaps() if (wallCapPrefab == null) return; - Direction outFacing = TileHelper.GetNextDir(GetDoorDirection()); + Direction outFacing = TileHelper.GetNextDir(DoorDirection); - bool isPresent = adjacencyMap.HasConnection(outFacing); + bool isPresent = _adjacencyMap.HasConnection(outFacing); CreateWallCaps(isPresent, outFacing); - isPresent = adjacencyMap.HasConnection(TileHelper.GetOpposite(outFacing)); + isPresent = _adjacencyMap.HasConnection(TileHelper.GetOpposite(outFacing)); CreateWallCaps(isPresent, TileHelper.GetOpposite(outFacing)); } /** - * Spawns a wall cap facing a direction, with appropriate position & settings - * Direction from the centre of the door - */ + * Spawns a wall cap facing a direction, with appropriate position & settings + * Direction from the centre of the door + */ private GameObject SpawnWallCap(Direction direction) { var wallCap = Instantiate(wallCapPrefab, transform); - Direction doorDirection = GetDoorDirection(); - Direction cardinalDirectionInput = TileHelper.GetRelativeDirection(direction, doorDirection); + Direction cardinalDirectionInput = TileHelper.GetRelativeDirection(direction, DoorDirection); var cardinal = TileHelper.ToCardinalVector(cardinalDirectionInput); - float rotation = TileHelper.AngleBetween(direction, doorDirection); + float rotation = TileHelper.AngleBetween(direction, DoorDirection); wallCap.transform.localRotation = Quaternion.Euler(0, rotation, 0); @@ -154,17 +94,7 @@ private GameObject SpawnWallCap(Direction direction) return wallCap; } - private Direction GetDoorDirection() - { - if (placedTileObject == null) - { - placedTileObject = GetComponent(); - } - - return placedTileObject.Direction; - } - - public bool IsConnected(Direction dir, PlacedTileObject neighbourObject) + public override bool IsConnected(Direction dir, PlacedTileObject neighbourObject) { return (neighbourObject && neighbourObject.HasAdjacencyConnector && neighbourObject.GenericType == TileObjectGenericType.Wall); diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/IMeshAndDirectionResolver.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/IMeshAndDirectionResolver.cs new file mode 100644 index 0000000000..f3fada01cb --- /dev/null +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/IMeshAndDirectionResolver.cs @@ -0,0 +1,11 @@ +using SS3D.Systems.Tile.Connections.AdjacencyTypes; +using SS3D.Systems.Tile.Connections; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using System; + +public interface IMeshAndDirectionResolver +{ + public MeshDirectionInfo GetMeshAndDirection(AdjacencyMap adjacencyMap); +} diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/IMeshAndDirectionResolver.cs.meta b/Assets/Scripts/SS3D/Systems/Tile/Connections/IMeshAndDirectionResolver.cs.meta new file mode 100644 index 0000000000..6232bcceec --- /dev/null +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/IMeshAndDirectionResolver.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 35605c4cd54efc2459983a7893c0c233 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs index 8e3fb31a6d..470aea8e0a 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs @@ -13,128 +13,12 @@ namespace SS3D.Systems.Tile.Connections /// /// Good for stuff that connects on the same layer only, horizontally, of the same specific and generic type. /// - public class SimpleAdjacencyConnector : NetworkBehaviour, IAdjacencyConnector + public class SimpleAdjacencyConnector : AbstractHorizontalConnector, IAdjacencyConnector { - /// - /// A type that specifies to which objects to connect to. Must be set if cross connect is used. - /// - [Tooltip("Generic ID that adjacent objects must be to count. If empty, any id is accepted.")] - [SerializeField] - private TileObjectGenericType _genericType; + [SerializeField] private SimpleConnector simpleAdjacency; + protected override IMeshAndDirectionResolver AdjacencyResolver => simpleAdjacency; - /// - /// Specific ID to differentiate objects when the generic is the same. - /// - [Tooltip("Specific ID to differentiate objects when the generic is the same.")] - [SerializeField] - private TileObjectSpecificType _specificType; - - [SerializeField] private SimpleConnector _simpleAdjacency; - - [SyncVar(OnChange = nameof(SyncAdjacencies))] - private byte _syncedConnections; - - private AdjacencyMap _adjacencyMap; - private MeshFilter _filter; - private bool _initialized; - private PlacedTileObject _placedObject; - - public override void OnStartClient() - { - base.OnStartClient(); - Setup(); - } - - private void Setup() - { - if (!_initialized) - { - _adjacencyMap = new AdjacencyMap(); - _filter = GetComponent(); - - _placedObject = GetComponent(); - if (_placedObject == null) - { - _genericType = TileObjectGenericType.None; - _specificType = TileObjectSpecificType.None; - } - else - { - _genericType = _placedObject.GenericType; - _specificType = _placedObject.SpecificType; - } - _initialized = true; - } - } - - private void SyncAdjacencies(byte oldValue, byte newValue, bool asServer) - { - if (!asServer) - { - Setup(); - - _adjacencyMap.DeserializeFromByte(newValue); - UpdateMeshAndDirection(); - } - } - - public bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObject, bool updateNeighbour) - { - Setup(); - - bool isConnected = IsConnected(dir, neighbourObject); - - // Update our neighbour as well - if (isConnected && updateNeighbour) - neighbourObject.UpdateSingleAdjacency(_placedObject, TileHelper.GetOpposite(dir)); - - bool isUpdated = _adjacencyMap.SetConnection(dir, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, isConnected)); - - if (isUpdated) - { - _syncedConnections = _adjacencyMap.SerializeToByte(); - UpdateMeshAndDirection(); - } - - return isUpdated; - } - - private void UpdateMeshAndDirection() - { - MeshDirectionInfo info = new(); - info = _simpleAdjacency.GetMeshAndDirection(_adjacencyMap); - - if (_filter == null) - { - Log.Warning(this, "Missing mesh {meshDirectionInfo}", Logs.Generic, info); - } - - _filter.mesh = info.Mesh; - - Quaternion localRotation = transform.localRotation; - Vector3 eulerRotation = localRotation.eulerAngles; - localRotation = Quaternion.Euler(eulerRotation.x, info.Rotation, eulerRotation.z); - - transform.localRotation = localRotation; - } - - public void UpdateAllConnections(PlacedTileObject[] neighbourObjects) - { - Setup(); - - bool changed = false; - for (int i = 0; i < neighbourObjects.Length; i++) - { - changed |= UpdateSingleConnection((Direction)i, neighbourObjects[i], true); - } - - if (changed) - { - UpdateMeshAndDirection(); - } - } - - public bool IsConnected(Direction dir, PlacedTileObject neighbourObject) + public override bool IsConnected(Direction dir, PlacedTileObject neighbourObject) { bool isConnected = false; if (neighbourObject != null) diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/WallAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/WallAdjacencyConnector.cs index 2801732ee1..790416df1f 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/WallAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/WallAdjacencyConnector.cs @@ -158,7 +158,7 @@ public void SetBlockedDirection(Direction dir, bool value) private bool IsConnectedToDoor(PlacedTileObject neighbourObject) { var doorConnector = neighbourObject.GetComponent(); - var door = doorConnector.placedTileObject; + var door = doorConnector.PlacedObject; if (door != null) { if (_placedObject.IsOnLeft(door) || _placedObject.IsOnRight(door)) From b7868886760fe3d59fb8e676832e918d2364cb29 Mon Sep 17 00:00:00 2001 From: stilnat Date: Sun, 8 Oct 2023 19:43:46 +0200 Subject: [PATCH 14/52] fix airlock generic type --- .../TileMap/Resources/Structures/Doors/AirlockCivilian.asset | 2 +- .../TileMap/Resources/Structures/Doors/AirlockSecurity.asset | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Assets/Content/Data/TileMap/Resources/Structures/Doors/AirlockCivilian.asset b/Assets/Content/Data/TileMap/Resources/Structures/Doors/AirlockCivilian.asset index cf4077ab61..e0ecc44f70 100644 --- a/Assets/Content/Data/TileMap/Resources/Structures/Doors/AirlockCivilian.asset +++ b/Assets/Content/Data/TileMap/Resources/Structures/Doors/AirlockCivilian.asset @@ -16,7 +16,7 @@ MonoBehaviour: prefab: {fileID: 7133738675197207439, guid: 84a5596b28f449e49bb34741abf89d30, type: 3} icon: {fileID: 0} layer: 1 - genericType: 3 + genericType: 13 specificType: 0 width: 1 height: 1 diff --git a/Assets/Content/Data/TileMap/Resources/Structures/Doors/AirlockSecurity.asset b/Assets/Content/Data/TileMap/Resources/Structures/Doors/AirlockSecurity.asset index d62f88f72a..d22fa049ef 100644 --- a/Assets/Content/Data/TileMap/Resources/Structures/Doors/AirlockSecurity.asset +++ b/Assets/Content/Data/TileMap/Resources/Structures/Doors/AirlockSecurity.asset @@ -16,7 +16,7 @@ MonoBehaviour: prefab: {fileID: 7133738675197207439, guid: d25b39d1e2379b64cba47629530ada78, type: 3} icon: {fileID: 0} layer: 1 - genericType: 3 + genericType: 13 specificType: 0 width: 1 height: 1 From f9f2f888228cc0b2b91bf56088c201539f806498 Mon Sep 17 00:00:00 2001 From: stilnat Date: Sun, 8 Oct 2023 22:11:09 +0200 Subject: [PATCH 15/52] trying to fix edge case for wall connector --- .../Connections/WallAdjacencyConnector.cs | 177 ++++-------------- 1 file changed, 40 insertions(+), 137 deletions(-) diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/WallAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/WallAdjacencyConnector.cs index 790416df1f..f7bfee79b7 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/WallAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/WallAdjacencyConnector.cs @@ -1,6 +1,7 @@ using DG.Tweening; using FishNet.Object; using FishNet.Object.Synchronizing; +using SS3D.Core; using SS3D.Logging; using SS3D.Systems.Tile.Connections; using SS3D.Systems.Tile.Connections.AdjacencyTypes; @@ -10,165 +11,51 @@ namespace SS3D.Systems.Tile.Connections { - public class WallAdjacencyConnector : NetworkBehaviour, IAdjacencyConnector + public class WallAdjacencyConnector : AbstractHorizontalConnector, IAdjacencyConnector { - /// - /// A type that specifies to which objects to connect to. Must be set if cross connect is used. - /// - [Tooltip("Generic ID that adjacent objects must be to count. If empty, any id is accepted.")] - [SerializeField] - private TileObjectGenericType _genericType; - - /// - /// Specific ID to differentiate objects when the generic is the same. - /// - [Tooltip("Specific ID to differentiate objects when the generic is the same.")] - [SerializeField] - private TileObjectSpecificType _specificType; [SerializeField] private AdvancedConnector _advancedAdjacency; - private AdjacencyMap _adjacencyMap; - - [SyncVar(OnChange = nameof(SyncAdjacencies))] - private byte _syncedConnections; - - private MeshFilter _filter; - private bool _initialized; - private PlacedTileObject _placedObject; + protected override IMeshAndDirectionResolver AdjacencyResolver => _advancedAdjacency; - public override void OnStartClient() - { - base.OnStartClient(); - Setup(); - } - - private void Setup() + private bool IsConnectedToDoor(PlacedTileObject neighbourObject) { - if (!_initialized) + var doorConnector = neighbourObject.GetComponent(); + var door = doorConnector.PlacedObject; + if (door != null) { - _adjacencyMap = new AdjacencyMap(); - _filter = GetComponent(); - - _placedObject = GetComponent(); - if (_placedObject == null) - { - _genericType = TileObjectGenericType.None; - _specificType = TileObjectSpecificType.None; - } - else + if (_placedObject.IsOnLeft(door) || _placedObject.IsOnRight(door)) { - _genericType = _placedObject.GenericType; - _specificType = _placedObject.SpecificType; + return true; } - _initialized = true; + } + return false; } - public bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObject, bool updateNeighbour) + private bool TryGetOnLeftOrRightDoor(out PlacedTileObject door) { - Setup(); - bool isConnected = IsConnected(dir, neighbourObject); - bool isUpdated = false; + var tileSystem = Subsystems.Get(); + var map = tileSystem.CurrentMap; + var neighbours = map.GetNeighbourPlacedObjects(_placedObject.Layer, _placedObject.transform.position); - if (neighbourObject != null) + foreach( var neighbour in neighbours ) { - isConnected = (neighbourObject && neighbourObject.HasAdjacencyConnector); + var doorConnector = neighbour?.GetComponent(); + if (doorConnector == null) continue; - isConnected &= neighbourObject.GenericType == TileObjectGenericType.Wall || - neighbourObject.GenericType == TileObjectGenericType.Door; - - if (neighbourObject.GetComponent() != null) + if (_placedObject.IsOnLeft(neighbour) || _placedObject.IsOnRight(neighbour)) { - isConnected &= IsConnectedToDoor(neighbourObject); - } - - // Update our neighbour as well - if (isConnected && updateNeighbour) - neighbourObject.UpdateSingleAdjacency(_placedObject, TileHelper.GetOpposite(dir)); - } - - isUpdated = _adjacencyMap.SetConnection(dir, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, isConnected)); - if (isUpdated) - { - _syncedConnections = _adjacencyMap.SerializeToByte(); - UpdateMeshAndDirection(); - } - - return isUpdated; - } - - public void UpdateAllConnections(PlacedTileObject[] neighbourObjects) - { - Setup(); - - bool changed = false; - for (int i = 0; i < neighbourObjects.Length; i++) - { - changed |= UpdateSingleConnection((Direction)i, neighbourObjects[i], true); - } - - if (changed) - { - UpdateMeshAndDirection(); - } - } - - private void UpdateMeshAndDirection() - { - MeshDirectionInfo info = new(); - info = _advancedAdjacency.GetMeshAndDirection(_adjacencyMap); - - if (_filter == null) - { - Log.Warning(this, "Missing mesh {meshDirectionInfo}", Logs.Generic, info); - } - - _filter.mesh = info.Mesh; - - Quaternion localRotation = transform.localRotation; - Vector3 eulerRotation = localRotation.eulerAngles; - localRotation = Quaternion.Euler(eulerRotation.x, info.Rotation, eulerRotation.z); - - transform.localRotation = localRotation; - } - - private void SyncAdjacencies(byte oldValue, byte newValue, bool asServer) - { - if (!asServer) - { - Setup(); - - _adjacencyMap.DeserializeFromByte(newValue); - UpdateMeshAndDirection(); - } - } - - /// - /// Sets a given direction blocked. This means that it will no longer be allowed to connect on that direction. - /// - /// - /// - public void SetBlockedDirection(Direction dir, bool value) - { - _adjacencyMap.SetConnection(dir, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, value)); - UpdateMeshAndDirection(); - } - - private bool IsConnectedToDoor(PlacedTileObject neighbourObject) - { - var doorConnector = neighbourObject.GetComponent(); - var door = doorConnector.PlacedObject; - if (door != null) - { - if (_placedObject.IsOnLeft(door) || _placedObject.IsOnRight(door)) + door = neighbour; return true; + } + } - + door = null; return false; } - public bool IsConnected(Direction dir, PlacedTileObject neighbourObject) + public override bool IsConnected(Direction dir, PlacedTileObject neighbourObject) { if(neighbourObject == null) return false; @@ -182,6 +69,22 @@ public bool IsConnected(Direction dir, PlacedTileObject neighbourObject) isConnected &= IsConnectedToDoor(neighbourObject); } + var tileSystem = Subsystems.Get(); + var map = tileSystem.CurrentMap; + + // Needed for a weird edge case when you put walls all around a door. Will avoid connecting + // to a wall in front or behind the door, if this wall is itself connected to door. + // This is to avoid the wall considering there's 3 connections, because if it does, it takes + // a L2 shape which allow to see through the wall. + + if(TryGetOnLeftOrRightDoor(out PlacedTileObject door) && neighbourObject.GetComponent() != null) + { + if (neighbourObject.IsInFront(door) || neighbourObject.IsBehind(door)) + { + isConnected &= false; + } + } + return isConnected; } } From f8256d61a658aa0b5ed7877429d6a6edde2e5947 Mon Sep 17 00:00:00 2001 From: stilnat Date: Mon, 9 Oct 2023 00:32:39 +0200 Subject: [PATCH 16/52] fix edge case wall, fix advancedAdjacency --- .../AdjacencyTypes/AdvancedAdjacency.cs | 6 +++--- .../Tile/PlacedObjects/PlacedTileObject.cs | 21 +++++++++++++++---- Assets/Scripts/SS3D/Systems/Tile/TileChunk.cs | 2 +- .../SS3D/Systems/Tile/TileConstants.cs | 11 ++++++++++ .../SS3D/Systems/Tile/TileConstants.cs.meta | 11 ++++++++++ Assets/Scripts/SS3D/Utils/MathUtility.cs | 14 +++++++++++++ Assets/Scripts/SS3D/Utils/MathUtility.cs.meta | 11 ++++++++++ 7 files changed, 68 insertions(+), 8 deletions(-) create mode 100644 Assets/Scripts/SS3D/Systems/Tile/TileConstants.cs create mode 100644 Assets/Scripts/SS3D/Systems/Tile/TileConstants.cs.meta create mode 100644 Assets/Scripts/SS3D/Utils/MathUtility.cs create mode 100644 Assets/Scripts/SS3D/Utils/MathUtility.cs.meta diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/AdvancedAdjacency.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/AdvancedAdjacency.cs index 89cbef84be..8ccdee58b7 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/AdvancedAdjacency.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/AdvancedAdjacency.cs @@ -97,9 +97,9 @@ public MeshDirectionInfo GetMeshAndDirection(AdjacencyMap adjacencyMap) case AdjacencyShape.XSingle: mesh = xSingle; Direction connectingDiagonal = adjacencyMap.GetSingleConnection(false); - rotation = connectingDiagonal == Direction.NorthEast ? 0f : - connectingDiagonal == Direction.SouthEast ? 90f : - connectingDiagonal == Direction.SouthWest ? 180f : -90f; + rotation = connectingDiagonal == Direction.NorthEast ? 180f : + connectingDiagonal == Direction.SouthEast ? 270f : + connectingDiagonal == Direction.SouthWest ? 0f : 90f; break; case AdjacencyShape.XOpposite: mesh = xOpposite; diff --git a/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs b/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs index 3576e32f46..aab39d1eb6 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs @@ -7,6 +7,7 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; +using math = SS3D.Utils.MathUtility; namespace SS3D.Systems.Tile { @@ -127,7 +128,10 @@ public SavedPlacedTileObject Save() /// public bool IsInFront(PlacedTileObject other) { - if(Origin == other.Origin + TileHelper.CoordinateDifferenceInFrontFacingDirection(other.Direction)) + Vector2Int diff = TileHelper.CoordinateDifferenceInFrontFacingDirection(other.Direction); + Vector2Int OtherMoved = new Vector2Int(math.mod(other.Origin.x + diff.x, TileConstants.ChunkSize), + math.mod(other.Origin.y + diff.y, TileConstants.ChunkSize)); + if (Origin == OtherMoved) return true; return false; @@ -138,7 +142,10 @@ public bool IsInFront(PlacedTileObject other) /// public bool IsBehind(PlacedTileObject other) { - if (Origin == other.Origin - TileHelper.CoordinateDifferenceInFrontFacingDirection(other.Direction)) + Vector2Int diff = TileHelper.CoordinateDifferenceInFrontFacingDirection(other.Direction); + Vector2Int OtherMoved = new Vector2Int(math.mod(other.Origin.x - diff.x, TileConstants.ChunkSize), + math.mod(other.Origin.y - diff.y, TileConstants.ChunkSize)); + if (Origin == OtherMoved) return true; return false; @@ -150,7 +157,10 @@ public bool IsBehind(PlacedTileObject other) public bool IsOnRight(PlacedTileObject other) { Direction dirOnRight = TileHelper.GetNextCardinalDir(other.Direction); - if (Origin == other.Origin + TileHelper.CoordinateDifferenceInFrontFacingDirection(dirOnRight)) + Vector2Int diff = TileHelper.CoordinateDifferenceInFrontFacingDirection(dirOnRight); + Vector2Int OtherMoved = new Vector2Int(math.mod(other.Origin.x + diff.x, TileConstants.ChunkSize), + math.mod(other.Origin.y + diff.y, TileConstants.ChunkSize)); + if (Origin == OtherMoved) return true; return false; @@ -162,7 +172,10 @@ public bool IsOnRight(PlacedTileObject other) public bool IsOnLeft(PlacedTileObject other) { Direction dirOnLeft = TileHelper.GetNextCardinalDir(other.Direction); - if (Origin == other.Origin - TileHelper.CoordinateDifferenceInFrontFacingDirection(dirOnLeft)) + Vector2Int diff = TileHelper.CoordinateDifferenceInFrontFacingDirection(dirOnLeft); + Vector2Int OtherMoved = new Vector2Int(math.mod(other.Origin.x - diff.x, TileConstants.ChunkSize), + math.mod(other.Origin.y - diff.y, TileConstants.ChunkSize)); + if (Origin == OtherMoved) return true; return false; diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileChunk.cs b/Assets/Scripts/SS3D/Systems/Tile/TileChunk.cs index 58bd4222c1..ee8a70fc35 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/TileChunk.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/TileChunk.cs @@ -17,7 +17,7 @@ public class TileChunk: NetworkBehaviour /// /// Number of TileObjects that should go in a chunk. 16 x 16 /// - public const int ChunkSize = 16; + public const int ChunkSize = TileConstants.ChunkSize; /// /// Grid for grouping TileObjects per layer. Can be used for walking through objects on the same layer fast. diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileConstants.cs b/Assets/Scripts/SS3D/Systems/Tile/TileConstants.cs new file mode 100644 index 0000000000..e104c8053f --- /dev/null +++ b/Assets/Scripts/SS3D/Systems/Tile/TileConstants.cs @@ -0,0 +1,11 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace SS3D.Systems.Tile +{ + public static class TileConstants + { + public const int ChunkSize = 16; + } +} diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileConstants.cs.meta b/Assets/Scripts/SS3D/Systems/Tile/TileConstants.cs.meta new file mode 100644 index 0000000000..eb2a00a2c6 --- /dev/null +++ b/Assets/Scripts/SS3D/Systems/Tile/TileConstants.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 99e1bf6c48bedee44bcba95eff20a9f3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/SS3D/Utils/MathUtility.cs b/Assets/Scripts/SS3D/Utils/MathUtility.cs new file mode 100644 index 0000000000..b94222ae9b --- /dev/null +++ b/Assets/Scripts/SS3D/Utils/MathUtility.cs @@ -0,0 +1,14 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace SS3D.Utils +{ + public static class MathUtility + { + public static int mod(int x, int m) + { + return (x % m + m) % m; + } + } +} diff --git a/Assets/Scripts/SS3D/Utils/MathUtility.cs.meta b/Assets/Scripts/SS3D/Utils/MathUtility.cs.meta new file mode 100644 index 0000000000..048f63afe8 --- /dev/null +++ b/Assets/Scripts/SS3D/Utils/MathUtility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fb04a492dbbe1234587b5fa00e5c5b19 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From d525f8b6e6821c49e2defa7072b1ab2c80297cac Mon Sep 17 00:00:00 2001 From: stilnat Date: Mon, 9 Oct 2023 09:46:12 +0200 Subject: [PATCH 17/52] fix pipes --- .../Pipes/Atmospherics/AtmosPipesL1.prefab | 65 +++++++------------ .../Pipes/Atmospherics/AtmosPipesL2.prefab | 60 +++++------------ .../Pipes/Atmospherics/AtmosPipesL3.prefab | 65 +++++++------------ .../Pipes/Atmospherics/AtmosPipesL4.prefab | 60 +++++------------ .../Pipes/Disposals/DisposalPipes.prefab | 4 +- .../AdjacencyTypes/OffsetAdjacency.cs | 6 +- .../AdjacencyTypes/SimpleAdjacency.cs | 8 +-- .../Connections/PipeAdjacencyConnector.cs | 27 ++++++++ .../PipeAdjacencyConnector.cs.meta | 11 ++++ 9 files changed, 131 insertions(+), 175 deletions(-) create mode 100644 Assets/Scripts/SS3D/Systems/Tile/Connections/PipeAdjacencyConnector.cs create mode 100644 Assets/Scripts/SS3D/Systems/Tile/Connections/PipeAdjacencyConnector.cs.meta diff --git a/Assets/Content/WorldObjects/Structures/Pipes/Atmospherics/AtmosPipesL1.prefab b/Assets/Content/WorldObjects/Structures/Pipes/Atmospherics/AtmosPipesL1.prefab index f6ec3550e6..ff354f853b 100644 --- a/Assets/Content/WorldObjects/Structures/Pipes/Atmospherics/AtmosPipesL1.prefab +++ b/Assets/Content/WorldObjects/Structures/Pipes/Atmospherics/AtmosPipesL1.prefab @@ -12,7 +12,7 @@ GameObject: - component: {fileID: -7727686409064562107} - component: {fileID: -1074477776341974781} - component: {fileID: -4998431523760016775} - - component: {fileID: -3045989321448604518} + - component: {fileID: 2229135679135330135} m_Layer: 0 m_Name: AtmosPipesL1 m_TagString: Untagged @@ -49,18 +49,25 @@ MonoBehaviour: m_EditorClassIdentifier: k__BackingField: 0 k__BackingField: 0 - _networkBehaviours: [] + k__BackingField: {fileID: 0} + _networkBehaviours: + - {fileID: 2229135679135330135} k__BackingField: {fileID: 0} k__BackingField: [] + SerializedTransformProperties: + Position: {x: 0, y: 0, z: 0} + Rotation: {x: 0, y: 0, z: 0, w: 0} + LocalScale: {x: 0, y: 0, z: 0} _isNetworked: 1 _isGlobal: 0 + _initializeOrder: 0 _defaultDespawnType: 0 NetworkObserver: {fileID: 0} - k__BackingField: -1 + k__BackingField: 80 + k__BackingField: 0 _scenePathHash: 0 k__BackingField: 0 k__BackingField: 8763632944401273062 - _sceneNetworkObjects: [] --- !u!33 &-1074477776341974781 MeshFilter: m_ObjectHideFlags: 0 @@ -111,7 +118,7 @@ MeshRenderer: m_SortingLayer: 0 m_SortingOrder: 0 m_AdditionalVertexStreams: {fileID: 0} ---- !u!114 &-3045989321448604518 +--- !u!114 &2229135679135330135 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -120,40 +127,17 @@ MonoBehaviour: m_GameObject: {fileID: 2802364579275783218} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 53a5cd0d46abb6d4d8686d11153009c2, type: 3} + m_Script: {fileID: 11500000, guid: 5a20750f8caa0c74a90e8083cc1cfc63, type: 3} m_Name: m_EditorClassIdentifier: - _componentIndexCache: 255 + _componentIndexCache: 0 _addedNetworkObject: {fileID: -7727686409064562107} - _networkObjectCache: {fileID: 0} - SelectedAdjacencyType: 2 - _simpleAdjacency: - o: {fileID: 0} - u: {fileID: 0} - i: {fileID: 0} - l: {fileID: 0} - t: {fileID: 0} - x: {fileID: 0} - _advancedAdjacency: - o: {fileID: 0} - u: {fileID: 0} - i: {fileID: 0} - lNone: {fileID: 0} - lSingle: {fileID: 0} - tNone: {fileID: 0} - tSingleRight: {fileID: 0} - tSingleLeft: {fileID: 0} - tDouble: {fileID: 0} - xNone: {fileID: 0} - xSingle: {fileID: 0} - xSide: {fileID: 0} - xOpposite: {fileID: 0} - xTriple: {fileID: 0} - xQuad: {fileID: 0} - viewObstacles: [] - opaque: 0 - _offsetAdjacency: - o: {fileID: -4913184590784469283, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} + _networkObjectCache: {fileID: -7727686409064562107} + _genericType: 1 + _specificType: 0 + _syncedConnections: 0 + _connector: + o: {fileID: 6771834481066591091, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} uNorth: {fileID: -4913184590784469283, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} uSouth: {fileID: -8982356636661201101, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} i: {fileID: 6771834481066591091, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} @@ -161,9 +145,8 @@ MonoBehaviour: lNW: {fileID: 2974487339661499261, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} lSE: {fileID: -8284340391569421606, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} lSW: {fileID: -710663454644857736, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} - tNEW: {fileID: -1565585996255746122, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} - tNSW: {fileID: -4415080472327585715, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} - tNSE: {fileID: -8084914691331622005, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} - tSWE: {fileID: -7828955826838884863, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} + tNEW: {fileID: -4415080472327585715, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} + tNSW: {fileID: -8084914691331622005, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} + tNSE: {fileID: -7828955826838884863, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} + tSWE: {fileID: -1565585996255746122, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} x: {fileID: 5978052073093224489, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} - _syncedConnections: 0 diff --git a/Assets/Content/WorldObjects/Structures/Pipes/Atmospherics/AtmosPipesL2.prefab b/Assets/Content/WorldObjects/Structures/Pipes/Atmospherics/AtmosPipesL2.prefab index f39e531cbc..2dc99469b5 100644 --- a/Assets/Content/WorldObjects/Structures/Pipes/Atmospherics/AtmosPipesL2.prefab +++ b/Assets/Content/WorldObjects/Structures/Pipes/Atmospherics/AtmosPipesL2.prefab @@ -12,7 +12,7 @@ GameObject: - component: {fileID: -7727686409064562107} - component: {fileID: -1074477776341974781} - component: {fileID: -4998431523760016775} - - component: {fileID: 3499879903942155925} + - component: {fileID: -6517569341867807780} m_Layer: 0 m_Name: AtmosPipesL2 m_TagString: Untagged @@ -49,18 +49,25 @@ MonoBehaviour: m_EditorClassIdentifier: k__BackingField: 0 k__BackingField: 0 - _networkBehaviours: [] + k__BackingField: {fileID: 0} + _networkBehaviours: + - {fileID: 0} k__BackingField: {fileID: 0} k__BackingField: [] + SerializedTransformProperties: + Position: {x: 0, y: 0, z: 0} + Rotation: {x: 0, y: 0, z: 0, w: 0} + LocalScale: {x: 0, y: 0, z: 0} _isNetworked: 1 _isGlobal: 0 + _initializeOrder: 0 _defaultDespawnType: 0 NetworkObserver: {fileID: 0} - k__BackingField: -1 + k__BackingField: 38 + k__BackingField: 0 _scenePathHash: 0 k__BackingField: 0 k__BackingField: 4320652076112192416 - _sceneNetworkObjects: [] --- !u!33 &-1074477776341974781 MeshFilter: m_ObjectHideFlags: 0 @@ -111,7 +118,7 @@ MeshRenderer: m_SortingLayer: 0 m_SortingOrder: 0 m_AdditionalVertexStreams: {fileID: 0} ---- !u!114 &3499879903942155925 +--- !u!114 &-6517569341867807780 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -120,50 +127,19 @@ MonoBehaviour: m_GameObject: {fileID: 2802364579275783218} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 53a5cd0d46abb6d4d8686d11153009c2, type: 3} + m_Script: {fileID: 11500000, guid: bc6615260753fbd48af09343d5d55332, type: 3} m_Name: m_EditorClassIdentifier: _componentIndexCache: 255 _addedNetworkObject: {fileID: -7727686409064562107} _networkObjectCache: {fileID: 0} - SelectedAdjacencyType: 0 - _simpleAdjacency: - o: {fileID: 6806338772768397739, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} + _genericType: 1 + _specificType: 0 + _syncedConnections: 0 + simpleAdjacency: + o: {fileID: 7036212505407254772, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} u: {fileID: 6806338772768397739, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} i: {fileID: 7036212505407254772, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} l: {fileID: -5256883499956230631, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} t: {fileID: 5050685859000262806, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} x: {fileID: -1235811834921956882, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} - _advancedAdjacency: - o: {fileID: 0} - u: {fileID: 0} - i: {fileID: 0} - lNone: {fileID: 0} - lSingle: {fileID: 0} - tNone: {fileID: 0} - tSingleRight: {fileID: 0} - tSingleLeft: {fileID: 0} - tDouble: {fileID: 0} - xNone: {fileID: 0} - xSingle: {fileID: 0} - xSide: {fileID: 0} - xOpposite: {fileID: 0} - xTriple: {fileID: 0} - xQuad: {fileID: 0} - viewObstacles: [] - opaque: 0 - _offsetAdjacency: - o: {fileID: 0} - uNorth: {fileID: 0} - uSouth: {fileID: 0} - i: {fileID: 0} - lNE: {fileID: 0} - lNW: {fileID: 0} - lSE: {fileID: 0} - lSW: {fileID: 0} - tNEW: {fileID: 0} - tNSW: {fileID: 0} - tNSE: {fileID: 0} - tSWE: {fileID: 0} - x: {fileID: 0} - _syncedConnections: 0 diff --git a/Assets/Content/WorldObjects/Structures/Pipes/Atmospherics/AtmosPipesL3.prefab b/Assets/Content/WorldObjects/Structures/Pipes/Atmospherics/AtmosPipesL3.prefab index 54c44ee689..76016c487f 100644 --- a/Assets/Content/WorldObjects/Structures/Pipes/Atmospherics/AtmosPipesL3.prefab +++ b/Assets/Content/WorldObjects/Structures/Pipes/Atmospherics/AtmosPipesL3.prefab @@ -12,7 +12,7 @@ GameObject: - component: {fileID: -7727686409064562107} - component: {fileID: -1074477776341974781} - component: {fileID: -4998431523760016775} - - component: {fileID: 7129601957079650942} + - component: {fileID: -4640464187372749131} m_Layer: 0 m_Name: AtmosPipesL3 m_TagString: Untagged @@ -49,18 +49,25 @@ MonoBehaviour: m_EditorClassIdentifier: k__BackingField: 0 k__BackingField: 0 - _networkBehaviours: [] + k__BackingField: {fileID: 0} + _networkBehaviours: + - {fileID: -4640464187372749131} k__BackingField: {fileID: 0} k__BackingField: [] + SerializedTransformProperties: + Position: {x: 0, y: 0, z: 0} + Rotation: {x: 0, y: 0, z: 0, w: 0} + LocalScale: {x: 0, y: 0, z: 0} _isNetworked: 1 _isGlobal: 0 + _initializeOrder: 0 _defaultDespawnType: 0 NetworkObserver: {fileID: 0} - k__BackingField: -1 + k__BackingField: 30 + k__BackingField: 0 _scenePathHash: 0 k__BackingField: 0 k__BackingField: 3164900015479896782 - _sceneNetworkObjects: [] --- !u!33 &-1074477776341974781 MeshFilter: m_ObjectHideFlags: 0 @@ -111,7 +118,7 @@ MeshRenderer: m_SortingLayer: 0 m_SortingOrder: 0 m_AdditionalVertexStreams: {fileID: 0} ---- !u!114 &7129601957079650942 +--- !u!114 &-4640464187372749131 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -120,40 +127,17 @@ MonoBehaviour: m_GameObject: {fileID: 2802364579275783218} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 53a5cd0d46abb6d4d8686d11153009c2, type: 3} + m_Script: {fileID: 11500000, guid: 5a20750f8caa0c74a90e8083cc1cfc63, type: 3} m_Name: m_EditorClassIdentifier: - _componentIndexCache: 255 + _componentIndexCache: 0 _addedNetworkObject: {fileID: -7727686409064562107} - _networkObjectCache: {fileID: 0} - SelectedAdjacencyType: 2 - _simpleAdjacency: - o: {fileID: 0} - u: {fileID: 0} - i: {fileID: 0} - l: {fileID: 0} - t: {fileID: 0} - x: {fileID: 0} - _advancedAdjacency: - o: {fileID: 0} - u: {fileID: 0} - i: {fileID: 0} - lNone: {fileID: 0} - lSingle: {fileID: 0} - tNone: {fileID: 0} - tSingleRight: {fileID: 0} - tSingleLeft: {fileID: 0} - tDouble: {fileID: 0} - xNone: {fileID: 0} - xSingle: {fileID: 0} - xSide: {fileID: 0} - xOpposite: {fileID: 0} - xTriple: {fileID: 0} - xQuad: {fileID: 0} - viewObstacles: [] - opaque: 0 - _offsetAdjacency: - o: {fileID: 3280808188743794696, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} + _networkObjectCache: {fileID: -7727686409064562107} + _genericType: 0 + _specificType: 0 + _syncedConnections: 0 + _connector: + o: {fileID: -1444037753683383277, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} uNorth: {fileID: 3280808188743794696, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} uSouth: {fileID: -3806360359158251138, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} i: {fileID: -1444037753683383277, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} @@ -161,9 +145,8 @@ MonoBehaviour: lNW: {fileID: -7474402538799832598, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} lSE: {fileID: -5765311014171972663, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} lSW: {fileID: -2676322450833060381, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} - tNEW: {fileID: -599376364307708729, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} - tNSW: {fileID: -1086356526325406277, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} - tNSE: {fileID: -7630757551065068057, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} - tSWE: {fileID: 35210991009650323, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} + tSWE: {fileID: -599376364307708729, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} + tNEW: {fileID: -1086356526325406277, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} + tNSW: {fileID: -7630757551065068057, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} + tNSE: {fileID: 35210991009650323, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} x: {fileID: 8288866924156647885, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} - _syncedConnections: 0 diff --git a/Assets/Content/WorldObjects/Structures/Pipes/Atmospherics/AtmosPipesL4.prefab b/Assets/Content/WorldObjects/Structures/Pipes/Atmospherics/AtmosPipesL4.prefab index bd40d773c5..180167eab8 100644 --- a/Assets/Content/WorldObjects/Structures/Pipes/Atmospherics/AtmosPipesL4.prefab +++ b/Assets/Content/WorldObjects/Structures/Pipes/Atmospherics/AtmosPipesL4.prefab @@ -12,7 +12,7 @@ GameObject: - component: {fileID: -7727686409064562107} - component: {fileID: -1074477776341974781} - component: {fileID: -4998431523760016775} - - component: {fileID: 5864662064664276516} + - component: {fileID: 4607519100304452876} m_Layer: 0 m_Name: AtmosPipesL4 m_TagString: Untagged @@ -49,18 +49,25 @@ MonoBehaviour: m_EditorClassIdentifier: k__BackingField: 0 k__BackingField: 0 - _networkBehaviours: [] + k__BackingField: {fileID: 0} + _networkBehaviours: + - {fileID: 0} k__BackingField: {fileID: 0} k__BackingField: [] + SerializedTransformProperties: + Position: {x: 0, y: 0, z: 0} + Rotation: {x: 0, y: 0, z: 0, w: 0} + LocalScale: {x: 0, y: 0, z: 0} _isNetworked: 1 _isGlobal: 0 + _initializeOrder: 0 _defaultDespawnType: 0 NetworkObserver: {fileID: 0} - k__BackingField: -1 + k__BackingField: 65535 + k__BackingField: 0 _scenePathHash: 0 k__BackingField: 0 k__BackingField: 4544942681371158276 - _sceneNetworkObjects: [] --- !u!33 &-1074477776341974781 MeshFilter: m_ObjectHideFlags: 0 @@ -111,7 +118,7 @@ MeshRenderer: m_SortingLayer: 0 m_SortingOrder: 0 m_AdditionalVertexStreams: {fileID: 0} ---- !u!114 &5864662064664276516 +--- !u!114 &4607519100304452876 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -120,50 +127,19 @@ MonoBehaviour: m_GameObject: {fileID: 2802364579275783218} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 53a5cd0d46abb6d4d8686d11153009c2, type: 3} + m_Script: {fileID: 11500000, guid: bc6615260753fbd48af09343d5d55332, type: 3} m_Name: m_EditorClassIdentifier: _componentIndexCache: 255 _addedNetworkObject: {fileID: -7727686409064562107} _networkObjectCache: {fileID: 0} - SelectedAdjacencyType: 0 - _simpleAdjacency: - o: {fileID: 6854876588585920493, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} + _genericType: 1 + _specificType: 0 + _syncedConnections: 0 + simpleAdjacency: + o: {fileID: 5763238997108834030, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} u: {fileID: 6854876588585920493, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} i: {fileID: 5763238997108834030, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} l: {fileID: 3234200807627564179, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} t: {fileID: 6267177117203792215, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} x: {fileID: -2318244788085852191, guid: 013a2e526b13e1849b628bdc478f9c03, type: 3} - _advancedAdjacency: - o: {fileID: 0} - u: {fileID: 0} - i: {fileID: 0} - lNone: {fileID: 0} - lSingle: {fileID: 0} - tNone: {fileID: 0} - tSingleRight: {fileID: 0} - tSingleLeft: {fileID: 0} - tDouble: {fileID: 0} - xNone: {fileID: 0} - xSingle: {fileID: 0} - xSide: {fileID: 0} - xOpposite: {fileID: 0} - xTriple: {fileID: 0} - xQuad: {fileID: 0} - viewObstacles: [] - opaque: 0 - _offsetAdjacency: - o: {fileID: 0} - uNorth: {fileID: 0} - uSouth: {fileID: 0} - i: {fileID: 0} - lNE: {fileID: 0} - lNW: {fileID: 0} - lSE: {fileID: 0} - lSW: {fileID: 0} - tNEW: {fileID: 0} - tNSW: {fileID: 0} - tNSE: {fileID: 0} - tSWE: {fileID: 0} - x: {fileID: 0} - _syncedConnections: 0 diff --git a/Assets/Content/WorldObjects/Structures/Pipes/Disposals/DisposalPipes.prefab b/Assets/Content/WorldObjects/Structures/Pipes/Disposals/DisposalPipes.prefab index 0a8443be41..9cef843cae 100644 --- a/Assets/Content/WorldObjects/Structures/Pipes/Disposals/DisposalPipes.prefab +++ b/Assets/Content/WorldObjects/Structures/Pipes/Disposals/DisposalPipes.prefab @@ -135,11 +135,11 @@ MonoBehaviour: _networkObjectCache: {fileID: -7727686409064562107} _genericType: 1 _specificType: 0 - _simpleAdjacency: + _syncedConnections: 0 + simpleAdjacency: o: {fileID: -6725049071555871357, guid: 8fa7941da6a6a8d4da717a97b11b2621, type: 3} u: {fileID: -6725049071555871357, guid: 8fa7941da6a6a8d4da717a97b11b2621, type: 3} i: {fileID: -6725049071555871357, guid: 8fa7941da6a6a8d4da717a97b11b2621, type: 3} l: {fileID: -7002929985465626668, guid: 8fa7941da6a6a8d4da717a97b11b2621, type: 3} t: {fileID: 7767200051770316982, guid: 8fa7941da6a6a8d4da717a97b11b2621, type: 3} x: {fileID: -7993494061914831054, guid: 8fa7941da6a6a8d4da717a97b11b2621, type: 3} - _syncedConnections: 0 diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/OffsetAdjacency.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/OffsetAdjacency.cs index ed43ce6edf..fd8df908eb 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/OffsetAdjacency.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/OffsetAdjacency.cs @@ -42,14 +42,14 @@ public enum OffsetOrientation public Mesh lSE; [Tooltip("A mesh where the south & west edges are connected")] public Mesh lSW; + [Tooltip("A mesh where the South, west, & east edges are connected")] + public Mesh tSWE; [Tooltip("A mesh where the north, east, & west edges are connected")] public Mesh tNEW; [Tooltip("A mesh where the north, south, & west edges are connected")] public Mesh tNSW; [Tooltip("A mesh where the north, south, & east edges are connected")] public Mesh tNSE; - [Tooltip("A mesh where the South, west, & east edges are connected")] - public Mesh tSWE; [Tooltip("A mesh where all edges are connected")] public Mesh x; @@ -81,7 +81,7 @@ public MeshDirectionInfo GetMeshAndDirection(AdjacencyMap adjacencyMap) case AdjacencyShape.USouth: mesh = uSouth; _orientation = OffsetOrientation.USouth; - rotation = TileHelper.AngleBetween(Direction.South, adjacencyMap.GetSingleNonConnection()); + rotation = TileHelper.AngleBetween(Direction.South, adjacencyMap.GetSingleConnection()); break; case AdjacencyShape.I: mesh = i; diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/SimpleAdjacency.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/SimpleAdjacency.cs index 1273974f0a..ab98abd2ff 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/SimpleAdjacency.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/SimpleAdjacency.cs @@ -36,19 +36,19 @@ public MeshDirectionInfo GetMeshAndDirection(AdjacencyMap adjacencyMap) break; case AdjacencyShape.U: mesh = u; - rotation = TileHelper.AngleBetween(Direction.South, adjacencyMap.GetSingleConnection()); + rotation = TileHelper.AngleBetween(Direction.North, adjacencyMap.GetSingleConnection()); break; case AdjacencyShape.I: mesh = i; - rotation = TileHelper.AngleBetween(Direction.South, adjacencyMap.HasConnection(Direction.South) ? Direction.South : Direction.West); + rotation = TileHelper.AngleBetween(Direction.North, adjacencyMap.HasConnection(Direction.South) ? Direction.South : Direction.West); break; case AdjacencyShape.L: mesh = l; - rotation = TileHelper.AngleBetween(Direction.SouthWest, adjacencyMap.GetDirectionBetweenTwoConnections()); + rotation = TileHelper.AngleBetween(Direction.NorthEast, adjacencyMap.GetDirectionBetweenTwoConnections()); break; case AdjacencyShape.T: mesh = t; - rotation = TileHelper.AngleBetween(Direction.South, adjacencyMap.GetSingleNonConnection()); + rotation = TileHelper.AngleBetween(Direction.North, adjacencyMap.GetSingleNonConnection()); break; case AdjacencyShape.X: mesh = x; diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/PipeAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/PipeAdjacencyConnector.cs new file mode 100644 index 0000000000..9e742f59dd --- /dev/null +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/PipeAdjacencyConnector.cs @@ -0,0 +1,27 @@ +using SS3D.Systems.Tile.Connections.AdjacencyTypes; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + + +namespace SS3D.Systems.Tile.Connections +{ + public class PipeAdjacencyConnector : AbstractHorizontalConnector + { + [SerializeField] + private OffsetConnector _connector; + protected override IMeshAndDirectionResolver AdjacencyResolver => _connector; + + public override bool IsConnected(Direction dir, PlacedTileObject neighbourObject) + { + bool isConnected = false; + if (neighbourObject != null) + { + isConnected = (neighbourObject && neighbourObject.HasAdjacencyConnector); + isConnected &= neighbourObject.GenericType == _genericType || _genericType == TileObjectGenericType.None; + isConnected &= neighbourObject.SpecificType == _specificType || _specificType == TileObjectSpecificType.None; + } + return isConnected; + } + } +} diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/PipeAdjacencyConnector.cs.meta b/Assets/Scripts/SS3D/Systems/Tile/Connections/PipeAdjacencyConnector.cs.meta new file mode 100644 index 0000000000..1507fff956 --- /dev/null +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/PipeAdjacencyConnector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5a20750f8caa0c74a90e8083cc1cfc63 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 6db61b240f6485e26baaf2e7ec134c675d42c3bb Mon Sep 17 00:00:00 2001 From: stilnat Date: Mon, 9 Oct 2023 10:52:50 +0200 Subject: [PATCH 18/52] change pipe tile layers --- .../Pipes/Atmospherics/AtmosphericsPipesL1.asset | 4 ++-- .../Pipes/Atmospherics/AtmosphericsPipesL2.asset | 4 ++-- .../Pipes/Atmospherics/AtmosphericsPipesL3.asset | 4 ++-- .../Pipes/Atmospherics/AtmosphericsPipesL4.asset | 2 +- Assets/Scripts/SS3D/Systems/Tile/Enums/TileLayer.cs | 9 ++++++--- .../SS3D/Systems/Tile/TileMapCreator/TileMapCreator.cs | 7 +++++-- 6 files changed, 18 insertions(+), 12 deletions(-) diff --git a/Assets/Content/Data/TileMap/Resources/Structures/Pipes/Atmospherics/AtmosphericsPipesL1.asset b/Assets/Content/Data/TileMap/Resources/Structures/Pipes/Atmospherics/AtmosphericsPipesL1.asset index e3a37203ec..09e2a329d7 100644 --- a/Assets/Content/Data/TileMap/Resources/Structures/Pipes/Atmospherics/AtmosphericsPipesL1.asset +++ b/Assets/Content/Data/TileMap/Resources/Structures/Pipes/Atmospherics/AtmosphericsPipesL1.asset @@ -15,8 +15,8 @@ MonoBehaviour: nameString: pipe_atmos1 prefab: {fileID: 2802364579275783218, guid: de6f06ad18d50134295959f438ba9c5d, type: 3} icon: {fileID: 0} - layer: 4 - genericType: 0 + layer: 11 + genericType: 1 specificType: 0 width: 1 height: 1 diff --git a/Assets/Content/Data/TileMap/Resources/Structures/Pipes/Atmospherics/AtmosphericsPipesL2.asset b/Assets/Content/Data/TileMap/Resources/Structures/Pipes/Atmospherics/AtmosphericsPipesL2.asset index 9943832656..75925e4e26 100644 --- a/Assets/Content/Data/TileMap/Resources/Structures/Pipes/Atmospherics/AtmosphericsPipesL2.asset +++ b/Assets/Content/Data/TileMap/Resources/Structures/Pipes/Atmospherics/AtmosphericsPipesL2.asset @@ -15,8 +15,8 @@ MonoBehaviour: nameString: pipe_atmos2 prefab: {fileID: 2802364579275783218, guid: 251dc2a5fbda518429c8205c3b62165f, type: 3} icon: {fileID: 0} - layer: 4 - genericType: 0 + layer: 10 + genericType: 1 specificType: 0 width: 1 height: 1 diff --git a/Assets/Content/Data/TileMap/Resources/Structures/Pipes/Atmospherics/AtmosphericsPipesL3.asset b/Assets/Content/Data/TileMap/Resources/Structures/Pipes/Atmospherics/AtmosphericsPipesL3.asset index bf645d57bd..023a91a060 100644 --- a/Assets/Content/Data/TileMap/Resources/Structures/Pipes/Atmospherics/AtmosphericsPipesL3.asset +++ b/Assets/Content/Data/TileMap/Resources/Structures/Pipes/Atmospherics/AtmosphericsPipesL3.asset @@ -15,8 +15,8 @@ MonoBehaviour: nameString: pipe_atmos3 prefab: {fileID: 2802364579275783218, guid: adc07a7f0fee8304691f45a201509b13, type: 3} icon: {fileID: 0} - layer: 4 - genericType: 0 + layer: 12 + genericType: 1 specificType: 0 width: 1 height: 1 diff --git a/Assets/Content/Data/TileMap/Resources/Structures/Pipes/Atmospherics/AtmosphericsPipesL4.asset b/Assets/Content/Data/TileMap/Resources/Structures/Pipes/Atmospherics/AtmosphericsPipesL4.asset index 16fa40114a..1fac33e096 100644 --- a/Assets/Content/Data/TileMap/Resources/Structures/Pipes/Atmospherics/AtmosphericsPipesL4.asset +++ b/Assets/Content/Data/TileMap/Resources/Structures/Pipes/Atmospherics/AtmosphericsPipesL4.asset @@ -16,7 +16,7 @@ MonoBehaviour: prefab: {fileID: 2802364579275783218, guid: 48efd00c91c310e4bb965d025c63b3ba, type: 3} icon: {fileID: 0} layer: 4 - genericType: 0 + genericType: 1 specificType: 0 width: 1 height: 1 diff --git a/Assets/Scripts/SS3D/Systems/Tile/Enums/TileLayer.cs b/Assets/Scripts/SS3D/Systems/Tile/Enums/TileLayer.cs index 4ad333909d..b29623d8b4 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Enums/TileLayer.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Enums/TileLayer.cs @@ -1,4 +1,4 @@ -using System.Collections; +using System.Collections; using System.Collections.Generic; using UnityEngine; @@ -13,11 +13,14 @@ public enum TileLayer Turf, Wire, Disposal, - Pipes, + PipeSurface, WallMountHigh, WallMountLow, FurnitureBase, FurnitureTop, - Overlays + Overlays, + PipeMiddle, + PipeLeft, + PipeRight, } } \ No newline at end of file diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileMapCreator/TileMapCreator.cs b/Assets/Scripts/SS3D/Systems/Tile/TileMapCreator/TileMapCreator.cs index 07601ef027..792a45c1b3 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/TileMapCreator/TileMapCreator.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/TileMapCreator/TileMapCreator.cs @@ -1,4 +1,4 @@ -using Coimbra; +using Coimbra; using FishNet.Connection; using FishNet.Object; using SS3D.Core; @@ -434,7 +434,10 @@ public void OnDropDownChange() { TileLayer.Wire, TileLayer.Disposal, - TileLayer.Pipes + TileLayer.PipeLeft, + TileLayer.PipeRight, + TileLayer.PipeSurface, + TileLayer.PipeMiddle }, false); break; From 9a3bf00003d9349f911eb004d576fe356ba664d1 Mon Sep 17 00:00:00 2001 From: stilnat Date: Mon, 9 Oct 2023 11:02:39 +0200 Subject: [PATCH 19/52] fix generic and specific type editablke in editor (should not) --- .../Generic/Surfaces/Tables/TablePoker.asset | 4 +- .../Generic/Surfaces/Tables/TableWood.asset | 4 +- .../Generic/Surfaces/Tables/TablePoker.prefab | 98 ++++++++--------- .../Generic/Surfaces/Tables/TableWood.prefab | 100 ++++++++---------- .../AbstractHorizontalConnector.cs | 13 +-- 5 files changed, 91 insertions(+), 128 deletions(-) diff --git a/Assets/Content/Data/TileMap/Resources/Furniture/Generic/Surfaces/Tables/TablePoker.asset b/Assets/Content/Data/TileMap/Resources/Furniture/Generic/Surfaces/Tables/TablePoker.asset index 56f672ec91..ad50653bbf 100644 --- a/Assets/Content/Data/TileMap/Resources/Furniture/Generic/Surfaces/Tables/TablePoker.asset +++ b/Assets/Content/Data/TileMap/Resources/Furniture/Generic/Surfaces/Tables/TablePoker.asset @@ -16,7 +16,7 @@ MonoBehaviour: prefab: {fileID: 3879826479501069436, guid: ebddb1721dcbe36499e4d093e5a7ff09, type: 3} icon: {fileID: 0} layer: 7 - genericType: 0 - specificType: 0 + genericType: 7 + specificType: 2 width: 1 height: 1 diff --git a/Assets/Content/Data/TileMap/Resources/Furniture/Generic/Surfaces/Tables/TableWood.asset b/Assets/Content/Data/TileMap/Resources/Furniture/Generic/Surfaces/Tables/TableWood.asset index b8cb704bf0..c8aa45c947 100644 --- a/Assets/Content/Data/TileMap/Resources/Furniture/Generic/Surfaces/Tables/TableWood.asset +++ b/Assets/Content/Data/TileMap/Resources/Furniture/Generic/Surfaces/Tables/TableWood.asset @@ -16,7 +16,7 @@ MonoBehaviour: prefab: {fileID: 3879826479501069436, guid: 5e8a02c5ce0073644ac01bdb55d72a70, type: 3} icon: {fileID: 0} layer: 7 - genericType: 0 - specificType: 0 + genericType: 7 + specificType: 4 width: 1 height: 1 diff --git a/Assets/Content/WorldObjects/Furniture/Generic/Surfaces/Tables/TablePoker.prefab b/Assets/Content/WorldObjects/Furniture/Generic/Surfaces/Tables/TablePoker.prefab index 6a3f885b7a..4157880e4d 100644 --- a/Assets/Content/WorldObjects/Furniture/Generic/Surfaces/Tables/TablePoker.prefab +++ b/Assets/Content/WorldObjects/Furniture/Generic/Surfaces/Tables/TablePoker.prefab @@ -12,8 +12,8 @@ GameObject: - component: {fileID: 72636884723696477} - component: {fileID: 4229887190052127918} - component: {fileID: 7514870336629038223} - - component: {fileID: 2413604077021371004} - component: {fileID: 5716146803221059512} + - component: {fileID: 5329512703703213614} m_Layer: 0 m_Name: TablePoker m_TagString: Untagged @@ -99,7 +99,7 @@ BoxCollider: serializedVersion: 2 m_Size: {x: 1, y: 0.75, z: 1} m_Center: {x: 0, y: 0.375, z: 0} ---- !u!114 &2413604077021371004 +--- !u!114 &5716146803221059512 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -108,21 +108,49 @@ MonoBehaviour: m_GameObject: {fileID: 3879826479501069436} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 53a5cd0d46abb6d4d8686d11153009c2, type: 3} + m_Script: {fileID: 11500000, guid: 26b716c41e9b56b4baafaf13a523ba2e, type: 3} m_Name: m_EditorClassIdentifier: - _componentIndexCache: 0 + k__BackingField: 0 + k__BackingField: 0 + k__BackingField: {fileID: 0} + _networkBehaviours: + - {fileID: 0} + k__BackingField: {fileID: 0} + k__BackingField: [] + SerializedTransformProperties: + Position: {x: 0, y: 0, z: 0} + Rotation: {x: 0, y: 0, z: 0, w: 0} + LocalScale: {x: 0, y: 0, z: 0} + _isNetworked: 1 + _isGlobal: 0 + _initializeOrder: 0 + _defaultDespawnType: 0 + NetworkObserver: {fileID: 0} + k__BackingField: 65535 + k__BackingField: 0 + _scenePathHash: 0 + k__BackingField: 0 + k__BackingField: 1168477607207407788 +--- !u!114 &5329512703703213614 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3879826479501069436} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ef4340642b9b436498fe733f9329ac87, type: 3} + m_Name: + m_EditorClassIdentifier: + _componentIndexCache: 255 _addedNetworkObject: {fileID: 5716146803221059512} - _networkObjectCache: {fileID: 5716146803221059512} - SelectedAdjacencyType: 1 - _simpleAdjacency: - o: {fileID: 0} - u: {fileID: 0} - i: {fileID: 0} - l: {fileID: 0} - t: {fileID: 0} - x: {fileID: 0} - _advancedAdjacency: + _networkObjectCache: {fileID: 0} + _genericType: 7 + _specificType: 2 + _syncedConnections: 0 + advancedAdjacency: o: {fileID: 24074734363293705, guid: 32ccf9db762cc7c4f8f4af524e3e7ee7, type: 3} u: {fileID: -9005001895540637488, guid: 32ccf9db762cc7c4f8f4af524e3e7ee7, type: 3} i: {fileID: 4166674255622024098, guid: 32ccf9db762cc7c4f8f4af524e3e7ee7, type: 3} @@ -140,45 +168,3 @@ MonoBehaviour: xQuad: {fileID: -3265789347127315492, guid: 32ccf9db762cc7c4f8f4af524e3e7ee7, type: 3} viewObstacles: [] opaque: 0 - _offsetAdjacency: - o: {fileID: 0} - uNorth: {fileID: 0} - uSouth: {fileID: 0} - i: {fileID: 0} - lNE: {fileID: 0} - lNW: {fileID: 0} - lSE: {fileID: 0} - lSW: {fileID: 0} - tNEW: {fileID: 0} - tNSW: {fileID: 0} - tNSE: {fileID: 0} - tSWE: {fileID: 0} - x: {fileID: 0} - _syncedConnections: 0 ---- !u!114 &5716146803221059512 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3879826479501069436} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 26b716c41e9b56b4baafaf13a523ba2e, type: 3} - m_Name: - m_EditorClassIdentifier: - k__BackingField: 0 - k__BackingField: 0 - _networkBehaviours: - - {fileID: 2413604077021371004} - k__BackingField: {fileID: 0} - k__BackingField: [] - _isNetworked: 1 - _isGlobal: 0 - _defaultDespawnType: 0 - NetworkObserver: {fileID: 0} - k__BackingField: -1 - _scenePathHash: 0 - k__BackingField: 0 - k__BackingField: 1168477607207407788 - _sceneNetworkObjects: [] diff --git a/Assets/Content/WorldObjects/Furniture/Generic/Surfaces/Tables/TableWood.prefab b/Assets/Content/WorldObjects/Furniture/Generic/Surfaces/Tables/TableWood.prefab index 22cab135d7..7a5d3233e6 100644 --- a/Assets/Content/WorldObjects/Furniture/Generic/Surfaces/Tables/TableWood.prefab +++ b/Assets/Content/WorldObjects/Furniture/Generic/Surfaces/Tables/TableWood.prefab @@ -12,8 +12,8 @@ GameObject: - component: {fileID: 72636884723696477} - component: {fileID: 4229887190052127918} - component: {fileID: 7514870336629038223} - - component: {fileID: 5450892481641768436} - component: {fileID: 9015187684533357890} + - component: {fileID: 617431495096137990} m_Layer: 0 m_Name: TableWood m_TagString: Untagged @@ -99,7 +99,7 @@ BoxCollider: serializedVersion: 2 m_Size: {x: 1, y: 0.75, z: 1} m_Center: {x: 0, y: 0.375, z: 0} ---- !u!114 &5450892481641768436 +--- !u!114 &9015187684533357890 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -108,21 +108,49 @@ MonoBehaviour: m_GameObject: {fileID: 3879826479501069436} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 53a5cd0d46abb6d4d8686d11153009c2, type: 3} + m_Script: {fileID: 11500000, guid: 26b716c41e9b56b4baafaf13a523ba2e, type: 3} m_Name: m_EditorClassIdentifier: - _componentIndexCache: 0 + k__BackingField: 0 + k__BackingField: 0 + k__BackingField: {fileID: 0} + _networkBehaviours: + - {fileID: 0} + k__BackingField: {fileID: 0} + k__BackingField: [] + SerializedTransformProperties: + Position: {x: 0, y: 0, z: 0} + Rotation: {x: 0, y: 0, z: 0, w: 0} + LocalScale: {x: 0, y: 0, z: 0} + _isNetworked: 1 + _isGlobal: 0 + _initializeOrder: 0 + _defaultDespawnType: 0 + NetworkObserver: {fileID: 0} + k__BackingField: 86 + k__BackingField: 0 + _scenePathHash: 0 + k__BackingField: 0 + k__BackingField: 9226908801999324862 +--- !u!114 &617431495096137990 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3879826479501069436} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ef4340642b9b436498fe733f9329ac87, type: 3} + m_Name: + m_EditorClassIdentifier: + _componentIndexCache: 255 _addedNetworkObject: {fileID: 9015187684533357890} - _networkObjectCache: {fileID: 9015187684533357890} - SelectedAdjacencyType: 1 - _simpleAdjacency: - o: {fileID: 0} - u: {fileID: 0} - i: {fileID: 0} - l: {fileID: 0} - t: {fileID: 0} - x: {fileID: 0} - _advancedAdjacency: + _networkObjectCache: {fileID: 0} + _genericType: 7 + _specificType: 4 + _syncedConnections: 0 + advancedAdjacency: o: {fileID: 3156538240660671990, guid: 32ccf9db762cc7c4f8f4af524e3e7ee7, type: 3} u: {fileID: -3792656056309247605, guid: 32ccf9db762cc7c4f8f4af524e3e7ee7, type: 3} i: {fileID: -1245183064925702563, guid: 32ccf9db762cc7c4f8f4af524e3e7ee7, type: 3} @@ -135,50 +163,8 @@ MonoBehaviour: xNone: {fileID: -5187669296468267644, guid: 32ccf9db762cc7c4f8f4af524e3e7ee7, type: 3} xSingle: {fileID: 5987645822847975186, guid: 32ccf9db762cc7c4f8f4af524e3e7ee7, type: 3} xSide: {fileID: 5221760642665961722, guid: 32ccf9db762cc7c4f8f4af524e3e7ee7, type: 3} - xOpposite: {fileID: 9165119008743474613, guid: 32ccf9db762cc7c4f8f4af524e3e7ee7, type: 3} + xOpposite: {fileID: -3100042264156035534, guid: 32ccf9db762cc7c4f8f4af524e3e7ee7, type: 3} xTriple: {fileID: -3100042264156035534, guid: 32ccf9db762cc7c4f8f4af524e3e7ee7, type: 3} xQuad: {fileID: -6010099680322335773, guid: 32ccf9db762cc7c4f8f4af524e3e7ee7, type: 3} viewObstacles: [] opaque: 0 - _offsetAdjacency: - o: {fileID: 0} - uNorth: {fileID: 0} - uSouth: {fileID: 0} - i: {fileID: 0} - lNE: {fileID: 0} - lNW: {fileID: 0} - lSE: {fileID: 0} - lSW: {fileID: 0} - tNEW: {fileID: 0} - tNSW: {fileID: 0} - tNSE: {fileID: 0} - tSWE: {fileID: 0} - x: {fileID: 0} - _syncedConnections: 0 ---- !u!114 &9015187684533357890 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3879826479501069436} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 26b716c41e9b56b4baafaf13a523ba2e, type: 3} - m_Name: - m_EditorClassIdentifier: - k__BackingField: 0 - k__BackingField: 0 - _networkBehaviours: - - {fileID: 5450892481641768436} - k__BackingField: {fileID: 0} - k__BackingField: [] - _isNetworked: 1 - _isGlobal: 0 - _defaultDespawnType: 0 - NetworkObserver: {fileID: 0} - k__BackingField: -1 - _scenePathHash: 0 - k__BackingField: 0 - k__BackingField: 9226908801999324862 - _sceneNetworkObjects: [] diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs index ca03ae756c..7710bc2686 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs @@ -1,5 +1,6 @@ using FishNet.Object.Synchronizing; using JetBrains.Annotations; +using SS3D.Attributes; using SS3D.Core.Behaviours; using SS3D.Logging; using SS3D.Systems.Tile.Connections.AdjacencyTypes; @@ -11,19 +12,9 @@ namespace SS3D.Systems.Tile.Connections { public abstract class AbstractHorizontalConnector : NetworkActor, IAdjacencyConnector { - - /// - /// A type that specifies to which objects to connect to. - /// - [Tooltip("Generic ID that adjacent objects must be to count. If empty, any id is accepted.")] - [SerializeField] protected TileObjectGenericType _genericType; - /// - /// Specific ID to differentiate objects when the generic is the same. - /// - [Tooltip("Specific ID to differentiate objects when the generic is the same.")] - [SerializeField] + protected TileObjectSpecificType _specificType; protected abstract IMeshAndDirectionResolver AdjacencyResolver { get; } From f0c7b555aff4fc0db14d093b61bbc4cebcc6b3ac Mon Sep 17 00:00:00 2001 From: stilnat Date: Mon, 9 Oct 2023 12:05:55 +0200 Subject: [PATCH 20/52] some doc and some cleanup --- .../AbstractHorizontalConnector.cs | 37 ++++++++++-- .../Connections/AdvancedAdjacencyConnector.cs | 3 + .../Connections/DoorAdjacencyConnector.cs | 26 ++++++-- .../Connections/IMeshAndDirectionResolver.cs | 4 ++ .../Connections/SimpleAdjacencyConnector.cs | 2 +- .../Scripts/SS3D/Systems/Tile/TileHelper.cs | 60 +++++++++++++------ .../Tile/TileMapCreator/GhostManager.cs | 4 +- 7 files changed, 105 insertions(+), 31 deletions(-) diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs index 7710bc2686..f83765f91d 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs @@ -10,6 +10,15 @@ namespace SS3D.Systems.Tile.Connections { + /// + /// Abstract class implementing the IAdjacencyConnector interface. + /// Idea of this class is to provide a basic implementation for all adjacency connector working mostly + /// on the same layer. This is because it uses the adjacencyMap, which consider only 8 possible connections. + /// It should be generic enough to work as a base class for most IAdjacencyConnector working with same + /// layer connections (so almost all of them). + /// It leaves to child classes to implement isConnected method, as this may vary greatly from one connector + /// to another. + /// public abstract class AbstractHorizontalConnector : NetworkActor, IAdjacencyConnector { protected TileObjectGenericType _genericType; @@ -22,6 +31,7 @@ public abstract class AbstractHorizontalConnector : NetworkActor, IAdjacencyConn protected AdjacencyMap _adjacencyMap; protected MeshFilter _filter; + protected PlacedTileObject _placedObject; public PlacedTileObject PlacedObject => _placedObject; @@ -31,12 +41,22 @@ public abstract class AbstractHorizontalConnector : NetworkActor, IAdjacencyConn private bool _initialized; + /// + /// Abstract method, as from one connector to another, the code to check for connection greatly changes. + /// + public abstract bool IsConnected(Direction dir, PlacedTileObject neighbourObject); + + public override void OnStartClient() { base.OnStartClient(); Setup(); } + /// + /// Simply set things up, including creating new references, and fetching generic and specific type + /// from the associated scriptable object. + /// private void Setup() { if (!_initialized) @@ -59,8 +79,9 @@ private void Setup() } } - public abstract bool IsConnected(Direction dir, PlacedTileObject neighbourObject); - + /// + /// Update all connections around this connector, updating mesh and directions eventually. + /// public virtual void UpdateAllConnections(PlacedTileObject[] neighbourObjects) { Setup(); @@ -77,6 +98,9 @@ public virtual void UpdateAllConnections(PlacedTileObject[] neighbourObjects) } } + /// + /// Update a single connection, in a specific direction. Eventually also update the neighbour connection. + /// public virtual bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObject, bool updateNeighbour) { Setup(); @@ -98,6 +122,9 @@ public virtual bool UpdateSingleConnection(Direction dir, PlacedTileObject neigh return isUpdated; } + /// + /// Sync adjacency map on client, and update mesh and direction using this new map. + /// private void SyncAdjacencies(byte oldValue, byte newValue, bool asServer) { if (!asServer) @@ -113,6 +140,7 @@ private void SyncAdjacencies(byte oldValue, byte newValue, bool asServer) protected void UpdateMeshAndDirection() { // Some connectors might not have to update mesh or direction at all. + // E.g : door connectors. if (AdjacencyResolver == null) return; MeshDirectionInfo info = new(); @@ -133,10 +161,9 @@ protected void UpdateMeshAndDirection() } /// - /// Sets a given direction blocked. This means that it will no longer be allowed to connect on that direction. + /// Sets a given direction blocked or unblocked. + /// If blocked, this means that it will no longer be allowed to connect on that direction (until further update). /// - /// - /// public void SetBlockedDirection(Direction dir, bool value) { _adjacencyMap.SetConnection(dir, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, value)); diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdvancedAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdvancedAdjacencyConnector.cs index a85c3fa33e..ef460bf7b5 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdvancedAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdvancedAdjacencyConnector.cs @@ -9,6 +9,9 @@ namespace SS3D.Systems.Tile.Connections { + /// + /// Basic connector using the Advanced connector struct for resolving shape and direction. + /// public class AdvancedAdjacencyConnector : AbstractHorizontalConnector, IAdjacencyConnector { [SerializeField] private AdvancedConnector advancedAdjacency; diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs index ff2a2b8efd..6fcb700b03 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs @@ -6,6 +6,10 @@ namespace SS3D.Systems.Tile.Connections { + /// + /// Connector for doors, handling adding wall caps, creating custom floor tile under the door. + /// TODO : add the custom floor. + /// public class DoorAdjacencyConnector : AbstractHorizontalConnector, IAdjacencyConnector { private enum DoorType @@ -45,9 +49,12 @@ public override void UpdateAllConnections(PlacedTileObject[] neighbourObjects) UpdateWallCaps(); } + /// + /// Destroy or add a wall cap. + /// private void CreateWallCaps(bool isPresent, Direction direction) { - int capIndex = TileHelper.GetDirectionIndex(direction); + int capIndex = GetWallCapIndex(direction); if (isPresent && wallCaps[capIndex] == null) { @@ -66,7 +73,7 @@ private void UpdateWallCaps() if (wallCapPrefab == null) return; - Direction outFacing = TileHelper.GetNextDir(DoorDirection); + Direction outFacing = TileHelper.GetNextCardinalDir(DoorDirection); bool isPresent = _adjacencyMap.HasConnection(outFacing); CreateWallCaps(isPresent, outFacing); @@ -75,10 +82,9 @@ private void UpdateWallCaps() CreateWallCaps(isPresent, TileHelper.GetOpposite(outFacing)); } - /** - * Spawns a wall cap facing a direction, with appropriate position & settings - * Direction from the centre of the door - */ + + /// Spawns a wall cap facing a direction, with appropriate position & settings + ///Direction from the centre of the door private GameObject SpawnWallCap(Direction direction) { var wallCap = Instantiate(wallCapPrefab, transform); @@ -99,6 +105,14 @@ public override bool IsConnected(Direction dir, PlacedTileObject neighbourObject return (neighbourObject && neighbourObject.HasAdjacencyConnector && neighbourObject.GenericType == TileObjectGenericType.Wall); } + + /// + /// Get the index of a wallcap in the wallcap Array. + /// + private int GetWallCapIndex(Direction dir) + { + return (int)dir / 2; + } } } diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/IMeshAndDirectionResolver.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/IMeshAndDirectionResolver.cs index f3fada01cb..9e4b03158c 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/IMeshAndDirectionResolver.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/IMeshAndDirectionResolver.cs @@ -5,6 +5,10 @@ using UnityEngine; using System; +/// +/// Interface for classes that help adjacency connectors to determine a given shape and direction for the mesh, +/// given an adjacency map representing connections. +/// public interface IMeshAndDirectionResolver { public MeshDirectionInfo GetMeshAndDirection(AdjacencyMap adjacencyMap); diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs index 470aea8e0a..f9a79d8548 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs @@ -11,7 +11,7 @@ namespace SS3D.Systems.Tile.Connections { /// - /// Good for stuff that connects on the same layer only, horizontally, of the same specific and generic type. + /// Basic connector using the simple connector struct for resolving shape and direction. /// public class SimpleAdjacencyConnector : AbstractHorizontalConnector, IAdjacencyConnector { diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileHelper.cs b/Assets/Scripts/SS3D/Systems/Tile/TileHelper.cs index 1cca7c76dc..0be84c9200 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/TileHelper.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/TileHelper.cs @@ -14,18 +14,12 @@ public static class TileHelper { private static TileLayer[] TileLayers; - public static Direction GetNextDir(Direction dir) - { - switch (dir) - { - default: - case Direction.South: return Direction.West; - case Direction.West: return Direction.North; - case Direction.North: return Direction.East; - case Direction.East: return Direction.South; - } - } + /// + /// Get a direction 90 degree clockwise from the one passed in parameter. + /// + /// + /// public static Direction GetNextCardinalDir(Direction dir) { switch (dir) @@ -42,11 +36,18 @@ public static Direction GetNextCardinalDir(Direction dir) } } + /// + /// Get the rotation angle of a particular dir. + /// E.g. assuming north is the initial position (should be), north return 0, north-east 45 ... + /// public static int GetRotationAngle(Direction dir) { return (int)dir * 45; } + /// + /// Get all different kind of tile layers. + /// public static TileLayer[] GetTileLayers() { if (TileLayers == null) @@ -56,6 +57,9 @@ public static TileLayer[] GetTileLayers() return TileLayers; } + /// + /// Get the offset in coordinates in a given direction. + /// public static Tuple ToCardinalVector(Direction direction) { return new Tuple( @@ -64,32 +68,43 @@ public static Tuple ToCardinalVector(Direction direction) ); } + /// + /// Get the closest round number world position on the plane where y = 0. + /// public static Vector3 GetClosestPosition(Vector3 worldPosition) { return new Vector3(Mathf.Round(worldPosition.x), 0, Mathf.Round(worldPosition.z)); } + /// + /// Get the relative direction between two direction. + /// E.g : to = North-East, from = South-West, return South. + /// TODO : maybe swith name of to and from, currently it feels it's the inverse way around. + /// public static Direction GetRelativeDirection(Direction to, Direction from) { return (Direction)((((int)to - (int)from) + 8) % 8); } - public static int GetDirectionIndex(Direction dir) - { - return (int)dir / 2; - } - - + /// + /// Return a list of the cardinal directions. + /// public static List CardinalDirections() { return new List { Direction.North, Direction.East, Direction.South, Direction.West }; } + /// + /// Return a list of the diagonal directions. + /// public static List DiagonalDirections() { return new List { Direction.NorthEast, Direction.SouthEast, Direction.SouthWest, Direction.NorthWest }; } + /// + /// Return the diagonal direction between two cardinal directions. + /// public static Direction GetDiagonalBetweenTwoCardinals(Direction cardinal1, Direction cardinal2) { List givenCardinals = new List { cardinal1, cardinal2 }; @@ -98,6 +113,9 @@ public static Direction GetDiagonalBetweenTwoCardinals(Direction cardinal1, Dire givenCardinals.Contains(Direction.West) ? Direction.NorthWest : Direction.NorthEast; } + /// + /// Return the cardinal direction between two diagonal directions. + /// public static Direction GetCardinalBetweenTwoDiagonals(Direction diagonal1, Direction diagonal2) { List givenDiagonals = new List { diagonal1, diagonal2 }; @@ -106,11 +124,18 @@ public static Direction GetCardinalBetweenTwoDiagonals(Direction diagonal1, Dire givenDiagonals.Contains(Direction.SouthWest) ? Direction.West : Direction.North; } + /// + /// Return the angle between two directions, clock wise is positive. + /// public static float AngleBetween(Direction from, Direction to) { return ((int)to - (int)from) * 45.0f; } + /// + /// Get the opposite direction from the one in parameter. + /// E.g : North opposite is south. South-East opposite is North-West. + /// public static Direction GetOpposite(Direction direction) { return (Direction)(((int)direction + 4) % 8); @@ -121,6 +146,7 @@ public static Direction GetOpposite(Direction direction) /// a particular direction. /// e.g If the original one is facing north, return (0,1), because, the tile in front of the original /// one will be just north of the original one (hence plus one on the y axis). + /// TODO : isn't "to cardinal vector" method doing the same thing ? /// public static Vector2Int CoordinateDifferenceInFrontFacingDirection(Direction direction) { diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileMapCreator/GhostManager.cs b/Assets/Scripts/SS3D/Systems/Tile/TileMapCreator/GhostManager.cs index ae76dcecb3..a3202070ef 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/TileMapCreator/GhostManager.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/TileMapCreator/GhostManager.cs @@ -1,4 +1,4 @@ -using Coimbra; +using Coimbra; using UnityEngine; using Actor = SS3D.Core.Behaviours.Actor; @@ -108,7 +108,7 @@ public void ChangeGhostColor(BuildMatMode mode) public void SetNextRotation() { - Dir = TileHelper.GetNextDir(Dir); + Dir = TileHelper.GetNextCardinalDir(Dir); } } } \ No newline at end of file From 385a822844a1283a488bb64830be6c0240f35b52 Mon Sep 17 00:00:00 2001 From: stilnat Date: Tue, 10 Oct 2023 12:28:08 +0200 Subject: [PATCH 21/52] fixing disposal pipes --- .../Models/Structures/Pipes/DisposalPipes.fbx | Bin 63212 -> 63212 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Assets/Art/Models/Structures/Pipes/DisposalPipes.fbx b/Assets/Art/Models/Structures/Pipes/DisposalPipes.fbx index 912cfe6e8a78cda70d40e398231d06eeb6ca982d..da9a1ce09470623c882eece55713c262ebaaed59 100644 GIT binary patch delta 24018 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 Date: Tue, 10 Oct 2023 22:14:35 +0200 Subject: [PATCH 22/52] make disposal pipe connect to disposal stuff --- .../Machines/Supply/DisposalBin.prefab | 45 ++- .../Machines/Supply/DisposalOutlet.prefab | 42 +-- .../Pipes/Disposals/DisposalPipes.prefab | 342 ++++++++++++++++-- .../SS3D/Systems/Furniture/DisposalBin.cs | 14 + .../Systems/Furniture/DisposalBin.cs.meta | 11 + .../SS3D/Systems/Furniture/DisposalOutlet.cs | 14 + .../Systems/Furniture/DisposalOutlet.cs.meta | 11 + .../Systems/Furniture/IDisposalElement.cs | 12 + .../Furniture/IDisposalElement.cs.meta | 11 + .../AbstractHorizontalConnector.cs | 2 +- .../Tile/Connections/AdjacencyShape.cs | 2 + .../AdjacencyTypes/PipeAdjacency.cs | 123 +++++++ .../AdjacencyTypes/PipeAdjacency.cs.meta | 11 + .../DisposalPipeAdjacencyConnector.cs | 220 +++++++++++ .../DisposalPipeAdjacencyConnector.cs.meta | 11 + Assets/Scripts/SS3D/Systems/Tile/TileMap.cs | 2 +- 16 files changed, 796 insertions(+), 77 deletions(-) create mode 100644 Assets/Scripts/SS3D/Systems/Furniture/DisposalBin.cs create mode 100644 Assets/Scripts/SS3D/Systems/Furniture/DisposalBin.cs.meta create mode 100644 Assets/Scripts/SS3D/Systems/Furniture/DisposalOutlet.cs create mode 100644 Assets/Scripts/SS3D/Systems/Furniture/DisposalOutlet.cs.meta create mode 100644 Assets/Scripts/SS3D/Systems/Furniture/IDisposalElement.cs create mode 100644 Assets/Scripts/SS3D/Systems/Furniture/IDisposalElement.cs.meta create mode 100644 Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/PipeAdjacency.cs create mode 100644 Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/PipeAdjacency.cs.meta create mode 100644 Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs create mode 100644 Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs.meta diff --git a/Assets/Content/WorldObjects/Furniture/Machines/Supply/DisposalBin.prefab b/Assets/Content/WorldObjects/Furniture/Machines/Supply/DisposalBin.prefab index 05a1d80bbe..670f3861bb 100644 --- a/Assets/Content/WorldObjects/Furniture/Machines/Supply/DisposalBin.prefab +++ b/Assets/Content/WorldObjects/Furniture/Machines/Supply/DisposalBin.prefab @@ -13,6 +13,7 @@ GameObject: - component: {fileID: 2658310835758749971} - component: {fileID: 7849163769786431713} - component: {fileID: 1871071288925904272} + - component: {fileID: 834667898589736169} m_Layer: 0 m_Name: DisposalBin m_TagString: Untagged @@ -114,40 +115,36 @@ MonoBehaviour: m_EditorClassIdentifier: k__BackingField: 0 k__BackingField: 0 - _networkBehaviours: - - {fileID: 0} + k__BackingField: {fileID: 0} + _networkBehaviours: [] k__BackingField: {fileID: 0} k__BackingField: [] + SerializedTransformProperties: + Position: {x: 0, y: 0, z: 0} + Rotation: {x: 0, y: 0, z: 0, w: 0} + LocalScale: {x: 0, y: 0, z: 0} _isNetworked: 1 _isGlobal: 0 + _initializeOrder: 0 _defaultDespawnType: 0 NetworkObserver: {fileID: 0} k__BackingField: 2 + k__BackingField: 0 _scenePathHash: 0 k__BackingField: 0 k__BackingField: 11648922087473007400 - _sceneNetworkObjects: - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 1871071288925904272} - - {fileID: 0} +--- !u!114 &834667898589736169 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2658310835758749969} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 05bf3c848b84c3b4db8ad292b49badf5, type: 3} + m_Name: + m_EditorClassIdentifier: --- !u!1 &3330818021912189620 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Content/WorldObjects/Furniture/Machines/Supply/DisposalOutlet.prefab b/Assets/Content/WorldObjects/Furniture/Machines/Supply/DisposalOutlet.prefab index 9b9c8f52a3..b2377ac60d 100644 --- a/Assets/Content/WorldObjects/Furniture/Machines/Supply/DisposalOutlet.prefab +++ b/Assets/Content/WorldObjects/Furniture/Machines/Supply/DisposalOutlet.prefab @@ -13,6 +13,7 @@ GameObject: - component: {fileID: 2658310835758749971} - component: {fileID: 7849163769786431713} - component: {fileID: 1871071288925904272} + - component: {fileID: 2869317171787391012} m_Layer: 0 m_Name: DisposalOutlet m_TagString: Untagged @@ -115,39 +116,36 @@ MonoBehaviour: m_EditorClassIdentifier: k__BackingField: 0 k__BackingField: 0 + k__BackingField: {fileID: 0} _networkBehaviours: [] k__BackingField: {fileID: 0} k__BackingField: [] + SerializedTransformProperties: + Position: {x: 0, y: 0, z: 0} + Rotation: {x: 0, y: 0, z: 0, w: 0} + LocalScale: {x: 0, y: 0, z: 0} _isNetworked: 1 _isGlobal: 0 + _initializeOrder: 0 _defaultDespawnType: 0 NetworkObserver: {fileID: 0} k__BackingField: 2 + k__BackingField: 0 _scenePathHash: 0 k__BackingField: 0 k__BackingField: 18291103587987570784 - _sceneNetworkObjects: - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 0} - - {fileID: 1871071288925904272} - - {fileID: 0} +--- !u!114 &2869317171787391012 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2658310835758749969} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 6b76aa9296aa20945be463a65f9e41b4, type: 3} + m_Name: + m_EditorClassIdentifier: --- !u!1 &4356345215162223831 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Content/WorldObjects/Structures/Pipes/Disposals/DisposalPipes.prefab b/Assets/Content/WorldObjects/Structures/Pipes/Disposals/DisposalPipes.prefab index 9cef843cae..b8a28a7db5 100644 --- a/Assets/Content/WorldObjects/Structures/Pipes/Disposals/DisposalPipes.prefab +++ b/Assets/Content/WorldObjects/Structures/Pipes/Disposals/DisposalPipes.prefab @@ -10,9 +10,7 @@ GameObject: m_Component: - component: {fileID: 4823056202419996052} - component: {fileID: -7727686409064562107} - - component: {fileID: -1074477776341974781} - - component: {fileID: -4998431523760016775} - - component: {fileID: 1729570281371340860} + - component: {fileID: 355159483773011154} m_Layer: 0 m_Name: DisposalPipes m_TagString: Untagged @@ -31,7 +29,11 @@ Transform: m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 - m_Children: [] + m_Children: + - {fileID: 5372635079475318011} + - {fileID: 1304632296797413523} + - {fileID: 1998967971414201473} + - {fileID: 9124324413506640243} m_Father: {fileID: 0} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} @@ -51,7 +53,7 @@ MonoBehaviour: k__BackingField: 0 k__BackingField: {fileID: 0} _networkBehaviours: - - {fileID: 1729570281371340860} + - {fileID: 0} k__BackingField: {fileID: 0} k__BackingField: [] SerializedTransformProperties: @@ -68,21 +70,245 @@ MonoBehaviour: _scenePathHash: 0 k__BackingField: 0 k__BackingField: 18330170179948219730 ---- !u!33 &-1074477776341974781 -MeshFilter: +--- !u!114 &355159483773011154 +MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 2802364579275783218} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9443ab9f38dffb74faddb22b6ed38d2c, type: 3} + m_Name: + m_EditorClassIdentifier: + _componentIndexCache: 255 + _addedNetworkObject: {fileID: -7727686409064562107} + _networkObjectCache: {fileID: 0} + _pipeAdjacency: + o: {fileID: -6725049071555871357, guid: 8fa7941da6a6a8d4da717a97b11b2621, type: 3} + u: {fileID: -6725049071555871357, guid: 8fa7941da6a6a8d4da717a97b11b2621, type: 3} + i: {fileID: -6725049071555871357, guid: 8fa7941da6a6a8d4da717a97b11b2621, type: 3} + l: {fileID: -7002929985465626668, guid: 8fa7941da6a6a8d4da717a97b11b2621, type: 3} + t: {fileID: 7767200051770316982, guid: 8fa7941da6a6a8d4da717a97b11b2621, type: 3} + x: {fileID: -7993494061914831054, guid: 8fa7941da6a6a8d4da717a97b11b2621, type: 3} + verticalMesh: {fileID: -6523086812048633060, guid: 8fa7941da6a6a8d4da717a97b11b2621, type: 3} + _verticalConnection: 0 + _syncedConnections: 0 +--- !u!1 &2921518019414602032 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1998967971414201473} + - component: {fileID: 7464676210236304092} + - component: {fileID: 7611436987726591712} + m_Layer: 0 + m_Name: Disposal3 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1998967971414201473 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2921518019414602032} + 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: 4823056202419996052} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!23 &7464676210236304092 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2921518019414602032} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 695c4de41b9578049a93f19b1eef7213, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &7611436987726591712 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2921518019414602032} + m_Mesh: {fileID: 0} +--- !u!1 &4171428647129982559 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1304632296797413523} + - component: {fileID: 6201482601325061296} + - component: {fileID: 3574773212546457757} + m_Layer: 0 + m_Name: Disposal2 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1304632296797413523 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4171428647129982559} + 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: 4823056202419996052} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!23 &6201482601325061296 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4171428647129982559} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 695c4de41b9578049a93f19b1eef7213, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &3574773212546457757 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4171428647129982559} + m_Mesh: {fileID: 0} +--- !u!1 &8602689170402263917 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5372635079475318011} + - component: {fileID: 4529554255918434919} + - component: {fileID: 6218853486968285847} + m_Layer: 0 + m_Name: Disposal1 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &5372635079475318011 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8602689170402263917} + 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: 4823056202419996052} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &4529554255918434919 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8602689170402263917} m_Mesh: {fileID: -6725049071555871357, guid: 8fa7941da6a6a8d4da717a97b11b2621, type: 3} ---- !u!23 &-4998431523760016775 +--- !u!23 &6218853486968285847 MeshRenderer: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2802364579275783218} + m_GameObject: {fileID: 8602689170402263917} m_Enabled: 1 m_CastShadows: 0 m_ReceiveShadows: 1 @@ -118,28 +344,86 @@ MeshRenderer: m_SortingLayer: 0 m_SortingOrder: 0 m_AdditionalVertexStreams: {fileID: 0} ---- !u!114 &1729570281371340860 -MonoBehaviour: +--- !u!1 &8703955908378342084 +GameObject: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2802364579275783218} + serializedVersion: 6 + m_Component: + - component: {fileID: 9124324413506640243} + - component: {fileID: 7425978706550481061} + - component: {fileID: 2731917978778670106} + m_Layer: 0 + m_Name: Disposal4 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &9124324413506640243 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8703955908378342084} + 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: 4823056202419996052} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!23 &7425978706550481061 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8703955908378342084} m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: bc6615260753fbd48af09343d5d55332, type: 3} - m_Name: - m_EditorClassIdentifier: - _componentIndexCache: 0 - _addedNetworkObject: {fileID: -7727686409064562107} - _networkObjectCache: {fileID: -7727686409064562107} - _genericType: 1 - _specificType: 0 - _syncedConnections: 0 - simpleAdjacency: - o: {fileID: -6725049071555871357, guid: 8fa7941da6a6a8d4da717a97b11b2621, type: 3} - u: {fileID: -6725049071555871357, guid: 8fa7941da6a6a8d4da717a97b11b2621, type: 3} - i: {fileID: -6725049071555871357, guid: 8fa7941da6a6a8d4da717a97b11b2621, type: 3} - l: {fileID: -7002929985465626668, guid: 8fa7941da6a6a8d4da717a97b11b2621, type: 3} - t: {fileID: 7767200051770316982, guid: 8fa7941da6a6a8d4da717a97b11b2621, type: 3} - x: {fileID: -7993494061914831054, guid: 8fa7941da6a6a8d4da717a97b11b2621, type: 3} + m_CastShadows: 0 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 695c4de41b9578049a93f19b1eef7213, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &2731917978778670106 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8703955908378342084} + m_Mesh: {fileID: 0} diff --git a/Assets/Scripts/SS3D/Systems/Furniture/DisposalBin.cs b/Assets/Scripts/SS3D/Systems/Furniture/DisposalBin.cs new file mode 100644 index 0000000000..1c6315a330 --- /dev/null +++ b/Assets/Scripts/SS3D/Systems/Furniture/DisposalBin.cs @@ -0,0 +1,14 @@ +using SS3D.Interactions.Interfaces; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + + +namespace SS3D.Systems.Furniture +{ + /// Currently a simple script to spot disposal Bins. + public class DisposalBin : MonoBehaviour, IDisposalElement + { + public GameObject GameObject => gameObject; + } +} diff --git a/Assets/Scripts/SS3D/Systems/Furniture/DisposalBin.cs.meta b/Assets/Scripts/SS3D/Systems/Furniture/DisposalBin.cs.meta new file mode 100644 index 0000000000..773a74a705 --- /dev/null +++ b/Assets/Scripts/SS3D/Systems/Furniture/DisposalBin.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 05bf3c848b84c3b4db8ad292b49badf5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/SS3D/Systems/Furniture/DisposalOutlet.cs b/Assets/Scripts/SS3D/Systems/Furniture/DisposalOutlet.cs new file mode 100644 index 0000000000..7596127c79 --- /dev/null +++ b/Assets/Scripts/SS3D/Systems/Furniture/DisposalOutlet.cs @@ -0,0 +1,14 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace SS3D.Systems.Furniture +{ + /// + /// Currently a simple script to spot disposal outlets. + /// + public class DisposalOutlet : MonoBehaviour, IDisposalElement + { + public GameObject GameObject => gameObject; + } +} diff --git a/Assets/Scripts/SS3D/Systems/Furniture/DisposalOutlet.cs.meta b/Assets/Scripts/SS3D/Systems/Furniture/DisposalOutlet.cs.meta new file mode 100644 index 0000000000..03cc240274 --- /dev/null +++ b/Assets/Scripts/SS3D/Systems/Furniture/DisposalOutlet.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6b76aa9296aa20945be463a65f9e41b4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/SS3D/Systems/Furniture/IDisposalElement.cs b/Assets/Scripts/SS3D/Systems/Furniture/IDisposalElement.cs new file mode 100644 index 0000000000..30f200c03c --- /dev/null +++ b/Assets/Scripts/SS3D/Systems/Furniture/IDisposalElement.cs @@ -0,0 +1,12 @@ +using SS3D.Interactions.Interfaces; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace SS3D.Systems.Furniture +{ + public interface IDisposalElement : IGameObjectProvider + { + + } +} diff --git a/Assets/Scripts/SS3D/Systems/Furniture/IDisposalElement.cs.meta b/Assets/Scripts/SS3D/Systems/Furniture/IDisposalElement.cs.meta new file mode 100644 index 0000000000..5b8e20677e --- /dev/null +++ b/Assets/Scripts/SS3D/Systems/Furniture/IDisposalElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c89bf766dbee52e4bbbe40a708677506 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs index f83765f91d..cac863eca1 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs @@ -137,7 +137,7 @@ private void SyncAdjacencies(byte oldValue, byte newValue, bool asServer) } - protected void UpdateMeshAndDirection() + protected virtual void UpdateMeshAndDirection() { // Some connectors might not have to update mesh or direction at all. // E.g : door connectors. diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyShape.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyShape.cs index e142006ce0..de6d7625b4 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyShape.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyShape.cs @@ -36,5 +36,7 @@ public enum AdjacencyShape TNorthSouthWest, TNorthSouthEast, TSouthWestEast, + //Vertical + Vertical, } } \ No newline at end of file diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/PipeAdjacency.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/PipeAdjacency.cs new file mode 100644 index 0000000000..b7b31cad6d --- /dev/null +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/PipeAdjacency.cs @@ -0,0 +1,123 @@ +using System; +using UnityEngine; + +namespace SS3D.Systems.Tile.Connections.AdjacencyTypes +{ + /// + /// + /// + [Serializable] + public struct DisposalPipeConnector + { + [Tooltip("Just set I shape for pipes")] + public Mesh o; + + [Tooltip("Just set I shape for pipes")] + public Mesh u; + + [Tooltip("A mesh where the South & south edges are connected")] + public Mesh i; + [Tooltip("A mesh where the South & West edges are connected")] + public Mesh l; + [Tooltip("A mesh where the South, West, and west edges are connected")] + public Mesh t; + [Tooltip("A mesh where all edges are connected")] + public Mesh x; + [Tooltip("A mesh where the South & south edges are connected")] + public Mesh verticalMesh; + + public MeshDirectionInfo[] GetMeshesAndDirections(AdjacencyMap adjacencyMap, bool vertical) + { + // Determine rotation and mesh specially for every single case. + float[] rotation; + Mesh[] mesh; + + AdjacencyShape shape = GetPipeShape(adjacencyMap, vertical); + switch (shape) + { + case AdjacencyShape.Vertical: + mesh = new Mesh[adjacencyMap.CardinalConnectionCount]; + rotation = new float[adjacencyMap.CardinalConnectionCount]; + int j = 0; + foreach (Direction dir in TileHelper.CardinalDirections()) + { + if (!adjacencyMap.HasConnection(dir)) continue; + mesh[j] = verticalMesh; + rotation[j] = TileHelper.AngleBetween(Direction.North, dir); + j++; + } + break; + + case AdjacencyShape.O: + mesh = new Mesh[] { o }; + rotation = new float[] { 0 }; + break; + case AdjacencyShape.U: + mesh = new Mesh[] { u }; + rotation = new float[1] { TileHelper.AngleBetween(Direction.North, + adjacencyMap.GetSingleConnection()) }; + break; + + case AdjacencyShape.I: + mesh = new Mesh[] { i }; + rotation = new float[1] { TileHelper.AngleBetween(Direction.North, + adjacencyMap.HasConnection(Direction.South) ? Direction.South : Direction.West) }; + break; + case AdjacencyShape.L: + mesh = new Mesh[] { l }; + rotation = new float[] { TileHelper.AngleBetween(Direction.NorthEast, + adjacencyMap.GetDirectionBetweenTwoConnections()) }; + break; + case AdjacencyShape.T: + mesh = new Mesh[] { t }; + rotation = new float[] { TileHelper.AngleBetween(Direction.North, adjacencyMap.GetSingleNonConnection()) }; + break; + case AdjacencyShape.X: + mesh = new Mesh[] { x }; + rotation = new float[] { 0 }; + break; + default: + Debug.LogError($"Received unexpected shape from simple shape resolver: {shape}"); + mesh = new Mesh[] { i }; + rotation = new float[] { 0 }; + break; + } + + MeshDirectionInfo[] MeshesAndDirections = new MeshDirectionInfo[mesh.Length]; + + for(int i=0; i< mesh.Length; i++) + { + MeshesAndDirections[i] = new MeshDirectionInfo { Mesh = mesh[i], Rotation = rotation[i] }; + } + + return MeshesAndDirections; + } + + private AdjacencyShape GetPipeShape(AdjacencyMap adjacencyMap, bool vertical) + { + if (vertical) return AdjacencyShape.Vertical; + + int connectionCount = adjacencyMap.CardinalConnectionCount; + + switch (connectionCount) + { + case 0: + return AdjacencyShape.O; + case 1: + return AdjacencyShape.U; + //When two connections, checks if they're opposite or adjacent + case 2: + return adjacencyMap.HasConnection(Direction.North) + == adjacencyMap.HasConnection(Direction.South) ? + AdjacencyShape.I : AdjacencyShape.L; + case 3: + return AdjacencyShape.T; + case 4: + return AdjacencyShape.X; + default: + Debug.LogError($"Could not resolve Simple Adjacency Shape for given Adjacency Map - {adjacencyMap}"); + return AdjacencyShape.I; + } + } + } +} diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/PipeAdjacency.cs.meta b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/PipeAdjacency.cs.meta new file mode 100644 index 0000000000..ed97ad8e5e --- /dev/null +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/PipeAdjacency.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 779abd1d92814f045ad9277b973517b7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs new file mode 100644 index 0000000000..a47eff9f53 --- /dev/null +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs @@ -0,0 +1,220 @@ +using FishNet.Object.Synchronizing; +using SS3D.Core; +using SS3D.Core.Behaviours; +using SS3D.Interactions.Interfaces; +using SS3D.Logging; +using SS3D.Systems.Furniture; +using SS3D.Systems.Tile.Connections; +using SS3D.Systems.Tile.Connections.AdjacencyTypes; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace SS3D.Systems.Tile.Connections + +{ + public class DisposalPipeAdjacencyConnector : NetworkActor, IAdjacencyConnector + { + [SerializeField] private DisposalPipeConnector _pipeAdjacency; + + protected AdjacencyMap _adjacencyMap; + + [SyncVar(OnChange = nameof(SyncVertical))] + protected bool _verticalConnection; + + protected MeshFilter[] _filters = new MeshFilter[4]; + + protected PlacedTileObject _placedObject; + + public PlacedTileObject PlacedObject => _placedObject; + + [SyncVar(OnChange = nameof(SyncAdjacencies))] + private byte _syncedConnections; + + private bool _initialized; + + protected TileObjectSpecificType _specificType; + + + private void Setup() + { + if (!_initialized) + { + _adjacencyMap = new AdjacencyMap(); + _filters = GetComponentsInChildren(); + + _placedObject = GetComponent(); + if (_placedObject == null) + { + _specificType = TileObjectSpecificType.None; + } + else + { + _specificType = _placedObject.SpecificType; + } + _initialized = true; + } + } + + public bool IsConnected(Direction dir, PlacedTileObject neighbourObject) + { + if (neighbourObject == null) return false; + + TileSystem tileSystem = Subsystems.Get(); + var map = tileSystem.CurrentMap; + + TryGetDisposalElementAbovePipe(out var aboveDisposalElement); + + if(neighbourObject.TryGetComponent(out var neighbourElement) + && neighbourElement == aboveDisposalElement) + { + return true; + } + + bool isConnected; + isConnected = (neighbourObject && neighbourObject.HasAdjacencyConnector); + isConnected &= neighbourObject.SpecificType == _specificType; + return isConnected; + } + + private bool TryGetDisposalElementAbovePipe(out IDisposalElement disposalOutlet) + { + TileSystem tileSystem = Subsystems.Get(); + var map = tileSystem.CurrentMap; + + TileChunk currentChunk = map.GetChunk(_placedObject.gameObject.transform.position); + var furnitureLocation = currentChunk.GetTileObject(TileLayer.FurnitureBase, _placedObject.Origin.x, _placedObject.Origin.y); + disposalOutlet = furnitureLocation.PlacedObject?.GetComponent(); + + return disposalOutlet != null; + } + + /// + /// Update a single connection, in a specific direction. Eventually also update the neighbour connection. + /// + public bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObject, bool updateNeighbour) + { + Setup(); + + bool isConnected = IsConnected(dir, neighbourObject); + + // Update our neighbour as well + if (isConnected && updateNeighbour) + neighbourObject.UpdateSingleAdjacency(_placedObject, TileHelper.GetOpposite(dir)); + + bool isUpdated; + bool isVertical; + + if(neighbourObject != null) + { + if (neighbourObject.GetComponent() != null) + { + isVertical = true; + isUpdated = _verticalConnection != isVertical; + } + else + { + isVertical = false; + isUpdated = _adjacencyMap.SetConnection(dir, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, isConnected)); + } + + if (isUpdated && !isVertical) + { + _syncedConnections = _adjacencyMap.SerializeToByte(); + UpdateMeshAndDirection(); + } + + if (isUpdated && isVertical) + { + _verticalConnection = isVertical; + UpdateMeshAndDirection(); + } + + return isUpdated; + } + + + isUpdated = _adjacencyMap.SetConnection(dir, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, isConnected)); + if (isUpdated) + { + UpdateMeshAndDirection(); + } + + return isUpdated; + } + + // TODO : maybe interface should let updateAllconnections handle retrieving neighbours + // object, as it might not mean the same thing for different connectors. + public void UpdateAllConnections(PlacedTileObject[] neighbourObjects) + { + Setup(); + + bool changed = false; + for (int i = 0; i < neighbourObjects.Length; i++) + { + changed |= UpdateSingleConnection((Direction)i, neighbourObjects[i], true); + } + + if(TryGetDisposalElementAbovePipe(out IDisposalElement disposalElement)) + { + var placedDisposal = disposalElement.GameObject.GetComponent(); + changed |= UpdateSingleConnection(0, placedDisposal, false); + } + + if (changed) + { + UpdateMeshAndDirection(); + } + } + + protected virtual void UpdateMeshAndDirection() + { + var infos = _pipeAdjacency.GetMeshesAndDirections(_adjacencyMap, _verticalConnection); + transform.localRotation = Quaternion.identity; + + int i = 0; + foreach(var info in infos) + { + _filters[i].transform.localPosition = Vector3.zero; + if (info.Mesh == _pipeAdjacency.verticalMesh) + { + _filters[i].transform.localPosition -= new Vector3(0,0.67f,0); + } + _filters[i].mesh = info.Mesh; + Quaternion localRotation = _filters[i].transform.localRotation; + Vector3 eulerRotation = localRotation.eulerAngles; + localRotation = Quaternion.Euler(eulerRotation.x, info.Rotation, eulerRotation.z); + _filters[i].transform.localRotation = localRotation; + i++; + } + } + + /// + /// Sync adjacency map on client, and update mesh and direction using this new map. + /// + private void SyncAdjacencies(byte oldValue, byte newValue, bool asServer) + { + if (!asServer) + { + Setup(); + + _adjacencyMap.DeserializeFromByte(newValue); + UpdateMeshAndDirection(); + } + } + + /// + /// Sync adjacency map on client, and update mesh and direction using this new map. + /// + private void SyncVertical(bool oldValue, bool newValue, bool asServer) + { + if (!asServer) + { + Setup(); + + _verticalConnection = newValue; + UpdateMeshAndDirection(); + } + } + } +} diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs.meta b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs.meta new file mode 100644 index 0000000000..4915110339 --- /dev/null +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9443ab9f38dffb74faddb22b6ed38d2c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs b/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs index d4e8c1019b..4043de5f7a 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs @@ -94,7 +94,7 @@ private TileChunk GetOrCreateChunk(Vector3 worldPosition) return chunk; } - private TileChunk GetChunk(Vector3 worldPosition) + public TileChunk GetChunk(Vector3 worldPosition) { Vector2Int key = GetKey(worldPosition); From 5422a116fb1c9fd6b8956abb0bd4d485d2b3e358 Mon Sep 17 00:00:00 2001 From: stilnat Date: Sat, 14 Oct 2023 21:20:21 +0200 Subject: [PATCH 23/52] remove multiple mesh on disposal pipe --- .../AdjacencyTypes/PipeAdjacency.cs | 56 +++++++------------ .../DisposalPipeAdjacencyConnector.cs | 27 ++++----- 2 files changed, 30 insertions(+), 53 deletions(-) diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/PipeAdjacency.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/PipeAdjacency.cs index b7b31cad6d..91ce814736 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/PipeAdjacency.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/PipeAdjacency.cs @@ -26,71 +26,53 @@ public struct DisposalPipeConnector [Tooltip("A mesh where the South & south edges are connected")] public Mesh verticalMesh; - public MeshDirectionInfo[] GetMeshesAndDirections(AdjacencyMap adjacencyMap, bool vertical) + public MeshDirectionInfo GetMeshAndDirection(AdjacencyMap adjacencyMap, bool vertical) { // Determine rotation and mesh specially for every single case. - float[] rotation; - Mesh[] mesh; + float rotation = 0; + Mesh mesh; AdjacencyShape shape = GetPipeShape(adjacencyMap, vertical); switch (shape) { case AdjacencyShape.Vertical: - mesh = new Mesh[adjacencyMap.CardinalConnectionCount]; - rotation = new float[adjacencyMap.CardinalConnectionCount]; - int j = 0; - foreach (Direction dir in TileHelper.CardinalDirections()) - { - if (!adjacencyMap.HasConnection(dir)) continue; - mesh[j] = verticalMesh; - rotation[j] = TileHelper.AngleBetween(Direction.North, dir); - j++; - } + mesh = verticalMesh; break; case AdjacencyShape.O: - mesh = new Mesh[] { o }; - rotation = new float[] { 0 }; + mesh = o ; break; case AdjacencyShape.U: - mesh = new Mesh[] { u }; - rotation = new float[1] { TileHelper.AngleBetween(Direction.North, - adjacencyMap.GetSingleConnection()) }; + mesh = u ; + rotation = TileHelper.AngleBetween(Direction.North, adjacencyMap.GetSingleConnection()); break; case AdjacencyShape.I: - mesh = new Mesh[] { i }; - rotation = new float[1] { TileHelper.AngleBetween(Direction.North, - adjacencyMap.HasConnection(Direction.South) ? Direction.South : Direction.West) }; + mesh = i ; + rotation = TileHelper.AngleBetween(Direction.North, + adjacencyMap.HasConnection(Direction.South) ? Direction.South : Direction.West); break; case AdjacencyShape.L: - mesh = new Mesh[] { l }; - rotation = new float[] { TileHelper.AngleBetween(Direction.NorthEast, - adjacencyMap.GetDirectionBetweenTwoConnections()) }; + mesh = l ; + rotation = TileHelper.AngleBetween(Direction.NorthEast, + adjacencyMap.GetDirectionBetweenTwoConnections()); break; case AdjacencyShape.T: - mesh = new Mesh[] { t }; - rotation = new float[] { TileHelper.AngleBetween(Direction.North, adjacencyMap.GetSingleNonConnection()) }; + mesh = t ; + rotation = TileHelper.AngleBetween(Direction.North, adjacencyMap.GetSingleNonConnection()); break; case AdjacencyShape.X: - mesh = new Mesh[] { x }; - rotation = new float[] { 0 }; + mesh = x ; break; default: Debug.LogError($"Received unexpected shape from simple shape resolver: {shape}"); - mesh = new Mesh[] { i }; - rotation = new float[] { 0 }; + mesh = i ; break; } - MeshDirectionInfo[] MeshesAndDirections = new MeshDirectionInfo[mesh.Length]; + MeshDirectionInfo MeshAndDirection = new MeshDirectionInfo { Mesh = mesh, Rotation = rotation } ; - for(int i=0; i< mesh.Length; i++) - { - MeshesAndDirections[i] = new MeshDirectionInfo { Mesh = mesh[i], Rotation = rotation[i] }; - } - - return MeshesAndDirections; + return MeshAndDirection; } private AdjacencyShape GetPipeShape(AdjacencyMap adjacencyMap, bool vertical) diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs index a47eff9f53..a511edc8d3 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs @@ -22,7 +22,7 @@ public class DisposalPipeAdjacencyConnector : NetworkActor, IAdjacencyConnector [SyncVar(OnChange = nameof(SyncVertical))] protected bool _verticalConnection; - protected MeshFilter[] _filters = new MeshFilter[4]; + protected MeshFilter _filter; protected PlacedTileObject _placedObject; @@ -41,7 +41,7 @@ private void Setup() if (!_initialized) { _adjacencyMap = new AdjacencyMap(); - _filters = GetComponentsInChildren(); + _filter = GetComponent(); _placedObject = GetComponent(); if (_placedObject == null) @@ -169,24 +169,19 @@ public void UpdateAllConnections(PlacedTileObject[] neighbourObjects) protected virtual void UpdateMeshAndDirection() { - var infos = _pipeAdjacency.GetMeshesAndDirections(_adjacencyMap, _verticalConnection); + var info = _pipeAdjacency.GetMeshAndDirection(_adjacencyMap, _verticalConnection); transform.localRotation = Quaternion.identity; + _filter.transform.localPosition = Vector3.zero; - int i = 0; - foreach(var info in infos) + if (info.Mesh == _pipeAdjacency.verticalMesh) { - _filters[i].transform.localPosition = Vector3.zero; - if (info.Mesh == _pipeAdjacency.verticalMesh) - { - _filters[i].transform.localPosition -= new Vector3(0,0.67f,0); - } - _filters[i].mesh = info.Mesh; - Quaternion localRotation = _filters[i].transform.localRotation; - Vector3 eulerRotation = localRotation.eulerAngles; - localRotation = Quaternion.Euler(eulerRotation.x, info.Rotation, eulerRotation.z); - _filters[i].transform.localRotation = localRotation; - i++; + _filter.transform.localPosition -= new Vector3(0,0.67f,0); } + _filter.mesh = info.Mesh; + Quaternion localRotation = _filter.transform.localRotation; + Vector3 eulerRotation = localRotation.eulerAngles; + localRotation = Quaternion.Euler(eulerRotation.x, info.Rotation, eulerRotation.z); + _filter.transform.localRotation = localRotation; } /// From 05d84dc2a54927ed1afe341b8c0f36f8fc8037b8 Mon Sep 17 00:00:00 2001 From: stilnat Date: Sat, 14 Oct 2023 22:35:00 +0200 Subject: [PATCH 24/52] fix position --- .../Pipes/Disposals/DisposalPipes.prefab | 304 +----------------- .../DisposalPipeAdjacencyConnector.cs | 10 +- 2 files changed, 18 insertions(+), 296 deletions(-) diff --git a/Assets/Content/WorldObjects/Structures/Pipes/Disposals/DisposalPipes.prefab b/Assets/Content/WorldObjects/Structures/Pipes/Disposals/DisposalPipes.prefab index b8a28a7db5..7f718fe5b0 100644 --- a/Assets/Content/WorldObjects/Structures/Pipes/Disposals/DisposalPipes.prefab +++ b/Assets/Content/WorldObjects/Structures/Pipes/Disposals/DisposalPipes.prefab @@ -11,6 +11,8 @@ GameObject: - component: {fileID: 4823056202419996052} - component: {fileID: -7727686409064562107} - component: {fileID: 355159483773011154} + - component: {fileID: 1702746743542006300} + - component: {fileID: 6841799689541215485} m_Layer: 0 m_Name: DisposalPipes m_TagString: Untagged @@ -29,11 +31,7 @@ Transform: m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 - m_Children: - - {fileID: 5372635079475318011} - - {fileID: 1304632296797413523} - - {fileID: 1998967971414201473} - - {fileID: 9124324413506640243} + m_Children: [] m_Father: {fileID: 0} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} @@ -53,7 +51,7 @@ MonoBehaviour: k__BackingField: 0 k__BackingField: {fileID: 0} _networkBehaviours: - - {fileID: 0} + - {fileID: 355159483773011154} k__BackingField: {fileID: 0} k__BackingField: [] SerializedTransformProperties: @@ -82,9 +80,9 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 9443ab9f38dffb74faddb22b6ed38d2c, type: 3} m_Name: m_EditorClassIdentifier: - _componentIndexCache: 255 + _componentIndexCache: 0 _addedNetworkObject: {fileID: -7727686409064562107} - _networkObjectCache: {fileID: 0} + _networkObjectCache: {fileID: -7727686409064562107} _pipeAdjacency: o: {fileID: -6725049071555871357, guid: 8fa7941da6a6a8d4da717a97b11b2621, type: 3} u: {fileID: -6725049071555871357, guid: 8fa7941da6a6a8d4da717a97b11b2621, type: 3} @@ -95,295 +93,21 @@ MonoBehaviour: verticalMesh: {fileID: -6523086812048633060, guid: 8fa7941da6a6a8d4da717a97b11b2621, type: 3} _verticalConnection: 0 _syncedConnections: 0 ---- !u!1 &2921518019414602032 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1998967971414201473} - - component: {fileID: 7464676210236304092} - - component: {fileID: 7611436987726591712} - m_Layer: 0 - m_Name: Disposal3 - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &1998967971414201473 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2921518019414602032} - 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: 4823056202419996052} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!23 &7464676210236304092 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2921518019414602032} - m_Enabled: 1 - m_CastShadows: 0 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_StaticShadowCaster: 0 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RayTracingMode: 2 - m_RayTraceProcedural: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: 695c4de41b9578049a93f19b1eef7213, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 1 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 - m_AdditionalVertexStreams: {fileID: 0} ---- !u!33 &7611436987726591712 +--- !u!33 &1702746743542006300 MeshFilter: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2921518019414602032} - m_Mesh: {fileID: 0} ---- !u!1 &4171428647129982559 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1304632296797413523} - - component: {fileID: 6201482601325061296} - - component: {fileID: 3574773212546457757} - m_Layer: 0 - m_Name: Disposal2 - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &1304632296797413523 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4171428647129982559} - 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: 4823056202419996052} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!23 &6201482601325061296 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4171428647129982559} - m_Enabled: 1 - m_CastShadows: 0 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_StaticShadowCaster: 0 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RayTracingMode: 2 - m_RayTraceProcedural: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: 695c4de41b9578049a93f19b1eef7213, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 1 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 - m_AdditionalVertexStreams: {fileID: 0} ---- !u!33 &3574773212546457757 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4171428647129982559} - m_Mesh: {fileID: 0} ---- !u!1 &8602689170402263917 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 5372635079475318011} - - component: {fileID: 4529554255918434919} - - component: {fileID: 6218853486968285847} - m_Layer: 0 - m_Name: Disposal1 - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &5372635079475318011 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 8602689170402263917} - 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: 4823056202419996052} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!33 &4529554255918434919 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 8602689170402263917} + m_GameObject: {fileID: 2802364579275783218} m_Mesh: {fileID: -6725049071555871357, guid: 8fa7941da6a6a8d4da717a97b11b2621, type: 3} ---- !u!23 &6218853486968285847 +--- !u!23 &6841799689541215485 MeshRenderer: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 8602689170402263917} - m_Enabled: 1 - m_CastShadows: 0 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_StaticShadowCaster: 0 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RayTracingMode: 2 - m_RayTraceProcedural: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: 695c4de41b9578049a93f19b1eef7213, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 1 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 - m_AdditionalVertexStreams: {fileID: 0} ---- !u!1 &8703955908378342084 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 9124324413506640243} - - component: {fileID: 7425978706550481061} - - component: {fileID: 2731917978778670106} - m_Layer: 0 - m_Name: Disposal4 - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &9124324413506640243 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 8703955908378342084} - 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: 4823056202419996052} - m_RootOrder: 3 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!23 &7425978706550481061 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 8703955908378342084} + m_GameObject: {fileID: 2802364579275783218} m_Enabled: 1 m_CastShadows: 0 m_ReceiveShadows: 1 @@ -419,11 +143,3 @@ MeshRenderer: m_SortingLayer: 0 m_SortingOrder: 0 m_AdditionalVertexStreams: {fileID: 0} ---- !u!33 &2731917978778670106 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 8703955908378342084} - m_Mesh: {fileID: 0} diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs index a511edc8d3..03e0da4142 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs @@ -171,11 +171,17 @@ protected virtual void UpdateMeshAndDirection() { var info = _pipeAdjacency.GetMeshAndDirection(_adjacencyMap, _verticalConnection); transform.localRotation = Quaternion.identity; - _filter.transform.localPosition = Vector3.zero; + + var pos = transform.position; if (info.Mesh == _pipeAdjacency.verticalMesh) { - _filter.transform.localPosition -= new Vector3(0,0.67f,0); + transform.position = new Vector3(pos.x, -0.67f, pos.z); + } + else if (_filter.mesh == _pipeAdjacency.verticalMesh) + { + transform.position = new Vector3(pos.x, 0f, pos.z); + return; } _filter.mesh = info.Mesh; Quaternion localRotation = _filter.transform.localRotation; From 65ff6e93af2e7ad947e01e4b9ff4db0cb3ffaad4 Mon Sep 17 00:00:00 2001 From: stilnat Date: Tue, 17 Oct 2023 14:57:45 +0200 Subject: [PATCH 25/52] fix some stuff for disposal --- .../Systems/Tile/Connections/AdjacencyMap.cs | 2 +- .../DisposalPipeAdjacencyConnector.cs | 43 ++++++++++++++++--- .../Tile/PlacedObjects/PlacedTileObject.cs | 5 +++ .../Scripts/SS3D/Systems/Tile/TileHelper.cs | 22 ++++++++-- Assets/Scripts/SS3D/Systems/Tile/TileMap.cs | 2 +- 5 files changed, 63 insertions(+), 11 deletions(-) diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyMap.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyMap.cs index c65357ddc5..8db9107184 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyMap.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyMap.cs @@ -106,7 +106,7 @@ public bool SetConnection(Direction direction, AdjacencyData data) return changed; } - private List GetAdjacencies(bool cardinal) + public List GetAdjacencies(bool cardinal) { //Are we getting adjacencies for cardinal or diagonal directions? List directionIndexes = cardinal ? diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs index 03e0da4142..8333c703e7 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs @@ -35,6 +35,8 @@ public class DisposalPipeAdjacencyConnector : NetworkActor, IAdjacencyConnector protected TileObjectSpecificType _specificType; + private bool _isVertical = false; + private void Setup() { @@ -172,20 +174,37 @@ protected virtual void UpdateMeshAndDirection() var info = _pipeAdjacency.GetMeshAndDirection(_adjacencyMap, _verticalConnection); transform.localRotation = Quaternion.identity; - var pos = transform.position; + Vector3 pos = transform.position; + Quaternion localRotation = _filter.transform.localRotation; + Vector3 eulerRotation = localRotation.eulerAngles; + _filter.mesh = info.Mesh; if (info.Mesh == _pipeAdjacency.verticalMesh) { + _isVertical= true; transform.position = new Vector3(pos.x, -0.67f, pos.z); + _filter.transform.localRotation = Quaternion.Euler(eulerRotation.x, TileHelper.GetRotationAngle(_placedObject.Direction), eulerRotation.z); + + if (!_isVertical) + { + var directions = TileHelper.AllDirections(); + directions.Remove(TileHelper.GetOpposite(_placedObject.Direction)); + SetBlockedDirection(directions, false); + + } + + return; } else if (_filter.mesh == _pipeAdjacency.verticalMesh) { transform.position = new Vector3(pos.x, 0f, pos.z); - return; } - _filter.mesh = info.Mesh; - Quaternion localRotation = _filter.transform.localRotation; - Vector3 eulerRotation = localRotation.eulerAngles; + + if (info.Mesh != _pipeAdjacency.verticalMesh) + { + _isVertical = false; + } + localRotation = Quaternion.Euler(eulerRotation.x, info.Rotation, eulerRotation.z); _filter.transform.localRotation = localRotation; } @@ -217,5 +236,19 @@ private void SyncVertical(bool oldValue, bool newValue, bool asServer) UpdateMeshAndDirection(); } } + + /// + /// Sets a given direction blocked or unblocked. + /// If blocked, this means that it will no longer be allowed to connect on that direction (until further update). + /// + private void SetBlockedDirection(List directions, bool value) + { + foreach(var dir in directions) + { + _adjacencyMap.SetConnection(dir, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, value)); + } + + UpdateMeshAndDirection(); + } } } diff --git a/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs b/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs index aab39d1eb6..9a05ee2732 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs @@ -123,6 +123,11 @@ public SavedPlacedTileObject Save() }; } + public void SetDirection(Direction dir) + { + _dir = dir; + } + /// /// Is this in front of the other object ? /// diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileHelper.cs b/Assets/Scripts/SS3D/Systems/Tile/TileHelper.cs index 0be84c9200..bac5d6d31d 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/TileHelper.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/TileHelper.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Runtime.CompilerServices; using UnityEngine; +using SS3D.Utils; namespace SS3D.Systems.Tile { @@ -57,6 +58,12 @@ public static TileLayer[] GetTileLayers() return TileLayers; } + public static Tuple GetAdjacentDirections(Direction dir) + { + return new Tuple( (Direction) MathUtility.mod((int) dir + 1, 8), + (Direction)MathUtility.mod((int)dir - 1, 8) ); + } + /// /// Get the offset in coordinates in a given direction. /// @@ -78,12 +85,10 @@ public static Vector3 GetClosestPosition(Vector3 worldPosition) /// /// Get the relative direction between two direction. - /// E.g : to = North-East, from = South-West, return South. - /// TODO : maybe swith name of to and from, currently it feels it's the inverse way around. /// - public static Direction GetRelativeDirection(Direction to, Direction from) + public static Direction GetRelativeDirection(Direction from, Direction to) { - return (Direction)((((int)to - (int)from) + 8) % 8); + return (Direction)((((int)from - (int)to) + 8) % 8); } /// @@ -94,6 +99,15 @@ public static List CardinalDirections() return new List { Direction.North, Direction.East, Direction.South, Direction.West }; } + /// + /// Return a list of the cardinal directions. + /// + public static List AllDirections() + { + return new List { Direction.North, Direction.NorthEast, Direction.East, Direction.SouthEast, + Direction.South, Direction.SouthWest, Direction.West, Direction.NorthWest }; + } + /// /// Return a list of the diagonal directions. /// diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs b/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs index 4043de5f7a..c9a04da15b 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs @@ -108,7 +108,7 @@ public TileChunk GetChunk(Vector3 worldPosition) } } - private TileObject GetTileObject(TileLayer layer, Vector3 worldPosition) + public TileObject GetTileObject(TileLayer layer, Vector3 worldPosition) { TileChunk chunk = GetOrCreateChunk(worldPosition); // TODO: creates unnessary empty chunk when checking whether building can be done return chunk.GetTileObject(layer, worldPosition); From d32abc407f88d2870db8848f86ad7316abe81558 Mon Sep 17 00:00:00 2001 From: stilnat Date: Wed, 1 Nov 2023 12:19:36 +0100 Subject: [PATCH 26/52] add disposal furniture connector --- .../Connections/DisposalFurnitureConnector.cs | 79 +++++++++++++++++++ .../DisposalFurnitureConnector.cs.meta | 11 +++ .../DisposalPipeAdjacencyConnector.cs | 2 + 3 files changed, 92 insertions(+) create mode 100644 Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs create mode 100644 Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs.meta diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs new file mode 100644 index 0000000000..06e0056c96 --- /dev/null +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs @@ -0,0 +1,79 @@ +using FishNet.Object.Synchronizing; +using SS3D.Core; +using SS3D.Core.Behaviours; +using SS3D.Interactions.Interfaces; +using SS3D.Logging; +using SS3D.Systems.Furniture; +using SS3D.Systems.Tile.Connections; +using SS3D.Systems.Tile.Connections.AdjacencyTypes; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace SS3D.Systems.Tile.Connections +{ + public class DisposalFurnitureConnector : NetworkActor, IAdjacencyConnector + { + private PlacedTileObject _placedObject; + + private bool _connectedToPipe; + + private void Setup() + { + _placedObject = GetComponent(); + } + + public bool IsConnected(Direction dir, PlacedTileObject neighbourObject) + { + if(neighbourObject == null) return false; + + if (!neighbourObject.TryGetComponent(out var pipeConnector)) + return false; + + Vector2Int neighbourPosition = neighbourObject.Origin; + + if(neighbourPosition != _placedObject.Origin) return false; + + if (pipeConnector.HorizontalConnectionCount >= 2) return false; + + return true; + } + + public void UpdateAllConnections(PlacedTileObject[] neighbourObjects) + { + // update pipe just below. + Setup(); + + if(TryGetPipeBelow(out PlacedTileObject pipe)) + { + UpdateSingleConnection(Direction.North, pipe, true); + }; + } + + public bool UpdateSingleConnection(Direction direction, PlacedTileObject neighbourObject, bool updateNeighbour) + { + Setup(); + + bool isConnected = IsConnected(direction, neighbourObject); + bool updated = _connectedToPipe != isConnected; + + // Update our neighbour as well + if (isConnected && updateNeighbour) + neighbourObject.UpdateSingleAdjacency(_placedObject, direction); + + return updated; + } + + private bool TryGetPipeBelow(out PlacedTileObject pipe) + { + TileSystem tileSystem = Subsystems.Get(); + var map = tileSystem.CurrentMap; + + TileChunk currentChunk = map.GetChunk(_placedObject.gameObject.transform.position); + var pipeLocation = currentChunk.GetTileObject(TileLayer.Disposal, _placedObject.Origin.x, _placedObject.Origin.y); + pipe = pipeLocation.PlacedObject; + + return pipe != null; + } + } +} diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs.meta b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs.meta new file mode 100644 index 0000000000..4857a3574f --- /dev/null +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9c8b1a8e25f9a0442a328450c55e1dcd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs index 8333c703e7..3cb3d9189b 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs @@ -37,6 +37,8 @@ public class DisposalPipeAdjacencyConnector : NetworkActor, IAdjacencyConnector private bool _isVertical = false; + public int HorizontalConnectionCount => _adjacencyMap.CardinalConnectionCount; + private void Setup() { From 06b870861af9adb84b6c7dbe2da41dade27c3494 Mon Sep 17 00:00:00 2001 From: stilnat Date: Wed, 1 Nov 2023 15:17:29 +0100 Subject: [PATCH 27/52] little stuff for adjacencymap --- Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyMap.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyMap.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyMap.cs index 8db9107184..ed955a6e3c 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyMap.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyMap.cs @@ -25,6 +25,11 @@ public class AdjacencyMap /// public int DiagonalConnectionCount => GetAdjacencies(false).Count; + /// + /// Get the total number of connections. + /// + public int ConnectionCount => GetAdjacencies(true).Count + GetAdjacencies(false).Count; + public AdjacencyMap() { _connections = new [] { From 9422baa0a7f84402747102aec7b398f0c25830ed Mon Sep 17 00:00:00 2001 From: stilnat Date: Wed, 1 Nov 2023 15:17:58 +0100 Subject: [PATCH 28/52] method for PlacedTileObject --- .../Tile/PlacedObjects/PlacedTileObject.cs | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs b/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs index 9a05ee2732..4f598f132a 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs @@ -107,7 +107,7 @@ public void UpdateAdjacencies(PlacedTileObject[] neighbourObjects) _connector.UpdateAllConnections(neighbourObjects); } - public void UpdateSingleAdjacency(PlacedTileObject neighbourObject, Direction dir) + public void UpdateSingleAdjacency(Direction dir, PlacedTileObject neighbourObject) { if (HasAdjacencyConnector) _connector.UpdateSingleConnection(dir, neighbourObject, false); @@ -185,5 +185,38 @@ public bool IsOnLeft(PlacedTileObject other) return false; } + + /// + /// Other is a neighbour, placed at some direction from this. + /// + /// another placedTileObject, which should be neighbouring this. + /// the found direction, north by default + /// true if other is a neighbour of this in term of coordinates + public bool NeighbourAtDirectionOf(PlacedTileObject other, out Direction direction) + { + direction = Direction.North; + if (other == null) return false; + Vector2Int coordinateDifference = other.Origin - Origin; + + if(coordinateDifference == Vector2Int.up) + direction = Direction.North; + else if(coordinateDifference == Vector2Int.down) + direction = Direction.South; + else if (coordinateDifference == Vector2Int.left) + direction = Direction.West; + else if (coordinateDifference == Vector2Int.right) + direction = Direction.East; + else if (coordinateDifference == Vector2Int.up + Vector2Int.right) + direction = Direction.NorthEast; + else if (coordinateDifference == Vector2Int.up + Vector2Int.left) + direction = Direction.NorthWest; + else if (coordinateDifference == Vector2Int.down + Vector2Int.left) + direction = Direction.SouthWest; + else if (coordinateDifference == Vector2Int.down + Vector2Int.right) + direction = Direction.SouthEast; + else return false; + + return true; + } } } \ No newline at end of file From 0c788c989f9a4816d34c9c7ab2e0803e2234c1bf Mon Sep 17 00:00:00 2001 From: stilnat Date: Wed, 1 Nov 2023 15:18:36 +0100 Subject: [PATCH 29/52] updating IAdjacencyConnector and all that depends on it --- .../AbstractHorizontalConnector.cs | 18 ++++-- .../Connections/AdvancedAdjacencyConnector.cs | 2 +- .../Connections/DisposalFurnitureConnector.cs | 15 +++-- .../DisposalPipeAdjacencyConnector.cs | 63 ++++++++++++++----- .../Connections/DoorAdjacencyConnector.cs | 6 +- .../Tile/Connections/IAdjacencyConnector.cs | 10 ++- .../Connections/MultiAdjacencyConnector.cs | 13 +++- .../Connections/PipeAdjacencyConnector.cs | 2 +- .../Connections/SimpleAdjacencyConnector.cs | 2 +- .../Connections/WallAdjacencyConnector.cs | 2 +- Assets/Scripts/SS3D/Systems/Tile/TileMap.cs | 31 ++++++--- 11 files changed, 122 insertions(+), 42 deletions(-) diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs index cac863eca1..a2053902b2 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs @@ -1,11 +1,13 @@ using FishNet.Object.Synchronizing; using JetBrains.Annotations; using SS3D.Attributes; +using SS3D.Core; using SS3D.Core.Behaviours; using SS3D.Logging; using SS3D.Systems.Tile.Connections.AdjacencyTypes; using System.Collections; using System.Collections.Generic; +using System.Linq; using UnityEngine; namespace SS3D.Systems.Tile.Connections @@ -44,7 +46,7 @@ public abstract class AbstractHorizontalConnector : NetworkActor, IAdjacencyConn /// /// Abstract method, as from one connector to another, the code to check for connection greatly changes. /// - public abstract bool IsConnected(Direction dir, PlacedTileObject neighbourObject); + public abstract bool IsConnected(PlacedTileObject neighbourObject); public override void OnStartClient() @@ -89,7 +91,7 @@ public virtual void UpdateAllConnections(PlacedTileObject[] neighbourObjects) bool changed = false; for (int i = 0; i < neighbourObjects.Length; i++) { - changed |= UpdateSingleConnection((Direction)i, neighbourObjects[i], true); + changed |= UpdateSingleConnection((Direction) i, neighbourObjects[i], true); } if (changed) @@ -105,11 +107,12 @@ public virtual bool UpdateSingleConnection(Direction dir, PlacedTileObject neigh { Setup(); - bool isConnected = IsConnected(dir, neighbourObject); + bool isConnected = IsConnected(neighbourObject); + // Update our neighbour as well if (isConnected && updateNeighbour) - neighbourObject.UpdateSingleAdjacency(_placedObject, TileHelper.GetOpposite(dir)); + neighbourObject.UpdateSingleAdjacency(TileHelper.GetOpposite(dir), _placedObject); bool isUpdated = _adjacencyMap.SetConnection(dir, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, isConnected)); @@ -169,5 +172,12 @@ public void SetBlockedDirection(Direction dir, bool value) _adjacencyMap.SetConnection(dir, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, value)); UpdateMeshAndDirection(); } + + public List GetNeighbours() + { + TileSystem tileSystem = Subsystems.Get(); + var map = tileSystem.CurrentMap; + return map.GetNeighbourPlacedObjects(_placedObject.Layer, _placedObject.gameObject.transform.position).ToList(); + } } } diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdvancedAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdvancedAdjacencyConnector.cs index ef460bf7b5..47e203a54e 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdvancedAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdvancedAdjacencyConnector.cs @@ -17,7 +17,7 @@ public class AdvancedAdjacencyConnector : AbstractHorizontalConnector, IAdjacenc [SerializeField] private AdvancedConnector advancedAdjacency; protected override IMeshAndDirectionResolver AdjacencyResolver => advancedAdjacency; - public override bool IsConnected(Direction dir, PlacedTileObject neighbourObject) + public override bool IsConnected(PlacedTileObject neighbourObject) { bool isConnected = false; if (neighbourObject) diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs index 06e0056c96..53e24b64c8 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs @@ -23,7 +23,7 @@ private void Setup() _placedObject = GetComponent(); } - public bool IsConnected(Direction dir, PlacedTileObject neighbourObject) + public bool IsConnected(PlacedTileObject neighbourObject) { if(neighbourObject == null) return false; @@ -50,16 +50,16 @@ public void UpdateAllConnections(PlacedTileObject[] neighbourObjects) }; } - public bool UpdateSingleConnection(Direction direction, PlacedTileObject neighbourObject, bool updateNeighbour) + public bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObject, bool updateNeighbour) { Setup(); - bool isConnected = IsConnected(direction, neighbourObject); + bool isConnected = IsConnected(neighbourObject); bool updated = _connectedToPipe != isConnected; // Update our neighbour as well if (isConnected && updateNeighbour) - neighbourObject.UpdateSingleAdjacency(_placedObject, direction); + neighbourObject.UpdateSingleAdjacency(TileHelper.GetOpposite(dir), _placedObject); return updated; } @@ -75,5 +75,12 @@ private bool TryGetPipeBelow(out PlacedTileObject pipe) return pipe != null; } + + public List GetNeighbours() + { + bool hasNeighbour = TryGetPipeBelow(out PlacedTileObject pipe); + if (hasNeighbour) return new List { pipe }; + else return new List(); + } } } diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs index 3cb3d9189b..176cb44477 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs @@ -8,6 +8,7 @@ using SS3D.Systems.Tile.Connections.AdjacencyTypes; using System.Collections; using System.Collections.Generic; +using System.Linq; using UnityEngine; namespace SS3D.Systems.Tile.Connections @@ -60,7 +61,7 @@ private void Setup() } } - public bool IsConnected(Direction dir, PlacedTileObject neighbourObject) + public bool IsConnected(PlacedTileObject neighbourObject) { if (neighbourObject == null) return false; @@ -100,15 +101,12 @@ public bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObje { Setup(); - bool isConnected = IsConnected(dir, neighbourObject); + bool isConnected = IsConnected(neighbourObject); - // Update our neighbour as well - if (isConnected && updateNeighbour) - neighbourObject.UpdateSingleAdjacency(_placedObject, TileHelper.GetOpposite(dir)); - - bool isUpdated; + bool isUpdated = false; bool isVertical; + if(neighbourObject != null) { if (neighbourObject.GetComponent() != null) @@ -134,15 +132,36 @@ public bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObje UpdateMeshAndDirection(); } + // Update our neighbour as well + if (isUpdated && updateNeighbour) + neighbourObject.UpdateSingleAdjacency(TileHelper.GetOpposite(dir), _placedObject); + return isUpdated; } - - - isUpdated = _adjacencyMap.SetConnection(dir, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, isConnected)); - if (isUpdated) + else { - UpdateMeshAndDirection(); + // the disposal above gets removed + if(!TryGetDisposalElementAbovePipe(out var disposalFurniture) && _verticalConnection == true) + { + _verticalConnection = false; + isUpdated = true; + } + // another pipe get removed + else + { + isUpdated = _adjacencyMap.SetConnection(dir, + new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, isConnected)); + } + + if (isUpdated) + { + UpdateMeshAndDirection(); + } } + + // Update our neighbour as well + if (isUpdated && updateNeighbour) + neighbourObject.UpdateSingleAdjacency(TileHelper.GetOpposite(dir), _placedObject); return isUpdated; } @@ -156,13 +175,13 @@ public void UpdateAllConnections(PlacedTileObject[] neighbourObjects) bool changed = false; for (int i = 0; i < neighbourObjects.Length; i++) { - changed |= UpdateSingleConnection((Direction)i, neighbourObjects[i], true); + changed |= UpdateSingleConnection((Direction) i,neighbourObjects[i], true); } if(TryGetDisposalElementAbovePipe(out IDisposalElement disposalElement)) { var placedDisposal = disposalElement.GameObject.GetComponent(); - changed |= UpdateSingleConnection(0, placedDisposal, false); + changed |= UpdateSingleConnection(Direction.North, placedDisposal, false) ; } if (changed) @@ -252,5 +271,21 @@ private void SetBlockedDirection(List directions, bool value) UpdateMeshAndDirection(); } + + public List GetNeighbours() + { + PlacedTileObject placedDisposal = null; + List neighbours; + if (TryGetDisposalElementAbovePipe(out IDisposalElement disposalElement)) + { + placedDisposal = disposalElement.GameObject.GetComponent(); + } + TileSystem tileSystem = Subsystems.Get(); + var map = tileSystem.CurrentMap; + neighbours = map.GetNeighbourPlacedObjects(_placedObject.Layer, _placedObject.gameObject.transform.position).ToList(); + if(placedDisposal != null) + neighbours.Add(placedDisposal); + return neighbours; + } } } diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs index 6fcb700b03..5961c85588 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs @@ -35,9 +35,9 @@ private enum DoorType // WallCap gameobjects, North, East, South, West. Null if not present. private GameObject[] wallCaps = new GameObject[4]; - public override bool UpdateSingleConnection(Direction direction, PlacedTileObject placedObject, bool updateNeighbours) + public override bool UpdateSingleConnection(Direction dir, PlacedTileObject placedObject, bool updateNeighbours) { - bool update = base.UpdateSingleConnection(direction, placedObject, updateNeighbours); + bool update = base.UpdateSingleConnection(dir, placedObject, updateNeighbours); if (update) UpdateWallCaps(); return update; @@ -100,7 +100,7 @@ private GameObject SpawnWallCap(Direction direction) return wallCap; } - public override bool IsConnected(Direction dir, PlacedTileObject neighbourObject) + public override bool IsConnected(PlacedTileObject neighbourObject) { return (neighbourObject && neighbourObject.HasAdjacencyConnector && neighbourObject.GenericType == TileObjectGenericType.Wall); diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/IAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/IAdjacencyConnector.cs index 2e98df709e..ef5ab87585 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/IAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/IAdjacencyConnector.cs @@ -1,12 +1,16 @@ -namespace SS3D.Systems.Tile.Connections +using System.Collections.Generic; + +namespace SS3D.Systems.Tile.Connections { /// /// Interface that all adjacency connectors should use. /// + /// TODO : add getneighbours method, remove neighbour parameters. public interface IAdjacencyConnector { - bool UpdateSingleConnection(Direction direction, PlacedTileObject neighbourObject, bool updateNeighbour); + bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObject, bool updateNeighbour); void UpdateAllConnections(PlacedTileObject[] neighbourObjects); - bool IsConnected(Direction dir, PlacedTileObject neighbourObject); + bool IsConnected(PlacedTileObject neighbourObject); + List GetNeighbours(); } } \ No newline at end of file diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/MultiAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/MultiAdjacencyConnector.cs index ec62bafa42..3f10e5781d 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/MultiAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/MultiAdjacencyConnector.cs @@ -1,9 +1,11 @@ using FishNet.Object; using FishNet.Object.Synchronizing; +using SS3D.Core; using SS3D.Logging; using SS3D.Systems.Tile.Connections.AdjacencyTypes; using System.Collections; using System.Collections.Generic; +using System.Linq; using UnityEngine; using UnityEngine.Serialization; @@ -86,7 +88,7 @@ public bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObje // Update our neighbour as well if (isConnected && updateNeighbour) - neighbourObject.UpdateSingleAdjacency(_placedObject, TileHelper.GetOpposite(dir)); + neighbourObject.UpdateSingleAdjacency(TileHelper.GetOpposite(dir), _placedObject); } isUpdated = _adjacencyMap.SetConnection(dir, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, isConnected)); @@ -156,9 +158,16 @@ private void SyncAdjacencies(byte oldValue, byte newValue, bool asServer) } } - public bool IsConnected(Direction dir, PlacedTileObject neighbourObject) + public bool IsConnected(PlacedTileObject neighbourObject) { throw new System.NotImplementedException(); } + + public List GetNeighbours() + { + TileSystem tileSystem = Subsystems.Get(); + var map = tileSystem.CurrentMap; + return map.GetNeighbourPlacedObjects(_placedObject.Layer, _placedObject.gameObject.transform.position).ToList(); + } } } \ No newline at end of file diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/PipeAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/PipeAdjacencyConnector.cs index 9e742f59dd..05ea05e557 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/PipeAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/PipeAdjacencyConnector.cs @@ -12,7 +12,7 @@ public class PipeAdjacencyConnector : AbstractHorizontalConnector private OffsetConnector _connector; protected override IMeshAndDirectionResolver AdjacencyResolver => _connector; - public override bool IsConnected(Direction dir, PlacedTileObject neighbourObject) + public override bool IsConnected(PlacedTileObject neighbourObject) { bool isConnected = false; if (neighbourObject != null) diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs index f9a79d8548..42f73422ca 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs @@ -18,7 +18,7 @@ public class SimpleAdjacencyConnector : AbstractHorizontalConnector, IAdjacencyC [SerializeField] private SimpleConnector simpleAdjacency; protected override IMeshAndDirectionResolver AdjacencyResolver => simpleAdjacency; - public override bool IsConnected(Direction dir, PlacedTileObject neighbourObject) + public override bool IsConnected(PlacedTileObject neighbourObject) { bool isConnected = false; if (neighbourObject != null) diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/WallAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/WallAdjacencyConnector.cs index f7bfee79b7..6687009f52 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/WallAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/WallAdjacencyConnector.cs @@ -55,7 +55,7 @@ private bool TryGetOnLeftOrRightDoor(out PlacedTileObject door) return false; } - public override bool IsConnected(Direction dir, PlacedTileObject neighbourObject) + public override bool IsConnected(PlacedTileObject neighbourObject) { if(neighbourObject == null) return false; diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs b/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs index c9a04da15b..ad451c4c2c 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs @@ -3,10 +3,12 @@ using JetBrains.Annotations; using SS3D.Core; using SS3D.Logging; +using SS3D.Systems.Tile.Connections; using System; using System.Collections; using System.Collections.Generic; using UnityEngine; +using static UnityEditor.FilePathAttribute; namespace SS3D.Systems.Tile { @@ -206,27 +208,40 @@ public bool PlaceTileObject(TileObjectSo tileObjectSo, Vector3 placePosition, Di public void ClearTileObject(Vector3 placePosition, TileLayer layer) { TileObject[] tileObjects = GetTileObjects(placePosition); - tileObjects[(int)layer].ClearPlacedObject(); + TileObject tileObject = tileObjects[(int)layer]; + PlacedTileObject placed = tileObject.PlacedObject; - // Update any neighbouring adjacencies - ResetAdjacencies(placePosition, layer); + + if (placed != null && placed.TryGetComponent(out IAdjacencyConnector connector)) + { + List neighbours = connector.GetNeighbours(); + ResetAdjacencies(placed, tileObject, neighbours); + } // Remove any invalid tile combinations List toRemoveObjects = BuildChecker.GetToBeDestroyedObjects(tileObjects); foreach (TileObject removeObject in toRemoveObjects) { + placed = removeObject.PlacedObject; + + if (placed != null && placed.TryGetComponent(out connector)) + { + List neighbours = connector.GetNeighbours(); + ResetAdjacencies(placed, removeObject, neighbours); + } + removeObject.ClearPlacedObject(); - ResetAdjacencies(placePosition, removeObject.Layer); } } - private void ResetAdjacencies(Vector3 placePosition, TileLayer layer) + private void ResetAdjacencies(PlacedTileObject placed, TileObject location, List neighbours) { - var neighbourTiles = GetNeighbourPlacedObjects(layer, placePosition); - for (int i = 0; i < neighbourTiles.Length; i++) + foreach (PlacedTileObject neighbour in neighbours) { - neighbourTiles[i]?.UpdateSingleAdjacency(null, TileHelper.GetOpposite((Direction)i)); + placed.NeighbourAtDirectionOf(neighbour, out var dir); + location.ClearPlacedObject(); + neighbour?.UpdateSingleAdjacency(TileHelper.GetOpposite(dir), null); } } From 26dacb355bf76b4bd02a1e45462ffa932999fb5e Mon Sep 17 00:00:00 2001 From: stilnat Date: Wed, 1 Nov 2023 15:19:02 +0100 Subject: [PATCH 30/52] adding the disposal connector scripts to prefabs --- .../Machines/Supply/DisposalBin.prefab | 18 +++++++++++++++++- .../Machines/Supply/DisposalOutlet.prefab | 18 +++++++++++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/Assets/Content/WorldObjects/Furniture/Machines/Supply/DisposalBin.prefab b/Assets/Content/WorldObjects/Furniture/Machines/Supply/DisposalBin.prefab index 670f3861bb..04229cce6d 100644 --- a/Assets/Content/WorldObjects/Furniture/Machines/Supply/DisposalBin.prefab +++ b/Assets/Content/WorldObjects/Furniture/Machines/Supply/DisposalBin.prefab @@ -14,6 +14,7 @@ GameObject: - component: {fileID: 7849163769786431713} - component: {fileID: 1871071288925904272} - component: {fileID: 834667898589736169} + - component: {fileID: 8748962403380742660} m_Layer: 0 m_Name: DisposalBin m_TagString: Untagged @@ -128,7 +129,7 @@ MonoBehaviour: _initializeOrder: 0 _defaultDespawnType: 0 NetworkObserver: {fileID: 0} - k__BackingField: 2 + k__BackingField: 110 k__BackingField: 0 _scenePathHash: 0 k__BackingField: 0 @@ -145,6 +146,21 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 05bf3c848b84c3b4db8ad292b49badf5, type: 3} m_Name: m_EditorClassIdentifier: +--- !u!114 &8748962403380742660 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2658310835758749969} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9c8b1a8e25f9a0442a328450c55e1dcd, type: 3} + m_Name: + m_EditorClassIdentifier: + _componentIndexCache: 255 + _addedNetworkObject: {fileID: 1871071288925904272} + _networkObjectCache: {fileID: 0} --- !u!1 &3330818021912189620 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Content/WorldObjects/Furniture/Machines/Supply/DisposalOutlet.prefab b/Assets/Content/WorldObjects/Furniture/Machines/Supply/DisposalOutlet.prefab index b2377ac60d..96b8fd6d0c 100644 --- a/Assets/Content/WorldObjects/Furniture/Machines/Supply/DisposalOutlet.prefab +++ b/Assets/Content/WorldObjects/Furniture/Machines/Supply/DisposalOutlet.prefab @@ -14,6 +14,7 @@ GameObject: - component: {fileID: 7849163769786431713} - component: {fileID: 1871071288925904272} - component: {fileID: 2869317171787391012} + - component: {fileID: -4327415787478915747} m_Layer: 0 m_Name: DisposalOutlet m_TagString: Untagged @@ -129,7 +130,7 @@ MonoBehaviour: _initializeOrder: 0 _defaultDespawnType: 0 NetworkObserver: {fileID: 0} - k__BackingField: 2 + k__BackingField: 165 k__BackingField: 0 _scenePathHash: 0 k__BackingField: 0 @@ -146,6 +147,21 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 6b76aa9296aa20945be463a65f9e41b4, type: 3} m_Name: m_EditorClassIdentifier: +--- !u!114 &-4327415787478915747 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2658310835758749969} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9c8b1a8e25f9a0442a328450c55e1dcd, type: 3} + m_Name: + m_EditorClassIdentifier: + _componentIndexCache: 255 + _addedNetworkObject: {fileID: 1871071288925904272} + _networkObjectCache: {fileID: 0} --- !u!1 &4356345215162223831 GameObject: m_ObjectHideFlags: 0 From 41b7ff36fa422cf66157daa020d5d8d74e187974 Mon Sep 17 00:00:00 2001 From: stilnat Date: Wed, 1 Nov 2023 16:06:33 +0100 Subject: [PATCH 31/52] add world origin for placed tile object. --- .../Systems/Tile/PlacedObjects/PlacedTileObject.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs b/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs index 4f598f132a..51b76d1bfc 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs @@ -35,7 +35,7 @@ public static PlacedTileObject Create(Vector3 worldPosition, Vector2Int origin, placedObject = placedGameObject.AddComponent(); } - placedObject.Setup(tileObjectSo, origin, dir); + placedObject.Setup(tileObjectSo, origin, worldPosition, dir); if (InstanceFinder.ServerManager != null) { @@ -59,6 +59,7 @@ public static PlacedTileObject Create(Vector3 worldPosition, Vector2Int origin, private Vector2Int _origin; private Direction _dir; private IAdjacencyConnector _connector; + private Vector2Int _worldOrigin; /// /// Returns a list of all grids positions that object occupies. @@ -68,6 +69,8 @@ public static PlacedTileObject Create(Vector3 worldPosition, Vector2Int origin, public Vector2Int Origin => _origin; + public Vector2Int WorldOrigin => _worldOrigin; + public TileObjectGenericType GenericType => _tileObjectSo.genericType; public TileObjectSpecificType SpecificType => _tileObjectSo.specificType; @@ -85,12 +88,13 @@ public static PlacedTileObject Create(Vector3 worldPosition, Vector2Int origin, /// /// /// - private void Setup(TileObjectSo tileObjectSo, Vector2Int origin, Direction dir) + private void Setup(TileObjectSo tileObjectSo, Vector2Int origin, Vector3 worldPosition, Direction dir) { _tileObjectSo = tileObjectSo; _origin = origin; _dir = dir; _connector = GetComponent(); + _worldOrigin = new Vector2Int((int)Math.Round(worldPosition.x), (int)Math.Round(worldPosition.z)); } /// @@ -196,7 +200,7 @@ public bool NeighbourAtDirectionOf(PlacedTileObject other, out Direction directi { direction = Direction.North; if (other == null) return false; - Vector2Int coordinateDifference = other.Origin - Origin; + Vector2Int coordinateDifference = other.WorldOrigin - WorldOrigin; if(coordinateDifference == Vector2Int.up) direction = Direction.North; From c2792c78b3d4720881902d61e6dd2e695a22ae88 Mon Sep 17 00:00:00 2001 From: stilnat Date: Wed, 1 Nov 2023 16:07:06 +0100 Subject: [PATCH 32/52] update neighbour if itself is updated --- .../Systems/Tile/Connections/AbstractHorizontalConnector.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs index a2053902b2..4be770eadf 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs @@ -109,15 +109,11 @@ public virtual bool UpdateSingleConnection(Direction dir, PlacedTileObject neigh bool isConnected = IsConnected(neighbourObject); - - // Update our neighbour as well - if (isConnected && updateNeighbour) - neighbourObject.UpdateSingleAdjacency(TileHelper.GetOpposite(dir), _placedObject); - bool isUpdated = _adjacencyMap.SetConnection(dir, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, isConnected)); if (isUpdated) { + neighbourObject?.UpdateSingleAdjacency(TileHelper.GetOpposite(dir), _placedObject); _syncedConnections = _adjacencyMap.SerializeToByte(); UpdateMeshAndDirection(); } From ee2cf6ca1ccf5e7e629322d3ca0038959c853665 Mon Sep 17 00:00:00 2001 From: stilnat Date: Wed, 1 Nov 2023 21:49:40 +0100 Subject: [PATCH 33/52] make disposal pipe work --- .../AbstractHorizontalConnector.cs | 2 +- .../AdjacencyTypes/PipeAdjacency.cs | 6 +- .../Connections/DisposalFurnitureConnector.cs | 2 +- .../DisposalPipeAdjacencyConnector.cs | 227 +++++++++--------- .../Connections/DoorAdjacencyConnector.cs | 2 +- .../Connections/MultiAdjacencyConnector.cs | 2 +- .../Connections/SimpleAdjacencyConnector.cs | 2 + .../Tile/PlacedObjects/PlacedTileObject.cs | 4 +- Assets/Scripts/SS3D/Systems/Tile/TileMap.cs | 14 +- 9 files changed, 134 insertions(+), 127 deletions(-) diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs index 4be770eadf..fe2efaa997 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs @@ -113,7 +113,7 @@ public virtual bool UpdateSingleConnection(Direction dir, PlacedTileObject neigh if (isUpdated) { - neighbourObject?.UpdateSingleAdjacency(TileHelper.GetOpposite(dir), _placedObject); + neighbourObject?.UpdateSingleAdjacency(TileHelper.GetOpposite(dir), _placedObject, false); _syncedConnections = _adjacencyMap.SerializeToByte(); UpdateMeshAndDirection(); } diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/PipeAdjacency.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/PipeAdjacency.cs index 91ce814736..3bc2706e6f 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/PipeAdjacency.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/PipeAdjacency.cs @@ -26,7 +26,7 @@ public struct DisposalPipeConnector [Tooltip("A mesh where the South & south edges are connected")] public Mesh verticalMesh; - public MeshDirectionInfo GetMeshAndDirection(AdjacencyMap adjacencyMap, bool vertical) + public Tuple GetMeshRotationShape(AdjacencyMap adjacencyMap, bool vertical) { // Determine rotation and mesh specially for every single case. float rotation = 0; @@ -70,9 +70,7 @@ public MeshDirectionInfo GetMeshAndDirection(AdjacencyMap adjacencyMap, bool ver break; } - MeshDirectionInfo MeshAndDirection = new MeshDirectionInfo { Mesh = mesh, Rotation = rotation } ; - - return MeshAndDirection; + return new Tuple(mesh, rotation, shape); } private AdjacencyShape GetPipeShape(AdjacencyMap adjacencyMap, bool vertical) diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs index 53e24b64c8..ab9beb57c6 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs @@ -59,7 +59,7 @@ public bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObje // Update our neighbour as well if (isConnected && updateNeighbour) - neighbourObject.UpdateSingleAdjacency(TileHelper.GetOpposite(dir), _placedObject); + neighbourObject.UpdateSingleAdjacency(TileHelper.GetOpposite(dir), _placedObject, true); return updated; } diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs index 176cb44477..df523aeab3 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs @@ -6,6 +6,7 @@ using SS3D.Systems.Furniture; using SS3D.Systems.Tile.Connections; using SS3D.Systems.Tile.Connections.AdjacencyTypes; +using System; using System.Collections; using System.Collections.Generic; using System.Linq; @@ -40,6 +41,8 @@ public class DisposalPipeAdjacencyConnector : NetworkActor, IAdjacencyConnector public int HorizontalConnectionCount => _adjacencyMap.CardinalConnectionCount; + private AdjacencyShape _currentShape; + private void Setup() { @@ -65,33 +68,79 @@ public bool IsConnected(PlacedTileObject neighbourObject) { if (neighbourObject == null) return false; - TileSystem tileSystem = Subsystems.Get(); - var map = tileSystem.CurrentMap; + if (_verticalConnection == true + && neighbourObject.TryGetComponent(out DisposalPipeAdjacencyConnector neighbourConnector)) + return IsVerticalAndNeighbourInRightPosition(neighbourObject); - TryGetDisposalElementAbovePipe(out var aboveDisposalElement); + if (neighbourObject.TryGetComponent(out var disposalFurniture)) + return IsConnectedToDisposalFurniture(neighbourObject); - if(neighbourObject.TryGetComponent(out var neighbourElement) - && neighbourElement == aboveDisposalElement) - { - return true; - } + if(neighbourObject.TryGetComponent(out DisposalPipeAdjacencyConnector neighbourConnectorAgain) + && neighbourConnectorAgain._verticalConnection == true) + return IsConnectedToVerticalPipe(neighbourObject); bool isConnected; - isConnected = (neighbourObject && neighbourObject.HasAdjacencyConnector); + isConnected = neighbourObject.HasAdjacencyConnector; isConnected &= neighbourObject.SpecificType == _specificType; return isConnected; } - private bool TryGetDisposalElementAbovePipe(out IDisposalElement disposalOutlet) + /// + /// check if the neighbour disposal pipe of this is connected to this, when this is a vertical pipe. + /// Basically check if the neighbour is positionned in front of the vertical pipe. + /// + private bool IsVerticalAndNeighbourInRightPosition(PlacedTileObject neighbourObject) + { + bool isConnected = neighbourObject != null; + isConnected &= _placedObject.NeighbourAtDirectionOf(neighbourObject, out Direction direction); + isConnected &= _placedObject.Direction == direction; + return isConnected; + } + + /// + /// Check if neighbour is the disposal furniture just above this disposal pipe. + /// + private bool IsConnectedToDisposalFurniture(PlacedTileObject neighbourObject) + { + // check if neighbour is the disposal furniture just above this. + bool IsDisposalFurnitureAbove = false; + TryGetDisposalElementAbovePipe(out var aboveDisposalFurniture); + + if (neighbourObject.TryGetComponent(out var disposalFurniture) + && disposalFurniture == aboveDisposalFurniture) + { + IsDisposalFurnitureAbove = true; + } + + return IsDisposalFurnitureAbove && HorizontalConnectionCount < 2; + } + + /// + /// Check if this disposal pipe is connected to its neighbour disposal pipe, when the neighbour is a vertical pipe. + /// + private bool IsConnectedToVerticalPipe(PlacedTileObject neighbourObject) + { + bool isConnected = neighbourObject != null; + isConnected &= neighbourObject.TryGetComponent(out DisposalPipeAdjacencyConnector neighbourConnector); + isConnected &= neighbourConnector._verticalConnection == true; + isConnected &= neighbourConnector._placedObject.NeighbourAtDirectionOf(_placedObject, out Direction direction); + isConnected &= neighbourConnector._placedObject.Direction == direction; + return isConnected; + } + + /// + /// Try to get the Disposal furniture (e.g : disposal bin) just above this disposal pipe, if it exists. + /// + private bool TryGetDisposalElementAbovePipe(out IDisposalElement disposalFurniture) { TileSystem tileSystem = Subsystems.Get(); var map = tileSystem.CurrentMap; TileChunk currentChunk = map.GetChunk(_placedObject.gameObject.transform.position); var furnitureLocation = currentChunk.GetTileObject(TileLayer.FurnitureBase, _placedObject.Origin.x, _placedObject.Origin.y); - disposalOutlet = furnitureLocation.PlacedObject?.GetComponent(); + disposalFurniture = furnitureLocation.PlacedObject?.GetComponent(); - return disposalOutlet != null; + return disposalFurniture != null; } /// @@ -102,67 +151,46 @@ public bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObje Setup(); bool isConnected = IsConnected(neighbourObject); + bool isUpdated; - bool isUpdated = false; - bool isVertical; - - - if(neighbourObject != null) + // If neighbour is a disposal furniture and this disposal pipe is connected to it + if (isConnected && IsConnectedToDisposalFurniture(neighbourObject)) { - if (neighbourObject.GetComponent() != null) - { - isVertical = true; - isUpdated = _verticalConnection != isVertical; - } - else - { - isVertical = false; - isUpdated = _adjacencyMap.SetConnection(dir, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, isConnected)); - } - - if (isUpdated && !isVertical) - { - _syncedConnections = _adjacencyMap.SerializeToByte(); - UpdateMeshAndDirection(); - } - - if (isUpdated && isVertical) - { - _verticalConnection = isVertical; - UpdateMeshAndDirection(); - } - - // Update our neighbour as well - if (isUpdated && updateNeighbour) - neighbourObject.UpdateSingleAdjacency(TileHelper.GetOpposite(dir), _placedObject); + isUpdated = _verticalConnection != true; + _verticalConnection = true; + } - return isUpdated; + // If neighbour is a removed disposal furniture which used to be connected to this disposal pipe. + else if (neighbourObject == null + && !TryGetDisposalElementAbovePipe(out IDisposalElement disposalFurniture) + && _verticalConnection == true) + { + isUpdated = true; + _verticalConnection = false; } + + // Else it's not a disposal furniture and we simply use the adjacency map for horizontal connections + // with other Disposal pipes. else { - // the disposal above gets removed - if(!TryGetDisposalElementAbovePipe(out var disposalFurniture) && _verticalConnection == true) - { - _verticalConnection = false; - isUpdated = true; - } - // another pipe get removed - else - { - isUpdated = _adjacencyMap.SetConnection(dir, - new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, isConnected)); - } + isUpdated = _adjacencyMap.SetConnection(dir, + new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, isConnected)); + } + + if (isUpdated) + { + UpdateMeshAndDirection(); + } - if (isUpdated) + if (isUpdated && updateNeighbour) + { + var connector = neighbourObject?.GetComponent(); + if(connector != null) { - UpdateMeshAndDirection(); + connector.UpdateAllConnections(new PlacedTileObject[] { }); } } - - // Update our neighbour as well - if (isUpdated && updateNeighbour) - neighbourObject.UpdateSingleAdjacency(TileHelper.GetOpposite(dir), _placedObject); - + return isUpdated; } @@ -172,16 +200,14 @@ public void UpdateAllConnections(PlacedTileObject[] neighbourObjects) { Setup(); + neighbourObjects = GetNeighbours().ToArray(); + bool changed = false; - for (int i = 0; i < neighbourObjects.Length; i++) - { - changed |= UpdateSingleConnection((Direction) i,neighbourObjects[i], true); - } - if(TryGetDisposalElementAbovePipe(out IDisposalElement disposalElement)) + foreach (var neighbourObject in neighbourObjects) { - var placedDisposal = disposalElement.GameObject.GetComponent(); - changed |= UpdateSingleConnection(Direction.North, placedDisposal, false) ; + _placedObject.NeighbourAtDirectionOf(neighbourObject, out Direction dir); + changed |= UpdateSingleConnection(dir, neighbourObject, true); } if (changed) @@ -192,42 +218,29 @@ public void UpdateAllConnections(PlacedTileObject[] neighbourObjects) protected virtual void UpdateMeshAndDirection() { - var info = _pipeAdjacency.GetMeshAndDirection(_adjacencyMap, _verticalConnection); + var info = _pipeAdjacency.GetMeshRotationShape(_adjacencyMap, _verticalConnection); transform.localRotation = Quaternion.identity; Vector3 pos = transform.position; Quaternion localRotation = _filter.transform.localRotation; Vector3 eulerRotation = localRotation.eulerAngles; - _filter.mesh = info.Mesh; + _filter.mesh = info.Item1; - if (info.Mesh == _pipeAdjacency.verticalMesh) + + if (info.Item3 == AdjacencyShape.Vertical) { - _isVertical= true; - transform.position = new Vector3(pos.x, -0.67f, pos.z); + // remove some y so the vertical model is at the right place in the ground. + transform.position = new Vector3(pos.x, -0.67f, pos.z); _filter.transform.localRotation = Quaternion.Euler(eulerRotation.x, TileHelper.GetRotationAngle(_placedObject.Direction), eulerRotation.z); - - if (!_isVertical) - { - var directions = TileHelper.AllDirections(); - directions.Remove(TileHelper.GetOpposite(_placedObject.Direction)); - SetBlockedDirection(directions, false); - - } - - return; } - else if (_filter.mesh == _pipeAdjacency.verticalMesh) + else { + // reinitialize y to 0 if the model is non vertical. transform.position = new Vector3(pos.x, 0f, pos.z); + _filter.transform.localRotation = Quaternion.Euler(eulerRotation.x, info.Item2, eulerRotation.z); } - if (info.Mesh != _pipeAdjacency.verticalMesh) - { - _isVertical = false; - } - - localRotation = Quaternion.Euler(eulerRotation.x, info.Rotation, eulerRotation.z); - _filter.transform.localRotation = localRotation; + _currentShape = info.Item3; } /// @@ -245,46 +258,32 @@ private void SyncAdjacencies(byte oldValue, byte newValue, bool asServer) } /// - /// Sync adjacency map on client, and update mesh and direction using this new map. + /// Sync vertical on client, and update mesh and direction. /// private void SyncVertical(bool oldValue, bool newValue, bool asServer) { if (!asServer) { Setup(); - - _verticalConnection = newValue; UpdateMeshAndDirection(); } } - /// - /// Sets a given direction blocked or unblocked. - /// If blocked, this means that it will no longer be allowed to connect on that direction (until further update). - /// - private void SetBlockedDirection(List directions, bool value) - { - foreach(var dir in directions) - { - _adjacencyMap.SetConnection(dir, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, value)); - } - - UpdateMeshAndDirection(); - } - public List GetNeighbours() { PlacedTileObject placedDisposal = null; - List neighbours; + List neighbours = new(); if (TryGetDisposalElementAbovePipe(out IDisposalElement disposalElement)) { placedDisposal = disposalElement.GameObject.GetComponent(); } + if (placedDisposal != null) + neighbours.Add(placedDisposal); + TileSystem tileSystem = Subsystems.Get(); var map = tileSystem.CurrentMap; - neighbours = map.GetNeighbourPlacedObjects(_placedObject.Layer, _placedObject.gameObject.transform.position).ToList(); - if(placedDisposal != null) - neighbours.Add(placedDisposal); + neighbours.AddRange(map.GetNeighbourPlacedObjects(_placedObject.Layer, _placedObject.gameObject.transform.position)); + neighbours.RemoveAll(x => x == null); return neighbours; } } diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs index 5961c85588..20bb3dd6d6 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs @@ -22,7 +22,7 @@ private enum DoorType protected override IMeshAndDirectionResolver AdjacencyResolver => null; - /** Based on peculiarities of the model, the appropriate position of the wall cap */ + // Based on peculiarities of the model, the appropriate position of the wall cap private const float WALL_CAP_DISTANCE_FROM_CENTRE = 0f; // As is the standard in the rest of the code, wallCap should face east. diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/MultiAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/MultiAdjacencyConnector.cs index 3f10e5781d..c163ec4ee8 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/MultiAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/MultiAdjacencyConnector.cs @@ -88,7 +88,7 @@ public bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObje // Update our neighbour as well if (isConnected && updateNeighbour) - neighbourObject.UpdateSingleAdjacency(TileHelper.GetOpposite(dir), _placedObject); + neighbourObject.UpdateSingleAdjacency(TileHelper.GetOpposite(dir), _placedObject, false); } isUpdated = _adjacencyMap.SetConnection(dir, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, isConnected)); diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs index 42f73422ca..df2f6f354d 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/SimpleAdjacencyConnector.cs @@ -12,6 +12,8 @@ namespace SS3D.Systems.Tile.Connections { /// /// Basic connector using the simple connector struct for resolving shape and direction. + /// Things do not need special connections in corners. + /// The only condition to connect to a neighbour is that they share generic and specific type. /// public class SimpleAdjacencyConnector : AbstractHorizontalConnector, IAdjacencyConnector { diff --git a/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs b/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs index 51b76d1bfc..39418099c1 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs @@ -111,10 +111,10 @@ public void UpdateAdjacencies(PlacedTileObject[] neighbourObjects) _connector.UpdateAllConnections(neighbourObjects); } - public void UpdateSingleAdjacency(Direction dir, PlacedTileObject neighbourObject) + public void UpdateSingleAdjacency(Direction dir, PlacedTileObject neighbourObject, bool updateNeighbour) { if (HasAdjacencyConnector) - _connector.UpdateSingleConnection(dir, neighbourObject, false); + _connector.UpdateSingleConnection(dir, neighbourObject, updateNeighbour); } public SavedPlacedTileObject Save() diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs b/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs index ad451c4c2c..01b0aaac64 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs @@ -237,11 +237,19 @@ public void ClearTileObject(Vector3 placePosition, TileLayer layer) private void ResetAdjacencies(PlacedTileObject placed, TileObject location, List neighbours) { + List neighboursAtDirection= new List(); foreach (PlacedTileObject neighbour in neighbours) { - placed.NeighbourAtDirectionOf(neighbour, out var dir); - location.ClearPlacedObject(); - neighbour?.UpdateSingleAdjacency(TileHelper.GetOpposite(dir), null); + placed.NeighbourAtDirectionOf(neighbour, out var dir); + neighboursAtDirection.Add(dir); + } + location.ClearPlacedObject(); + int i = 0; + foreach (PlacedTileObject neighbour in neighbours) + { + Direction dir = neighboursAtDirection[i]; + neighbour?.UpdateSingleAdjacency(TileHelper.GetOpposite(dir), null, false); + i++; } } From 79ef9591987081370ebeb4d2a76a2ff2372c0b12 Mon Sep 17 00:00:00 2001 From: stilnat Date: Wed, 1 Nov 2023 21:54:11 +0100 Subject: [PATCH 34/52] remove random using --- Assets/Scripts/SS3D/Systems/Tile/TileMap.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs b/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs index 01b0aaac64..3f18da3b34 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs @@ -8,7 +8,6 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; -using static UnityEditor.FilePathAttribute; namespace SS3D.Systems.Tile { From 3a56f32cfb908afd22002bf9e84627514b1fb56b Mon Sep 17 00:00:00 2001 From: stilnat Date: Thu, 2 Nov 2023 01:07:56 +0100 Subject: [PATCH 35/52] fix disposal pipes --- .../Pipes/Disposals/DisposalPipes.prefab | 20 ++++++++- .../Connections/DisposalFurnitureConnector.cs | 4 +- .../DisposalPipeAdjacencyConnector.cs | 45 +++++++++++++------ .../Tile/PlacedObjects/PlacedTileObject.cs | 5 ++- 4 files changed, 56 insertions(+), 18 deletions(-) diff --git a/Assets/Content/WorldObjects/Structures/Pipes/Disposals/DisposalPipes.prefab b/Assets/Content/WorldObjects/Structures/Pipes/Disposals/DisposalPipes.prefab index 7f718fe5b0..9d5e11d61f 100644 --- a/Assets/Content/WorldObjects/Structures/Pipes/Disposals/DisposalPipes.prefab +++ b/Assets/Content/WorldObjects/Structures/Pipes/Disposals/DisposalPipes.prefab @@ -13,6 +13,7 @@ GameObject: - component: {fileID: 355159483773011154} - component: {fileID: 1702746743542006300} - component: {fileID: 6841799689541215485} + - component: {fileID: 4188904223884923263} m_Layer: 0 m_Name: DisposalPipes m_TagString: Untagged @@ -56,8 +57,8 @@ MonoBehaviour: k__BackingField: [] SerializedTransformProperties: Position: {x: 0, y: 0, z: 0} - Rotation: {x: 0, y: 0, z: 0, w: 0} - LocalScale: {x: 0, y: 0, z: 0} + Rotation: {x: 0, y: 0, z: 0, w: 1} + LocalScale: {x: 1, y: 1, z: 1} _isNetworked: 1 _isGlobal: 0 _initializeOrder: 0 @@ -143,3 +144,18 @@ MeshRenderer: m_SortingLayer: 0 m_SortingOrder: 0 m_AdditionalVertexStreams: {fileID: 0} +--- !u!114 &4188904223884923263 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2802364579275783218} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ff65a9dda1ef18f4cbc16ee4d1aee066, type: 3} + m_Name: + m_EditorClassIdentifier: + _componentIndexCache: 255 + _addedNetworkObject: {fileID: -7727686409064562107} + _networkObjectCache: {fileID: 0} diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs index ab9beb57c6..71f5d12021 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs @@ -58,8 +58,8 @@ public bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObje bool updated = _connectedToPipe != isConnected; // Update our neighbour as well - if (isConnected && updateNeighbour) - neighbourObject.UpdateSingleAdjacency(TileHelper.GetOpposite(dir), _placedObject, true); + if (updated) + neighbourObject.UpdateAdjacencies(new PlacedTileObject[0]); return updated; } diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs index df523aeab3..43d488e915 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs @@ -24,6 +24,9 @@ public class DisposalPipeAdjacencyConnector : NetworkActor, IAdjacencyConnector [SyncVar(OnChange = nameof(SyncVertical))] protected bool _verticalConnection; + [SyncVar(OnChange = nameof(SyncDirection))] + protected Direction _direction; + protected MeshFilter _filter; protected PlacedTileObject _placedObject; @@ -50,16 +53,19 @@ private void Setup() { _adjacencyMap = new AdjacencyMap(); _filter = GetComponent(); - - _placedObject = GetComponent(); - if (_placedObject == null) + if (IsServer) { - _specificType = TileObjectSpecificType.None; - } - else - { - _specificType = _placedObject.SpecificType; + _placedObject = GetComponent(); + if (_placedObject == null) + { + _specificType = TileObjectSpecificType.None; + } + else + { + _specificType = _placedObject.SpecificType; + } } + _initialized = true; } } @@ -152,6 +158,7 @@ public bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObje bool isConnected = IsConnected(neighbourObject); bool isUpdated; + bool neighbourIsRemovedDisposalFurniture = false; // If neighbour is a disposal furniture and this disposal pipe is connected to it if (isConnected && IsConnectedToDisposalFurniture(neighbourObject)) @@ -165,6 +172,7 @@ public bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObje && !TryGetDisposalElementAbovePipe(out IDisposalElement disposalFurniture) && _verticalConnection == true) { + neighbourIsRemovedDisposalFurniture = true; isUpdated = true; _verticalConnection = false; } @@ -179,16 +187,18 @@ public bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObje if (isUpdated) { + _syncedConnections = _adjacencyMap.SerializeToByte(); + _direction = _placedObject.Direction; UpdateMeshAndDirection(); - } - - if (isUpdated && updateNeighbour) - { var connector = neighbourObject?.GetComponent(); if(connector != null) { connector.UpdateAllConnections(new PlacedTileObject[] { }); } + if (neighbourIsRemovedDisposalFurniture) + { + UpdateAllConnections(new PlacedTileObject[] { }); + } } return isUpdated; @@ -231,7 +241,7 @@ protected virtual void UpdateMeshAndDirection() { // remove some y so the vertical model is at the right place in the ground. transform.position = new Vector3(pos.x, -0.67f, pos.z); - _filter.transform.localRotation = Quaternion.Euler(eulerRotation.x, TileHelper.GetRotationAngle(_placedObject.Direction), eulerRotation.z); + _filter.transform.localRotation = Quaternion.Euler(eulerRotation.x, TileHelper.GetRotationAngle(_direction), eulerRotation.z); } else { @@ -269,6 +279,15 @@ private void SyncVertical(bool oldValue, bool newValue, bool asServer) } } + private void SyncDirection(Direction oldValue, Direction newValue, bool asServer) + { + if (!asServer) + { + Setup(); + UpdateMeshAndDirection(); + } + } + public List GetNeighbours() { PlacedTileObject placedDisposal = null; diff --git a/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs b/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs index 39418099c1..f067c19503 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs @@ -17,7 +17,8 @@ namespace SS3D.Systems.Tile public class PlacedTileObject: NetworkBehaviour { /// - /// Creates a new PlacedTileObject from a TileObjectSO at a given position and direction. Uses NetworkServer.Spawn() if a server is running. + /// Creates a new PlacedTileObject from a TileObjectSO at a given position and direction. + /// Uses NetworkServer.Spawn() if a server is running. /// /// /// @@ -37,6 +38,8 @@ public static PlacedTileObject Create(Vector3 worldPosition, Vector2Int origin, placedObject.Setup(tileObjectSo, origin, worldPosition, dir); + // TODO : Spawning the placed game object does not spawn with it everything. In particular, the values + // such as tileobjectSO, origin or world position are not spawned. This might (or not) be an issue later on. if (InstanceFinder.ServerManager != null) { if (placedObject.GetComponent() == null) From b8fcf52d359ff7639b49733256c6962844193afc Mon Sep 17 00:00:00 2001 From: stilnat Date: Thu, 2 Nov 2023 01:24:30 +0100 Subject: [PATCH 36/52] remove neighbour objects parameter from updateAllConnections --- .../Tile/Connections/AbstractHorizontalConnector.cs | 13 +++++++++---- .../Tile/Connections/DisposalFurnitureConnector.cs | 4 ++-- .../Connections/DisposalPipeAdjacencyConnector.cs | 8 ++++---- .../Tile/Connections/DoorAdjacencyConnector.cs | 4 ++-- .../Systems/Tile/Connections/IAdjacencyConnector.cs | 2 +- .../Tile/Connections/MultiAdjacencyConnector.cs | 9 ++++++--- .../Systems/Tile/PlacedObjects/PlacedTileObject.cs | 4 ++-- Assets/Scripts/SS3D/Systems/Tile/TileMap.cs | 5 ++--- 8 files changed, 28 insertions(+), 21 deletions(-) diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs index fe2efaa997..a2fb9b4a2a 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs @@ -84,14 +84,17 @@ private void Setup() /// /// Update all connections around this connector, updating mesh and directions eventually. /// - public virtual void UpdateAllConnections(PlacedTileObject[] neighbourObjects) + public virtual void UpdateAllConnections() { Setup(); + var neighbourObjects = GetNeighbours(); + bool changed = false; - for (int i = 0; i < neighbourObjects.Length; i++) + foreach (var neighbourObject in neighbourObjects) { - changed |= UpdateSingleConnection((Direction) i, neighbourObjects[i], true); + _placedObject.NeighbourAtDirectionOf(neighbourObject, out Direction dir); + changed |= UpdateSingleConnection(dir, neighbourObject, true); } if (changed) @@ -173,7 +176,9 @@ public List GetNeighbours() { TileSystem tileSystem = Subsystems.Get(); var map = tileSystem.CurrentMap; - return map.GetNeighbourPlacedObjects(_placedObject.Layer, _placedObject.gameObject.transform.position).ToList(); + var neighbours = map.GetNeighbourPlacedObjects(_placedObject.Layer, _placedObject.gameObject.transform.position).ToList(); + neighbours.RemoveAll(x => x == null); + return neighbours; } } } diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs index 71f5d12021..5d7f56e734 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs @@ -39,7 +39,7 @@ public bool IsConnected(PlacedTileObject neighbourObject) return true; } - public void UpdateAllConnections(PlacedTileObject[] neighbourObjects) + public void UpdateAllConnections() { // update pipe just below. Setup(); @@ -59,7 +59,7 @@ public bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObje // Update our neighbour as well if (updated) - neighbourObject.UpdateAdjacencies(new PlacedTileObject[0]); + neighbourObject.UpdateAdjacencies(); return updated; } diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs index 43d488e915..0fbea11c36 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs @@ -193,11 +193,11 @@ public bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObje var connector = neighbourObject?.GetComponent(); if(connector != null) { - connector.UpdateAllConnections(new PlacedTileObject[] { }); + connector.UpdateAllConnections(); } if (neighbourIsRemovedDisposalFurniture) { - UpdateAllConnections(new PlacedTileObject[] { }); + UpdateAllConnections(); } } @@ -206,11 +206,11 @@ public bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObje // TODO : maybe interface should let updateAllconnections handle retrieving neighbours // object, as it might not mean the same thing for different connectors. - public void UpdateAllConnections(PlacedTileObject[] neighbourObjects) + public void UpdateAllConnections() { Setup(); - neighbourObjects = GetNeighbours().ToArray(); + var neighbourObjects = GetNeighbours(); bool changed = false; diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs index 20bb3dd6d6..03bfc75bb4 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DoorAdjacencyConnector.cs @@ -43,9 +43,9 @@ public override bool UpdateSingleConnection(Direction dir, PlacedTileObject plac return update; } - public override void UpdateAllConnections(PlacedTileObject[] neighbourObjects) + public override void UpdateAllConnections() { - base.UpdateAllConnections(neighbourObjects); + base.UpdateAllConnections(); UpdateWallCaps(); } diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/IAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/IAdjacencyConnector.cs index ef5ab87585..55dfc14363 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/IAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/IAdjacencyConnector.cs @@ -9,7 +9,7 @@ namespace SS3D.Systems.Tile.Connections public interface IAdjacencyConnector { bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObject, bool updateNeighbour); - void UpdateAllConnections(PlacedTileObject[] neighbourObjects); + void UpdateAllConnections(); bool IsConnected(PlacedTileObject neighbourObject); List GetNeighbours(); } diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/MultiAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/MultiAdjacencyConnector.cs index c163ec4ee8..79035fd415 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/MultiAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/MultiAdjacencyConnector.cs @@ -101,14 +101,17 @@ public bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObje return isUpdated; } - public void UpdateAllConnections(PlacedTileObject[] neighbourObjects) + public void UpdateAllConnections() { Setup(); + var neighbourObjects = GetNeighbours(); + bool changed = false; - for (int i = 0; i < neighbourObjects.Length; i++) + foreach (var neighbourObject in neighbourObjects) { - changed |= UpdateSingleConnection((Direction)i, neighbourObjects[i], true); + _placedObject.NeighbourAtDirectionOf(neighbourObject, out Direction dir); + changed |= UpdateSingleConnection(dir, neighbourObject, true); } if (changed) diff --git a/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs b/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs index f067c19503..73d5d9ad09 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/PlacedObjects/PlacedTileObject.cs @@ -108,10 +108,10 @@ public void DestroySelf() InstanceFinder.ServerManager.Despawn(gameObject); } - public void UpdateAdjacencies(PlacedTileObject[] neighbourObjects) + public void UpdateAdjacencies() { if (HasAdjacencyConnector) - _connector.UpdateAllConnections(neighbourObjects); + _connector.UpdateAllConnections(); } public void UpdateSingleAdjacency(Direction dir, PlacedTileObject neighbourObject, bool updateNeighbour) diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs b/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs index 3f18da3b34..3c0b991833 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs @@ -195,8 +195,7 @@ public bool PlaceTileObject(TileObjectSo tileObjectSo, Vector3 placePosition, Di // Handle Adjacency connectors, can skip it particulary when loading the map. if (!skipAdjacency){ - var neighbourTiles = GetNeighbourPlacedObjects(tileObjectSo.layer, placePosition); - placedObject.UpdateAdjacencies(neighbourTiles); + placedObject.UpdateAdjacencies(); } } @@ -368,7 +367,7 @@ private void UpdateAllAdjacencies() if (obj.HasAdjacencyConnector) { var pos = chunk.GetWorldPosition(obj.Origin.x, obj.Origin.y); - obj.UpdateAdjacencies(GetNeighbourPlacedObjects(obj.Layer, pos)); + obj.UpdateAdjacencies(); } } } From 6c2ba53cbf96d2e08ef6bcc7164ffb19ba5531f3 Mon Sep 17 00:00:00 2001 From: stilnat Date: Thu, 2 Nov 2023 01:35:09 +0100 Subject: [PATCH 37/52] doc on the interface --- .../Tile/Connections/IAdjacencyConnector.cs | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/IAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/IAdjacencyConnector.cs index 55dfc14363..cf71d2e47b 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/IAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/IAdjacencyConnector.cs @@ -5,12 +5,40 @@ namespace SS3D.Systems.Tile.Connections /// /// Interface that all adjacency connectors should use. /// - /// TODO : add getneighbours method, remove neighbour parameters. public interface IAdjacencyConnector { + /// + /// Update a single connection, and eventually update the neighbour as well. + /// neighbour object can be null, which generally means the neighbour object is removed. + /// dir should indicate the direction in which the neighbour object is, if it makes sense, and if + /// it's useful. For some neighbours,in some particula cases, it might not be useful. + /// e.g : Disposal furniture above disposal pipes, in that case direction is not useful, so it can take + /// any value. + /// bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObject, bool updateNeighbour); + + /// + /// Update all connections of this Connector, generally, it means update all neighbour placed tile + /// objects of the placed object linked to this connector. + /// void UpdateAllConnections(); + + /// + /// Check if a given neighbour of the placed object linked to this connector is connected to + /// the placed object linked to this connector. Connection conditions + /// may vary widely from a connector to another. + /// bool IsConnected(PlacedTileObject neighbourObject); + + /// + /// Get all neighbours from the placed object this connector is attached to. + /// The definition of neighbours may vary from one connector to another. + /// For most, it'll simply be other placed object placed on the same layer, on adjacent tiles. + /// Some might have more exotic definitions, such as the disposal pipes, which can consider + /// some disposal furnitures to be their neighbour. + /// A neighbour is a potential candidate for a connection, it means the placed object + /// linked to this connector will not necessarily be connected with its neighbour. + /// List GetNeighbours(); } } \ No newline at end of file From 838f3bb8f2b12fb6330b3d5559f818699ef3abaf Mon Sep 17 00:00:00 2001 From: stilnat Date: Thu, 2 Nov 2023 01:36:45 +0100 Subject: [PATCH 38/52] clean doc --- .../Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs index 0fbea11c36..507317c8e1 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs @@ -149,9 +149,6 @@ private bool TryGetDisposalElementAbovePipe(out IDisposalElement disposalFurnitu return disposalFurniture != null; } - /// - /// Update a single connection, in a specific direction. Eventually also update the neighbour connection. - /// public bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObject, bool updateNeighbour) { Setup(); From 700b8c63186967deb3848987cda0cacc94dd8cc2 Mon Sep 17 00:00:00 2001 From: stilnat Date: Thu, 2 Nov 2023 11:04:09 +0100 Subject: [PATCH 39/52] put back the right disposal pipes file --- .../Structures/Pipes/DisposalPipes.fbx.meta | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/Assets/Art/Models/Structures/Pipes/DisposalPipes.fbx.meta b/Assets/Art/Models/Structures/Pipes/DisposalPipes.fbx.meta index 68373a927b..edd5744ee8 100644 --- a/Assets/Art/Models/Structures/Pipes/DisposalPipes.fbx.meta +++ b/Assets/Art/Models/Structures/Pipes/DisposalPipes.fbx.meta @@ -1,16 +1,11 @@ fileFormatVersion: 2 guid: 8fa7941da6a6a8d4da717a97b11b2621 ModelImporter: - serializedVersion: 21202 + serializedVersion: 21300 internalIDToNameTable: [] - externalObjects: - - first: - type: UnityEngine:Material - assembly: UnityEngine.CoreModule - name: Palette05 - second: {fileID: 2100000, guid: 695c4de41b9578049a93f19b1eef7213, type: 2} + externalObjects: {} materials: - materialImportMode: 1 + materialImportMode: 2 materialName: 0 materialSearch: 1 materialLocation: 1 @@ -19,7 +14,7 @@ ModelImporter: bakeSimulation: 0 resampleCurves: 1 optimizeGameObjects: 0 - removeConstantScaleCurves: 0 + removeConstantScaleCurves: 1 motionNodeName: rigImportErrors: rigImportWarnings: @@ -49,8 +44,8 @@ ModelImporter: importBlendShapes: 1 importCameras: 1 importLights: 1 - nodeNameCollisionStrategy: 0 - fileIdsGeneration: 1 + nodeNameCollisionStrategy: 1 + fileIdsGeneration: 2 swapUVChannels: 0 generateSecondaryUV: 0 useFileUnits: 1 @@ -103,7 +98,8 @@ ModelImporter: animationType: 2 humanoidOversampling: 1 avatarSetup: 0 - addHumanoidExtraRootOnlyWhenUsingAvatar: 0 + addHumanoidExtraRootOnlyWhenUsingAvatar: 1 + remapMaterialsIfMaterialImportModeIsNone: 0 additionalBone: 0 userData: assetBundleName: From 11cc5403e7ca22c6c4043dda0bc7b24277893860 Mon Sep 17 00:00:00 2001 From: stilnat Date: Thu, 2 Nov 2023 12:18:04 +0100 Subject: [PATCH 40/52] complete doc --- .../Systems/Furniture/IDisposalElement.cs | 5 ++ .../AbstractHorizontalConnector.cs | 38 ++++++++- .../AdjacencyTypes/PipeAdjacency.cs | 10 ++- .../Connections/DisposalFurnitureConnector.cs | 21 ++++- .../DisposalPipeAdjacencyConnector.cs | 85 ++++++++++++------- .../Connections/PipeAdjacencyConnector.cs | 3 + .../Tile/Connections/TileObjectType.cs | 3 +- .../Connections/WallAdjacencyConnector.cs | 23 ++++- .../SS3D/Systems/Tile/TileConstants.cs | 6 ++ .../Scripts/SS3D/Systems/Tile/TileHelper.cs | 7 +- Assets/Scripts/SS3D/Systems/Tile/TileMap.cs | 8 ++ Assets/Scripts/SS3D/Utils/MathUtility.cs | 6 ++ 12 files changed, 172 insertions(+), 43 deletions(-) diff --git a/Assets/Scripts/SS3D/Systems/Furniture/IDisposalElement.cs b/Assets/Scripts/SS3D/Systems/Furniture/IDisposalElement.cs index 30f200c03c..c23a54d908 100644 --- a/Assets/Scripts/SS3D/Systems/Furniture/IDisposalElement.cs +++ b/Assets/Scripts/SS3D/Systems/Furniture/IDisposalElement.cs @@ -5,6 +5,11 @@ namespace SS3D.Systems.Furniture { + /// + /// A simple interface for all disposal furniture. It helps with abstracting over the type + /// of furnitures, when they all need to be treated the same. e.g : disposal pipes + /// wants to connect with disposal elements, they don't care about their specificity. + /// public interface IDisposalElement : IGameObjectProvider { diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs index a2fb9b4a2a..f7a7fa2d84 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AbstractHorizontalConnector.cs @@ -23,24 +23,50 @@ namespace SS3D.Systems.Tile.Connections /// public abstract class AbstractHorizontalConnector : NetworkActor, IAdjacencyConnector { + /// + /// Is this a table ? A Door ? A carpet ? A pipe ? + /// protected TileObjectGenericType _genericType; + /// + /// Is this a wooden table ? A glass table ? A poker table ? + /// protected TileObjectSpecificType _specificType; + /// + /// Script that help with resolving the specific mesh a connectable should take. + /// protected abstract IMeshAndDirectionResolver AdjacencyResolver { get; } + /// + /// A structure containing data regarding connection of this PlacedTileObject with all 8 + /// adjacent neighbours (cardinal and diagonal connections). + /// protected AdjacencyMap _adjacencyMap; + /// + /// The specific mesh this connectable has. + /// protected MeshFilter _filter; + /// + /// The Placed tile object linked to this connector. It's this placed object that this + /// connector update. + /// protected PlacedTileObject _placedObject; public PlacedTileObject PlacedObject => _placedObject; + /// + /// A byte, representing the 8 possible connections with neighbours. + /// [SyncVar(OnChange = nameof(SyncAdjacencies))] private byte _syncedConnections; + /// + /// Upon Setup, this should stay true. + /// private bool _initialized; /// @@ -138,11 +164,12 @@ private void SyncAdjacencies(byte oldValue, byte newValue, bool asServer) } } - + /// + /// Update the current mesh of the game object this connector is onto, as well + /// as it's rotation. + /// protected virtual void UpdateMeshAndDirection() { - // Some connectors might not have to update mesh or direction at all. - // E.g : door connectors. if (AdjacencyResolver == null) return; MeshDirectionInfo info = new(); @@ -172,6 +199,11 @@ public void SetBlockedDirection(Direction dir, bool value) UpdateMeshAndDirection(); } + /// + /// Get all neighbour placed objects from this placed object. + /// Return only existing neighbours. Neighbours here are adjacent (cardinal and diagonal) + /// tile objects on the same layer. + /// public List GetNeighbours() { TileSystem tileSystem = Subsystems.Get(); diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/PipeAdjacency.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/PipeAdjacency.cs index 3bc2706e6f..f31bcb3a28 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/PipeAdjacency.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/AdjacencyTypes/PipeAdjacency.cs @@ -4,7 +4,8 @@ namespace SS3D.Systems.Tile.Connections.AdjacencyTypes { /// - /// + /// Script helping disposal pipes to determine their shape, mesh and rotation. + /// Disposal pipes are a bit special because they can connect vertically with disposal furniture. /// [Serializable] public struct DisposalPipeConnector @@ -26,9 +27,14 @@ public struct DisposalPipeConnector [Tooltip("A mesh where the South & south edges are connected")] public Mesh verticalMesh; + /// + /// Get all info needed to update correctly disposal pipes. + /// + /// Disposal pipe connections with all horizontal neighbours + /// Disposal pipe connections with its single potential + /// vertical neighbour. True if it exists. public Tuple GetMeshRotationShape(AdjacencyMap adjacencyMap, bool vertical) { - // Determine rotation and mesh specially for every single case. float rotation = 0; Mesh mesh; diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs index 5d7f56e734..b3b0402444 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs @@ -12,6 +12,11 @@ namespace SS3D.Systems.Tile.Connections { + /// + /// Connector for disposal furniture. e.g disposal outlets and disposal bins. + /// It doesn't do much, except checking for an available pipe just below itself, and + /// signaling this pipe to update itself upon adding or clearing the disposal furniture. + /// public class DisposalFurnitureConnector : NetworkActor, IAdjacencyConnector { private PlacedTileObject _placedObject; @@ -23,6 +28,10 @@ private void Setup() _placedObject = GetComponent(); } + /// + /// Disposal furnitures are connected when they have a disposal pipe just below them + /// and this pipe has less than two connections already. + /// public bool IsConnected(PlacedTileObject neighbourObject) { if(neighbourObject == null) return false; @@ -41,10 +50,11 @@ public bool IsConnected(PlacedTileObject neighbourObject) public void UpdateAllConnections() { - // update pipe just below. + Setup(); - if(TryGetPipeBelow(out PlacedTileObject pipe)) + // update pipe just below. + if (TryGetPipeBelow(out PlacedTileObject pipe)) { UpdateSingleConnection(Direction.North, pipe, true); }; @@ -57,13 +67,15 @@ public bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObje bool isConnected = IsConnected(neighbourObject); bool updated = _connectedToPipe != isConnected; - // Update our neighbour as well if (updated) neighbourObject.UpdateAdjacencies(); return updated; } + /// + /// Just get the pipe below the disposal furniture if it exists. + /// private bool TryGetPipeBelow(out PlacedTileObject pipe) { TileSystem tileSystem = Subsystems.Get(); @@ -76,6 +88,9 @@ private bool TryGetPipeBelow(out PlacedTileObject pipe) return pipe != null; } + /// + /// The only neighbour of a disposal furniture is the eventual disposal pipe just below it. + /// public List GetNeighbours() { bool hasNeighbour = TryGetPipeBelow(out PlacedTileObject pipe); diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs index 507317c8e1..46b038531e 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs @@ -15,37 +15,63 @@ namespace SS3D.Systems.Tile.Connections { + /// + /// Connector for disposal pipes only. + /// public class DisposalPipeAdjacencyConnector : NetworkActor, IAdjacencyConnector { + /// + /// Structure helping to determine disposal pipes shape and rotation. + /// [SerializeField] private DisposalPipeConnector _pipeAdjacency; - protected AdjacencyMap _adjacencyMap; + /// + /// Adjacency map for all horizontal connections. + /// + private AdjacencyMap _adjacencyMap; + /// + /// true if connected to a disposal furniture. + /// [SyncVar(OnChange = nameof(SyncVertical))] - protected bool _verticalConnection; + private bool _verticalConnection; + /// + /// Direction of the disposal pipe. Useful to update it on client. + /// [SyncVar(OnChange = nameof(SyncDirection))] - protected Direction _direction; + private Direction _direction; - protected MeshFilter _filter; + /// + /// The mesh of the disposal pipe. + /// + private MeshFilter _filter; - protected PlacedTileObject _placedObject; + /// + /// The placed object for this disposal pipe. + /// + private PlacedTileObject _placedObject; - public PlacedTileObject PlacedObject => _placedObject; + /// + /// A byte, representing the 8 possible connections with other pipes neighbours. + /// [SyncVar(OnChange = nameof(SyncAdjacencies))] private byte _syncedConnections; + /// + /// Upon Setup, this should stay true. + /// private bool _initialized; - protected TileObjectSpecificType _specificType; - private bool _isVertical = false; + private TileObjectGenericType _disposalType = TileObjectGenericType.Disposal; + /// + /// Number of horizontal connections of the disposal pipe, only count cardinal connections. + /// public int HorizontalConnectionCount => _adjacencyMap.CardinalConnectionCount; - private AdjacencyShape _currentShape; - private void Setup() { @@ -53,23 +79,17 @@ private void Setup() { _adjacencyMap = new AdjacencyMap(); _filter = GetComponent(); - if (IsServer) - { - _placedObject = GetComponent(); - if (_placedObject == null) - { - _specificType = TileObjectSpecificType.None; - } - else - { - _specificType = _placedObject.SpecificType; - } - } - + _placedObject = GetComponent(); _initialized = true; } } + /// + /// Connection for disposal pipes is not completely trivial. Disposal pipes should + /// not connect to neighbour pipe if they are vertical, unless they are in front of them. + /// If there is a disposal furniture above them, they should connected to it if they have a single + /// connection or none. They otherwise connect only to other disposal pipes. + /// public bool IsConnected(PlacedTileObject neighbourObject) { if (neighbourObject == null) return false; @@ -85,10 +105,7 @@ public bool IsConnected(PlacedTileObject neighbourObject) && neighbourConnectorAgain._verticalConnection == true) return IsConnectedToVerticalPipe(neighbourObject); - bool isConnected; - isConnected = neighbourObject.HasAdjacencyConnector; - isConnected &= neighbourObject.SpecificType == _specificType; - return isConnected; + return neighbourObject.HasAdjacencyConnector && neighbourObject.GenericType == _disposalType; } /// @@ -187,6 +204,9 @@ public bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObje _syncedConnections = _adjacencyMap.SerializeToByte(); _direction = _placedObject.Direction; UpdateMeshAndDirection(); + + // Update neighbour connector if they are pipes, + // and itself in all directions if it just removed a furniture above var connector = neighbourObject?.GetComponent(); if(connector != null) { @@ -201,8 +221,6 @@ public bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObje return isUpdated; } - // TODO : maybe interface should let updateAllconnections handle retrieving neighbours - // object, as it might not mean the same thing for different connectors. public void UpdateAllConnections() { Setup(); @@ -246,8 +264,6 @@ protected virtual void UpdateMeshAndDirection() transform.position = new Vector3(pos.x, 0f, pos.z); _filter.transform.localRotation = Quaternion.Euler(eulerRotation.x, info.Item2, eulerRotation.z); } - - _currentShape = info.Item3; } /// @@ -276,6 +292,9 @@ private void SyncVertical(bool oldValue, bool newValue, bool asServer) } } + /// + /// Sync direction on the client, and update mesh and direction. + /// private void SyncDirection(Direction oldValue, Direction newValue, bool asServer) { if (!asServer) @@ -285,6 +304,10 @@ private void SyncDirection(Direction oldValue, Direction newValue, bool asServer } } + /// + /// Get the neighbours of this disposal pipe. This include all disposal pipes + /// adjacents (cardinal and diagonal) and eventually the disposal furniture above it. + /// public List GetNeighbours() { PlacedTileObject placedDisposal = null; diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/PipeAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/PipeAdjacencyConnector.cs index 05ea05e557..6fb7ba0526 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/PipeAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/PipeAdjacencyConnector.cs @@ -6,6 +6,9 @@ namespace SS3D.Systems.Tile.Connections { + /// + /// Simple connector for pipes with a possible offset, such as atmos pipes. + /// public class PipeAdjacencyConnector : AbstractHorizontalConnector { [SerializeField] diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/TileObjectType.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/TileObjectType.cs index 9190133b2d..37ace6275a 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/TileObjectType.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/TileObjectType.cs @@ -22,7 +22,8 @@ public enum TileObjectGenericType Counter, Cable, Wire, - Door + Door, + Disposal, } /// diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/WallAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/WallAdjacencyConnector.cs index 6687009f52..8e272b0908 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/WallAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/WallAdjacencyConnector.cs @@ -11,13 +11,24 @@ namespace SS3D.Systems.Tile.Connections { + /// + /// Walls are mostly simply working like advanced connectors, but there is a few exceptions, + /// in particular with the way they connect with doors, hence why they need their own connector + /// script. + /// public class WallAdjacencyConnector : AbstractHorizontalConnector, IAdjacencyConnector { - + /// + /// Script to help walls to choose their shape. + /// [SerializeField] private AdvancedConnector _advancedAdjacency; protected override IMeshAndDirectionResolver AdjacencyResolver => _advancedAdjacency; + /// + /// Check if this wall is conencted to the neighbour object when it's a door. + /// Walls only connect to doors when they are on left or on right of doors. + /// private bool IsConnectedToDoor(PlacedTileObject neighbourObject) { var doorConnector = neighbourObject.GetComponent(); @@ -33,6 +44,9 @@ private bool IsConnectedToDoor(PlacedTileObject neighbourObject) return false; } + /// + /// Try to get a door on the left or on the right of this wall. + /// private bool TryGetOnLeftOrRightDoor(out PlacedTileObject door) { var tileSystem = Subsystems.Get(); @@ -55,6 +69,10 @@ private bool TryGetOnLeftOrRightDoor(out PlacedTileObject door) return false; } + /// + /// Walls connect to other walls, and to doors, when doors are placed on their left or on their + /// right. + /// public override bool IsConnected(PlacedTileObject neighbourObject) { if(neighbourObject == null) return false; @@ -77,7 +95,8 @@ public override bool IsConnected(PlacedTileObject neighbourObject) // This is to avoid the wall considering there's 3 connections, because if it does, it takes // a L2 shape which allow to see through the wall. - if(TryGetOnLeftOrRightDoor(out PlacedTileObject door) && neighbourObject.GetComponent() != null) + if(TryGetOnLeftOrRightDoor(out PlacedTileObject door) + && neighbourObject.GetComponent() != null) { if (neighbourObject.IsInFront(door) || neighbourObject.IsBehind(door)) { diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileConstants.cs b/Assets/Scripts/SS3D/Systems/Tile/TileConstants.cs index e104c8053f..92161d4d30 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/TileConstants.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/TileConstants.cs @@ -4,8 +4,14 @@ namespace SS3D.Systems.Tile { + /// + /// File to easily access some tile related constants. + /// public static class TileConstants { + /// + /// length of a chunk in tiles. Chunks are made of ChunkSize * ChunkSize tiles. + /// public const int ChunkSize = 16; } } diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileHelper.cs b/Assets/Scripts/SS3D/Systems/Tile/TileHelper.cs index bac5d6d31d..5661f08630 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/TileHelper.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/TileHelper.cs @@ -58,6 +58,11 @@ public static TileLayer[] GetTileLayers() return TileLayers; } + /// + /// Get the two adjacent directions from dir passed in parameter. + /// e.g if dir is North, return NorthWest and NorthEast. + /// + public static Tuple GetAdjacentDirections(Direction dir) { return new Tuple( (Direction) MathUtility.mod((int) dir + 1, 8), @@ -100,7 +105,7 @@ public static List CardinalDirections() } /// - /// Return a list of the cardinal directions. + /// Return a list of all existing directions. /// public static List AllDirections() { diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs b/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs index 3c0b991833..4ab79ecefb 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs @@ -236,12 +236,20 @@ public void ClearTileObject(Vector3 placePosition, TileLayer layer) private void ResetAdjacencies(PlacedTileObject placed, TileObject location, List neighbours) { List neighboursAtDirection= new List(); + + // First get the directions of all neighbours, relative to this placed object. + // Direction is not always relevant (e.g disposal pipes with disposal furnitures) + // but it is in most cases. It's up to the connectors to choose what they do with this info. foreach (PlacedTileObject neighbour in neighbours) { placed.NeighbourAtDirectionOf(neighbour, out var dir); neighboursAtDirection.Add(dir); } + // then destroy this placed object. It's important to do it here, before updating + // adjacencies, as some connectors might be looking for it. location.ClearPlacedObject(); + + // Then update all neighbours, using their directions. int i = 0; foreach (PlacedTileObject neighbour in neighbours) { diff --git a/Assets/Scripts/SS3D/Utils/MathUtility.cs b/Assets/Scripts/SS3D/Utils/MathUtility.cs index b94222ae9b..a44af95f43 100644 --- a/Assets/Scripts/SS3D/Utils/MathUtility.cs +++ b/Assets/Scripts/SS3D/Utils/MathUtility.cs @@ -6,6 +6,12 @@ namespace SS3D.Utils { public static class MathUtility { + /// + /// Real modulus operation working with negative numbers as well. + /// e.g mod(-3,5) = 2. + /// This is necessary because % operator is not a modulus operation, + /// it would return -3 instead of 2. + /// public static int mod(int x, int m) { return (x % m + m) % m; From ab131dc882dc339332a346a77d9ed15571f5f092 Mon Sep 17 00:00:00 2001 From: stilnat Date: Thu, 2 Nov 2023 12:23:14 +0100 Subject: [PATCH 41/52] update disposal pipes generic type --- .../Resources/Structures/Pipes/Disposals/DisposalPipes.asset | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/Content/Data/TileMap/Resources/Structures/Pipes/Disposals/DisposalPipes.asset b/Assets/Content/Data/TileMap/Resources/Structures/Pipes/Disposals/DisposalPipes.asset index 6405acea4d..9cc04e3bf4 100644 --- a/Assets/Content/Data/TileMap/Resources/Structures/Pipes/Disposals/DisposalPipes.asset +++ b/Assets/Content/Data/TileMap/Resources/Structures/Pipes/Disposals/DisposalPipes.asset @@ -16,7 +16,7 @@ MonoBehaviour: prefab: {fileID: 2802364579275783218, guid: 12a989ad41a83a3468d1ae9aff9628d3, type: 3} icon: {fileID: 0} layer: 3 - genericType: 0 + genericType: 14 specificType: 0 width: 1 height: 1 From 68a3caab5fe6d4165717389420f4a477e278acc7 Mon Sep 17 00:00:00 2001 From: stilnat Date: Mon, 6 Nov 2023 00:30:57 +0100 Subject: [PATCH 42/52] adapt code to multiple tile objects --- .../SS3D/Systems/Tile/CardinalTileLocation.cs | 5 ++ .../Connections/DisposalFurnitureConnector.cs | 3 +- .../DisposalPipeAdjacencyConnector.cs | 2 +- .../SS3D/Systems/Tile/ITileLocation.cs | 2 + .../SS3D/Systems/Tile/SingleTileLocation.cs | 6 ++ Assets/Scripts/SS3D/Systems/Tile/TileChunk.cs | 7 ++- .../Scripts/SS3D/Systems/Tile/TileHelper.cs | 8 ++- Assets/Scripts/SS3D/Systems/Tile/TileMap.cs | 57 ++++++++++--------- 8 files changed, 56 insertions(+), 34 deletions(-) diff --git a/Assets/Scripts/SS3D/Systems/Tile/CardinalTileLocation.cs b/Assets/Scripts/SS3D/Systems/Tile/CardinalTileLocation.cs index c3bdc7e615..df0aff9b84 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/CardinalTileLocation.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/CardinalTileLocation.cs @@ -127,5 +127,10 @@ private Direction IndexToDir(int i) { return (Direction) (i*2); } + + public List GetAllPlacedObject() + { + return _cardinalPlacedTileObject.Where(x => x!= null).ToList(); + } } } diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs index b3b0402444..9b0e8f7718 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalFurnitureConnector.cs @@ -82,7 +82,8 @@ private bool TryGetPipeBelow(out PlacedTileObject pipe) var map = tileSystem.CurrentMap; TileChunk currentChunk = map.GetChunk(_placedObject.gameObject.transform.position); - var pipeLocation = currentChunk.GetTileObject(TileLayer.Disposal, _placedObject.Origin.x, _placedObject.Origin.y); + SingleTileLocation pipeLocation = (SingleTileLocation) currentChunk.GetTileLocation(TileLayer.Disposal, + _placedObject.Origin.x, _placedObject.Origin.y); pipe = pipeLocation.PlacedObject; return pipe != null; diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs index 46b038531e..68003037ee 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/Connections/DisposalPipeAdjacencyConnector.cs @@ -160,7 +160,7 @@ private bool TryGetDisposalElementAbovePipe(out IDisposalElement disposalFurnitu var map = tileSystem.CurrentMap; TileChunk currentChunk = map.GetChunk(_placedObject.gameObject.transform.position); - var furnitureLocation = currentChunk.GetTileObject(TileLayer.FurnitureBase, _placedObject.Origin.x, _placedObject.Origin.y); + SingleTileLocation furnitureLocation = (SingleTileLocation) currentChunk.GetTileLocation(TileLayer.FurnitureBase, _placedObject.Origin.x, _placedObject.Origin.y); disposalFurniture = furnitureLocation.PlacedObject?.GetComponent(); return disposalFurniture != null; diff --git a/Assets/Scripts/SS3D/Systems/Tile/ITileLocation.cs b/Assets/Scripts/SS3D/Systems/Tile/ITileLocation.cs index 28e336d703..357dca0182 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/ITileLocation.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/ITileLocation.cs @@ -21,6 +21,8 @@ public TileLayer Layer /// public bool TryGetPlacedObject(out PlacedTileObject placedObject, Direction direction = Direction.North); + public List GetAllPlacedObject(); + /// /// Check if the tile is empty for a given direction. /// diff --git a/Assets/Scripts/SS3D/Systems/Tile/SingleTileLocation.cs b/Assets/Scripts/SS3D/Systems/Tile/SingleTileLocation.cs index 270ccfde34..5983b5d6d2 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/SingleTileLocation.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/SingleTileLocation.cs @@ -84,5 +84,11 @@ public void AddPlacedObject(PlacedTileObject tileObject, Direction direction = D { PlacedObject = tileObject; } + + public List GetAllPlacedObject() + { + return PlacedObject != null ? + new List { PlacedObject } : new List(); + } } } \ No newline at end of file diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileChunk.cs b/Assets/Scripts/SS3D/Systems/Tile/TileChunk.cs index 9a3e24c99d..699582cd78 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/TileChunk.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/TileChunk.cs @@ -209,11 +209,12 @@ public List GetAllTilePlacedObjects() var list = new List(); foreach(TileGrid grid in _tileGridList) { - foreach(TileObject obj in grid.TileObjectsGrid) + foreach(ITileLocation location in grid.TileObjectsGrid) { - if(obj.PlacedObject != null) + + if(location != null) { - list.Add(obj.PlacedObject); + list.AddRange(location.GetAllPlacedObject()); } } } diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileHelper.cs b/Assets/Scripts/SS3D/Systems/Tile/TileHelper.cs index 1374fc4e5a..3f826da7a4 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/TileHelper.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/TileHelper.cs @@ -224,7 +224,13 @@ public static ITileLocation CreateTileLocation(TileLayer layer, int x, int y) return new SingleTileLocation(layer, x, y); case TileLayer.Disposal: return new SingleTileLocation(layer, x, y); - case TileLayer.Pipes: + case TileLayer.PipeSurface: + return new SingleTileLocation(layer, x, y); + case TileLayer.PipeMiddle: + return new SingleTileLocation(layer, x, y); + case TileLayer.PipeRight: + return new SingleTileLocation(layer, x, y); + case TileLayer.PipeLeft: return new SingleTileLocation(layer, x, y); case TileLayer.WallMountHigh: return new CardinalTileLocation(layer, x, y); diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs b/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs index 3aac22a2c5..853406eb4d 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs @@ -9,6 +9,7 @@ using System.Collections.Generic; using System.Linq; using UnityEngine; +using static UnityEditor.FilePathAttribute; namespace SS3D.Systems.Tile { @@ -139,7 +140,7 @@ private ITileLocation[] GetTileLocations(Vector3 worldPosition) /// /// /// - private PlacedTileObject[] GetNeighbourPlacedObjects(TileLayer layer, Vector3 worldPosition) + public PlacedTileObject[] GetNeighbourPlacedObjects(TileLayer layer, Vector3 worldPosition) { PlacedTileObject[] adjacentObjects = new PlacedTileObject[8]; @@ -217,11 +218,9 @@ public bool PlaceTileObject(TileObjectSo tileObjectSo, Vector3 placePosition, Di public void ClearTileObject(Vector3 placePosition, TileLayer layer, Direction dir) { - TileObject[] tileObjects = GetTileObjects(placePosition); - TileObject tileObject = tileObjects[(int)layer]; - PlacedTileObject placed = tileObject.PlacedObject; ITileLocation[] tileObjects = GetTileLocations(placePosition); - tileObjects[(int)layer].TryClearPlacedObject(dir); + ITileLocation tileObject = tileObjects[(int)layer]; + tileObject.TryGetPlacedObject(out var placed, dir); if (placed != null && placed.TryGetComponent(out IAdjacencyConnector connector)) @@ -235,21 +234,22 @@ public void ClearTileObject(Vector3 placePosition, TileLayer layer, Direction di foreach (ITileLocation clearLocation in toClearLocations) { - placed = removeObject.PlacedObject; + var allPlaced = clearLocation.GetAllPlacedObject(); - if (placed != null && placed.TryGetComponent(out connector)) + foreach (PlacedTileObject placedToClear in allPlaced) { - List neighbours = connector.GetNeighbours(); - ResetAdjacencies(placed, removeObject, neighbours); + if (placed != null && placedToClear.TryGetComponent(out connector)) + { + List neighbours = connector.GetNeighbours(); + ResetAdjacencies(placed, clearLocation, neighbours); + } } - removeObject.ClearPlacedObject(); clearLocation.ClearAllPlacedObject(); - ResetAdjacencies(placePosition, clearLocation.Layer); } } - private void ResetAdjacencies(PlacedTileObject placed, TileObject location, List neighbours) + private void ResetAdjacencies(PlacedTileObject placed, ITileLocation location, List neighbours) { List neighboursAtDirection= new List(); @@ -263,7 +263,7 @@ private void ResetAdjacencies(PlacedTileObject placed, TileObject location, List } // then destroy this placed object. It's important to do it here, before updating // adjacencies, as some connectors might be looking for it. - location.ClearPlacedObject(); + location.ClearAllPlacedObject(); // Then update all neighbours, using their directions. int i = 0; @@ -345,11 +345,11 @@ public SavedTileMap Save() public void Load([CanBeNull] SavedTileMap saveObject) { - if (saveObject == null) - { + if (saveObject == null) + { Log.Warning(this, "The intended save object is null"); - return; - } + return; + } Clear(); @@ -362,24 +362,25 @@ public void Load([CanBeNull] SavedTileMap saveObject) foreach (var savedTile in savedTiles) { - foreach(SavedPlacedTileObject savedObject in savedTile.GetPlacedObjects()) + foreach (SavedPlacedTileObject savedObject in savedTile.GetPlacedObjects()) { TileObjectSo toBePlaced = (TileObjectSo)tileSystem.GetAsset(savedObject.tileObjectSOName); Vector3 placePosition = chunk.GetWorldPosition(savedTile.Location.x, savedTile.Location.y); - // Skipping build check here to allow loading tile objects in a non-valid order - PlaceTileObject(toBePlaced, placePosition, savedTile.placedSaveObject.dir, true, false, true); + // Skipping build check here to allow loading tile objects in a non-valid order + PlaceTileObject(toBePlaced, placePosition, savedObject.dir, true, false, true); + } } - } - foreach (SavedPlacedItemObject savedItem in saveObject.savedItemList) - { - ItemObjectSo toBePlaced = (ItemObjectSo)tileSystem.GetAsset(savedItem.itemName); - PlaceItemObject(savedItem.worldPosition, savedItem.rotation, toBePlaced); - } + foreach (SavedPlacedItemObject savedItem in saveObject.savedItemList) + { + ItemObjectSo toBePlaced = (ItemObjectSo)tileSystem.GetAsset(savedItem.itemName); + PlaceItemObject(savedItem.worldPosition, savedItem.rotation, toBePlaced); + } - OnMapLoaded?.Invoke(this, EventArgs.Empty); - UpdateAllAdjacencies(); + OnMapLoaded?.Invoke(this, EventArgs.Empty); + UpdateAllAdjacencies(); + } } /// From f7d06e4e9f01f619f1babb23e50c37c9a50b7323 Mon Sep 17 00:00:00 2001 From: stilnat Date: Mon, 6 Nov 2023 00:51:40 +0100 Subject: [PATCH 43/52] remove multi adjacency update some prefabs --- .../Generic/Surfaces/Tables/TableGlass.prefab | 95 ++++------ .../Generic/Surfaces/Tables/TableSteel.prefab | 95 ++++------ .../Structures/Floors/Plenum.prefab | 65 +------ .../Structures/Walls/SteelGirder.prefab | 51 ++--- .../Connections/MultiAdjacencyConnector.cs | 176 ------------------ .../MultiAdjacencyConnector.cs.meta | 11 -- 6 files changed, 102 insertions(+), 391 deletions(-) delete mode 100644 Assets/Scripts/SS3D/Systems/Tile/Connections/MultiAdjacencyConnector.cs delete mode 100644 Assets/Scripts/SS3D/Systems/Tile/Connections/MultiAdjacencyConnector.cs.meta diff --git a/Assets/Content/WorldObjects/Furniture/Generic/Surfaces/Tables/TableGlass.prefab b/Assets/Content/WorldObjects/Furniture/Generic/Surfaces/Tables/TableGlass.prefab index 9a0ca4726c..2311b988ec 100644 --- a/Assets/Content/WorldObjects/Furniture/Generic/Surfaces/Tables/TableGlass.prefab +++ b/Assets/Content/WorldObjects/Furniture/Generic/Surfaces/Tables/TableGlass.prefab @@ -12,8 +12,8 @@ GameObject: - component: {fileID: 1422391141370617402} - component: {fileID: 2885897057548802505} - component: {fileID: 8860121059280945640} - - component: {fileID: 7988096599566893515} - component: {fileID: 6244957436306937818} + - component: {fileID: 2130642872359250283} m_Layer: 0 m_Name: TableGlass m_TagString: Untagged @@ -100,7 +100,39 @@ BoxCollider: serializedVersion: 2 m_Size: {x: 1, y: 0.75, z: 1} m_Center: {x: 0, y: 0.375, z: 0} ---- !u!114 &7988096599566893515 +--- !u!114 &6244957436306937818 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2839728781945606427} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 26b716c41e9b56b4baafaf13a523ba2e, type: 3} + m_Name: + m_EditorClassIdentifier: + k__BackingField: 0 + k__BackingField: 0 + k__BackingField: {fileID: 0} + _networkBehaviours: [] + k__BackingField: {fileID: 0} + k__BackingField: [] + SerializedTransformProperties: + Position: {x: 0, y: 0, z: 0} + Rotation: {x: 0, y: 0, z: 0, w: 0} + LocalScale: {x: 0, y: 0, z: 0} + _isNetworked: 1 + _isGlobal: 0 + _initializeOrder: 0 + _defaultDespawnType: 0 + NetworkObserver: {fileID: 0} + k__BackingField: 65535 + k__BackingField: 0 + _scenePathHash: 0 + k__BackingField: 0 + k__BackingField: 10426574306644170534 +--- !u!114 &2130642872359250283 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -109,21 +141,14 @@ MonoBehaviour: m_GameObject: {fileID: 2839728781945606427} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 53a5cd0d46abb6d4d8686d11153009c2, type: 3} + m_Script: {fileID: 11500000, guid: ef4340642b9b436498fe733f9329ac87, type: 3} m_Name: m_EditorClassIdentifier: - _componentIndexCache: 0 + _componentIndexCache: 255 _addedNetworkObject: {fileID: 6244957436306937818} - _networkObjectCache: {fileID: 6244957436306937818} - SelectedAdjacencyType: 1 - _simpleAdjacency: - o: {fileID: 0} - u: {fileID: 0} - i: {fileID: 0} - l: {fileID: 0} - t: {fileID: 0} - x: {fileID: 0} - _advancedAdjacency: + _networkObjectCache: {fileID: 0} + _syncedConnections: 0 + advancedAdjacency: o: {fileID: -6474879442438147634, guid: 32ccf9db762cc7c4f8f4af524e3e7ee7, type: 3} u: {fileID: -7482589699367499308, guid: 32ccf9db762cc7c4f8f4af524e3e7ee7, type: 3} i: {fileID: -2157360573737795375, guid: 32ccf9db762cc7c4f8f4af524e3e7ee7, type: 3} @@ -141,45 +166,3 @@ MonoBehaviour: xQuad: {fileID: 2518676867277241252, guid: 32ccf9db762cc7c4f8f4af524e3e7ee7, type: 3} viewObstacles: [] opaque: 0 - _offsetAdjacency: - o: {fileID: 0} - uNorth: {fileID: 0} - uSouth: {fileID: 0} - i: {fileID: 0} - lNE: {fileID: 0} - lNW: {fileID: 0} - lSE: {fileID: 0} - lSW: {fileID: 0} - tNEW: {fileID: 0} - tNSW: {fileID: 0} - tNSE: {fileID: 0} - tSWE: {fileID: 0} - x: {fileID: 0} - _syncedConnections: 0 ---- !u!114 &6244957436306937818 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2839728781945606427} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 26b716c41e9b56b4baafaf13a523ba2e, type: 3} - m_Name: - m_EditorClassIdentifier: - k__BackingField: 0 - k__BackingField: 0 - _networkBehaviours: - - {fileID: 7988096599566893515} - k__BackingField: {fileID: 0} - k__BackingField: [] - _isNetworked: 1 - _isGlobal: 0 - _defaultDespawnType: 0 - NetworkObserver: {fileID: 0} - k__BackingField: -1 - _scenePathHash: 0 - k__BackingField: 0 - k__BackingField: 10426574306644170534 - _sceneNetworkObjects: [] diff --git a/Assets/Content/WorldObjects/Furniture/Generic/Surfaces/Tables/TableSteel.prefab b/Assets/Content/WorldObjects/Furniture/Generic/Surfaces/Tables/TableSteel.prefab index e3a409c7ab..d842833e6e 100644 --- a/Assets/Content/WorldObjects/Furniture/Generic/Surfaces/Tables/TableSteel.prefab +++ b/Assets/Content/WorldObjects/Furniture/Generic/Surfaces/Tables/TableSteel.prefab @@ -12,8 +12,8 @@ GameObject: - component: {fileID: 6583449581753452249} - component: {fileID: 6984099654956712234} - component: {fileID: 3608857327747406091} - - component: {fileID: 3121066318499380073} - component: {fileID: 8635336608555116780} + - component: {fileID: 867590509919929168} m_Layer: 0 m_Name: TableSteel m_TagString: Untagged @@ -99,7 +99,39 @@ BoxCollider: serializedVersion: 2 m_Size: {x: 1, y: 0.75, z: 1} m_Center: {x: 0, y: 0.375, z: 0} ---- !u!114 &3121066318499380073 +--- !u!114 &8635336608555116780 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8036950609662249464} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 26b716c41e9b56b4baafaf13a523ba2e, type: 3} + m_Name: + m_EditorClassIdentifier: + k__BackingField: 0 + k__BackingField: 0 + k__BackingField: {fileID: 0} + _networkBehaviours: [] + k__BackingField: {fileID: 0} + k__BackingField: [] + SerializedTransformProperties: + Position: {x: 0, y: 0, z: 0} + Rotation: {x: 0, y: 0, z: 0, w: 0} + LocalScale: {x: 0, y: 0, z: 0} + _isNetworked: 1 + _isGlobal: 0 + _initializeOrder: 0 + _defaultDespawnType: 0 + NetworkObserver: {fileID: 0} + k__BackingField: 65535 + k__BackingField: 0 + _scenePathHash: 0 + k__BackingField: 0 + k__BackingField: 10626543207120909748 +--- !u!114 &867590509919929168 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -108,21 +140,14 @@ MonoBehaviour: m_GameObject: {fileID: 8036950609662249464} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 53a5cd0d46abb6d4d8686d11153009c2, type: 3} + m_Script: {fileID: 11500000, guid: ef4340642b9b436498fe733f9329ac87, type: 3} m_Name: m_EditorClassIdentifier: - _componentIndexCache: 0 + _componentIndexCache: 255 _addedNetworkObject: {fileID: 8635336608555116780} - _networkObjectCache: {fileID: 8635336608555116780} - SelectedAdjacencyType: 1 - _simpleAdjacency: - o: {fileID: 0} - u: {fileID: 0} - i: {fileID: 0} - l: {fileID: 0} - t: {fileID: 0} - x: {fileID: 0} - _advancedAdjacency: + _networkObjectCache: {fileID: 0} + _syncedConnections: 0 + advancedAdjacency: o: {fileID: -6584651252408597845, guid: 32ccf9db762cc7c4f8f4af524e3e7ee7, type: 3} u: {fileID: 1516601059846573687, guid: 32ccf9db762cc7c4f8f4af524e3e7ee7, type: 3} i: {fileID: -7725530803512371161, guid: 32ccf9db762cc7c4f8f4af524e3e7ee7, type: 3} @@ -140,45 +165,3 @@ MonoBehaviour: xQuad: {fileID: -7024319511112420413, guid: 32ccf9db762cc7c4f8f4af524e3e7ee7, type: 3} viewObstacles: [] opaque: 0 - _offsetAdjacency: - o: {fileID: 0} - uNorth: {fileID: 0} - uSouth: {fileID: 0} - i: {fileID: 0} - lNE: {fileID: 0} - lNW: {fileID: 0} - lSE: {fileID: 0} - lSW: {fileID: 0} - tNEW: {fileID: 0} - tNSW: {fileID: 0} - tNSE: {fileID: 0} - tSWE: {fileID: 0} - x: {fileID: 0} - _syncedConnections: 0 ---- !u!114 &8635336608555116780 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 8036950609662249464} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 26b716c41e9b56b4baafaf13a523ba2e, type: 3} - m_Name: - m_EditorClassIdentifier: - k__BackingField: 0 - k__BackingField: 0 - _networkBehaviours: - - {fileID: 3121066318499380073} - k__BackingField: {fileID: 0} - k__BackingField: [] - _isNetworked: 1 - _isGlobal: 0 - _defaultDespawnType: 0 - NetworkObserver: {fileID: 0} - k__BackingField: -1 - _scenePathHash: 0 - k__BackingField: 0 - k__BackingField: 10626543207120909748 - _sceneNetworkObjects: [] diff --git a/Assets/Content/WorldObjects/Structures/Floors/Plenum.prefab b/Assets/Content/WorldObjects/Structures/Floors/Plenum.prefab index ec0d9c7d4f..5ee1ccedf5 100644 --- a/Assets/Content/WorldObjects/Structures/Floors/Plenum.prefab +++ b/Assets/Content/WorldObjects/Structures/Floors/Plenum.prefab @@ -180,7 +180,6 @@ GameObject: - component: {fileID: 2586358896294450200} - component: {fileID: 5107901468329445811} - component: {fileID: 7564222845035831833} - - component: {fileID: -3175721348291802995} m_Layer: 0 m_Name: Plenum m_TagString: Untagged @@ -282,71 +281,21 @@ MonoBehaviour: m_EditorClassIdentifier: k__BackingField: 0 k__BackingField: 0 + k__BackingField: {fileID: 0} _networkBehaviours: [] k__BackingField: {fileID: 0} k__BackingField: [] + SerializedTransformProperties: + Position: {x: 0, y: 0, z: 0} + Rotation: {x: 0, y: 0, z: 0, w: 0} + LocalScale: {x: 0, y: 0, z: 0} _isNetworked: 1 _isGlobal: 0 + _initializeOrder: 0 _defaultDespawnType: 0 NetworkObserver: {fileID: 0} k__BackingField: 16 + k__BackingField: 0 _scenePathHash: 0 k__BackingField: 0 k__BackingField: 1135847911748521981 - _sceneNetworkObjects: [] ---- !u!114 &-3175721348291802995 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 8028539322119499722} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 53a5cd0d46abb6d4d8686d11153009c2, type: 3} - m_Name: - m_EditorClassIdentifier: - _componentIndexCache: 255 - _addedNetworkObject: {fileID: 7564222845035831833} - _networkObjectCache: {fileID: 0} - SelectedAdjacencyType: 1 - _simpleAdjacency: - o: {fileID: 0} - u: {fileID: 0} - i: {fileID: 0} - l: {fileID: 0} - t: {fileID: 0} - x: {fileID: 0} - _advancedAdjacency: - o: {fileID: -1186837388861869702, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} - u: {fileID: 8670779871488701567, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} - i: {fileID: 2136686312440598757, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} - lNone: {fileID: 4400090147443950985, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} - lSingle: {fileID: 4907585101989539511, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} - tNone: {fileID: -5997185706695327500, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} - tSingleRight: {fileID: -7342849457706584406, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} - tSingleLeft: {fileID: -4854898696076092651, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} - tDouble: {fileID: -53862880159183297, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} - xNone: {fileID: 77848856100225938, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} - xSingle: {fileID: -8966661648484664196, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} - xSide: {fileID: -513754039711199066, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} - xOpposite: {fileID: 6731330203905936185, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} - xTriple: {fileID: 4104832187742309709, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} - xQuad: {fileID: 2496505603022733099, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} - viewObstacles: [] - opaque: 0 - _offsetAdjacency: - o: {fileID: 0} - uNorth: {fileID: 0} - uSouth: {fileID: 0} - i: {fileID: 0} - lNE: {fileID: 0} - lNW: {fileID: 0} - lSE: {fileID: 0} - lSW: {fileID: 0} - tNEW: {fileID: 0} - tNSW: {fileID: 0} - tNSE: {fileID: 0} - tSWE: {fileID: 0} - x: {fileID: 0} - _syncedConnections: 0 diff --git a/Assets/Content/WorldObjects/Structures/Walls/SteelGirder.prefab b/Assets/Content/WorldObjects/Structures/Walls/SteelGirder.prefab index c4f4b82fe3..075f301621 100644 --- a/Assets/Content/WorldObjects/Structures/Walls/SteelGirder.prefab +++ b/Assets/Content/WorldObjects/Structures/Walls/SteelGirder.prefab @@ -13,7 +13,7 @@ GameObject: - component: {fileID: 6696866361892651655} - component: {fileID: 7033236083530598125} - component: {fileID: -2900075557854325373} - - component: {fileID: 1492278076387892290} + - component: {fileID: 8380654261086022907} m_Layer: 0 m_Name: SteelGirder m_TagString: Untagged @@ -114,20 +114,25 @@ MonoBehaviour: m_EditorClassIdentifier: k__BackingField: 0 k__BackingField: 0 - _networkBehaviours: - - {fileID: 1492278076387892290} + k__BackingField: {fileID: 0} + _networkBehaviours: [] k__BackingField: {fileID: 0} k__BackingField: [] + SerializedTransformProperties: + Position: {x: 0, y: 0, z: 0} + Rotation: {x: 0, y: 0, z: 0, w: 0} + LocalScale: {x: 0, y: 0, z: 0} _isNetworked: 1 _isGlobal: 0 + _initializeOrder: 0 _defaultDespawnType: 0 NetworkObserver: {fileID: 0} - k__BackingField: -1 + k__BackingField: 65535 + k__BackingField: 0 _scenePathHash: 0 k__BackingField: 0 k__BackingField: 10701242530576259807 - _sceneNetworkObjects: [] ---- !u!114 &1492278076387892290 +--- !u!114 &8380654261086022907 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -136,22 +141,15 @@ MonoBehaviour: m_GameObject: {fileID: 3591147544166670882} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 53a5cd0d46abb6d4d8686d11153009c2, type: 3} + m_Script: {fileID: 11500000, guid: ef4340642b9b436498fe733f9329ac87, type: 3} m_Name: m_EditorClassIdentifier: - _componentIndexCache: 0 + _componentIndexCache: 255 _addedNetworkObject: {fileID: -2900075557854325373} - _networkObjectCache: {fileID: -2900075557854325373} - SelectedAdjacencyType: 1 - _simpleAdjacency: - o: {fileID: 0} - u: {fileID: 0} - i: {fileID: 0} - l: {fileID: 0} - t: {fileID: 0} - x: {fileID: 0} - _advancedAdjacency: - o: {fileID: -7104584066017280917, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} + _networkObjectCache: {fileID: 0} + _syncedConnections: 0 + advancedAdjacency: + o: {fileID: -3462111060628849216, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} u: {fileID: 2256514625206161274, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} i: {fileID: -8265987230191886290, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} lNone: {fileID: 8776228716606939545, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} @@ -168,18 +166,3 @@ MonoBehaviour: xQuad: {fileID: 4011312947144960823, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} viewObstacles: [] opaque: 0 - _offsetAdjacency: - o: {fileID: 0} - uNorth: {fileID: 0} - uSouth: {fileID: 0} - i: {fileID: 0} - lNE: {fileID: 0} - lNW: {fileID: 0} - lSE: {fileID: 0} - lSW: {fileID: 0} - tNEW: {fileID: 0} - tNSW: {fileID: 0} - tNSE: {fileID: 0} - tSWE: {fileID: 0} - x: {fileID: 0} - _syncedConnections: 0 diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/MultiAdjacencyConnector.cs b/Assets/Scripts/SS3D/Systems/Tile/Connections/MultiAdjacencyConnector.cs deleted file mode 100644 index 79035fd415..0000000000 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/MultiAdjacencyConnector.cs +++ /dev/null @@ -1,176 +0,0 @@ -using FishNet.Object; -using FishNet.Object.Synchronizing; -using SS3D.Core; -using SS3D.Logging; -using SS3D.Systems.Tile.Connections.AdjacencyTypes; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using UnityEngine; -using UnityEngine.Serialization; - -namespace SS3D.Systems.Tile.Connections -{ - /// - /// Main adjacency connector class that should fulfill the majority of the use cases. This class ensures that similar objects will have their meshes seamlessly connect to each other. - /// - public class MultiAdjacencyConnector : NetworkBehaviour, IAdjacencyConnector - { - /// - /// Determines which adjacency type should be used. - /// - [FormerlySerializedAs("selectedAdjacencyType")] public AdjacencyType SelectedAdjacencyType; - - /// - /// A type that specifies to which objects to connect to. Must be set if cross connect is used. - /// - [Tooltip("Generic ID that adjacent objects must be to count. If empty, any id is accepted.")] - private TileObjectGenericType _genericType; - - /// - /// Specific ID to differentiate objects when the generic is the same. - /// - [Tooltip("Specific ID to differentiate objects when the generic is the same.")] - private TileObjectSpecificType _specificType; - - [FormerlySerializedAs("simpleAdjacency")] [SerializeField] private SimpleConnector _simpleAdjacency; - [FormerlySerializedAs("advancedAdjacency")] [SerializeField] private AdvancedConnector _advancedAdjacency; - [FormerlySerializedAs("offsetAdjacency")] [SerializeField] private OffsetConnector _offsetAdjacency; - - private AdjacencyMap _adjacencyMap; - - [SyncVar(OnChange = nameof(SyncAdjacencies))] - private byte _syncedConnections; - - private MeshFilter _filter; - private bool _initialized; - private PlacedTileObject _placedObject; - - public override void OnStartClient() - { - base.OnStartClient(); - Setup(); - } - - private void Setup() - { - if (!_initialized) - { - _adjacencyMap = new AdjacencyMap(); - _filter = GetComponent(); - - _placedObject = GetComponent(); - if (_placedObject == null) - { - _genericType = TileObjectGenericType.None; - _specificType = TileObjectSpecificType.None; - } - else - { - _genericType = _placedObject.GenericType; - _specificType = _placedObject.SpecificType; - } - _initialized = true; - } - } - - public bool UpdateSingleConnection(Direction dir, PlacedTileObject neighbourObject, bool updateNeighbour) - { - Setup(); - bool isConnected = false; - bool isUpdated = false; - - if (neighbourObject) - { - isConnected = (neighbourObject && neighbourObject.HasAdjacencyConnector); - isConnected &= neighbourObject.GenericType == _genericType || _genericType == TileObjectGenericType.None; - isConnected &= neighbourObject.SpecificType == _specificType || _specificType == TileObjectSpecificType.None; - - // Update our neighbour as well - if (isConnected && updateNeighbour) - neighbourObject.UpdateSingleAdjacency(TileHelper.GetOpposite(dir), _placedObject, false); - } - - isUpdated = _adjacencyMap.SetConnection(dir, new AdjacencyData(TileObjectGenericType.None, TileObjectSpecificType.None, isConnected)); - if (isUpdated) - { - _syncedConnections = _adjacencyMap.SerializeToByte(); - UpdateMeshAndDirection(); - } - - return isUpdated; - } - - public void UpdateAllConnections() - { - Setup(); - - var neighbourObjects = GetNeighbours(); - - bool changed = false; - foreach (var neighbourObject in neighbourObjects) - { - _placedObject.NeighbourAtDirectionOf(neighbourObject, out Direction dir); - changed |= UpdateSingleConnection(dir, neighbourObject, true); - } - - if (changed) - { - UpdateMeshAndDirection(); - } - } - - private void UpdateMeshAndDirection() - { - MeshDirectionInfo info = new(); - switch (SelectedAdjacencyType) - { - case AdjacencyType.Simple: - info = _simpleAdjacency.GetMeshAndDirection(_adjacencyMap); - break; - case AdjacencyType.Advanced: - info = _advancedAdjacency.GetMeshAndDirection(_adjacencyMap); - break; - case AdjacencyType.Offset: - info = _offsetAdjacency.GetMeshAndDirection(_adjacencyMap); - break; - } - - if (_filter == null) - { - Log.Warning(this, "Missing mesh {meshDirectionInfo}", Logs.Generic, info ); - } - - _filter.mesh = info.Mesh; - - Quaternion localRotation = transform.localRotation; - Vector3 eulerRotation = localRotation.eulerAngles; - localRotation = Quaternion.Euler(eulerRotation.x, info.Rotation, eulerRotation.z); - - transform.localRotation = localRotation; - } - - private void SyncAdjacencies(byte oldValue, byte newValue, bool asServer) - { - if (!asServer) - { - Setup(); - - _adjacencyMap.DeserializeFromByte(newValue); - UpdateMeshAndDirection(); - } - } - - public bool IsConnected(PlacedTileObject neighbourObject) - { - throw new System.NotImplementedException(); - } - - public List GetNeighbours() - { - TileSystem tileSystem = Subsystems.Get(); - var map = tileSystem.CurrentMap; - return map.GetNeighbourPlacedObjects(_placedObject.Layer, _placedObject.gameObject.transform.position).ToList(); - } - } -} \ No newline at end of file diff --git a/Assets/Scripts/SS3D/Systems/Tile/Connections/MultiAdjacencyConnector.cs.meta b/Assets/Scripts/SS3D/Systems/Tile/Connections/MultiAdjacencyConnector.cs.meta deleted file mode 100644 index 2715ec5d88..0000000000 --- a/Assets/Scripts/SS3D/Systems/Tile/Connections/MultiAdjacencyConnector.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 53a5cd0d46abb6d4d8686d11153009c2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: From d9f33f862558868e0e4dbcc33fa7ee2fd6bddd48 Mon Sep 17 00:00:00 2001 From: stilnat Date: Mon, 6 Nov 2023 11:58:02 +0100 Subject: [PATCH 44/52] fix missing scripts --- .../Walls/SteelWallReinforced.prefab | 48 ++++++----------- .../Structures/Walls/SteelWindow.prefab | 47 ++++++---------- .../Walls/SteelWindowReinforced.prefab | 49 ++++++----------- .../Structures/Wires/Cables.prefab | 53 +++++-------------- 4 files changed, 60 insertions(+), 137 deletions(-) diff --git a/Assets/Content/WorldObjects/Structures/Walls/SteelWallReinforced.prefab b/Assets/Content/WorldObjects/Structures/Walls/SteelWallReinforced.prefab index 9e149af730..ac31c7c746 100644 --- a/Assets/Content/WorldObjects/Structures/Walls/SteelWallReinforced.prefab +++ b/Assets/Content/WorldObjects/Structures/Walls/SteelWallReinforced.prefab @@ -148,7 +148,7 @@ GameObject: - component: {fileID: 6696866361892651655} - component: {fileID: 7033236083530598125} - component: {fileID: -2900075557854325373} - - component: {fileID: 1492278076387892290} + - component: {fileID: 3011383631706744183} m_Layer: 0 m_Name: SteelWallReinforced m_TagString: Untagged @@ -253,20 +253,26 @@ MonoBehaviour: m_EditorClassIdentifier: k__BackingField: 0 k__BackingField: 0 + k__BackingField: {fileID: 0} _networkBehaviours: - - {fileID: 1492278076387892290} + - {fileID: 0} k__BackingField: {fileID: 0} k__BackingField: [] + SerializedTransformProperties: + Position: {x: 0, y: 0, z: 0} + Rotation: {x: 0, y: 0, z: 0, w: 0} + LocalScale: {x: 0, y: 0, z: 0} _isNetworked: 1 _isGlobal: 0 + _initializeOrder: 0 _defaultDespawnType: 0 NetworkObserver: {fileID: 0} - k__BackingField: -1 + k__BackingField: 65535 + k__BackingField: 0 _scenePathHash: 0 k__BackingField: 0 k__BackingField: 15843822419293565003 - _sceneNetworkObjects: [] ---- !u!114 &1492278076387892290 +--- !u!114 &3011383631706744183 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -275,20 +281,13 @@ MonoBehaviour: m_GameObject: {fileID: 3591147544166670882} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 53a5cd0d46abb6d4d8686d11153009c2, type: 3} + m_Script: {fileID: 11500000, guid: d3995769f8fecf9469d1783a30e75625, type: 3} m_Name: m_EditorClassIdentifier: - _componentIndexCache: 0 + _componentIndexCache: 255 _addedNetworkObject: {fileID: -2900075557854325373} - _networkObjectCache: {fileID: -2900075557854325373} - SelectedAdjacencyType: 1 - _simpleAdjacency: - o: {fileID: 0} - u: {fileID: 0} - i: {fileID: 0} - l: {fileID: 0} - t: {fileID: 0} - x: {fileID: 0} + _networkObjectCache: {fileID: 0} + _syncedConnections: 0 _advancedAdjacency: o: {fileID: -3335109427502187752, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} u: {fileID: -4617469110243651000, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} @@ -304,24 +303,9 @@ MonoBehaviour: xSide: {fileID: 9163509131738271192, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} xOpposite: {fileID: -7744038958267161825, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} xTriple: {fileID: 5869884649093938551, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} - xQuad: {fileID: 4199670461815796357, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} + xQuad: {fileID: 5869884649093938551, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} viewObstacles: [] opaque: 0 - _offsetAdjacency: - o: {fileID: 0} - uNorth: {fileID: 0} - uSouth: {fileID: 0} - i: {fileID: 0} - lNE: {fileID: 0} - lNW: {fileID: 0} - lSE: {fileID: 0} - lSW: {fileID: 0} - tNEW: {fileID: 0} - tNSW: {fileID: 0} - tNSE: {fileID: 0} - tSWE: {fileID: 0} - x: {fileID: 0} - _syncedConnections: 0 --- !u!1 &7790124558541205835 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Content/WorldObjects/Structures/Walls/SteelWindow.prefab b/Assets/Content/WorldObjects/Structures/Walls/SteelWindow.prefab index 7b8a60ea91..abaf37e009 100644 --- a/Assets/Content/WorldObjects/Structures/Walls/SteelWindow.prefab +++ b/Assets/Content/WorldObjects/Structures/Walls/SteelWindow.prefab @@ -13,7 +13,7 @@ GameObject: - component: {fileID: 6696866361892651655} - component: {fileID: 7033236083530598125} - component: {fileID: -2900075557854325373} - - component: {fileID: 1492278076387892290} + - component: {fileID: 1177000688717996335} m_Layer: 0 m_Name: SteelWindow m_TagString: Untagged @@ -115,20 +115,25 @@ MonoBehaviour: m_EditorClassIdentifier: k__BackingField: 0 k__BackingField: 0 - _networkBehaviours: - - {fileID: 1492278076387892290} + k__BackingField: {fileID: 0} + _networkBehaviours: [] k__BackingField: {fileID: 0} k__BackingField: [] + SerializedTransformProperties: + Position: {x: 0, y: 0, z: 0} + Rotation: {x: 0, y: 0, z: 0, w: 0} + LocalScale: {x: 0, y: 0, z: 0} _isNetworked: 1 _isGlobal: 0 + _initializeOrder: 0 _defaultDespawnType: 0 NetworkObserver: {fileID: 0} - k__BackingField: -1 + k__BackingField: 65535 + k__BackingField: 0 _scenePathHash: 0 k__BackingField: 0 k__BackingField: 17271989988591409099 - _sceneNetworkObjects: [] ---- !u!114 &1492278076387892290 +--- !u!114 &1177000688717996335 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -137,20 +142,13 @@ MonoBehaviour: m_GameObject: {fileID: 3591147544166670882} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 53a5cd0d46abb6d4d8686d11153009c2, type: 3} + m_Script: {fileID: 11500000, guid: d3995769f8fecf9469d1783a30e75625, type: 3} m_Name: m_EditorClassIdentifier: - _componentIndexCache: 0 + _componentIndexCache: 255 _addedNetworkObject: {fileID: -2900075557854325373} - _networkObjectCache: {fileID: -2900075557854325373} - SelectedAdjacencyType: 1 - _simpleAdjacency: - o: {fileID: 0} - u: {fileID: 0} - i: {fileID: 0} - l: {fileID: 0} - t: {fileID: 0} - x: {fileID: 0} + _networkObjectCache: {fileID: 0} + _syncedConnections: 0 _advancedAdjacency: o: {fileID: 3274458310347382516, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} u: {fileID: -2386277492448864069, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} @@ -169,18 +167,3 @@ MonoBehaviour: xQuad: {fileID: -4646627001110862441, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} viewObstacles: [] opaque: 0 - _offsetAdjacency: - o: {fileID: 0} - uNorth: {fileID: 0} - uSouth: {fileID: 0} - i: {fileID: 0} - lNE: {fileID: 0} - lNW: {fileID: 0} - lSE: {fileID: 0} - lSW: {fileID: 0} - tNEW: {fileID: 0} - tNSW: {fileID: 0} - tNSE: {fileID: 0} - tSWE: {fileID: 0} - x: {fileID: 0} - _syncedConnections: 0 diff --git a/Assets/Content/WorldObjects/Structures/Walls/SteelWindowReinforced.prefab b/Assets/Content/WorldObjects/Structures/Walls/SteelWindowReinforced.prefab index 65990661f6..623f0fe5eb 100644 --- a/Assets/Content/WorldObjects/Structures/Walls/SteelWindowReinforced.prefab +++ b/Assets/Content/WorldObjects/Structures/Walls/SteelWindowReinforced.prefab @@ -13,7 +13,7 @@ GameObject: - component: {fileID: 6696866361892651655} - component: {fileID: 7033236083530598125} - component: {fileID: -2900075557854325373} - - component: {fileID: 1492278076387892290} + - component: {fileID: 4137545864262984256} m_Layer: 0 m_Name: SteelWindowReinforced m_TagString: Untagged @@ -115,20 +115,25 @@ MonoBehaviour: m_EditorClassIdentifier: k__BackingField: 0 k__BackingField: 0 - _networkBehaviours: - - {fileID: 1492278076387892290} + k__BackingField: {fileID: 0} + _networkBehaviours: [] k__BackingField: {fileID: 0} k__BackingField: [] + SerializedTransformProperties: + Position: {x: 0, y: 0, z: 0} + Rotation: {x: 0, y: 0, z: 0, w: 0} + LocalScale: {x: 0, y: 0, z: 0} _isNetworked: 1 _isGlobal: 0 + _initializeOrder: 0 _defaultDespawnType: 0 NetworkObserver: {fileID: 0} - k__BackingField: -1 + k__BackingField: 65535 + k__BackingField: 0 _scenePathHash: 0 k__BackingField: 0 k__BackingField: 2644125336701811203 - _sceneNetworkObjects: [] ---- !u!114 &1492278076387892290 +--- !u!114 &4137545864262984256 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -137,20 +142,13 @@ MonoBehaviour: m_GameObject: {fileID: 3591147544166670882} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 53a5cd0d46abb6d4d8686d11153009c2, type: 3} + m_Script: {fileID: 11500000, guid: d3995769f8fecf9469d1783a30e75625, type: 3} m_Name: m_EditorClassIdentifier: - _componentIndexCache: 0 + _componentIndexCache: 255 _addedNetworkObject: {fileID: -2900075557854325373} - _networkObjectCache: {fileID: -2900075557854325373} - SelectedAdjacencyType: 1 - _simpleAdjacency: - o: {fileID: 0} - u: {fileID: 0} - i: {fileID: 0} - l: {fileID: 0} - t: {fileID: 0} - x: {fileID: 0} + _networkObjectCache: {fileID: 0} + _syncedConnections: 0 _advancedAdjacency: o: {fileID: 2802706056601887283, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} u: {fileID: 5076968874085622753, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} @@ -166,21 +164,6 @@ MonoBehaviour: xSide: {fileID: 791389691363571250, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} xOpposite: {fileID: -8791185763750810588, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} xTriple: {fileID: -4842746724093398965, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} - xQuad: {fileID: -4646627001110862441, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} + xQuad: {fileID: -4842746724093398965, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} viewObstacles: [] opaque: 0 - _offsetAdjacency: - o: {fileID: 0} - uNorth: {fileID: 0} - uSouth: {fileID: 0} - i: {fileID: 0} - lNE: {fileID: 0} - lNW: {fileID: 0} - lSE: {fileID: 0} - lSW: {fileID: 0} - tNEW: {fileID: 0} - tNSW: {fileID: 0} - tNSE: {fileID: 0} - tSWE: {fileID: 0} - x: {fileID: 0} - _syncedConnections: 0 diff --git a/Assets/Content/WorldObjects/Structures/Wires/Cables.prefab b/Assets/Content/WorldObjects/Structures/Wires/Cables.prefab index 35e53b0d95..8242d02bab 100644 --- a/Assets/Content/WorldObjects/Structures/Wires/Cables.prefab +++ b/Assets/Content/WorldObjects/Structures/Wires/Cables.prefab @@ -12,7 +12,7 @@ GameObject: - component: {fileID: -7727686409064562107} - component: {fileID: -1074477776341974781} - component: {fileID: -4998431523760016775} - - component: {fileID: -3462450205292552653} + - component: {fileID: 687402633161505411} m_Layer: 0 m_Name: Cables m_TagString: Untagged @@ -49,18 +49,24 @@ MonoBehaviour: m_EditorClassIdentifier: k__BackingField: 0 k__BackingField: 0 + k__BackingField: {fileID: 0} _networkBehaviours: [] k__BackingField: {fileID: 0} k__BackingField: [] + SerializedTransformProperties: + Position: {x: 0, y: 0, z: 0} + Rotation: {x: 0, y: 0, z: 0, w: 0} + LocalScale: {x: 0, y: 0, z: 0} _isNetworked: 1 _isGlobal: 0 + _initializeOrder: 0 _defaultDespawnType: 0 NetworkObserver: {fileID: 0} - k__BackingField: -1 + k__BackingField: 65535 + k__BackingField: 0 _scenePathHash: 0 k__BackingField: 0 k__BackingField: 18187315780351828922 - _sceneNetworkObjects: [] --- !u!33 &-1074477776341974781 MeshFilter: m_ObjectHideFlags: 0 @@ -111,7 +117,7 @@ MeshRenderer: m_SortingLayer: 0 m_SortingOrder: 0 m_AdditionalVertexStreams: {fileID: 0} ---- !u!114 &-3462450205292552653 +--- !u!114 &687402633161505411 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -120,50 +126,17 @@ MonoBehaviour: m_GameObject: {fileID: 2802364579275783218} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 53a5cd0d46abb6d4d8686d11153009c2, type: 3} + m_Script: {fileID: 11500000, guid: bc6615260753fbd48af09343d5d55332, type: 3} m_Name: m_EditorClassIdentifier: _componentIndexCache: 255 _addedNetworkObject: {fileID: -7727686409064562107} _networkObjectCache: {fileID: 0} - SelectedAdjacencyType: 0 - _simpleAdjacency: + _syncedConnections: 0 + simpleAdjacency: o: {fileID: -8711453034529356013, guid: 3e69413026bf051418bf84fec0ce5919, type: 3} u: {fileID: -1590738978952025886, guid: 3e69413026bf051418bf84fec0ce5919, type: 3} i: {fileID: -2043613833257120371, guid: 3e69413026bf051418bf84fec0ce5919, type: 3} l: {fileID: -9081922812702010850, guid: 3e69413026bf051418bf84fec0ce5919, type: 3} t: {fileID: -5358326586770029455, guid: 3e69413026bf051418bf84fec0ce5919, type: 3} x: {fileID: -8228826546953468662, guid: 3e69413026bf051418bf84fec0ce5919, type: 3} - _advancedAdjacency: - o: {fileID: 0} - u: {fileID: 0} - i: {fileID: 0} - lNone: {fileID: 0} - lSingle: {fileID: 0} - tNone: {fileID: 0} - tSingleRight: {fileID: 0} - tSingleLeft: {fileID: 0} - tDouble: {fileID: 0} - xNone: {fileID: 0} - xSingle: {fileID: 0} - xSide: {fileID: 0} - xOpposite: {fileID: 0} - xTriple: {fileID: 0} - xQuad: {fileID: 0} - viewObstacles: [] - opaque: 0 - _offsetAdjacency: - o: {fileID: 0} - uNorth: {fileID: 0} - uSouth: {fileID: 0} - i: {fileID: 0} - lNE: {fileID: 0} - lNW: {fileID: 0} - lSE: {fileID: 0} - lSW: {fileID: 0} - tNEW: {fileID: 0} - tNSW: {fileID: 0} - tNSE: {fileID: 0} - tSWE: {fileID: 0} - x: {fileID: 0} - _syncedConnections: 0 From 178bb639ff6b1ed696b3507001fef7f5c5a2c0a4 Mon Sep 17 00:00:00 2001 From: stilnat Date: Mon, 6 Nov 2023 12:53:21 +0100 Subject: [PATCH 45/52] fix build --- Assets/Scripts/SS3D/Systems/Tile/TileMap.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs b/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs index 853406eb4d..35126aa151 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/TileMap.cs @@ -9,7 +9,6 @@ using System.Collections.Generic; using System.Linq; using UnityEngine; -using static UnityEditor.FilePathAttribute; namespace SS3D.Systems.Tile { From 76812b9044a5eca775c957ccbe7d6812a0bf4b92 Mon Sep 17 00:00:00 2001 From: stilnat Date: Thu, 9 Nov 2023 11:12:30 +0100 Subject: [PATCH 46/52] added x6 from steelwall for steelwall reinforced --- .../Structures/Walls/SteelWallReinforced.prefab | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Assets/Content/WorldObjects/Structures/Walls/SteelWallReinforced.prefab b/Assets/Content/WorldObjects/Structures/Walls/SteelWallReinforced.prefab index ac31c7c746..649e52f90d 100644 --- a/Assets/Content/WorldObjects/Structures/Walls/SteelWallReinforced.prefab +++ b/Assets/Content/WorldObjects/Structures/Walls/SteelWallReinforced.prefab @@ -255,7 +255,7 @@ MonoBehaviour: k__BackingField: 0 k__BackingField: {fileID: 0} _networkBehaviours: - - {fileID: 0} + - {fileID: 3011383631706744183} k__BackingField: {fileID: 0} k__BackingField: [] SerializedTransformProperties: @@ -267,7 +267,7 @@ MonoBehaviour: _initializeOrder: 0 _defaultDespawnType: 0 NetworkObserver: {fileID: 0} - k__BackingField: 65535 + k__BackingField: 138 k__BackingField: 0 _scenePathHash: 0 k__BackingField: 0 @@ -284,9 +284,9 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: d3995769f8fecf9469d1783a30e75625, type: 3} m_Name: m_EditorClassIdentifier: - _componentIndexCache: 255 + _componentIndexCache: 0 _addedNetworkObject: {fileID: -2900075557854325373} - _networkObjectCache: {fileID: 0} + _networkObjectCache: {fileID: -2900075557854325373} _syncedConnections: 0 _advancedAdjacency: o: {fileID: -3335109427502187752, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} @@ -303,7 +303,7 @@ MonoBehaviour: xSide: {fileID: 9163509131738271192, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} xOpposite: {fileID: -7744038958267161825, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} xTriple: {fileID: 5869884649093938551, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} - xQuad: {fileID: 5869884649093938551, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} + xQuad: {fileID: 4199670461815796357, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} viewObstacles: [] opaque: 0 --- !u!1 &7790124558541205835 From b9d183b18c32dddc4869a02905a521e7e3d2ea04 Mon Sep 17 00:00:00 2001 From: stilnat Date: Thu, 9 Nov 2023 11:18:43 +0100 Subject: [PATCH 47/52] fix plenum ? --- .../Structures/Floors/Plenum.prefab | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/Assets/Content/WorldObjects/Structures/Floors/Plenum.prefab b/Assets/Content/WorldObjects/Structures/Floors/Plenum.prefab index 5ee1ccedf5..8118b0f5dc 100644 --- a/Assets/Content/WorldObjects/Structures/Floors/Plenum.prefab +++ b/Assets/Content/WorldObjects/Structures/Floors/Plenum.prefab @@ -180,6 +180,7 @@ GameObject: - component: {fileID: 2586358896294450200} - component: {fileID: 5107901468329445811} - component: {fileID: 7564222845035831833} + - component: {fileID: 9057318044260736153} m_Layer: 0 m_Name: Plenum m_TagString: Untagged @@ -299,3 +300,37 @@ MonoBehaviour: _scenePathHash: 0 k__BackingField: 0 k__BackingField: 1135847911748521981 +--- !u!114 &9057318044260736153 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8028539322119499722} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ef4340642b9b436498fe733f9329ac87, type: 3} + m_Name: + m_EditorClassIdentifier: + _componentIndexCache: 255 + _addedNetworkObject: {fileID: 7564222845035831833} + _networkObjectCache: {fileID: 0} + _syncedConnections: 0 + advancedAdjacency: + o: {fileID: -1186837388861869702, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} + u: {fileID: 8670779871488701567, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} + i: {fileID: 2136686312440598757, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} + lNone: {fileID: 4400090147443950985, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} + lSingle: {fileID: 4907585101989539511, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} + tNone: {fileID: -5997185706695327500, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} + tSingleRight: {fileID: -7342849457706584406, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} + tSingleLeft: {fileID: -4854898696076092651, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} + tDouble: {fileID: -53862880159183297, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} + xNone: {fileID: 77848856100225938, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} + xSingle: {fileID: -8966661648484664196, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} + xSide: {fileID: -513754039711199066, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} + xOpposite: {fileID: 6731330203905936185, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} + xTriple: {fileID: 4104832187742309709, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} + xQuad: {fileID: 2496505603022733099, guid: 4c8857a063a69ee4b8abb5e9e668b2bf, type: 3} + viewObstacles: [] + opaque: 0 From 8f1825b89c6cce3b5f158e4a228bdabbad85b8c9 Mon Sep 17 00:00:00 2001 From: stilnat Date: Thu, 9 Nov 2023 21:12:41 +0100 Subject: [PATCH 48/52] fix indentation --- .../Tile/TileMapCreator/TileMapCreator.cs | 892 +++++++++--------- 1 file changed, 446 insertions(+), 446 deletions(-) diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileMapCreator/TileMapCreator.cs b/Assets/Scripts/SS3D/Systems/Tile/TileMapCreator/TileMapCreator.cs index 57b79ea374..f6d896064a 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/TileMapCreator/TileMapCreator.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/TileMapCreator/TileMapCreator.cs @@ -1,4 +1,4 @@ -using Coimbra; +using Coimbra; using DynamicPanels; using FishNet.Connection; using FishNet.Object; @@ -17,262 +17,262 @@ namespace SS3D.Systems.Tile.TileMapCreator { - /// - /// In-game editor for placing and deleting items/objects in a tilemap. - /// - public class TileMapCreator : NetworkSystem, IPointerEnterHandler, IPointerExitHandler - { - public GameObject _menuRoot; - public GameObject _contentRoot; - public GameObject _slotPrefab; - public TMP_Dropdown _layerPlacementDropdown; - - private bool _enabled = false; - private bool _initalized = false; - private bool _isDeleting = false; - private bool _itemPlacement = false; - private bool _mouseOverUI = false; - - private Vector3 _lastSnappedPosition; - private GenericObjectSo _selectedObject; - - private TileSystem _tileSystem; - private GhostManager _ghostManager; - private Plane _plane; - - private List _objectDatabase; - private Controls.TileCreatorActions _controls; - private InputSystem _inputSystem; + /// + /// In-game editor for placing and deleting items/objects in a tilemap. + /// + public class TileMapCreator : NetworkSystem, IPointerEnterHandler, IPointerExitHandler + { + public GameObject _menuRoot; + public GameObject _contentRoot; + public GameObject _slotPrefab; + public TMP_Dropdown _layerPlacementDropdown; + + private bool _enabled = false; + private bool _initalized = false; + private bool _isDeleting = false; + private bool _itemPlacement = false; + private bool _mouseOverUI = false; + + private Vector3 _lastSnappedPosition; + private GenericObjectSo _selectedObject; + + private TileSystem _tileSystem; + private GhostManager _ghostManager; + private Plane _plane; + + private List _objectDatabase; + private Controls.TileCreatorActions _controls; + private InputSystem _inputSystem; private PanelTab _tab; - public bool IsDeleting - { - get => _isDeleting; - set - { - if (_selectedObject == null) - { - return; - } - - _isDeleting = value; - RefreshGhost(); - } - } - - [ServerOrClient] - protected override void OnStart() - { - base.OnStart(); + public bool IsDeleting + { + get => _isDeleting; + set + { + if (_selectedObject == null) + { + return; + } + + _isDeleting = value; + RefreshGhost(); + } + } + + [ServerOrClient] + protected override void OnStart() + { + base.OnStart(); _tab = PanelUtils.GetAssociatedTab(GetComponent()); ShowUI(false); _inputSystem = Subsystems.Get(); - _controls = _inputSystem.Inputs.TileCreator; - _inputSystem.ToggleAction(_controls.ToggleMenu, true); + _controls = _inputSystem.Inputs.TileCreator; + _inputSystem.ToggleAction(_controls.ToggleMenu, true); _controls.ToggleMenu.performed += HandleToggleMenu; - _controls.Replace.performed += HandleReplace; - _controls.Replace.canceled += HandleReplace; - _controls.Place.performed += HandlePlace; - _controls.Rotate.performed += HandleRotate; + _controls.Replace.performed += HandleReplace; + _controls.Replace.canceled += HandleReplace; + _controls.Place.performed += HandlePlace; + _controls.Rotate.performed += HandleRotate; - } - - private void HandleToggleMenu(InputAction.CallbackContext context) - { - if (_enabled) - { - _inputSystem.ToggleActionMap(_controls, false, new[] - { - _controls.ToggleMenu - }); - - _inputSystem.ToggleCollisions(_controls, true); - } - else - { - _inputSystem.ToggleActionMap(_controls, true, new[] - { - _controls.ToggleMenu - }); - - _inputSystem.ToggleCollisions(_controls, false); - } - - _enabled = !_enabled; - ShowUI(_enabled); - Initialize(); - } - - private void HandleRotate(InputAction.CallbackContext context) - { - _ghostManager.SetNextRotation(); - RefreshGhost(); - } - - private void HandleReplace(InputAction.CallbackContext context) - { - RefreshGhost(); - } - - private void HandlePlace(InputAction.CallbackContext context) - { - if (_mouseOverUI) - { - return; - } - - HandleMouseClick(_lastSnappedPosition, _controls.Replace.phase == InputActionPhase.Performed); - } - - [ServerOrClient] - private void Initialize() - { - if (_initalized) - { - return; - } - - _tileSystem = Subsystems.Get(); - _ghostManager = GetComponent(); - _plane = new Plane(Vector3.up, 0); - - LoadObjectGrid(new[] - { - TileLayer.Plenum - }, false); - - _initalized = true; - } - - [ServerOrClient] - private void Update() - { - if (!_initalized) - { - return; - } - // Clean-up if we are not building - if (_selectedObject == null) - { + } + + private void HandleToggleMenu(InputAction.CallbackContext context) + { + if (_enabled) + { + _inputSystem.ToggleActionMap(_controls, false, new[] + { + _controls.ToggleMenu + }); + + _inputSystem.ToggleCollisions(_controls, true); + } + else + { + _inputSystem.ToggleActionMap(_controls, true, new[] + { + _controls.ToggleMenu + }); + + _inputSystem.ToggleCollisions(_controls, false); + } + + _enabled = !_enabled; + ShowUI(_enabled); + Initialize(); + } + + private void HandleRotate(InputAction.CallbackContext context) + { + _ghostManager.SetNextRotation(); + RefreshGhost(); + } + + private void HandleReplace(InputAction.CallbackContext context) + { + RefreshGhost(); + } + + private void HandlePlace(InputAction.CallbackContext context) + { + if (_mouseOverUI) + { + return; + } + + HandleMouseClick(_lastSnappedPosition, _controls.Replace.phase == InputActionPhase.Performed); + } + + [ServerOrClient] + private void Initialize() + { + if (_initalized) + { + return; + } + + _tileSystem = Subsystems.Get(); + _ghostManager = GetComponent(); + _plane = new Plane(Vector3.up, 0); + + LoadObjectGrid(new[] + { + TileLayer.Plenum + }, false); + + _initalized = true; + } + + [ServerOrClient] + private void Update() + { + if (!_initalized) + { + return; + } + // Clean-up if we are not building + if (_selectedObject == null) + { _ghostManager.DestroyGhost(); return; - } - - _ghostManager.CreateGhost(_selectedObject.prefab); - - // Check if mouse moved - Vector3 snappedPosition = TileHelper.GetClosestPosition(GetMousePosition()); - - if (snappedPosition != _lastSnappedPosition && !_itemPlacement) - { - _ghostManager.SetTargetPosition(snappedPosition); - _lastSnappedPosition = snappedPosition; - RefreshGhost(); - } - - if (_itemPlacement) - { - Vector3 newPosition = GetMousePosition(); - _ghostManager.SetTargetPosition(newPosition); - _lastSnappedPosition = newPosition; - } - - _ghostManager.MoveGhost(); - } - - [ServerOrClient] - private void HandleMouseClick(Vector3 snappedPosition, bool replaceExisting) - { - if (_isDeleting) - { - if (_itemPlacement) - { - FindAndDeleteItem(snappedPosition); - } - else - { - _tileSystem.RpcClearTileObject(_selectedObject.nameString, snappedPosition, _ghostManager.Dir); - } - } - else - { - if (_selectedObject == null) - { - return; - } - - _tileSystem.RpcPlaceObject(_selectedObject.nameString, snappedPosition, _ghostManager.Dir, replaceExisting); - RefreshGhost(); - } - } - - [ServerOrClient] - private void FindAndDeleteItem(Vector3 worldPosition) - { - Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); - - if (Physics.Raycast(ray, out RaycastHit hitInfo)) - { - PlacedItemObject placedItem = hitInfo.collider.gameObject.GetComponent(); - - if (placedItem != null) - { - _tileSystem.RpcClearItemObject(placedItem.NameString, worldPosition); - } - } - } - - [ServerOrClient] - private Vector3 GetMousePosition() - { - Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); - - if (_plane.Raycast(ray, out float distance)) - { - return ray.GetPoint(distance); - } - - return Vector3.zero; - } - - [ServerOrClient] - private void CheckBuildValidity(Vector3 placePosition, bool replaceExisting) - { - RpcSendCanBuild(_selectedObject.nameString, placePosition, _ghostManager.Dir, replaceExisting, LocalConnection); - } - - // Ownership not required since a client can request whether it is possible to build - [Client] - [ServerRpc(RequireOwnership = false)] - public void RpcSendCanBuild(string tileObjectSoName, Vector3 placePosition, Direction dir, bool replaceExisting, NetworkConnection conn) - { - if (_tileSystem == null) - { - _tileSystem = Subsystems.Get(); - } - - TileObjectSo tileObjectSo = (TileObjectSo)_tileSystem.GetAsset(tileObjectSoName); - - if (tileObjectSo == null) - { - return; - } - - bool canBuild = _tileSystem.CanBuild(tileObjectSo, placePosition, dir, replaceExisting); - RpcReceiveCanBuild(conn, canBuild); - } - - [Client] - [TargetRpc] - private void RpcReceiveCanBuild(NetworkConnection conn, bool canBuild) - { - _ghostManager.ChangeGhostColor(canBuild ? GhostManager.BuildMatMode.Valid : GhostManager.BuildMatMode.Invalid); - } - - [ServerOrClient] - private void ShowUI(bool show) - { + } + + _ghostManager.CreateGhost(_selectedObject.prefab); + + // Check if mouse moved + Vector3 snappedPosition = TileHelper.GetClosestPosition(GetMousePosition()); + + if (snappedPosition != _lastSnappedPosition && !_itemPlacement) + { + _ghostManager.SetTargetPosition(snappedPosition); + _lastSnappedPosition = snappedPosition; + RefreshGhost(); + } + + if (_itemPlacement) + { + Vector3 newPosition = GetMousePosition(); + _ghostManager.SetTargetPosition(newPosition); + _lastSnappedPosition = newPosition; + } + + _ghostManager.MoveGhost(); + } + + [ServerOrClient] + private void HandleMouseClick(Vector3 snappedPosition, bool replaceExisting) + { + if (_isDeleting) + { + if (_itemPlacement) + { + FindAndDeleteItem(snappedPosition); + } + else + { + _tileSystem.RpcClearTileObject(_selectedObject.nameString, snappedPosition, _ghostManager.Dir); + } + } + else + { + if (_selectedObject == null) + { + return; + } + + _tileSystem.RpcPlaceObject(_selectedObject.nameString, snappedPosition, _ghostManager.Dir, replaceExisting); + RefreshGhost(); + } + } + + [ServerOrClient] + private void FindAndDeleteItem(Vector3 worldPosition) + { + Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); + + if (Physics.Raycast(ray, out RaycastHit hitInfo)) + { + PlacedItemObject placedItem = hitInfo.collider.gameObject.GetComponent(); + + if (placedItem != null) + { + _tileSystem.RpcClearItemObject(placedItem.NameString, worldPosition); + } + } + } + + [ServerOrClient] + private Vector3 GetMousePosition() + { + Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); + + if (_plane.Raycast(ray, out float distance)) + { + return ray.GetPoint(distance); + } + + return Vector3.zero; + } + + [ServerOrClient] + private void CheckBuildValidity(Vector3 placePosition, bool replaceExisting) + { + RpcSendCanBuild(_selectedObject.nameString, placePosition, _ghostManager.Dir, replaceExisting, LocalConnection); + } + + // Ownership not required since a client can request whether it is possible to build + [Client] + [ServerRpc(RequireOwnership = false)] + public void RpcSendCanBuild(string tileObjectSoName, Vector3 placePosition, Direction dir, bool replaceExisting, NetworkConnection conn) + { + if (_tileSystem == null) + { + _tileSystem = Subsystems.Get(); + } + + TileObjectSo tileObjectSo = (TileObjectSo)_tileSystem.GetAsset(tileObjectSoName); + + if (tileObjectSo == null) + { + return; + } + + bool canBuild = _tileSystem.CanBuild(tileObjectSo, placePosition, dir, replaceExisting); + RpcReceiveCanBuild(conn, canBuild); + } + + [Client] + [TargetRpc] + private void RpcReceiveCanBuild(NetworkConnection conn, bool canBuild) + { + _ghostManager.ChangeGhostColor(canBuild ? GhostManager.BuildMatMode.Valid : GhostManager.BuildMatMode.Invalid); + } + + [ServerOrClient] + private void ShowUI(bool show) + { if (!show) { if (_ghostManager) @@ -282,206 +282,206 @@ private void ShowUI(bool show) _tab.Detach(); } _tab.Panel.gameObject.SetActive(show); - _menuRoot.SetActive(show); - } - - /// - /// Loads a list of tile objects and places them in the UI box grid. - /// - /// - /// - [ServerOrClient] - private void LoadObjectGrid(TileLayer[] allowedLayers, bool isItems) - { - ClearGrid(); - - _objectDatabase = _tileSystem.Loader.Assets; - - foreach (GenericObjectSo asset in _objectDatabase) - { - switch (isItems) - { - case true when asset is not ItemObjectSo: - case false when asset is ItemObjectSo: - case false when asset is TileObjectSo so && !allowedLayers.Contains(so.layer): - continue; - } - - GameObject slot = Instantiate(_slotPrefab, _contentRoot.transform, true); - - TileMapCreatorTab tab = slot.AddComponent(); - - tab.Setup(asset); - } - } - - [ServerOrClient] - private void ClearGrid() - { - for (int i = 0; i < _contentRoot.transform.childCount; i++) - { - _contentRoot.transform.GetChild(i).gameObject.Dispose(true); - } - } - - [ServerOrClient] - private void RefreshGhost() - { - if (_selectedObject == null) - { - return; - } - - if (_isDeleting) - { - _ghostManager.ChangeGhostColor(GhostManager.BuildMatMode.Deleting); - } - else - { - switch (_itemPlacement) - { - case true: - _ghostManager.ChangeGhostColor(GhostManager.BuildMatMode.Valid); - - break; - case false when _controls.Replace.phase == InputActionPhase.Performed: - CheckBuildValidity(_lastSnappedPosition, true); - - break; - case false: - CheckBuildValidity(_lastSnappedPosition, false); - - break; - } - } - } - - [ServerOrClient] - public void SetSelectedObject(GenericObjectSo genericObjectSo) - { - _itemPlacement = genericObjectSo switch - { - TileObjectSo => false, - ItemObjectSo => true, - _ => _itemPlacement, - }; - - _selectedObject = genericObjectSo; - _ghostManager.DestroyGhost(); - _ghostManager.CreateGhost(genericObjectSo.prefab); - - RefreshGhost(); - } - - [Server] - public void LoadMap() - { - if (IsServer) - { - _tileSystem.Load(); - } - else - { - Log.Information(this, "Cannot load the map on a client"); - } - } - - [Server] - public void SaveMap() - { - if (IsServer) - { - _tileSystem.Save(); - } - else - { - Log.Information(this, "Cannot save the map on a client"); - } - } - - - /// - /// Change the currently displayed tiles/items when a new layer is selected in the drop down menu. - /// - [ServerOrClient] - public void OnDropDownChange() - { - int index = _layerPlacementDropdown.value; - - switch (index) - { - case 0: - LoadObjectGrid(new[] - { - TileLayer.Plenum - }, false); - - break; - case 1: - LoadObjectGrid(new[] - { - TileLayer.Turf - }, false); - - break; - case 2: - LoadObjectGrid(new[] - { - TileLayer.FurnitureBase, - TileLayer.FurnitureTop - }, false); - - break; - case 3: - LoadObjectGrid(new[] - { - TileLayer.WallMountHigh, - TileLayer.WallMountLow - }, false); - - break; - case 4: - LoadObjectGrid(new[] - { - TileLayer.Wire, - TileLayer.Disposal, - TileLayer.PipeLeft, + _menuRoot.SetActive(show); + } + + /// + /// Loads a list of tile objects and places them in the UI box grid. + /// + /// + /// + [ServerOrClient] + private void LoadObjectGrid(TileLayer[] allowedLayers, bool isItems) + { + ClearGrid(); + + _objectDatabase = _tileSystem.Loader.Assets; + + foreach (GenericObjectSo asset in _objectDatabase) + { + switch (isItems) + { + case true when asset is not ItemObjectSo: + case false when asset is ItemObjectSo: + case false when asset is TileObjectSo so && !allowedLayers.Contains(so.layer): + continue; + } + + GameObject slot = Instantiate(_slotPrefab, _contentRoot.transform, true); + + TileMapCreatorTab tab = slot.AddComponent(); + + tab.Setup(asset); + } + } + + [ServerOrClient] + private void ClearGrid() + { + for (int i = 0; i < _contentRoot.transform.childCount; i++) + { + _contentRoot.transform.GetChild(i).gameObject.Dispose(true); + } + } + + [ServerOrClient] + private void RefreshGhost() + { + if (_selectedObject == null) + { + return; + } + + if (_isDeleting) + { + _ghostManager.ChangeGhostColor(GhostManager.BuildMatMode.Deleting); + } + else + { + switch (_itemPlacement) + { + case true: + _ghostManager.ChangeGhostColor(GhostManager.BuildMatMode.Valid); + + break; + case false when _controls.Replace.phase == InputActionPhase.Performed: + CheckBuildValidity(_lastSnappedPosition, true); + + break; + case false: + CheckBuildValidity(_lastSnappedPosition, false); + + break; + } + } + } + + [ServerOrClient] + public void SetSelectedObject(GenericObjectSo genericObjectSo) + { + _itemPlacement = genericObjectSo switch + { + TileObjectSo => false, + ItemObjectSo => true, + _ => _itemPlacement, + }; + + _selectedObject = genericObjectSo; + _ghostManager.DestroyGhost(); + _ghostManager.CreateGhost(genericObjectSo.prefab); + + RefreshGhost(); + } + + [Server] + public void LoadMap() + { + if (IsServer) + { + _tileSystem.Load(); + } + else + { + Log.Information(this, "Cannot load the map on a client"); + } + } + + [Server] + public void SaveMap() + { + if (IsServer) + { + _tileSystem.Save(); + } + else + { + Log.Information(this, "Cannot save the map on a client"); + } + } + + + /// + /// Change the currently displayed tiles/items when a new layer is selected in the drop down menu. + /// + [ServerOrClient] + public void OnDropDownChange() + { + int index = _layerPlacementDropdown.value; + + switch (index) + { + case 0: + LoadObjectGrid(new[] + { + TileLayer.Plenum + }, false); + + break; + case 1: + LoadObjectGrid(new[] + { + TileLayer.Turf + }, false); + + break; + case 2: + LoadObjectGrid(new[] + { + TileLayer.FurnitureBase, + TileLayer.FurnitureTop + }, false); + + break; + case 3: + LoadObjectGrid(new[] + { + TileLayer.WallMountHigh, + TileLayer.WallMountLow + }, false); + + break; + case 4: + LoadObjectGrid(new[] + { + TileLayer.Wire, + TileLayer.Disposal, + TileLayer.PipeLeft, TileLayer.PipeRight, TileLayer.PipeSurface, TileLayer.PipeMiddle - }, false); - - break; - case 5: - LoadObjectGrid(new[] - { - TileLayer.Overlays - }, false); - - break; - case 6: - LoadObjectGrid(null, true); - - break; - default: - ClearGrid(); - - break; - } - } - - [ServerOrClient] - public void OnPointerEnter(PointerEventData eventData) - { - _mouseOverUI = true; - Subsystems.Get().ToggleBinding("/scroll/y", false); - } - - [ServerOrClient] - public void OnPointerExit(PointerEventData eventData) - { - _mouseOverUI = false; - Subsystems.Get().ToggleBinding("/scroll/y", true); - } - } + }, false); + + break; + case 5: + LoadObjectGrid(new[] + { + TileLayer.Overlays + }, false); + + break; + case 6: + LoadObjectGrid(null, true); + + break; + default: + ClearGrid(); + + break; + } + } + + [ServerOrClient] + public void OnPointerEnter(PointerEventData eventData) + { + _mouseOverUI = true; + Subsystems.Get().ToggleBinding("/scroll/y", false); + } + + [ServerOrClient] + public void OnPointerExit(PointerEventData eventData) + { + _mouseOverUI = false; + Subsystems.Get().ToggleBinding("/scroll/y", true); + } + } } \ No newline at end of file From 5113da9e6c4a02dc77957409bdccd9060243f0b5 Mon Sep 17 00:00:00 2001 From: stilnat Date: Thu, 9 Nov 2023 21:13:55 +0100 Subject: [PATCH 49/52] fix X6 for reinforced steel windows --- .../WorldObjects/Structures/Walls/SteelWindowReinforced.prefab | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/Content/WorldObjects/Structures/Walls/SteelWindowReinforced.prefab b/Assets/Content/WorldObjects/Structures/Walls/SteelWindowReinforced.prefab index 623f0fe5eb..ce71447fd9 100644 --- a/Assets/Content/WorldObjects/Structures/Walls/SteelWindowReinforced.prefab +++ b/Assets/Content/WorldObjects/Structures/Walls/SteelWindowReinforced.prefab @@ -164,6 +164,6 @@ MonoBehaviour: xSide: {fileID: 791389691363571250, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} xOpposite: {fileID: -8791185763750810588, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} xTriple: {fileID: -4842746724093398965, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} - xQuad: {fileID: -4842746724093398965, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} + xQuad: {fileID: -4646627001110862441, guid: 9c0b392ffb24ca248a002fe36b08bae8, type: 3} viewObstacles: [] opaque: 0 From 7b3a504a40beb5be11573b14ed1636a8da79e292 Mon Sep 17 00:00:00 2001 From: stilnat Date: Thu, 9 Nov 2023 21:19:37 +0100 Subject: [PATCH 50/52] changed material of disposal pipes --- Assets/Art/Models/Structures/Pipes/DisposalPipes.fbx.meta | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Assets/Art/Models/Structures/Pipes/DisposalPipes.fbx.meta b/Assets/Art/Models/Structures/Pipes/DisposalPipes.fbx.meta index edd5744ee8..d438f56dc4 100644 --- a/Assets/Art/Models/Structures/Pipes/DisposalPipes.fbx.meta +++ b/Assets/Art/Models/Structures/Pipes/DisposalPipes.fbx.meta @@ -3,7 +3,12 @@ guid: 8fa7941da6a6a8d4da717a97b11b2621 ModelImporter: serializedVersion: 21300 internalIDToNameTable: [] - externalObjects: {} + externalObjects: + - first: + type: UnityEngine:Material + assembly: UnityEngine.CoreModule + name: Palette05 + second: {fileID: 2100000, guid: 695c4de41b9578049a93f19b1eef7213, type: 2} materials: materialImportMode: 2 materialName: 0 From 2f8292118b9d65d23a53ee67216bf077844b7c24 Mon Sep 17 00:00:00 2001 From: stilnat Date: Thu, 9 Nov 2023 21:19:43 +0100 Subject: [PATCH 51/52] Revert "fix indentation" This reverts commit 8f1825b89c6cce3b5f158e4a228bdabbad85b8c9. --- .../Tile/TileMapCreator/TileMapCreator.cs | 892 +++++++++--------- 1 file changed, 446 insertions(+), 446 deletions(-) diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileMapCreator/TileMapCreator.cs b/Assets/Scripts/SS3D/Systems/Tile/TileMapCreator/TileMapCreator.cs index f6d896064a..57b79ea374 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/TileMapCreator/TileMapCreator.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/TileMapCreator/TileMapCreator.cs @@ -1,4 +1,4 @@ -using Coimbra; +using Coimbra; using DynamicPanels; using FishNet.Connection; using FishNet.Object; @@ -17,262 +17,262 @@ namespace SS3D.Systems.Tile.TileMapCreator { - /// - /// In-game editor for placing and deleting items/objects in a tilemap. - /// - public class TileMapCreator : NetworkSystem, IPointerEnterHandler, IPointerExitHandler - { - public GameObject _menuRoot; - public GameObject _contentRoot; - public GameObject _slotPrefab; - public TMP_Dropdown _layerPlacementDropdown; - - private bool _enabled = false; - private bool _initalized = false; - private bool _isDeleting = false; - private bool _itemPlacement = false; - private bool _mouseOverUI = false; - - private Vector3 _lastSnappedPosition; - private GenericObjectSo _selectedObject; - - private TileSystem _tileSystem; - private GhostManager _ghostManager; - private Plane _plane; - - private List _objectDatabase; - private Controls.TileCreatorActions _controls; - private InputSystem _inputSystem; + /// + /// In-game editor for placing and deleting items/objects in a tilemap. + /// + public class TileMapCreator : NetworkSystem, IPointerEnterHandler, IPointerExitHandler + { + public GameObject _menuRoot; + public GameObject _contentRoot; + public GameObject _slotPrefab; + public TMP_Dropdown _layerPlacementDropdown; + + private bool _enabled = false; + private bool _initalized = false; + private bool _isDeleting = false; + private bool _itemPlacement = false; + private bool _mouseOverUI = false; + + private Vector3 _lastSnappedPosition; + private GenericObjectSo _selectedObject; + + private TileSystem _tileSystem; + private GhostManager _ghostManager; + private Plane _plane; + + private List _objectDatabase; + private Controls.TileCreatorActions _controls; + private InputSystem _inputSystem; private PanelTab _tab; - public bool IsDeleting - { - get => _isDeleting; - set - { - if (_selectedObject == null) - { - return; - } - - _isDeleting = value; - RefreshGhost(); - } - } - - [ServerOrClient] - protected override void OnStart() - { - base.OnStart(); + public bool IsDeleting + { + get => _isDeleting; + set + { + if (_selectedObject == null) + { + return; + } + + _isDeleting = value; + RefreshGhost(); + } + } + + [ServerOrClient] + protected override void OnStart() + { + base.OnStart(); _tab = PanelUtils.GetAssociatedTab(GetComponent()); ShowUI(false); _inputSystem = Subsystems.Get(); - _controls = _inputSystem.Inputs.TileCreator; - _inputSystem.ToggleAction(_controls.ToggleMenu, true); + _controls = _inputSystem.Inputs.TileCreator; + _inputSystem.ToggleAction(_controls.ToggleMenu, true); _controls.ToggleMenu.performed += HandleToggleMenu; - _controls.Replace.performed += HandleReplace; - _controls.Replace.canceled += HandleReplace; - _controls.Place.performed += HandlePlace; - _controls.Rotate.performed += HandleRotate; + _controls.Replace.performed += HandleReplace; + _controls.Replace.canceled += HandleReplace; + _controls.Place.performed += HandlePlace; + _controls.Rotate.performed += HandleRotate; - } - - private void HandleToggleMenu(InputAction.CallbackContext context) - { - if (_enabled) - { - _inputSystem.ToggleActionMap(_controls, false, new[] - { - _controls.ToggleMenu - }); - - _inputSystem.ToggleCollisions(_controls, true); - } - else - { - _inputSystem.ToggleActionMap(_controls, true, new[] - { - _controls.ToggleMenu - }); - - _inputSystem.ToggleCollisions(_controls, false); - } - - _enabled = !_enabled; - ShowUI(_enabled); - Initialize(); - } - - private void HandleRotate(InputAction.CallbackContext context) - { - _ghostManager.SetNextRotation(); - RefreshGhost(); - } - - private void HandleReplace(InputAction.CallbackContext context) - { - RefreshGhost(); - } - - private void HandlePlace(InputAction.CallbackContext context) - { - if (_mouseOverUI) - { - return; - } - - HandleMouseClick(_lastSnappedPosition, _controls.Replace.phase == InputActionPhase.Performed); - } - - [ServerOrClient] - private void Initialize() - { - if (_initalized) - { - return; - } - - _tileSystem = Subsystems.Get(); - _ghostManager = GetComponent(); - _plane = new Plane(Vector3.up, 0); - - LoadObjectGrid(new[] - { - TileLayer.Plenum - }, false); - - _initalized = true; - } - - [ServerOrClient] - private void Update() - { - if (!_initalized) - { - return; - } - // Clean-up if we are not building - if (_selectedObject == null) - { + } + + private void HandleToggleMenu(InputAction.CallbackContext context) + { + if (_enabled) + { + _inputSystem.ToggleActionMap(_controls, false, new[] + { + _controls.ToggleMenu + }); + + _inputSystem.ToggleCollisions(_controls, true); + } + else + { + _inputSystem.ToggleActionMap(_controls, true, new[] + { + _controls.ToggleMenu + }); + + _inputSystem.ToggleCollisions(_controls, false); + } + + _enabled = !_enabled; + ShowUI(_enabled); + Initialize(); + } + + private void HandleRotate(InputAction.CallbackContext context) + { + _ghostManager.SetNextRotation(); + RefreshGhost(); + } + + private void HandleReplace(InputAction.CallbackContext context) + { + RefreshGhost(); + } + + private void HandlePlace(InputAction.CallbackContext context) + { + if (_mouseOverUI) + { + return; + } + + HandleMouseClick(_lastSnappedPosition, _controls.Replace.phase == InputActionPhase.Performed); + } + + [ServerOrClient] + private void Initialize() + { + if (_initalized) + { + return; + } + + _tileSystem = Subsystems.Get(); + _ghostManager = GetComponent(); + _plane = new Plane(Vector3.up, 0); + + LoadObjectGrid(new[] + { + TileLayer.Plenum + }, false); + + _initalized = true; + } + + [ServerOrClient] + private void Update() + { + if (!_initalized) + { + return; + } + // Clean-up if we are not building + if (_selectedObject == null) + { _ghostManager.DestroyGhost(); return; - } - - _ghostManager.CreateGhost(_selectedObject.prefab); - - // Check if mouse moved - Vector3 snappedPosition = TileHelper.GetClosestPosition(GetMousePosition()); - - if (snappedPosition != _lastSnappedPosition && !_itemPlacement) - { - _ghostManager.SetTargetPosition(snappedPosition); - _lastSnappedPosition = snappedPosition; - RefreshGhost(); - } - - if (_itemPlacement) - { - Vector3 newPosition = GetMousePosition(); - _ghostManager.SetTargetPosition(newPosition); - _lastSnappedPosition = newPosition; - } - - _ghostManager.MoveGhost(); - } - - [ServerOrClient] - private void HandleMouseClick(Vector3 snappedPosition, bool replaceExisting) - { - if (_isDeleting) - { - if (_itemPlacement) - { - FindAndDeleteItem(snappedPosition); - } - else - { - _tileSystem.RpcClearTileObject(_selectedObject.nameString, snappedPosition, _ghostManager.Dir); - } - } - else - { - if (_selectedObject == null) - { - return; - } - - _tileSystem.RpcPlaceObject(_selectedObject.nameString, snappedPosition, _ghostManager.Dir, replaceExisting); - RefreshGhost(); - } - } - - [ServerOrClient] - private void FindAndDeleteItem(Vector3 worldPosition) - { - Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); - - if (Physics.Raycast(ray, out RaycastHit hitInfo)) - { - PlacedItemObject placedItem = hitInfo.collider.gameObject.GetComponent(); - - if (placedItem != null) - { - _tileSystem.RpcClearItemObject(placedItem.NameString, worldPosition); - } - } - } - - [ServerOrClient] - private Vector3 GetMousePosition() - { - Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); - - if (_plane.Raycast(ray, out float distance)) - { - return ray.GetPoint(distance); - } - - return Vector3.zero; - } - - [ServerOrClient] - private void CheckBuildValidity(Vector3 placePosition, bool replaceExisting) - { - RpcSendCanBuild(_selectedObject.nameString, placePosition, _ghostManager.Dir, replaceExisting, LocalConnection); - } - - // Ownership not required since a client can request whether it is possible to build - [Client] - [ServerRpc(RequireOwnership = false)] - public void RpcSendCanBuild(string tileObjectSoName, Vector3 placePosition, Direction dir, bool replaceExisting, NetworkConnection conn) - { - if (_tileSystem == null) - { - _tileSystem = Subsystems.Get(); - } - - TileObjectSo tileObjectSo = (TileObjectSo)_tileSystem.GetAsset(tileObjectSoName); - - if (tileObjectSo == null) - { - return; - } - - bool canBuild = _tileSystem.CanBuild(tileObjectSo, placePosition, dir, replaceExisting); - RpcReceiveCanBuild(conn, canBuild); - } - - [Client] - [TargetRpc] - private void RpcReceiveCanBuild(NetworkConnection conn, bool canBuild) - { - _ghostManager.ChangeGhostColor(canBuild ? GhostManager.BuildMatMode.Valid : GhostManager.BuildMatMode.Invalid); - } - - [ServerOrClient] - private void ShowUI(bool show) - { + } + + _ghostManager.CreateGhost(_selectedObject.prefab); + + // Check if mouse moved + Vector3 snappedPosition = TileHelper.GetClosestPosition(GetMousePosition()); + + if (snappedPosition != _lastSnappedPosition && !_itemPlacement) + { + _ghostManager.SetTargetPosition(snappedPosition); + _lastSnappedPosition = snappedPosition; + RefreshGhost(); + } + + if (_itemPlacement) + { + Vector3 newPosition = GetMousePosition(); + _ghostManager.SetTargetPosition(newPosition); + _lastSnappedPosition = newPosition; + } + + _ghostManager.MoveGhost(); + } + + [ServerOrClient] + private void HandleMouseClick(Vector3 snappedPosition, bool replaceExisting) + { + if (_isDeleting) + { + if (_itemPlacement) + { + FindAndDeleteItem(snappedPosition); + } + else + { + _tileSystem.RpcClearTileObject(_selectedObject.nameString, snappedPosition, _ghostManager.Dir); + } + } + else + { + if (_selectedObject == null) + { + return; + } + + _tileSystem.RpcPlaceObject(_selectedObject.nameString, snappedPosition, _ghostManager.Dir, replaceExisting); + RefreshGhost(); + } + } + + [ServerOrClient] + private void FindAndDeleteItem(Vector3 worldPosition) + { + Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); + + if (Physics.Raycast(ray, out RaycastHit hitInfo)) + { + PlacedItemObject placedItem = hitInfo.collider.gameObject.GetComponent(); + + if (placedItem != null) + { + _tileSystem.RpcClearItemObject(placedItem.NameString, worldPosition); + } + } + } + + [ServerOrClient] + private Vector3 GetMousePosition() + { + Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); + + if (_plane.Raycast(ray, out float distance)) + { + return ray.GetPoint(distance); + } + + return Vector3.zero; + } + + [ServerOrClient] + private void CheckBuildValidity(Vector3 placePosition, bool replaceExisting) + { + RpcSendCanBuild(_selectedObject.nameString, placePosition, _ghostManager.Dir, replaceExisting, LocalConnection); + } + + // Ownership not required since a client can request whether it is possible to build + [Client] + [ServerRpc(RequireOwnership = false)] + public void RpcSendCanBuild(string tileObjectSoName, Vector3 placePosition, Direction dir, bool replaceExisting, NetworkConnection conn) + { + if (_tileSystem == null) + { + _tileSystem = Subsystems.Get(); + } + + TileObjectSo tileObjectSo = (TileObjectSo)_tileSystem.GetAsset(tileObjectSoName); + + if (tileObjectSo == null) + { + return; + } + + bool canBuild = _tileSystem.CanBuild(tileObjectSo, placePosition, dir, replaceExisting); + RpcReceiveCanBuild(conn, canBuild); + } + + [Client] + [TargetRpc] + private void RpcReceiveCanBuild(NetworkConnection conn, bool canBuild) + { + _ghostManager.ChangeGhostColor(canBuild ? GhostManager.BuildMatMode.Valid : GhostManager.BuildMatMode.Invalid); + } + + [ServerOrClient] + private void ShowUI(bool show) + { if (!show) { if (_ghostManager) @@ -282,206 +282,206 @@ private void ShowUI(bool show) _tab.Detach(); } _tab.Panel.gameObject.SetActive(show); - _menuRoot.SetActive(show); - } - - /// - /// Loads a list of tile objects and places them in the UI box grid. - /// - /// - /// - [ServerOrClient] - private void LoadObjectGrid(TileLayer[] allowedLayers, bool isItems) - { - ClearGrid(); - - _objectDatabase = _tileSystem.Loader.Assets; - - foreach (GenericObjectSo asset in _objectDatabase) - { - switch (isItems) - { - case true when asset is not ItemObjectSo: - case false when asset is ItemObjectSo: - case false when asset is TileObjectSo so && !allowedLayers.Contains(so.layer): - continue; - } - - GameObject slot = Instantiate(_slotPrefab, _contentRoot.transform, true); - - TileMapCreatorTab tab = slot.AddComponent(); - - tab.Setup(asset); - } - } - - [ServerOrClient] - private void ClearGrid() - { - for (int i = 0; i < _contentRoot.transform.childCount; i++) - { - _contentRoot.transform.GetChild(i).gameObject.Dispose(true); - } - } - - [ServerOrClient] - private void RefreshGhost() - { - if (_selectedObject == null) - { - return; - } - - if (_isDeleting) - { - _ghostManager.ChangeGhostColor(GhostManager.BuildMatMode.Deleting); - } - else - { - switch (_itemPlacement) - { - case true: - _ghostManager.ChangeGhostColor(GhostManager.BuildMatMode.Valid); - - break; - case false when _controls.Replace.phase == InputActionPhase.Performed: - CheckBuildValidity(_lastSnappedPosition, true); - - break; - case false: - CheckBuildValidity(_lastSnappedPosition, false); - - break; - } - } - } - - [ServerOrClient] - public void SetSelectedObject(GenericObjectSo genericObjectSo) - { - _itemPlacement = genericObjectSo switch - { - TileObjectSo => false, - ItemObjectSo => true, - _ => _itemPlacement, - }; - - _selectedObject = genericObjectSo; - _ghostManager.DestroyGhost(); - _ghostManager.CreateGhost(genericObjectSo.prefab); - - RefreshGhost(); - } - - [Server] - public void LoadMap() - { - if (IsServer) - { - _tileSystem.Load(); - } - else - { - Log.Information(this, "Cannot load the map on a client"); - } - } - - [Server] - public void SaveMap() - { - if (IsServer) - { - _tileSystem.Save(); - } - else - { - Log.Information(this, "Cannot save the map on a client"); - } - } - - - /// - /// Change the currently displayed tiles/items when a new layer is selected in the drop down menu. - /// - [ServerOrClient] - public void OnDropDownChange() - { - int index = _layerPlacementDropdown.value; - - switch (index) - { - case 0: - LoadObjectGrid(new[] - { - TileLayer.Plenum - }, false); - - break; - case 1: - LoadObjectGrid(new[] - { - TileLayer.Turf - }, false); - - break; - case 2: - LoadObjectGrid(new[] - { - TileLayer.FurnitureBase, - TileLayer.FurnitureTop - }, false); - - break; - case 3: - LoadObjectGrid(new[] - { - TileLayer.WallMountHigh, - TileLayer.WallMountLow - }, false); - - break; - case 4: - LoadObjectGrid(new[] - { - TileLayer.Wire, - TileLayer.Disposal, - TileLayer.PipeLeft, + _menuRoot.SetActive(show); + } + + /// + /// Loads a list of tile objects and places them in the UI box grid. + /// + /// + /// + [ServerOrClient] + private void LoadObjectGrid(TileLayer[] allowedLayers, bool isItems) + { + ClearGrid(); + + _objectDatabase = _tileSystem.Loader.Assets; + + foreach (GenericObjectSo asset in _objectDatabase) + { + switch (isItems) + { + case true when asset is not ItemObjectSo: + case false when asset is ItemObjectSo: + case false when asset is TileObjectSo so && !allowedLayers.Contains(so.layer): + continue; + } + + GameObject slot = Instantiate(_slotPrefab, _contentRoot.transform, true); + + TileMapCreatorTab tab = slot.AddComponent(); + + tab.Setup(asset); + } + } + + [ServerOrClient] + private void ClearGrid() + { + for (int i = 0; i < _contentRoot.transform.childCount; i++) + { + _contentRoot.transform.GetChild(i).gameObject.Dispose(true); + } + } + + [ServerOrClient] + private void RefreshGhost() + { + if (_selectedObject == null) + { + return; + } + + if (_isDeleting) + { + _ghostManager.ChangeGhostColor(GhostManager.BuildMatMode.Deleting); + } + else + { + switch (_itemPlacement) + { + case true: + _ghostManager.ChangeGhostColor(GhostManager.BuildMatMode.Valid); + + break; + case false when _controls.Replace.phase == InputActionPhase.Performed: + CheckBuildValidity(_lastSnappedPosition, true); + + break; + case false: + CheckBuildValidity(_lastSnappedPosition, false); + + break; + } + } + } + + [ServerOrClient] + public void SetSelectedObject(GenericObjectSo genericObjectSo) + { + _itemPlacement = genericObjectSo switch + { + TileObjectSo => false, + ItemObjectSo => true, + _ => _itemPlacement, + }; + + _selectedObject = genericObjectSo; + _ghostManager.DestroyGhost(); + _ghostManager.CreateGhost(genericObjectSo.prefab); + + RefreshGhost(); + } + + [Server] + public void LoadMap() + { + if (IsServer) + { + _tileSystem.Load(); + } + else + { + Log.Information(this, "Cannot load the map on a client"); + } + } + + [Server] + public void SaveMap() + { + if (IsServer) + { + _tileSystem.Save(); + } + else + { + Log.Information(this, "Cannot save the map on a client"); + } + } + + + /// + /// Change the currently displayed tiles/items when a new layer is selected in the drop down menu. + /// + [ServerOrClient] + public void OnDropDownChange() + { + int index = _layerPlacementDropdown.value; + + switch (index) + { + case 0: + LoadObjectGrid(new[] + { + TileLayer.Plenum + }, false); + + break; + case 1: + LoadObjectGrid(new[] + { + TileLayer.Turf + }, false); + + break; + case 2: + LoadObjectGrid(new[] + { + TileLayer.FurnitureBase, + TileLayer.FurnitureTop + }, false); + + break; + case 3: + LoadObjectGrid(new[] + { + TileLayer.WallMountHigh, + TileLayer.WallMountLow + }, false); + + break; + case 4: + LoadObjectGrid(new[] + { + TileLayer.Wire, + TileLayer.Disposal, + TileLayer.PipeLeft, TileLayer.PipeRight, TileLayer.PipeSurface, TileLayer.PipeMiddle - }, false); - - break; - case 5: - LoadObjectGrid(new[] - { - TileLayer.Overlays - }, false); - - break; - case 6: - LoadObjectGrid(null, true); - - break; - default: - ClearGrid(); - - break; - } - } - - [ServerOrClient] - public void OnPointerEnter(PointerEventData eventData) - { - _mouseOverUI = true; - Subsystems.Get().ToggleBinding("/scroll/y", false); - } - - [ServerOrClient] - public void OnPointerExit(PointerEventData eventData) - { - _mouseOverUI = false; - Subsystems.Get().ToggleBinding("/scroll/y", true); - } - } + }, false); + + break; + case 5: + LoadObjectGrid(new[] + { + TileLayer.Overlays + }, false); + + break; + case 6: + LoadObjectGrid(null, true); + + break; + default: + ClearGrid(); + + break; + } + } + + [ServerOrClient] + public void OnPointerEnter(PointerEventData eventData) + { + _mouseOverUI = true; + Subsystems.Get().ToggleBinding("/scroll/y", false); + } + + [ServerOrClient] + public void OnPointerExit(PointerEventData eventData) + { + _mouseOverUI = false; + Subsystems.Get().ToggleBinding("/scroll/y", true); + } + } } \ No newline at end of file From 1f478132eab2cf82349631bce4f12f1601ffc86e Mon Sep 17 00:00:00 2001 From: stilnat Date: Thu, 9 Nov 2023 21:21:02 +0100 Subject: [PATCH 52/52] fix indentation --- .../Tile/TileMapCreator/TileMapCreator.cs | 870 +++++++++--------- 1 file changed, 435 insertions(+), 435 deletions(-) diff --git a/Assets/Scripts/SS3D/Systems/Tile/TileMapCreator/TileMapCreator.cs b/Assets/Scripts/SS3D/Systems/Tile/TileMapCreator/TileMapCreator.cs index 56ed471b13..9f5d8b3de2 100644 --- a/Assets/Scripts/SS3D/Systems/Tile/TileMapCreator/TileMapCreator.cs +++ b/Assets/Scripts/SS3D/Systems/Tile/TileMapCreator/TileMapCreator.cs @@ -17,264 +17,264 @@ namespace SS3D.Systems.Tile.TileMapCreator { - /// - /// In-game editor for placing and deleting items/objects in a tilemap. - /// - public class TileMapCreator : NetworkSystem, IPointerEnterHandler, IPointerExitHandler - { - public GameObject _menuRoot; - public GameObject _contentRoot; - public GameObject _slotPrefab; - public TMP_Dropdown _layerPlacementDropdown; + /// + /// In-game editor for placing and deleting items/objects in a tilemap. + /// + public class TileMapCreator : NetworkSystem, IPointerEnterHandler, IPointerExitHandler + { + public GameObject _menuRoot; + public GameObject _contentRoot; + public GameObject _slotPrefab; + public TMP_Dropdown _layerPlacementDropdown; [SerializeField] private TMP_InputField _inputField; - private bool _enabled = false; - private bool _initalized = false; - private bool _isDeleting = false; - private bool _itemPlacement = false; - private bool _mouseOverUI = false; + private bool _enabled = false; + private bool _initalized = false; + private bool _isDeleting = false; + private bool _itemPlacement = false; + private bool _mouseOverUI = false; - private Vector3 _lastSnappedPosition; - private GenericObjectSo _selectedObject; + private Vector3 _lastSnappedPosition; + private GenericObjectSo _selectedObject; - private TileSystem _tileSystem; - private GhostManager _ghostManager; - private Plane _plane; + private TileSystem _tileSystem; + private GhostManager _ghostManager; + private Plane _plane; - private List _objectDatabase; - private Controls.TileCreatorActions _controls; - private InputSystem _inputSystem; + private List _objectDatabase; + private Controls.TileCreatorActions _controls; + private InputSystem _inputSystem; private PanelTab _tab; - public bool IsDeleting - { - get => _isDeleting; - set - { - if (_selectedObject == null) - { - return; - } - - _isDeleting = value; - RefreshGhost(); - } - } - - [ServerOrClient] - protected override void OnStart() - { - base.OnStart(); + public bool IsDeleting + { + get => _isDeleting; + set + { + if (_selectedObject == null) + { + return; + } + + _isDeleting = value; + RefreshGhost(); + } + } + + [ServerOrClient] + protected override void OnStart() + { + base.OnStart(); _tab = PanelUtils.GetAssociatedTab(GetComponent()); ShowUI(false); _inputSystem = Subsystems.Get(); - _controls = _inputSystem.Inputs.TileCreator; - _inputSystem.ToggleAction(_controls.ToggleMenu, true); + _controls = _inputSystem.Inputs.TileCreator; + _inputSystem.ToggleAction(_controls.ToggleMenu, true); _controls.ToggleMenu.performed += HandleToggleMenu; - _controls.Replace.performed += HandleReplace; - _controls.Replace.canceled += HandleReplace; - _controls.Place.performed += HandlePlace; - _controls.Rotate.performed += HandleRotate; + _controls.Replace.performed += HandleReplace; + _controls.Replace.canceled += HandleReplace; + _controls.Place.performed += HandlePlace; + _controls.Rotate.performed += HandleRotate; - } - - private void HandleToggleMenu(InputAction.CallbackContext context) - { - if (_enabled) - { - _inputSystem.ToggleActionMap(_controls, false, new[] - { - _controls.ToggleMenu - }); - - _inputSystem.ToggleCollisions(_controls, true); - } - else - { - _inputSystem.ToggleActionMap(_controls, true, new[] - { - _controls.ToggleMenu - }); - - _inputSystem.ToggleCollisions(_controls, false); - } - - _enabled = !_enabled; - ShowUI(_enabled); - Initialize(); - } - - private void HandleRotate(InputAction.CallbackContext context) - { - _ghostManager.SetNextRotation(); - RefreshGhost(); - } - - private void HandleReplace(InputAction.CallbackContext context) - { - RefreshGhost(); - } - - private void HandlePlace(InputAction.CallbackContext context) - { - if (_mouseOverUI) - { - return; - } - - HandleMouseClick(_lastSnappedPosition, _controls.Replace.phase == InputActionPhase.Performed); - } - - [ServerOrClient] - private void Initialize() - { - if (_initalized) - { - return; - } - - _tileSystem = Subsystems.Get(); - _ghostManager = GetComponent(); - _plane = new Plane(Vector3.up, 0); - - LoadObjectGrid(new[] - { - TileLayer.Plenum - }, false); - - _initalized = true; - } - - [ServerOrClient] - private void Update() - { - if (!_initalized) - { - return; - } - // Clean-up if we are not building - if (_selectedObject == null) - { + } + + private void HandleToggleMenu(InputAction.CallbackContext context) + { + if (_enabled) + { + _inputSystem.ToggleActionMap(_controls, false, new[] + { + _controls.ToggleMenu + }); + + _inputSystem.ToggleCollisions(_controls, true); + } + else + { + _inputSystem.ToggleActionMap(_controls, true, new[] + { + _controls.ToggleMenu + }); + + _inputSystem.ToggleCollisions(_controls, false); + } + + _enabled = !_enabled; + ShowUI(_enabled); + Initialize(); + } + + private void HandleRotate(InputAction.CallbackContext context) + { + _ghostManager.SetNextRotation(); + RefreshGhost(); + } + + private void HandleReplace(InputAction.CallbackContext context) + { + RefreshGhost(); + } + + private void HandlePlace(InputAction.CallbackContext context) + { + if (_mouseOverUI) + { + return; + } + + HandleMouseClick(_lastSnappedPosition, _controls.Replace.phase == InputActionPhase.Performed); + } + + [ServerOrClient] + private void Initialize() + { + if (_initalized) + { + return; + } + + _tileSystem = Subsystems.Get(); + _ghostManager = GetComponent(); + _plane = new Plane(Vector3.up, 0); + + LoadObjectGrid(new[] + { + TileLayer.Plenum + }, false); + + _initalized = true; + } + + [ServerOrClient] + private void Update() + { + if (!_initalized) + { + return; + } + // Clean-up if we are not building + if (_selectedObject == null) + { _ghostManager.DestroyGhost(); return; - } - - _ghostManager.CreateGhost(_selectedObject.prefab); - - // Check if mouse moved - Vector3 snappedPosition = TileHelper.GetClosestPosition(GetMousePosition()); - - if (snappedPosition != _lastSnappedPosition && !_itemPlacement) - { - _ghostManager.SetTargetPosition(snappedPosition); - _lastSnappedPosition = snappedPosition; - RefreshGhost(); - } - - if (_itemPlacement) - { - Vector3 newPosition = GetMousePosition(); - _ghostManager.SetTargetPosition(newPosition); - _lastSnappedPosition = newPosition; - } - - _ghostManager.MoveGhost(); - } - - [ServerOrClient] - private void HandleMouseClick(Vector3 snappedPosition, bool replaceExisting) - { - if (_isDeleting) - { - if (_itemPlacement) - { - FindAndDeleteItem(snappedPosition); - } - else - { - _tileSystem.RpcClearTileObject(_selectedObject.nameString, snappedPosition, _ghostManager.Dir); - } - } - else - { - if (_selectedObject == null) - { - return; - } - - _tileSystem.RpcPlaceObject(_selectedObject.nameString, snappedPosition, _ghostManager.Dir, replaceExisting); - RefreshGhost(); - } - } - - [ServerOrClient] - private void FindAndDeleteItem(Vector3 worldPosition) - { - Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); - - if (Physics.Raycast(ray, out RaycastHit hitInfo)) - { - PlacedItemObject placedItem = hitInfo.collider.gameObject.GetComponent(); - - if (placedItem != null) - { - _tileSystem.RpcClearItemObject(placedItem.NameString, worldPosition); - } - } - } - - [ServerOrClient] - private Vector3 GetMousePosition() - { - Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); - - if (_plane.Raycast(ray, out float distance)) - { - return ray.GetPoint(distance); - } - - return Vector3.zero; - } - - [ServerOrClient] - private void CheckBuildValidity(Vector3 placePosition, bool replaceExisting) - { - RpcSendCanBuild(_selectedObject.nameString, placePosition, _ghostManager.Dir, replaceExisting, LocalConnection); - } - - // Ownership not required since a client can request whether it is possible to build - [Client] - [ServerRpc(RequireOwnership = false)] - public void RpcSendCanBuild(string tileObjectSoName, Vector3 placePosition, Direction dir, bool replaceExisting, NetworkConnection conn) - { - if (_tileSystem == null) - { - _tileSystem = Subsystems.Get(); - } - - TileObjectSo tileObjectSo = (TileObjectSo)_tileSystem.GetAsset(tileObjectSoName); - - if (tileObjectSo == null) - { - return; - } - - bool canBuild = _tileSystem.CanBuild(tileObjectSo, placePosition, dir, replaceExisting); - RpcReceiveCanBuild(conn, canBuild); - } - - [Client] - [TargetRpc] - private void RpcReceiveCanBuild(NetworkConnection conn, bool canBuild) - { - _ghostManager.ChangeGhostColor(canBuild ? GhostManager.BuildMatMode.Valid : GhostManager.BuildMatMode.Invalid); - } - - [ServerOrClient] - private void ShowUI(bool show) - { + } + + _ghostManager.CreateGhost(_selectedObject.prefab); + + // Check if mouse moved + Vector3 snappedPosition = TileHelper.GetClosestPosition(GetMousePosition()); + + if (snappedPosition != _lastSnappedPosition && !_itemPlacement) + { + _ghostManager.SetTargetPosition(snappedPosition); + _lastSnappedPosition = snappedPosition; + RefreshGhost(); + } + + if (_itemPlacement) + { + Vector3 newPosition = GetMousePosition(); + _ghostManager.SetTargetPosition(newPosition); + _lastSnappedPosition = newPosition; + } + + _ghostManager.MoveGhost(); + } + + [ServerOrClient] + private void HandleMouseClick(Vector3 snappedPosition, bool replaceExisting) + { + if (_isDeleting) + { + if (_itemPlacement) + { + FindAndDeleteItem(snappedPosition); + } + else + { + _tileSystem.RpcClearTileObject(_selectedObject.nameString, snappedPosition, _ghostManager.Dir); + } + } + else + { + if (_selectedObject == null) + { + return; + } + + _tileSystem.RpcPlaceObject(_selectedObject.nameString, snappedPosition, _ghostManager.Dir, replaceExisting); + RefreshGhost(); + } + } + + [ServerOrClient] + private void FindAndDeleteItem(Vector3 worldPosition) + { + Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); + + if (Physics.Raycast(ray, out RaycastHit hitInfo)) + { + PlacedItemObject placedItem = hitInfo.collider.gameObject.GetComponent(); + + if (placedItem != null) + { + _tileSystem.RpcClearItemObject(placedItem.NameString, worldPosition); + } + } + } + + [ServerOrClient] + private Vector3 GetMousePosition() + { + Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); + + if (_plane.Raycast(ray, out float distance)) + { + return ray.GetPoint(distance); + } + + return Vector3.zero; + } + + [ServerOrClient] + private void CheckBuildValidity(Vector3 placePosition, bool replaceExisting) + { + RpcSendCanBuild(_selectedObject.nameString, placePosition, _ghostManager.Dir, replaceExisting, LocalConnection); + } + + // Ownership not required since a client can request whether it is possible to build + [Client] + [ServerRpc(RequireOwnership = false)] + public void RpcSendCanBuild(string tileObjectSoName, Vector3 placePosition, Direction dir, bool replaceExisting, NetworkConnection conn) + { + if (_tileSystem == null) + { + _tileSystem = Subsystems.Get(); + } + + TileObjectSo tileObjectSo = (TileObjectSo)_tileSystem.GetAsset(tileObjectSoName); + + if (tileObjectSo == null) + { + return; + } + + bool canBuild = _tileSystem.CanBuild(tileObjectSo, placePosition, dir, replaceExisting); + RpcReceiveCanBuild(conn, canBuild); + } + + [Client] + [TargetRpc] + private void RpcReceiveCanBuild(NetworkConnection conn, bool canBuild) + { + _ghostManager.ChangeGhostColor(canBuild ? GhostManager.BuildMatMode.Valid : GhostManager.BuildMatMode.Invalid); + } + + [ServerOrClient] + private void ShowUI(bool show) + { if (!show) { if (_ghostManager) @@ -284,193 +284,193 @@ private void ShowUI(bool show) _tab.Detach(); } _tab.Panel.gameObject.SetActive(show); - _menuRoot.SetActive(show); - } - - /// - /// Loads a list of tile objects and places them in the UI box grid. - /// - /// - /// - [ServerOrClient] - private void LoadObjectGrid(TileLayer[] allowedLayers, bool isItems) - { - ClearGrid(); - - _objectDatabase = _tileSystem.Loader.Assets; - - foreach (GenericObjectSo asset in _objectDatabase) - { - switch (isItems) - { - case true when asset is not ItemObjectSo: - case false when asset is ItemObjectSo: - case false when asset is TileObjectSo so && !allowedLayers.Contains(so.layer): - continue; - } - - GameObject slot = Instantiate(_slotPrefab, _contentRoot.transform, true); - - TileMapCreatorTab tab = slot.AddComponent(); - - tab.Setup(asset); - } - } - - [ServerOrClient] - private void ClearGrid() - { - for (int i = 0; i < _contentRoot.transform.childCount; i++) - { - _contentRoot.transform.GetChild(i).gameObject.Dispose(true); - } - } - - [ServerOrClient] - private void RefreshGhost() - { - if (_selectedObject == null) - { - return; - } - - if (_isDeleting) - { - _ghostManager.ChangeGhostColor(GhostManager.BuildMatMode.Deleting); - } - else - { - switch (_itemPlacement) - { - case true: - _ghostManager.ChangeGhostColor(GhostManager.BuildMatMode.Valid); - - break; - case false when _controls.Replace.phase == InputActionPhase.Performed: - CheckBuildValidity(_lastSnappedPosition, true); - - break; - case false: - CheckBuildValidity(_lastSnappedPosition, false); - - break; - } - } - } - - [ServerOrClient] - public void SetSelectedObject(GenericObjectSo genericObjectSo) - { - _itemPlacement = genericObjectSo switch - { - TileObjectSo => false, - ItemObjectSo => true, - _ => _itemPlacement, - }; - - _selectedObject = genericObjectSo; - _ghostManager.DestroyGhost(); - _ghostManager.CreateGhost(genericObjectSo.prefab); - - RefreshGhost(); - } - - [Server] - public void LoadMap() - { - if (IsServer) - { - _tileSystem.Load(); - } - else - { - Log.Information(this, "Cannot load the map on a client"); - } - } - - [Server] - public void SaveMap() - { - if (IsServer) - { - _tileSystem.Save(); - } - else - { - Log.Information(this, "Cannot save the map on a client"); - } - } - - - /// - /// Change the currently displayed tiles/items when a new layer is selected in the drop down menu. - /// - [ServerOrClient] - public void OnDropDownChange() - { - int index = _layerPlacementDropdown.value; - - switch (index) - { - case 0: - LoadObjectGrid(new[] - { - TileLayer.Plenum - }, false); - - break; - case 1: - LoadObjectGrid(new[] - { - TileLayer.Turf - }, false); - - break; - case 2: - LoadObjectGrid(new[] - { - TileLayer.FurnitureBase, - TileLayer.FurnitureTop - }, false); - - break; - case 3: - LoadObjectGrid(new[] - { - TileLayer.WallMountHigh, - TileLayer.WallMountLow - }, false); - - break; - case 4: - LoadObjectGrid(new[] - { - TileLayer.Wire, - TileLayer.Disposal, - TileLayer.PipeLeft, + _menuRoot.SetActive(show); + } + + /// + /// Loads a list of tile objects and places them in the UI box grid. + /// + /// + /// + [ServerOrClient] + private void LoadObjectGrid(TileLayer[] allowedLayers, bool isItems) + { + ClearGrid(); + + _objectDatabase = _tileSystem.Loader.Assets; + + foreach (GenericObjectSo asset in _objectDatabase) + { + switch (isItems) + { + case true when asset is not ItemObjectSo: + case false when asset is ItemObjectSo: + case false when asset is TileObjectSo so && !allowedLayers.Contains(so.layer): + continue; + } + + GameObject slot = Instantiate(_slotPrefab, _contentRoot.transform, true); + + TileMapCreatorTab tab = slot.AddComponent(); + + tab.Setup(asset); + } + } + + [ServerOrClient] + private void ClearGrid() + { + for (int i = 0; i < _contentRoot.transform.childCount; i++) + { + _contentRoot.transform.GetChild(i).gameObject.Dispose(true); + } + } + + [ServerOrClient] + private void RefreshGhost() + { + if (_selectedObject == null) + { + return; + } + + if (_isDeleting) + { + _ghostManager.ChangeGhostColor(GhostManager.BuildMatMode.Deleting); + } + else + { + switch (_itemPlacement) + { + case true: + _ghostManager.ChangeGhostColor(GhostManager.BuildMatMode.Valid); + + break; + case false when _controls.Replace.phase == InputActionPhase.Performed: + CheckBuildValidity(_lastSnappedPosition, true); + + break; + case false: + CheckBuildValidity(_lastSnappedPosition, false); + + break; + } + } + } + + [ServerOrClient] + public void SetSelectedObject(GenericObjectSo genericObjectSo) + { + _itemPlacement = genericObjectSo switch + { + TileObjectSo => false, + ItemObjectSo => true, + _ => _itemPlacement, + }; + + _selectedObject = genericObjectSo; + _ghostManager.DestroyGhost(); + _ghostManager.CreateGhost(genericObjectSo.prefab); + + RefreshGhost(); + } + + [Server] + public void LoadMap() + { + if (IsServer) + { + _tileSystem.Load(); + } + else + { + Log.Information(this, "Cannot load the map on a client"); + } + } + + [Server] + public void SaveMap() + { + if (IsServer) + { + _tileSystem.Save(); + } + else + { + Log.Information(this, "Cannot save the map on a client"); + } + } + + + /// + /// Change the currently displayed tiles/items when a new layer is selected in the drop down menu. + /// + [ServerOrClient] + public void OnDropDownChange() + { + int index = _layerPlacementDropdown.value; + + switch (index) + { + case 0: + LoadObjectGrid(new[] + { + TileLayer.Plenum + }, false); + + break; + case 1: + LoadObjectGrid(new[] + { + TileLayer.Turf + }, false); + + break; + case 2: + LoadObjectGrid(new[] + { + TileLayer.FurnitureBase, + TileLayer.FurnitureTop + }, false); + + break; + case 3: + LoadObjectGrid(new[] + { + TileLayer.WallMountHigh, + TileLayer.WallMountLow + }, false); + + break; + case 4: + LoadObjectGrid(new[] + { + TileLayer.Wire, + TileLayer.Disposal, + TileLayer.PipeLeft, TileLayer.PipeRight, TileLayer.PipeSurface, TileLayer.PipeMiddle - }, false); + }, false); - break; - case 5: - LoadObjectGrid(new[] - { - TileLayer.Overlays - }, false); + break; + case 5: + LoadObjectGrid(new[] + { + TileLayer.Overlays + }, false); - break; - case 6: - LoadObjectGrid(null, true); + break; + case 6: + LoadObjectGrid(null, true); - break; - default: - ClearGrid(); + break; + default: + ClearGrid(); - break; - } - } + break; + } + } public void OnInputFieldChanged() { @@ -503,17 +503,17 @@ public void OnInputFieldDeselect() } [ServerOrClient] - public void OnPointerEnter(PointerEventData eventData) - { - _mouseOverUI = true; - Subsystems.Get().ToggleBinding("/scroll/y", false); - } - - [ServerOrClient] - public void OnPointerExit(PointerEventData eventData) - { - _mouseOverUI = false; - Subsystems.Get().ToggleBinding("/scroll/y", true); - } - } + public void OnPointerEnter(PointerEventData eventData) + { + _mouseOverUI = true; + Subsystems.Get().ToggleBinding("/scroll/y", false); + } + + [ServerOrClient] + public void OnPointerExit(PointerEventData eventData) + { + _mouseOverUI = false; + Subsystems.Get().ToggleBinding("/scroll/y", true); + } + } } \ No newline at end of file