Files
2026-07-21 08:56:10 +03:00

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
}