Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
You are viewing a potentially older version of this package.
View all versions.
| Date uploaded | a day ago |
| Version | 1.0.0 |
| Download link | Quexxle-OcCubeValuables-1.0.0.zip |
| Downloads | 40 |
| Dependency string | Quexxle-OcCubeValuables-1.0.0 |
This mod requires the following mods to function
README
using System; using System.Collections; using System.Collections.Generic; using Photon.Pun; using UnityEngine; using UnityEngine.AI;
public class ValuableObject : MonoBehaviour { [Serializable] public class ExtractionPointTracking { public GameObject extractionPoint;
public int closestRingReached;
public float localPlayerHaulToExtraction;
public ExtractionPointTracking(GameObject _extractionPoint)
{
extractionPoint = _extractionPoint;
closestRingReached = -1;
localPlayerHaulToExtraction = 0f;
}
}
[Space(40f)]
[Header("Presets")]
public Durability durabilityPreset;
public Value valuePreset;
public PhysAttribute physAttributePreset;
public PhysAudio audioPreset;
[Range(0.5f, 3f)]
public float audioPresetPitch = 1f;
public Gradient particleColors;
[Space(70f)]
public ValuableVolume.Type volumeType;
public bool debugVolume = true;
private PhysGrabObjectImpactDetector impactDetector;
[Space(20f)]
internal float dollarValueOriginal = 100f;
internal float dollarValueCurrent = 100f;
internal bool dollarValueSet;
internal int dollarValueOverride;
private Rigidbody rb;
private PhotonView photonView;
private NavMeshObstacle navMeshObstacle;
private bool inStartRoom;
private float inStartRoomCheckTimer;
internal RoomVolumeCheck roomVolumeCheck;
internal PhysGrabObject physGrabObject;
internal bool discovered;
internal bool discoveredReminder;
private float discoveredReminderTimer;
private List<ExtractionPointTracking> extractionPointTrackings = new List<ExtractionPointTracking>();
private bool extractionTrackingInitialized;
private Vector3 lastExtractionTrackingPosition;
private Dictionary<PhysGrabber, float> playerGrabbedTime = new Dictionary<PhysGrabber, float>();
private Dictionary<PhysGrabCart, Dictionary<PhysGrabber, float>> cartSnapshots = new Dictionary<PhysGrabCart, Dictionary<PhysGrabber, float>>();
private float lastGrabbedTimeUpdate;
[SerializeField]
private DebugValuableMeshes debugValuableMeshes;
private void Awake()
{
photonView = GetComponent<PhotonView>();
}
private void Start()
{
physGrabObject = GetComponent<PhysGrabObject>();
roomVolumeCheck = GetComponent<RoomVolumeCheck>();
impactDetector = GetComponent<PhysGrabObjectImpactDetector>();
float num = Mathf.Max(base.transform.localScale.x, base.transform.localScale.y, base.transform.localScale.z);
if (num > 1f)
{
float t = Mathf.Clamp01((num - 1f) / 1f);
audioPresetPitch = Mathf.Lerp(audioPresetPitch, 0.65f, t);
}
navMeshObstacle = GetComponent<NavMeshObstacle>();
if ((bool)navMeshObstacle)
{
Debug.LogError(base.gameObject.name + " has a NavMeshObstacle component. Please remove it.");
}
StartCoroutine(DollarValueSet());
rb = GetComponent<Rigidbody>();
if ((bool)physAttributePreset)
{
if ((bool)rb)
{
rb.mass = physAttributePreset.mass;
}
if ((bool)physGrabObject)
{
physGrabObject.massOriginal = physAttributePreset.mass;
}
}
else if ((bool)rb || (bool)physGrabObject || (bool)impactDetector)
{
Debug.LogError(base.gameObject.name + " is missing a PhysAttributePreset.", base.gameObject);
}
if (!LevelGenerator.Instance.Generated)
{
ValuableDirector.instance.valuableSpawnAmount++;
}
ValuableDirector.instance.valuableList.Add(this);
if (volumeType <= ValuableVolume.Type.Small)
{
physGrabObject.clientNonKinematic = true;
}
}
private void AddToDollarHaulList()
{
if (GameManager.instance.gameMode == 1)
{
photonView.RPC("AddToDollarHaulListRPC", RpcTarget.All);
}
else if ((bool)GetComponent<ValuableObject>() && !RoundDirector.instance.dollarHaulList.Contains(base.gameObject))
{
RoundDirector.instance.dollarHaulList.Add(base.gameObject);
}
}
[PunRPC]
public void AddToDollarHaulListRPC(PhotonMessageInfo _info = default(PhotonMessageInfo))
{
if (SemiFunc.MasterOnlyRPC(_info) && (bool)GetComponent<ValuableObject>() && !RoundDirector.instance.dollarHaulList.Contains(base.gameObject))
{
RoundDirector.instance.dollarHaulList.Add(base.gameObject);
}
}
private void RemoveFromDollarHaulList()
{
if (GameManager.instance.gameMode == 1)
{
photonView.RPC("RemoveFromDollarHaulListRPC", RpcTarget.All);
}
else if ((bool)GetComponent<ValuableObject>() && RoundDirector.instance.dollarHaulList.Contains(base.gameObject))
{
RoundDirector.instance.dollarHaulList.Remove(base.gameObject);
}
}
[PunRPC]
public void RemoveFromDollarHaulListRPC(PhotonMessageInfo _info = default(PhotonMessageInfo))
{
if (SemiFunc.MasterOnlyRPC(_info) && (bool)GetComponent<ValuableObject>() && RoundDirector.instance.dollarHaulList.Contains(base.gameObject))
{
RoundDirector.instance.dollarHaulList.Remove(base.gameObject);
}
}
private void Update()
{
if (GameManager.instance.gameMode == 0 || PhotonNetwork.IsMasterClient)
{
if (inStartRoomCheckTimer > 0f)
{
inStartRoomCheckTimer -= Time.deltaTime;
}
else
{
bool flag = false;
foreach (RoomVolume currentRoom in roomVolumeCheck.CurrentRooms)
{
if (currentRoom.Extraction)
{
if (!inStartRoom)
{
AddToDollarHaulList();
inStartRoom = true;
}
flag = true;
}
}
if (!flag && inStartRoom)
{
RemoveFromDollarHaulList();
inStartRoom = false;
}
inStartRoomCheckTimer = 0.5f;
}
}
if (!extractionTrackingInitialized)
{
InitializeExtractionTracking();
}
else if (Vector3.Distance(base.transform.position, lastExtractionTrackingPosition) >= 2f)
{
UpdateExtractionTracking();
lastExtractionTrackingPosition = base.transform.position;
}
UpdatePlayerGrabbedTime();
UpdateCartSnapshots();
DiscoverReminderLogic();
}
private IEnumerator DollarValueSet()
{
yield return new WaitForSeconds(0.05f);
while (LevelGenerator.Instance.State <= LevelGenerator.LevelState.Valuable)
{
yield return new WaitForSeconds(0.05f);
}
while (SemiFunc.IsMultiplayer() && photonView.ViewID == 0)
{
yield return new WaitForSeconds(0.05f);
}
if (!SemiFunc.IsMultiplayer())
{
DollarValueSetLogic();
}
else if (SemiFunc.IsMasterClient())
{
DollarValueSetLogic();
photonView.RPC("DollarValueSetRPC", RpcTarget.Others, dollarValueCurrent);
}
if (SemiFunc.IsMasterClientOrSingleplayer())
{
RoundDirector.instance.haulGoalMax += (int)dollarValueCurrent;
}
}
public void DollarValueSetLogic()
{
if (!dollarValueSet)
{
if (dollarValueOverride != 0)
{
dollarValueOriginal = dollarValueOverride;
dollarValueCurrent = dollarValueOverride;
}
else
{
dollarValueOriginal = Mathf.Round(UnityEngine.Random.Range(valuePreset.valueMin, valuePreset.valueMax));
dollarValueOriginal = Mathf.Round(dollarValueOriginal / 100f) * 100f;
dollarValueCurrent = dollarValueOriginal;
}
dollarValueSet = true;
}
}
private void DiscoverReminderLogic()
{
if (!discovered || discoveredReminder)
{
return;
}
if (discoveredReminderTimer > 0f)
{
discoveredReminderTimer -= Time.deltaTime;
return;
}
discoveredReminderTimer = UnityEngine.Random.Range(2f, 5f);
if (!physGrabObject.impactDetector.inCart && (bool)PlayerController.instance && PlayerController.instance.isActiveAndEnabled)
{
if (Vector3.Distance(base.transform.position, PlayerController.instance.transform.position) > 20f)
{
discoveredReminder = true;
}
}
else
{
discoveredReminder = false;
}
}
public bool Discover(ValuableDiscoverGraphic.State _state)
{
bool result = false;
if (!discovered)
{
result = true;
if (!GameManager.Multiplayer())
{
DiscoverRPC();
}
else
{
if (photonView.ViewID == 0)
{
return false;
}
photonView.RPC("DiscoverRPC", RpcTarget.All);
}
}
ValuableDiscover.instance.New(physGrabObject, _state);
return result;
}
[PunRPC]
private void DiscoverRPC()
{
discovered = true;
Map.Instance.AddValuable(this);
}
[PunRPC]
public void DollarValueSetRPC(float value, PhotonMessageInfo _info = default(PhotonMessageInfo))
{
if (SemiFunc.MasterOnlyRPC(_info))
{
dollarValueOriginal = value;
dollarValueCurrent = value;
dollarValueSet = true;
}
}
private void InitializeExtractionTracking()
{
if (LevelGenerator.Instance.State <= LevelGenerator.LevelState.Valuable || RoundDirector.instance == null || RoundDirector.instance.extractionPointList == null)
{
return;
}
foreach (GameObject extractionPoint in RoundDirector.instance.extractionPointList)
{
if ((bool)extractionPoint)
{
ExtractionPointTracking extractionPointTracking = new ExtractionPointTracking(extractionPoint);
float num = Vector3.Distance(base.transform.position, extractionPoint.transform.position);
if (num < 60f)
{
int closestRingReached = Mathf.FloorToInt(num / 2f);
extractionPointTracking.closestRingReached = closestRingReached;
}
extractionPointTrackings.Add(extractionPointTracking);
}
}
lastExtractionTrackingPosition = base.transform.position;
extractionTrackingInitialized = true;
}
private void UpdateExtractionTracking()
{
if (!extractionTrackingInitialized)
{
return;
}
foreach (ExtractionPointTracking extractionPointTracking in extractionPointTrackings)
{
if (!extractionPointTracking.extractionPoint)
{
continue;
}
float num = Vector3.Distance(base.transform.position, extractionPointTracking.extractionPoint.transform.position);
if (num >= 60f)
{
continue;
}
int num2 = Mathf.FloorToInt(num / 2f);
if (extractionPointTracking.closestRingReached == -1)
{
extractionPointTracking.closestRingReached = num2;
}
else if (num2 < extractionPointTracking.closestRingReached)
{
if (physGrabObject.grabbedLocal)
{
extractionPointTracking.localPlayerHaulToExtraction += 1f;
}
else if (impactDetector.inCart)
{
float localPlayerPercentageForCurrentCart = GetLocalPlayerPercentageForCurrentCart();
extractionPointTracking.localPlayerHaulToExtraction += 0.2f * localPlayerPercentageForCurrentCart;
}
extractionPointTracking.closestRingReached = num2;
}
}
}
public float GetLocalPlayerHaulScore(GameObject _extractionPoint)
{
foreach (ExtractionPointTracking extractionPointTracking in extractionPointTrackings)
{
if (extractionPointTracking.extractionPoint == _extractionPoint)
{
return extractionPointTracking.localPlayerHaulToExtraction;
}
}
return 0f;
}
private PhysGrabCart GetCurrentCart()
{
if (!impactDetector)
{
return null;
}
return impactDetector.currentCart;
}
private float GetLocalPlayerPercentageForCurrentCart()
{
PhysGrabCart currentCart = GetCurrentCart();
if (!currentCart)
{
return 0f;
}
if (!cartSnapshots.ContainsKey(currentCart))
{
return 0f;
}
Dictionary<PhysGrabber, float> dictionary = cartSnapshots[currentCart];
float num = 0f;
float num2 = 0f;
foreach (KeyValuePair<PhysGrabber, float> item in dictionary)
{
if ((bool)item.Key)
{
num += item.Value;
bool flag = true;
if ((!GameManager.Multiplayer()) ? item.Key.isLocal : item.Key.photonView.IsMine)
{
num2 = item.Value;
}
}
}
if (num <= 0f)
{
return 0f;
}
return num2 / num;
}
private void UpdatePlayerGrabbedTime()
{
if (impactDetector.inCart || physGrabObject.playerGrabbing.Count == 0)
{
return;
}
float num = Time.time - lastGrabbedTimeUpdate;
lastGrabbedTimeUpdate = Time.time;
float num2 = num / (float)physGrabObject.playerGrabbing.Count;
foreach (PhysGrabber item in physGrabObject.playerGrabbing)
{
if ((bool)item)
{
if (!playerGrabbedTime.ContainsKey(item))
{
playerGrabbedTime[item] = 0f;
}
playerGrabbedTime[item] += num2;
}
}
}
private void UpdateCartSnapshots()
{
if (impactDetector.inCart)
{
PhysGrabCart currentCart = GetCurrentCart();
if ((bool)currentCart && !cartSnapshots.ContainsKey(currentCart))
{
Dictionary<PhysGrabber, float> value = new Dictionary<PhysGrabber, float>(playerGrabbedTime);
cartSnapshots[currentCart] = value;
}
}
}
private void OnDrawGizmos()
{
if (debugVolume)
{
Gizmos.color = new Color(1f, 0.92f, 0.02f, 0.2f);
Gizmos.matrix = base.transform.localToWorldMatrix;
Mesh mesh = null;
if ((bool)debugValuableMeshes)
{
mesh = volumeType switch
{
ValuableVolume.Type.Tiny => debugValuableMeshes.tiny,
ValuableVolume.Type.Small => debugValuableMeshes.small,
ValuableVolume.Type.Medium => debugValuableMeshes.medium,
ValuableVolume.Type.Big => debugValuableMeshes.big,
ValuableVolume.Type.Wide => debugValuableMeshes.wide,
ValuableVolume.Type.Tall => debugValuableMeshes.tall,
ValuableVolume.Type.VeryTall => debugValuableMeshes.veryTall,
_ => null,
};
}
Gizmos.DrawMesh(mesh, Vector3.zero, Quaternion.identity, Vector3.one);
Gizmos.DrawWireMesh(mesh, Vector3.zero, Quaternion.identity, Vector3.one);
}
}
}