407 lines
11 KiB
C#
407 lines
11 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Net.Sockets;
|
|
using UnityEngine;
|
|
|
|
public class SocketContainer : MonoBehaviour
|
|
{
|
|
[Header("Socket Management")]
|
|
[SerializeField] private List<SocketPoint> sockets = new List<SocketPoint>();
|
|
|
|
// This list will now control the order and availability of manual iteration
|
|
[SerializeField] private List<SocketPoint> iterativeSockets = new List<SocketPoint>();
|
|
[SerializeField] private bool autoDetectSockets = true;
|
|
|
|
[Header("Cycling Behavior")]
|
|
[SerializeField] private bool allowCycling = true;
|
|
[SerializeField] private bool wrapAround = true;
|
|
private BlockContainerInit containerInit;
|
|
|
|
private int currentSocketIndex = 0;
|
|
private SocketPoint currentActiveSocket;
|
|
|
|
void Awake()
|
|
{
|
|
InitializeSockets();
|
|
}
|
|
|
|
private void InitializeSockets()
|
|
{
|
|
if (autoDetectSockets)
|
|
{
|
|
sockets.Clear();
|
|
SocketPoint[] foundSockets = GetComponentsInChildren<SocketPoint>();
|
|
sockets.AddRange(foundSockets);
|
|
|
|
if (sockets.Count > 0)
|
|
{
|
|
Debug.Log($"{gameObject.name} detected {sockets.Count} total sockets");
|
|
}
|
|
}
|
|
|
|
// Initialize iteration state using iterativeSockets list
|
|
if (iterativeSockets.Count > 0)
|
|
{
|
|
currentSocketIndex = 0;
|
|
currentActiveSocket = iterativeSockets[0];
|
|
}
|
|
else if (sockets.Count > 0)
|
|
{
|
|
containerInit = gameObject.GetComponent<BlockContainerInit>();
|
|
if (containerInit == null)
|
|
return;
|
|
|
|
iterativeSockets = containerInit.InitBlockContainer(sockets);
|
|
|
|
currentSocketIndex = 0;
|
|
currentActiveSocket = iterativeSockets[0];
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updated: Returns the active socket from the ITERATIVE list
|
|
/// </summary>
|
|
public SocketPoint GetActiveSocket()
|
|
{
|
|
if (iterativeSockets.Count == 0) return null;
|
|
return iterativeSockets[currentSocketIndex];
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updated: Cycles through iterativeSockets
|
|
/// </summary>
|
|
public void CycleToNextSocket()
|
|
{
|
|
if (!allowCycling || iterativeSockets.Count <= 1) return;
|
|
|
|
if (iterativeSockets[currentSocketIndex] != null)
|
|
iterativeSockets[currentSocketIndex].Highlight(HighlightState.Default);
|
|
|
|
currentSocketIndex++;
|
|
|
|
if (currentSocketIndex >= iterativeSockets.Count)
|
|
currentSocketIndex = wrapAround ? 0 : iterativeSockets.Count - 1;
|
|
|
|
currentActiveSocket = iterativeSockets[currentSocketIndex];
|
|
if (currentActiveSocket != null)
|
|
currentActiveSocket.Highlight(HighlightState.Active);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updated: Cycles through iterativeSockets
|
|
/// </summary>
|
|
public void CycleToPreviousSocket()
|
|
{
|
|
if (!allowCycling || iterativeSockets.Count <= 1) return;
|
|
|
|
if (iterativeSockets[currentSocketIndex] != null)
|
|
iterativeSockets[currentSocketIndex].Highlight(HighlightState.Default);
|
|
|
|
currentSocketIndex--;
|
|
|
|
if (currentSocketIndex < 0)
|
|
currentSocketIndex = wrapAround ? iterativeSockets.Count - 1 : 0;
|
|
|
|
currentActiveSocket = iterativeSockets[currentSocketIndex];
|
|
if (currentActiveSocket != null)
|
|
currentActiveSocket.Highlight(HighlightState.Active);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updated: Targets iterativeSockets
|
|
/// </summary>
|
|
public void SetActiveSocketByIndex(int index)
|
|
{
|
|
if (index < 0 || index >= iterativeSockets.Count) return;
|
|
|
|
if (iterativeSockets[currentSocketIndex] != null)
|
|
iterativeSockets[currentSocketIndex].Highlight(HighlightState.Default);
|
|
|
|
currentSocketIndex = index;
|
|
currentActiveSocket = iterativeSockets[currentSocketIndex];
|
|
|
|
if (currentActiveSocket != null)
|
|
currentActiveSocket.Highlight(HighlightState.Active);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updated: Finds the index within the iterativeSockets list
|
|
/// </summary>
|
|
public void SetActiveSocket(SocketPoint socket)
|
|
{
|
|
int index = iterativeSockets.IndexOf(socket);
|
|
if (index >= 0) SetActiveSocketByIndex(index);
|
|
}
|
|
|
|
public void ResetToFirstSocket()
|
|
{
|
|
if (iterativeSockets.Count == 0) return;
|
|
ClearAllHighlights();
|
|
currentSocketIndex = 0;
|
|
currentActiveSocket = iterativeSockets[0];
|
|
if (currentActiveSocket != null) currentActiveSocket.Highlight(HighlightState.Active);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get all sockets in this container
|
|
/// </summary>
|
|
public List<SocketPoint> GetAllSockets()
|
|
{
|
|
return new List<SocketPoint>(sockets);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get all unoccupied sockets
|
|
/// </summary>
|
|
public List<SocketPoint> GetAvailableSockets()
|
|
{
|
|
List<SocketPoint> available = new List<SocketPoint>();
|
|
|
|
foreach (SocketPoint socket in sockets)
|
|
{
|
|
if (socket != null && !socket.IsOccupied())
|
|
{
|
|
available.Add(socket);
|
|
}
|
|
}
|
|
|
|
return available;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get all occupied sockets
|
|
/// </summary>
|
|
public List<SocketPoint> GetOccupiedSockets()
|
|
{
|
|
List<SocketPoint> occupied = new List<SocketPoint>();
|
|
|
|
foreach (SocketPoint socket in sockets)
|
|
{
|
|
if (socket != null && socket.IsOccupied())
|
|
{
|
|
occupied.Add(socket);
|
|
}
|
|
}
|
|
|
|
return occupied;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find the nearest compatible socket to a given world position
|
|
/// </summary>
|
|
public SocketPoint FindNearestCompatibleSocket(Vector3 worldPosition, SocketPoint sourceSocket)
|
|
{
|
|
SocketPoint nearest = null;
|
|
float minDistance = float.MaxValue;
|
|
|
|
foreach (SocketPoint socket in sockets)
|
|
{
|
|
// Skip occupied sockets
|
|
if (socket.IsOccupied()) continue;
|
|
|
|
// Check compatibility
|
|
if (sourceSocket != null && !socket.CanAccept(sourceSocket)) continue;
|
|
|
|
// Calculate distance
|
|
float distance = Vector3.Distance(socket.GetTransform().position, worldPosition);
|
|
|
|
if (distance < minDistance)
|
|
{
|
|
minDistance = distance;
|
|
nearest = socket;
|
|
}
|
|
}
|
|
|
|
return nearest;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find all sockets within a certain radius of a position
|
|
/// </summary>
|
|
public List<SocketPoint> FindSocketsInRadius(Vector3 worldPosition, float radius, bool onlyAvailable = true)
|
|
{
|
|
List<SocketPoint> socketsInRadius = new List<SocketPoint>();
|
|
|
|
foreach (SocketPoint socket in sockets)
|
|
{
|
|
if (onlyAvailable && socket.IsOccupied()) continue;
|
|
|
|
float distance = Vector3.Distance(socket.GetTransform().position, worldPosition);
|
|
|
|
if (distance <= radius)
|
|
{
|
|
socketsInRadius.Add(socket);
|
|
}
|
|
}
|
|
|
|
return socketsInRadius;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get sockets by type
|
|
/// </summary>
|
|
public List<SocketPoint> GetSocketsByType(SocketType type)
|
|
{
|
|
List<SocketPoint> filtered = new List<SocketPoint>();
|
|
|
|
foreach (SocketPoint socket in sockets)
|
|
{
|
|
if (socket.GetSocketType() == type)
|
|
{
|
|
filtered.Add(socket);
|
|
}
|
|
}
|
|
|
|
return filtered;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Highlight all sockets with a specific state
|
|
/// </summary>
|
|
public void HighlightAllSockets(HighlightState state)
|
|
{
|
|
foreach (SocketPoint socket in sockets)
|
|
{
|
|
if (socket != null)
|
|
{
|
|
socket.Highlight(state);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clear all socket highlights
|
|
/// </summary>
|
|
public void ClearAllHighlights()
|
|
{
|
|
foreach (SocketPoint socket in sockets)
|
|
{
|
|
if (socket != null)
|
|
{
|
|
socket.Highlight(HighlightState.Default);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Manually add a socket to the container
|
|
/// </summary>
|
|
public void AddSocket(SocketPoint socket)
|
|
{
|
|
if (!sockets.Contains(socket))
|
|
{
|
|
sockets.Add(socket);
|
|
Debug.Log($"Added socket {socket.name} to container");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove a socket from the container
|
|
/// </summary>
|
|
public void RemoveSocket(SocketPoint socket)
|
|
{
|
|
if (sockets.Contains(socket))
|
|
{
|
|
sockets.Remove(socket);
|
|
|
|
// If we removed the active socket, reset to first
|
|
if (socket == currentActiveSocket && sockets.Count > 0)
|
|
{
|
|
currentSocketIndex = 0;
|
|
currentActiveSocket = sockets[0];
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get count of total sockets
|
|
/// </summary>
|
|
public int GetSocketCount()
|
|
{
|
|
return sockets.Count;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check if container has any sockets
|
|
/// </summary>
|
|
public bool HasSockets()
|
|
{
|
|
return sockets.Count > 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the current socket index
|
|
/// </summary>
|
|
public int GetCurrentSocketIndex()
|
|
{
|
|
return currentSocketIndex;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find sockets that can connect to a specific joint block
|
|
/// </summary>
|
|
public List<SocketPoint> FindSocketsCompatibleWithJoint(JointBlock jointBlock)
|
|
{
|
|
List<SocketPoint> compatible = new List<SocketPoint>();
|
|
|
|
SocketPoint jointEnd1 = jointBlock.GetSocketEnd1();
|
|
SocketPoint jointEnd2 = jointBlock.GetSocketEnd2();
|
|
|
|
foreach (SocketPoint socket in sockets)
|
|
{
|
|
if (socket.IsOccupied()) continue;
|
|
|
|
if (jointEnd1 != null && socket.CanAccept(jointEnd1))
|
|
{
|
|
compatible.Add(socket);
|
|
}
|
|
else if (jointEnd2 != null && socket.CanAccept(jointEnd2))
|
|
{
|
|
compatible.Add(socket);
|
|
}
|
|
}
|
|
|
|
return compatible;
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
/// <summary>
|
|
/// Visualize sockets in editor
|
|
/// </summary>
|
|
private void OnDrawGizmos()
|
|
{
|
|
if (sockets.Count == 0) return;
|
|
|
|
foreach (SocketPoint socket in sockets)
|
|
{
|
|
if (socket == null) continue;
|
|
|
|
// Draw sphere at socket position
|
|
Gizmos.color = socket.IsOccupied() ? Color.red : Color.green;
|
|
Gizmos.DrawWireSphere(socket.GetTransform().position, socket.GetSocketRadius());
|
|
|
|
// Draw normal direction
|
|
Gizmos.color = Color.blue;
|
|
Gizmos.DrawRay(socket.GetTransform().position, socket.GetNormal() * 0.2f);
|
|
}
|
|
|
|
// Highlight active socket
|
|
if (currentActiveSocket != null)
|
|
{
|
|
Gizmos.color = Color.yellow;
|
|
Gizmos.DrawWireSphere(currentActiveSocket.GetTransform().position, currentActiveSocket.GetSocketRadius() * 1.2f);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Editor button to refresh socket list
|
|
/// </summary>
|
|
[ContextMenu("Refresh Sockets")]
|
|
private void EditorRefreshSockets()
|
|
{
|
|
InitializeSockets();
|
|
}
|
|
#endif
|
|
}
|