Files
UltimateFishing/Assets/Scripts/Assembly-CSharp/vp_Respawner.cs
2026-02-21 16:45:37 +08:00

269 lines
6.0 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
[Serializable]
public class vp_Respawner : MonoBehaviour
{
public enum SpawnMode
{
SamePosition = 0,
SpawnPoint = 1
}
public enum ObstructionSolver
{
Wait = 0,
AdjustPlacement = 1
}
public SpawnMode m_SpawnMode;
public string SpawnPointTag = string.Empty;
public ObstructionSolver m_ObstructionSolver;
public float ObstructionRadius = 1f;
public float MinRespawnTime = 3f;
public float MaxRespawnTime = 3f;
public float LastRespawnTime;
public bool SpawnOnAwake;
public AudioClip SpawnSound;
public GameObject[] SpawnFXPrefabs;
protected Vector3 m_InitialPosition = Vector3.zero;
protected Quaternion m_InitialRotation;
protected vp_Placement Placement = new vp_Placement();
protected Transform m_Transform;
protected AudioSource m_Audio;
protected bool m_IsInitialSpawnOnAwake;
protected vp_Timer.Handle m_RespawnTimer = new vp_Timer.Handle();
protected static Dictionary<Collider, vp_Respawner> m_Instances;
protected static vp_Respawner m_GetInstanceResult;
protected Renderer m_Renderer;
public static Dictionary<Collider, vp_Respawner> Instances
{
get
{
if (m_Instances == null)
{
m_Instances = new Dictionary<Collider, vp_Respawner>(100);
}
return m_Instances;
}
}
public Renderer Renderer
{
get
{
if (m_Renderer == null)
{
m_Renderer = GetComponent<Renderer>();
}
return m_Renderer;
}
}
protected virtual void Awake()
{
m_Transform = base.transform;
m_Audio = GetComponent<AudioSource>();
Placement.Position = (m_InitialPosition = m_Transform.position);
Placement.Rotation = (m_InitialRotation = m_Transform.rotation);
if (m_SpawnMode == SpawnMode.SamePosition)
{
SpawnPointTag = string.Empty;
}
if (SpawnOnAwake)
{
m_IsInitialSpawnOnAwake = true;
vp_Utility.Activate(base.gameObject, false);
PickSpawnPoint();
}
}
protected virtual void OnEnable()
{
if (GetComponent<Collider>() != null && !Instances.ContainsValue(this))
{
Instances.Add(GetComponent<Collider>(), this);
}
}
protected virtual void OnDisable()
{
}
protected virtual void SpawnFX()
{
if (!m_IsInitialSpawnOnAwake)
{
if (m_Audio != null)
{
m_Audio.pitch = Time.timeScale;
m_Audio.PlayOneShot(SpawnSound);
}
if (SpawnFXPrefabs != null && SpawnFXPrefabs.Length > 0)
{
GameObject[] spawnFXPrefabs = SpawnFXPrefabs;
foreach (GameObject gameObject in spawnFXPrefabs)
{
if (gameObject != null)
{
vp_Utility.Instantiate(gameObject, m_Transform.position, m_Transform.rotation);
}
}
}
}
m_IsInitialSpawnOnAwake = false;
}
protected virtual void Die()
{
vp_Timer.In(UnityEngine.Random.Range(MinRespawnTime, MaxRespawnTime), PickSpawnPoint, m_RespawnTimer);
}
public virtual void PickSpawnPoint()
{
if (this == null)
{
return;
}
if (m_SpawnMode == SpawnMode.SamePosition || vp_SpawnPoint.SpawnPoints.Count < 1)
{
Placement.Position = m_InitialPosition;
Placement.Rotation = m_InitialRotation;
if (Placement.IsObstructed(ObstructionRadius))
{
switch (m_ObstructionSolver)
{
case ObstructionSolver.Wait:
vp_Timer.In(UnityEngine.Random.Range(MinRespawnTime, MaxRespawnTime), PickSpawnPoint, m_RespawnTimer);
return;
case ObstructionSolver.AdjustPlacement:
if (!vp_Placement.AdjustPosition(Placement, ObstructionRadius))
{
vp_Timer.In(UnityEngine.Random.Range(MinRespawnTime, MaxRespawnTime), PickSpawnPoint, m_RespawnTimer);
return;
}
break;
}
}
}
else
{
switch (m_ObstructionSolver)
{
case ObstructionSolver.Wait:
Placement = vp_SpawnPoint.GetRandomPlacement(0f, SpawnPointTag);
if (Placement == null)
{
Placement = new vp_Placement();
m_SpawnMode = SpawnMode.SamePosition;
PickSpawnPoint();
}
if (Placement.IsObstructed(ObstructionRadius))
{
vp_Timer.In(UnityEngine.Random.Range(MinRespawnTime, MaxRespawnTime), PickSpawnPoint, m_RespawnTimer);
return;
}
break;
case ObstructionSolver.AdjustPlacement:
Placement = vp_SpawnPoint.GetRandomPlacement(ObstructionRadius, SpawnPointTag);
if (Placement == null)
{
vp_Timer.In(UnityEngine.Random.Range(MinRespawnTime, MaxRespawnTime), PickSpawnPoint, m_RespawnTimer);
return;
}
break;
}
}
Respawn();
}
public virtual void PickSpawnPoint(Vector3 position, Quaternion rotation)
{
Placement.Position = position;
Placement.Rotation = rotation;
Respawn();
}
public virtual void Respawn()
{
LastRespawnTime = Time.time;
vp_Utility.Activate(base.gameObject);
SpawnFX();
if (vp_Gameplay.isMultiplayer && vp_Gameplay.isMaster)
{
vp_GlobalEvent<Transform, vp_Placement>.Send("TransmitRespawn", base.transform.root, Placement);
}
SendMessage("Reset");
Placement.Position = m_InitialPosition;
Placement.Rotation = m_InitialRotation;
}
public virtual void Reset()
{
if (Application.isPlaying)
{
m_Transform.position = Placement.Position;
m_Transform.rotation = Placement.Rotation;
if (GetComponent<Rigidbody>() != null && !GetComponent<Rigidbody>().isKinematic)
{
GetComponent<Rigidbody>().angularVelocity = Vector3.zero;
GetComponent<Rigidbody>().velocity = Vector3.zero;
}
}
}
public static void ResetAll(bool reInitTimers = false)
{
foreach (vp_Respawner value in Instances.Values)
{
if (!(value == null) && (!vp_Utility.IsActive(value.gameObject) || (value is vp_PlayerRespawner && (value as vp_PlayerRespawner).Player.Dead.Active)))
{
if (reInitTimers)
{
value.Die();
}
else
{
value.PickSpawnPoint();
}
}
}
}
public static vp_Respawner GetByCollider(Collider col)
{
if (!Instances.TryGetValue(col, out m_GetInstanceResult))
{
m_GetInstanceResult = col.transform.root.GetComponentInChildren<vp_Respawner>();
Instances.Add(col, m_GetInstanceResult);
}
return m_GetInstanceResult;
}
protected void OnLevelWasLoaded()
{
Instances.Clear();
}
}