using UnityEngine; using UnityEngine.Assertions; namespace DunGen { public class DungeonAttachmentSettings { /// /// The doorway to attach the dungeon to. If set, the new dungeon must be attached to this doorway /// public Doorway AttachmentDoorway { get; private set; } /// /// The tile to attach the dungeon to. If set, the new dungeon will attach to this tile, but the doorway /// will be chosen randomly /// public Tile AttachmentTile { get; private set; } public TileProxy TileProxy { get; private set; } public DungeonAttachmentSettings(Doorway attachmentDoorway) { Assert.IsNotNull(attachmentDoorway, "attachmentDoorway cannot be null"); AttachmentDoorway = attachmentDoorway; } public DungeonAttachmentSettings(Tile attachmentTile) { Assert.IsNotNull(attachmentTile, "attachmentTile cannot be null"); AttachmentTile = attachmentTile; } public TileProxy GenerateAttachmentProxy(Vector3 upVector, RandomStream randomStream) { if (AttachmentTile != null) { // This tile wasn't placed by DunGen so we'll need to do // some extra setup to ensure we have all the data we'll need later if (AttachmentTile.Prefab == null) PrepareManuallyPlacedTile(AttachmentTile, upVector, randomStream); TileProxy = new TileProxy(AttachmentTile.Prefab, (doorway, index) => AttachmentTile.UnusedDoorways.Contains(AttachmentTile.AllDoorways[index])); // Ensure chosen doorway is unused TileProxy.Placement.Position = AttachmentTile.transform.localPosition; TileProxy.Placement.Rotation = AttachmentTile.transform.localRotation; } else if (AttachmentDoorway != null) { var attachmentTile = AttachmentDoorway.Tile; if(attachmentTile == null) { attachmentTile = AttachmentDoorway.GetComponentInParent(); if(attachmentTile == null) { Debug.LogError($"Cannot attach to a doorway that doesn't belong to a Tile. Ensure the Doorway is parented to a GameObject with a Tile component"); return null; } } if(attachmentTile.Prefab == null) PrepareManuallyPlacedTile(attachmentTile, upVector, randomStream); if (AttachmentDoorway.Tile.UsedDoorways.Contains(AttachmentDoorway)) Debug.LogError($"Cannot attach dungeon to doorway '{AttachmentDoorway.name}' as it is already in use"); TileProxy = new TileProxy(AttachmentDoorway.Tile.Prefab, (doorway, index) => index == attachmentTile.AllDoorways.IndexOf(AttachmentDoorway)); TileProxy.Placement.Position = AttachmentDoorway.Tile.transform.localPosition; TileProxy.Placement.Rotation = AttachmentDoorway.Tile.transform.localRotation; } return TileProxy; } private void PrepareManuallyPlacedTile(Tile tileToPrepare, Vector3 upVector, RandomStream randomStream) { tileToPrepare.Prefab = tileToPrepare.gameObject; foreach (var doorway in tileToPrepare.GetComponentsInChildren()) { doorway.Tile = tileToPrepare; tileToPrepare.AllDoorways.Add(doorway); tileToPrepare.UnusedDoorways.Add(doorway); doorway.ProcessDoorwayObjects(false, randomStream); } Bounds bounds; if (tileToPrepare.OverrideAutomaticTileBounds) bounds = tileToPrepare.TileBoundsOverride; else bounds = UnityUtil.CalculateProxyBounds(tileToPrepare.gameObject, upVector); tileToPrepare.Placement.LocalBounds = UnityUtil.CondenseBounds(bounds, tileToPrepare.AllDoorways); } public Tile GetAttachmentTile() { Tile attachmentTile = null; if (AttachmentTile != null) attachmentTile = AttachmentTile; else if (AttachmentDoorway != null) attachmentTile = AttachmentDoorway.Tile; return attachmentTile; } } }