LethalCompany/Lethal Company/ExportedProject/Assets/Scripts/Assembly-CSharp/DunGen/TileProxy.cs

138 lines
4.7 KiB
C#
Raw Normal View History

2023-12-22 22:51:17 +00:00
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using UnityEngine;
namespace DunGen
{
public sealed class TileProxy
{
private List<DoorwayProxy> doorways = new List<DoorwayProxy>();
public GameObject Prefab { get; private set; }
public Tile PrefabTile { get; private set; }
public TilePlacementData Placement { get; internal set; }
public DoorwayProxy Entrance { get; private set; }
public DoorwayProxy Exit { get; private set; }
public ReadOnlyCollection<DoorwayProxy> Doorways { get; private set; }
public IEnumerable<DoorwayProxy> UsedDoorways => doorways.Where((DoorwayProxy d) => d.Used);
public IEnumerable<DoorwayProxy> UnusedDoorways => doorways.Where((DoorwayProxy d) => !d.Used);
public TileProxy(TileProxy existingTile)
{
Prefab = existingTile.Prefab;
PrefabTile = existingTile.PrefabTile;
Placement = new TilePlacementData(existingTile.Placement);
Doorways = new ReadOnlyCollection<DoorwayProxy>(doorways);
foreach (DoorwayProxy doorway in existingTile.doorways)
{
DoorwayProxy doorwayProxy = new DoorwayProxy(this, doorway);
doorways.Add(doorwayProxy);
if (existingTile.Entrance == doorway)
{
Entrance = doorwayProxy;
}
if (existingTile.Exit == doorway)
{
Exit = doorwayProxy;
}
}
}
public TileProxy(GameObject prefab, bool ignoreSpriteRendererBounds, Vector3 upVector)
{
prefab.transform.localPosition = Vector3.zero;
prefab.transform.localRotation = Quaternion.identity;
Prefab = prefab;
PrefabTile = prefab.GetComponent<Tile>();
if (PrefabTile == null)
{
PrefabTile = prefab.AddComponent<Tile>();
}
Placement = new TilePlacementData();
Doorways = new ReadOnlyCollection<DoorwayProxy>(doorways);
Doorway[] componentsInChildren = prefab.GetComponentsInChildren<Doorway>();
for (int i = 0; i < componentsInChildren.Length; i++)
{
Doorway doorway = componentsInChildren[i];
Vector3 position = doorway.transform.position;
Quaternion rotation = doorway.transform.rotation;
DoorwayProxy doorwayProxy = new DoorwayProxy(this, i, doorway, position, rotation);
doorways.Add(doorwayProxy);
if (PrefabTile.Entrance == doorway)
{
Entrance = doorwayProxy;
}
if (PrefabTile.Exit == doorway)
{
Exit = doorwayProxy;
}
}
Bounds bounds = ((!(PrefabTile != null) || !PrefabTile.OverrideAutomaticTileBounds) ? UnityUtil.CalculateProxyBounds(Prefab, ignoreSpriteRendererBounds, upVector) : PrefabTile.TileBoundsOverride);
if (bounds.size.x <= 0f || bounds.size.y <= 0f || bounds.size.z <= 0f)
{
Debug.LogError($"Tile prefab '{prefab}' has automatic bounds that are zero or negative in size. The bounding volume for this tile will need to be manually defined.", prefab);
}
Placement.LocalBounds = UnityUtil.CondenseBounds(bounds, Prefab.GetComponentsInChildren<Doorway>());
}
public void PositionBySocket(DoorwayProxy myDoorway, DoorwayProxy otherDoorway)
{
Quaternion quaternion = Quaternion.LookRotation(-otherDoorway.Forward, otherDoorway.Up);
Placement.Rotation = quaternion * Quaternion.Inverse(Quaternion.Inverse(Placement.Rotation) * (Placement.Rotation * myDoorway.LocalRotation));
Vector3 position = otherDoorway.Position;
Placement.Position = position - (myDoorway.Position - Placement.Position);
}
private Vector3 CalculateOverlap(TileProxy other)
{
Bounds bounds = Placement.Bounds;
Bounds bounds2 = other.Placement.Bounds;
float a = bounds.max.x - bounds2.min.x;
float b = bounds2.max.x - bounds.min.x;
float a2 = bounds.max.y - bounds2.min.y;
float b2 = bounds2.max.y - bounds.min.y;
float a3 = bounds.max.z - bounds2.min.z;
return new Vector3(z: Mathf.Min(a3, bounds2.max.z - bounds.min.z), x: Mathf.Min(a, b), y: Mathf.Min(a2, b2));
}
public bool IsOverlapping(TileProxy other, float maxOverlap)
{
Vector3 vector = CalculateOverlap(other);
return Mathf.Min(vector.x, vector.y, vector.z) > maxOverlap;
}
public bool IsOverlappingOrOverhanging(TileProxy other, AxisDirection upDirection, float maxOverlap)
{
Vector3 vector = UnityUtil.CalculatePerAxisOverlap(other.Placement.Bounds, Placement.Bounds);
float num;
switch (upDirection)
{
case AxisDirection.PosX:
case AxisDirection.NegX:
num = Mathf.Min(vector.y, vector.z);
break;
case AxisDirection.PosY:
case AxisDirection.NegY:
num = Mathf.Min(vector.x, vector.z);
break;
case AxisDirection.PosZ:
case AxisDirection.NegZ:
num = Mathf.Min(vector.x, vector.y);
break;
default:
throw new NotImplementedException("AxisDirection '" + upDirection.ToString() + "' is not implemented");
}
return num > maxOverlap;
}
}
}