using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using FistVR;
using H3MP;
using H3MP.Networking;
using H3MP.Scripts;
using H3MP.Tracking;
using HarmonyLib;
using MapGenerator;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Sodalite.Api;
using SupplyRaid;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("Wilnath/marbL-")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Library for building containers of randomized items in H3VR.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Wilnath.Lootations")]
[assembly: AssemblyTitle("Lootations")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace BepInEx
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
internal sealed class BepInAutoPluginAttribute : Attribute
{
public BepInAutoPluginAttribute(string id = null, string name = null, string version = null)
{
}
}
}
namespace BepInEx.Preloader.Core.Patching
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
internal sealed class PatcherAutoPluginAttribute : Attribute
{
public PatcherAutoPluginAttribute(string id = null, string name = null, string version = null)
{
}
}
}
namespace Lootations
{
public class EnableHook : MonoBehaviour
{
public GameObject LootObjectOwner;
public bool Inverted;
public void Awake()
{
LootObject component = LootObjectOwner.GetComponent<LootObject>();
if ((Object)(object)component == (Object)null)
{
Lootations.Logger.LogError((object)"VisibilityHook could not find LootObject.");
return;
}
component.LootObjectTriggered += Triggered;
component.OnTriggerReset += Reset;
SetEnabled(visible: true);
}
private void Reset()
{
SetEnabled(visible: true);
}
private void Triggered()
{
SetEnabled(visible: false);
}
private void SetEnabled(bool visible)
{
if (Inverted)
{
visible = !visible;
}
Renderer component = ((Component)this).GetComponent<Renderer>();
if ((Object)(object)component != (Object)null)
{
component.enabled = visible;
}
Collider component2 = ((Component)this).GetComponent<Collider>();
if ((Object)(object)component2 != (Object)null)
{
component2.enabled = visible;
}
}
}
public class EnemySpawn : MonoBehaviour
{
private class SpawnParameters
{
public int IFF;
public SosigEnemyID[] pool = (SosigEnemyID[])(object)new SosigEnemyID[1] { (SosigEnemyID)160 };
public int squadSize = 3;
}
public bool UseGlobalSpawnSettings = true;
public float PlayerDistanceToDespawn = 125f;
public float PlayerDistanceToSpawn = 100f;
public float PlayerSpawnGrace = 25f;
private List<Sosig> spawnedSosigs = new List<Sosig>();
private bool spawned;
public void Awake()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
if (Utilities.PlayerWithinDistance(((Component)this).transform.position, PlayerSpawnGrace))
{
Lootations.Logger.LogDebug((object)"Skipped enemy spawn to grace");
spawned = true;
}
}
public void Update()
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
if (!spawned && (!Lootations.h3mpEnabled || !Networking.IsClient()) && Utilities.PlayerWithinDistance(((Component)this).transform.position, PlayerDistanceToSpawn))
{
Spawn();
spawned = true;
}
}
private SpawnParameters GetSpawnParameters()
{
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Expected I4, but got Unknown
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Expected I4, but got Unknown
SpawnParameters spawnParameters = new SpawnParameters();
if (((Behaviour)SR_Manager.instance).isActiveAndEnabled)
{
FactionLevel factionLevel = SR_Manager.GetFactionLevel();
spawnParameters.IFF = 1;
spawnParameters.squadSize = Random.Range(factionLevel.squadSizeMin, factionLevel.squadSizeMax);
spawnParameters.pool = factionLevel.squadPool.sosigEnemyID;
return spawnParameters;
}
if (((Behaviour)GM.TNH_Manager).isActiveAndEnabled)
{
List<Patrol> patrols = GM.TNH_Manager.m_curLevel.PatrolChallenge.Patrols;
Patrol val = patrols[Random.Range(0, patrols.Count)];
spawnParameters.IFF = 1;
spawnParameters.squadSize = val.PatrolSize;
spawnParameters.pool = (SosigEnemyID[])(object)new SosigEnemyID[2]
{
(SosigEnemyID)(int)val.EType,
(SosigEnemyID)(int)val.LType
};
return spawnParameters;
}
return spawnParameters;
}
public void Spawn()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Expected O, but got Unknown
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
//IL_0103: Unknown result type (might be due to invalid IL or missing references)
//IL_010d: Unknown result type (might be due to invalid IL or missing references)
//IL_0112: Unknown result type (might be due to invalid IL or missing references)
SpawnParameters spawnParameters = GetSpawnParameters();
SpawnOptions val = new SpawnOptions
{
SpawnActivated = true,
SpawnState = (SosigOrder)1,
IFF = spawnParameters.IFF,
SpawnWithFullAmmo = true,
EquipmentMode = (EquipmentSlots)7,
SosigTargetPosition = ((Component)this).transform.position,
SosigTargetRotation = ((Component)this).transform.eulerAngles
};
for (int i = 0; i < spawnParameters.squadSize; i++)
{
SosigEnemyID randomSosigIDFromPool = SR_Global.GetRandomSosigIDFromPool(spawnParameters.pool);
Quaternion val2 = Quaternion.Euler(0f, Random.Range(0f, 360f), 0f);
if (!Utilities.RandomPointOnNavmesh(((Component)this).transform.position, 0.5f, out var result))
{
Lootations.Logger.LogDebug((object)"Could not find spawn position for EnemySpawn sosig");
continue;
}
Sosig val3 = SosigAPI.Spawn(ManagerSingleton<IM>.Instance.odicSosigObjsByID[randomSosigIDFromPool], val, result, val2);
spawnedSosigs.Add(val3);
if (((Behaviour)SR_Manager.instance).isActiveAndEnabled)
{
foreach (Sosig spawnedSosig in spawnedSosigs)
{
spawnedSosig.StateSightRangeMults *= SR_Manager.sosigSightMultiplier;
}
SR_Manager.instance.AddCustomSosig(val3, false);
}
else if (((Behaviour)GM.TNH_Manager).isActiveAndEnabled)
{
GM.TNH_Manager.AddToMiscEnemies(((Component)val3).gameObject);
}
}
}
public void OnDestroy()
{
foreach (Sosig spawnedSosig in spawnedSosigs)
{
if (spawnedSosig != null)
{
spawnedSosig.KillSosig();
}
}
spawnedSosigs.Clear();
}
private void OnDrawGizmosSelected()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
Gizmos.color = Color.red;
if (UseGlobalSpawnSettings)
{
Gizmos.DrawSphere(((Component)this).transform.position, 0.25f);
}
else
{
Gizmos.DrawSphere(((Component)this).transform.position, PlayerDistanceToSpawn);
}
}
private void OnDrawGizmos()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
Gizmos.color = Color.red;
Gizmos.DrawSphere(((Component)this).transform.position, 0.1f);
}
}
public static class LootManager
{
private static readonly int MAX_SPAWNS;
private static int LootTriggerCounter;
public static Dictionary<GameObject, LootSpawnPoint> spawnedLoot;
private static List<LootObject> LootObjects;
private static List<LootSpawnPoint> LootSpawns;
private static List<LootObjectRandomizer> ObjectSpawns;
private static Dictionary<int, ILootTrigger> LootTriggers;
private static Dictionary<ILootTrigger, int> LootTriggerIds;
private static int spawnPointsActivated;
public static readonly Vector2 MAG_AMOUNT_RANGE;
public static readonly float Y_SPAWN_INCREMENT;
static LootManager()
{
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Expected O, but got Unknown
MAX_SPAWNS = -1;
LootTriggerCounter = 0;
spawnedLoot = new Dictionary<GameObject, LootSpawnPoint>();
LootObjects = new List<LootObject>();
LootSpawns = new List<LootSpawnPoint>();
ObjectSpawns = new List<LootObjectRandomizer>();
LootTriggers = new Dictionary<int, ILootTrigger>();
LootTriggerIds = new Dictionary<ILootTrigger, int>();
spawnPointsActivated = 0;
MAG_AMOUNT_RANGE = new Vector2(2f, 4f);
Y_SPAWN_INCREMENT = 0.05f;
SR_Manager.SupplyPointChangeEvent += new SupplyPointChangeDelegate(OnSupplyPointChange);
}
public static bool AddLootSpawn(LootSpawnPoint lootable)
{
LootSpawns.Add(lootable);
return true;
}
public static void RemoveLootSpawn(LootSpawnPoint lootable)
{
if (LootSpawns.Contains(lootable))
{
LootSpawns.Remove(lootable);
}
}
public static bool AddLootObject(LootObject obj)
{
LootObjects.Add(obj);
return true;
}
public static ILootTrigger GetLootTriggerById(int id)
{
if (!LootTriggers.ContainsKey(id))
{
return null;
}
return LootTriggers[id];
}
public static int GetLootTriggerId(ILootTrigger trigger)
{
return LootTriggerIds[trigger];
}
public static bool AddLootTrigger(ILootTrigger trigger)
{
LootTriggers.Add(LootTriggerCounter, trigger);
LootTriggerIds.Add(trigger, LootTriggerCounter);
LootTriggerCounter++;
return true;
}
public static bool RemoveLootTrigger(ILootTrigger trigger)
{
int key = LootTriggerIds[trigger];
LootTriggerIds.Remove(trigger);
LootTriggers.Remove(key);
return true;
}
public static bool RemoveLootObject(LootObject obj)
{
if (!LootObjects.Contains(obj))
{
return false;
}
LootObjects.Remove(obj);
return true;
}
public static bool AddRandomObject(LootObjectRandomizer obj)
{
ObjectSpawns.Add(obj);
return true;
}
public static void OnPhysicalObjectPickup(GameObject obj)
{
if (Lootations.h3mpEnabled && Networking.IsClient())
{
Networking.SendItemGrab(obj);
}
if (spawnedLoot.ContainsKey(obj))
{
Lootations.Logger.LogDebug((object)"Removed object from tracked spawned loot pool.");
spawnedLoot[obj].StopTrackingObject(obj);
spawnedLoot.Remove(obj);
}
}
public static void OnSceneSwitched()
{
Lootations.Logger.LogInfo((object)"Removing track of spawned items.");
spawnedLoot.Clear();
LootSpawns.Clear();
LootObjects.Clear();
ObjectSpawns.Clear();
LootTriggers.Clear();
LootTriggerIds.Clear();
LootTriggerCounter = 0;
}
public static void StopTrackingNetworkId(int trackingId)
{
Lootations.Logger.LogDebug((object)("Attempting to remove " + trackingId));
if (Server.objects == null)
{
Lootations.Logger.LogError((object)"that stuff is null even");
return;
}
if (trackingId < 0 && trackingId >= Server.objects.Length)
{
Lootations.Logger.LogError((object)"Clients.objects does not work like that it turns out");
return;
}
TrackedObjectData val = Server.objects[trackingId];
if (val == null)
{
Lootations.Logger.LogError((object)"stop tracking null check obj");
return;
}
TrackedObject physical = val.physical;
if ((Object)(object)physical == (Object)null)
{
Lootations.Logger.LogError((object)"stop tracking null check physical");
return;
}
GameObject gameObject = ((Component)physical).gameObject;
if ((Object)(object)gameObject == (Object)null)
{
Lootations.Logger.LogError((object)"stop tracking null check gameObj");
}
else if (spawnedLoot.ContainsKey(gameObject))
{
Lootations.Logger.LogDebug((object)"REMOVED IT!");
spawnedLoot[gameObject].StopTrackingObject(gameObject);
}
}
private static void ShuffleObjectRandomizers()
{
ObjectSpawns = ObjectSpawns.OrderBy((LootObjectRandomizer _) => Random.Range(0, int.MaxValue)).ToList();
}
private static void OnSupplyPointChange()
{
if (Lootations.h3mpEnabled && Networking.IsConnected())
{
if (Networking.IsClient())
{
Lootations.Logger.LogDebug((object)"Awaiting reroll of loot as client.");
return;
}
Lootations.Logger.LogDebug((object)"Rolling loot as host.");
int frameCount = Time.frameCount;
RerollLoot(frameCount);
Networking.SendRerollLoot(frameCount);
}
else
{
Lootations.Logger.LogDebug((object)"Rolling loot as offline.");
RerollLoot();
}
}
public static void OnTNHLevelSet(int level)
{
RerollLoot(Time.frameCount);
}
public static void RerollLoot(int seed = -1)
{
if (seed == -1)
{
seed = Time.frameCount;
}
int level = 0;
if (((Behaviour)SR_Manager.instance).isActiveAndEnabled)
{
level = SR_Manager.instance.CurrentCaptures;
}
Lootations.Logger.LogDebug((object)("Respawning objects with seed: " + seed));
Random.InitState(seed);
spawnPointsActivated = 0;
ShuffleObjectRandomizers();
spawnedLoot = new Dictionary<GameObject, LootSpawnPoint>();
for (int i = 0; i < LootSpawns.Count; i++)
{
LootSpawns[i].Reset();
}
bool flag = false;
for (int j = 0; j < ObjectSpawns.Count; j++)
{
if (MAX_SPAWNS != -1 && j >= MAX_SPAWNS)
{
ManualLogSource logger = Lootations.Logger;
int mAX_SPAWNS = MAX_SPAWNS;
logger.LogDebug((object)("Stopping respawn of loot objects, hit config limit of " + mAX_SPAWNS));
flag = true;
break;
}
if (((Behaviour)MG_Manager.instance).isActiveAndEnabled && MG_Manager.profile.srLootSpawns != 0 && j >= MG_Manager.profile.srLootSpawns)
{
Lootations.Logger.LogDebug((object)("Stopping respawn of loot objects, hit MG profile limit of " + MG_Manager.profile.srLootSpawns));
flag = true;
break;
}
ObjectSpawns[j].RollAndSpawn();
spawnPointsActivated++;
}
if (!flag)
{
Lootations.Logger.LogDebug((object)"No limit hit for ObjectRandomizer rerolls.");
}
Lootations.Logger.LogDebug((object)("Spawned " + spawnPointsActivated + " objects."));
for (int k = 0; k < LootObjects.Count; k++)
{
LootObjects[k].Reset();
}
for (int l = 0; l < LootSpawns.Count; l++)
{
LootSpawns[l].SetLevel(level);
}
}
public static Quaternion RandomRotation()
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
return Quaternion.Euler(0f, Random.Range(0f, 360f), 0f);
}
}
public class LootObject : MonoBehaviour
{
public delegate void TriggerResetDelegate();
public delegate void LootObjectTriggeredDelegate();
public GameObject[] LootSpawnPoints;
private LootSpawnPoint[] spawnPoints;
public bool OneShot;
public bool HasResetDistanceGrace = true;
[HideInInspector]
public bool Triggered;
public readonly float PLAYER_PROXIMITY_GRACE_DISTANCE = 25f;
public event TriggerResetDelegate OnTriggerReset;
public event LootObjectTriggeredDelegate LootObjectTriggered;
public static void HookTrigger(GameObject lootObjectOwner, MonoBehaviour trigger)
{
LootObject lootObject = ((!((Object)(object)lootObjectOwner == (Object)null)) ? lootObjectOwner.GetComponent<LootObject>() : ((Component)trigger).GetComponent<LootObject>());
if ((Object)(object)lootObject == (Object)null)
{
Lootations.Logger.LogError((object)("Cannot hook loot trigger on object without one: " + ((Object)lootObject).name));
}
else if (trigger is ILootTrigger)
{
ILootTrigger lootTrigger = trigger as ILootTrigger;
lootObject.OnTriggerReset += lootTrigger.LootReset;
lootTrigger.OnTriggered += lootObject.Trigger;
LootManager.AddLootTrigger(lootTrigger);
}
}
public void Awake()
{
if (LootSpawnPoints == null)
{
Lootations.Logger.LogWarning((object)"LootTrigger skipped initialization due to missing loot points.");
}
spawnPoints = Utilities.GameObjectsToPoints(LootSpawnPoints);
LootManager.AddLootObject(this);
}
public void Trigger(ILootTrigger trigger)
{
if (Triggered)
{
return;
}
Triggered = true;
this.LootObjectTriggered?.Invoke();
if (Lootations.h3mpEnabled && Networking.IsConnected())
{
Networking.SendTriggerActivated(LootManager.GetLootTriggerId(trigger));
if (Networking.IsClient())
{
return;
}
}
SpawnItemsAtLootSpawns();
}
private void SpawnItemsAtLootSpawns()
{
LootSpawnPoint[] array = spawnPoints;
foreach (LootSpawnPoint lootSpawnPoint in array)
{
if (lootSpawnPoint == null)
{
Lootations.Logger.LogError((object)("Object: " + ((Object)this).name + " contained non loot spawn point!"));
}
else
{
lootSpawnPoint.Trigger();
}
}
}
public void Reset()
{
if (!OneShot)
{
Triggered = false;
this.OnTriggerReset?.Invoke();
}
}
public void OnDestroy()
{
LootManager.RemoveLootObject(this);
}
}
public class LootObjectRandomizer : MonoBehaviour
{
public GameObject[] Objects;
public bool RandomizeRotation;
private GameObject spawnedObject;
public readonly float PLAYER_PROXIMITY_GRACE_DISTANCE = 35f;
public bool ResetGrace = true;
public void Awake()
{
LootManager.AddRandomObject(this);
if (Objects.Length == 0)
{
Lootations.Logger.LogError((object)"LootObjectRandomizer has Objects of length 0.");
}
}
public void Destroy()
{
if ((Object)(object)spawnedObject != (Object)null)
{
Object.Destroy((Object)(object)spawnedObject);
}
spawnedObject = null;
}
public void RollAndSpawn()
{
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
if (Objects.Length == 0)
{
Lootations.Logger.LogWarning((object)"ObjectRandomizer told to spawn with objects of length 0.");
return;
}
if ((Object)(object)spawnedObject != (Object)null)
{
Object.Destroy((Object)(object)spawnedObject);
}
int num = Random.Range(0, Objects.Length);
spawnedObject = Objects[num];
if ((Object)(object)spawnedObject == (Object)null)
{
Lootations.Logger.LogDebug((object)"ObjectRandomizer rolled null");
return;
}
spawnedObject = Object.Instantiate<GameObject>(spawnedObject, ((Component)this).transform);
if (RandomizeRotation)
{
spawnedObject.transform.Rotate(new Vector3(0f, Random.Range(0f, 360f), 0f));
}
}
private void OnDrawGizmos()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
Gizmos.color = Color.green;
Gizmos.DrawCube(((Component)this).transform.position + new Vector3(0f, 0.5f, 0f), new Vector3(1f, 1f, 1f));
}
}
public class LootSpawnPoint : MonoBehaviour
{
public delegate void LootRolledDelegate(List<string> newLoot);
public string[] ProgressiveLootTables = new string[5] { "Level 0", "Level 1", "Level 2", "Level 3", "Level 4" };
public float SpawnRadius = 0.25f;
[Header("Instance Settings")]
public bool UseInstanceSettings;
public float CullDistance = 250f;
private bool HasSpawnedLoot;
private bool Culled;
private float cullDistance = 50f;
private List<GameObject> spawnedLoot = new List<GameObject>();
private static readonly float CULL_MIN_TIMER = 0.5f;
private static readonly float CULL_RANDOM_DELAY_MAX = 2.5f;
private Coroutine CullUpdateRoutine;
public List<string> ObjectIds { get; set; } = new List<string>();
public string TableName { get; set; } = "NONE";
public event LootRolledDelegate LootRolled;
private void Awake()
{
bool active = LootManager.AddLootSpawn(this);
((Component)this).gameObject.SetActive(active);
if (Lootations.CullingEnabled.Value)
{
CullUpdateRoutine = ((MonoBehaviour)this).StartCoroutine(CullUpdate());
if (UseInstanceSettings)
{
cullDistance = CullDistance;
}
else
{
cullDistance = Lootations.ItemCullingDistance.Value;
}
}
if ((Object)(object)SR_Manager.instance != (Object)null)
{
SetLevel(SR_Manager.instance.CurrentCaptures);
}
else
{
SetLevel(0);
}
}
private IEnumerator CullUpdate()
{
while (true)
{
if (HasSpawnedLoot)
{
if (Culled)
{
if (Utilities.PlayerWithinDistance(((Component)this).transform.position, cullDistance))
{
foreach (GameObject item in spawnedLoot)
{
item.SetActive(true);
}
Culled = false;
}
}
else if (!Utilities.PlayerWithinDistance(((Component)this).transform.position, cullDistance))
{
foreach (GameObject item2 in spawnedLoot)
{
item2.SetActive(false);
}
Culled = true;
}
}
yield return (object)new WaitForSeconds(CULL_MIN_TIMER + Random.Range(0f, CULL_RANDOM_DELAY_MAX));
}
}
public void StopTrackingObject(GameObject obj)
{
if (spawnedLoot.Contains(obj))
{
spawnedLoot.Remove(obj);
}
}
public void SetLevel(int level)
{
if (ProgressiveLootTables.Length == 0)
{
Lootations.Logger.LogWarning((object)"Spawn point has no loot tables at all.");
return;
}
level = Mathf.Clamp(level, 0, ProgressiveLootTables.Length - 1);
TableName = ProgressiveLootTables[level];
}
public void Reset()
{
if (Lootations.h3mpEnabled && Networking.IsClient())
{
return;
}
foreach (GameObject item in spawnedLoot)
{
Object.Destroy((Object)(object)item);
}
spawnedLoot = new List<GameObject>();
HasSpawnedLoot = false;
Culled = false;
}
public virtual void Trigger()
{
ObjectIds = TableManager.GetTable(TableName).RollObjectId();
this.LootRolled?.Invoke(ObjectIds);
((MonoBehaviour)this).StartCoroutine(SpawnLoot());
}
private void OnDrawGizmos()
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
//IL_0104: Unknown result type (might be due to invalid IL or missing references)
//IL_010e: Unknown result type (might be due to invalid IL or missing references)
//IL_0119: Unknown result type (might be due to invalid IL or missing references)
//IL_011e: Unknown result type (might be due to invalid IL or missing references)
Gizmos.color = new Color(0f, 0.6f, 0f, 0.5f);
Gizmos.DrawLine(((Component)this).transform.position, ((Component)this).transform.position + ((Component)this).transform.forward * SpawnRadius);
Gizmos.color = new Color(0.6f, 0f, 0f, 0.5f);
Gizmos.DrawLine(((Component)this).transform.position, ((Component)this).transform.position + ((Component)this).transform.forward * -1f * SpawnRadius);
Gizmos.DrawLine(((Component)this).transform.position, ((Component)this).transform.position + ((Component)this).transform.right * SpawnRadius);
Gizmos.DrawLine(((Component)this).transform.position, ((Component)this).transform.position + ((Component)this).transform.right * -1f * SpawnRadius);
}
private void OnDestroy()
{
LootManager.RemoveLootSpawn(this);
if (CullUpdateRoutine != null)
{
((MonoBehaviour)this).StopCoroutine(CullUpdateRoutine);
}
}
public IEnumerator SpawnLoot()
{
if (Lootations.h3mpEnabled && Networking.IsClient())
{
yield break;
}
if (ObjectIds.Count == 0)
{
Lootations.Logger.LogWarning((object)"Skipped spawn due to empty lootable.");
yield break;
}
Vector3 val = default(Vector3);
for (int i = 0; i < ObjectIds.Count; i++)
{
string text = ObjectIds[i];
if (!IM.OD.TryGetValue(text, out var obj))
{
Lootations.Logger.LogError((object)("No object found with id '" + text + "'."));
break;
}
Transform transform = ((Component)this).gameObject.transform;
if ((Object)(object)obj != (Object)null && (int)obj.Category == 1)
{
FVRObject mag = ((!FirearmAPI.HasMagazine(obj)) ? obj.CompatibleSingleRounds[0] : FirearmAPI.GetSmallestMagazine(obj, (Func<FVRObject, bool>)null));
int spawnAmount = Random.Range((int)LootManager.MAG_AMOUNT_RANGE.x, (int)LootManager.MAG_AMOUNT_RANGE.y);
for (int j = 0; j < spawnAmount; j++)
{
AnvilCallback<GameObject> magCallback = ((AnvilAsset)mag).GetGameObjectAsync();
yield return magCallback;
((Vector3)(ref val))..ctor(Random.Range(0f - SpawnRadius, SpawnRadius), (float)j * LootManager.Y_SPAWN_INCREMENT, Random.Range(0f - SpawnRadius, SpawnRadius));
GameObject val2 = Object.Instantiate<GameObject>(magCallback.Result, transform.position + val, transform.rotation * LootManager.RandomRotation());
LootManager.spawnedLoot.Add(val2, this);
spawnedLoot.Add(val2);
val2.SetActive(true);
yield return null;
}
}
AnvilCallback<GameObject> callback = ((AnvilAsset)obj).GetGameObjectAsync();
yield return callback;
HasSpawnedLoot = true;
GameObject val3 = Object.Instantiate<GameObject>(callback.Result, transform.position, transform.rotation * LootManager.RandomRotation());
LootManager.spawnedLoot.Add(val3, this);
spawnedLoot.Add(val3);
val3.SetActive(true);
yield return null;
obj = null;
}
}
}
public static class Networking
{
[CompilerGenerated]
private static class <>O
{
public static CustomPacketHandlerReceivedDelegate <0>__ReceiveClientPacketSync;
}
private static readonly string ITEM_GRAB_STRING_ID = "Lootations_ItemGrab";
private static readonly string REROLL_LOOT_STRING_ID = "Lootations_RerollLoot";
private static readonly string TRIGGER_ACTIVATED_STRING_ID = "Lootations_TriggerActivated";
private static Dictionary<string, CustomPacketHandler> packetHandlers = new Dictionary<string, CustomPacketHandler>
{
{
ITEM_GRAB_STRING_ID,
new CustomPacketHandler(ReceiveItemGrab)
},
{
REROLL_LOOT_STRING_ID,
new CustomPacketHandler(ReceiveRerollLoot)
},
{
TRIGGER_ACTIVATED_STRING_ID,
new CustomPacketHandler(ReceiveTriggerActivated)
}
};
private static Dictionary<string, int> packetIds = new Dictionary<string, int>();
public static void OnSceneSwitched(Scene old_scene, Scene new_scene)
{
InitializeNetworking();
}
public static void InitializeNetworking()
{
if (IsConnected())
{
SetupPacketTypes();
}
}
private static void SetupPacketTypes()
{
//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
//IL_01ee: Expected O, but got Unknown
Lootations.Logger.LogDebug((object)"Setting up packet types.");
foreach (KeyValuePair<string, CustomPacketHandler> packetHandler in packetHandlers)
{
if (!packetIds.ContainsKey(packetHandler.Key))
{
Lootations.Logger.LogDebug((object)("Adding handler " + packetHandler.Key + " as default ID"));
packetIds.Add(packetHandler.Key, -1);
}
}
if (IsHost())
{
Lootations.Logger.LogDebug((object)"Setting up packets as host.");
{
foreach (KeyValuePair<string, CustomPacketHandler> packetHandler2 in packetHandlers)
{
Lootations.Logger.LogDebug((object)("Setting up handler " + packetHandler2.Key));
if (Mod.registeredCustomPacketIDs.ContainsKey(packetHandler2.Key))
{
packetIds[packetHandler2.Key] = Mod.registeredCustomPacketIDs[packetHandler2.Key];
Lootations.Logger.LogDebug((object)("Handler already existed as id " + packetIds[packetHandler2.Key]));
}
else
{
packetIds[packetHandler2.Key] = Server.RegisterCustomPacketType(packetHandler2.Key, 0);
Lootations.Logger.LogDebug((object)("Handler registered as id " + packetIds[packetHandler2.Key]));
}
Mod.customPacketHandlers[packetIds[packetHandler2.Key]] = packetHandler2.Value;
}
return;
}
}
if (!IsClient())
{
return;
}
Lootations.Logger.LogDebug((object)"Setting up packets as client.");
object obj = <>O.<0>__ReceiveClientPacketSync;
if (obj == null)
{
CustomPacketHandlerReceivedDelegate val = ReceiveClientPacketSync;
<>O.<0>__ReceiveClientPacketSync = val;
obj = (object)val;
}
Mod.CustomPacketHandlerReceived += (CustomPacketHandlerReceivedDelegate)obj;
foreach (KeyValuePair<string, CustomPacketHandler> packetHandler3 in packetHandlers)
{
Lootations.Logger.LogDebug((object)("Processing handler " + packetHandler3.Key.ToString()));
if (Mod.registeredCustomPacketIDs.ContainsKey(packetHandler3.Key))
{
packetIds[packetHandler3.Key] = Mod.registeredCustomPacketIDs[packetHandler3.Key];
Mod.customPacketHandlers[packetIds[packetHandler3.Key]] = packetHandlers[packetHandler3.Key];
Lootations.Logger.LogDebug((object)("Handler already registered as id " + packetIds[packetHandler3.Key]));
}
else
{
Lootations.Logger.LogDebug((object)"Registering the handler as new, awaiting ID from host.");
ClientSend.RegisterCustomPacketType(packetHandler3.Key);
}
}
}
public static void ReceiveClientPacketSync(string ID, int index)
{
Lootations.Logger.LogDebug((object)("Got ClientPacketSync for HandlerID " + ID + " index: " + index));
if (packetHandlers.ContainsKey(ID))
{
packetIds[ID] = index;
Mod.customPacketHandlers[index] = packetHandlers[ID];
Lootations.Logger.LogDebug((object)("Successfully connected handling for packet ID: " + ID));
}
}
public static bool IsConnected()
{
if (Lootations.h3mpEnabled)
{
return (Object)(object)Mod.managerObject != (Object)null;
}
return false;
}
public static bool IsClient()
{
if (IsConnected())
{
return !ThreadManager.host;
}
return false;
}
public static bool IsHost()
{
if (IsConnected())
{
return ThreadManager.host;
}
return false;
}
public static int[] GetPlayerIds()
{
int[] array = new int[GameManager.players.Count];
int num = 0;
foreach (KeyValuePair<int, PlayerManager> player in GameManager.players)
{
array[num] = player.Key;
num++;
}
return array;
}
public static Vector3 GetPlayerPosition(int id)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
return ((Component)PlayerData.GetPlayer(id).head).transform.position;
}
public static void SendItemGrab(GameObject obj)
{
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Expected O, but got Unknown
if (!IsClient())
{
return;
}
if ((Object)(object)obj == (Object)null)
{
Lootations.Logger.LogDebug((object)"Obj is, somehow, null");
return;
}
TrackedItem component = obj.GetComponent<TrackedItem>();
if ((Object)(object)component == (Object)null)
{
Lootations.Logger.LogDebug((object)"Obj found but no TrackedItem");
return;
}
TrackedObjectData data = ((TrackedObject)component).data;
if (data == null)
{
Lootations.Logger.LogDebug((object)"Tried to get tracking of object that doesn't have it!");
return;
}
Packet val = new Packet(packetIds[ITEM_GRAB_STRING_ID]);
val.Write(data.trackedID);
ClientSend.SendTCPData(val, true);
}
public static void ReceiveItemGrab(int clientId, Packet packet)
{
Lootations.Logger.LogDebug((object)"Item grab packet received");
LootManager.StopTrackingNetworkId(packet.ReadInt(true));
}
public static void SendRerollLoot(int seed)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Expected O, but got Unknown
Packet val = new Packet(packetIds[REROLL_LOOT_STRING_ID]);
val.Write(seed);
ServerSend.SendTCPDataToAll(val, true);
}
public static void ReceiveRerollLoot(int clientId, Packet p)
{
int seed = p.ReadInt(true);
if (IsHost())
{
Lootations.Logger.LogInfo((object)"Ignoring reroll loot packet as host.");
}
else
{
LootManager.RerollLoot(seed);
}
}
public static void SendTriggerActivated(int id)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Expected O, but got Unknown
Packet val = new Packet(packetIds[TRIGGER_ACTIVATED_STRING_ID]);
val.Write(id);
if (IsClient())
{
ClientSend.SendTCPData(val, true);
}
else
{
ServerSend.SendTCPDataToAll(val, true);
}
}
public static void ReceiveTriggerActivated(int clientId, Packet packet)
{
ILootTrigger lootTriggerById = LootManager.GetLootTriggerById(packet.ReadInt(true));
if (lootTriggerById == null)
{
Lootations.Logger.LogError((object)"Got packet to trigger non-existing loot trigger!");
}
else
{
lootTriggerById.Trigger();
}
}
}
[HarmonyPatch(typeof(FVRPhysicalObject), "BeginInteraction")]
internal class FVRPhysicalObjectPatch
{
private static void Postfix(FVRPhysicalObject __instance)
{
LootManager.OnPhysicalObjectPickup(((Component)__instance).gameObject);
}
}
[HarmonyPatch(typeof(IM), "GenerateItemDBs")]
public class GenerateItemDBsPatch
{
public static void Postfix()
{
TableManager.Initialize();
}
}
[HarmonyPatch(typeof(TNH_Manager), "SetLevel")]
public class TNHManagerSetLevelHook
{
public static void Postfix(int level)
{
Lootations.Logger.LogDebug((object)"TNH SetLevel hook fired");
LootManager.OnTNHLevelSet(level);
}
}
[BepInProcess("h3vr.exe")]
[BepInPlugin("Wilnath.Lootations", "Lootations", "1.0.0")]
public class Lootations : BaseUnityPlugin
{
public static bool h3mpEnabled;
public static ConfigEntry<int> MaxRandomLootObjectSpawns;
public static ConfigEntry<float> ProximitySpawnDistance;
public static ConfigEntry<float> ItemCullingDistance;
public static ConfigEntry<float> SosigSpawnDistance;
public static ConfigEntry<float> SosigDeSpawnDistance;
public static ConfigEntry<bool> CullingEnabled;
public static ConfigEntry<string> DisabledModDrops;
private static Harmony harmonyInstance;
public const string Id = "Wilnath.Lootations";
internal static ManualLogSource Logger { get; private set; }
public static string Name => "Lootations";
public static string Version => "1.0.0";
private void Awake()
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Expected O, but got Unknown
Logger = ((BaseUnityPlugin)this).Logger;
harmonyInstance = new Harmony("LootationsHarmonyInstance");
harmonyInstance.PatchAll();
SetupConfig();
h3mpEnabled = Chainloader.PluginInfos.ContainsKey("VIP.TommySoucy.H3MP");
SceneManager.activeSceneChanged += OnSceneSwitched;
if (h3mpEnabled)
{
Logger.LogDebug((object)"H3MP Detected as enabled");
HookNetworking();
}
else
{
Logger.LogDebug((object)"Starting with no H3MP");
}
}
private void HookNetworking()
{
SceneManager.activeSceneChanged += Networking.OnSceneSwitched;
}
private void OnSceneSwitched(Scene old_scene, Scene new_scene)
{
Logger.LogDebug((object)"Scene switch occurred");
LootManager.OnSceneSwitched();
}
private void SetupConfig()
{
MaxRandomLootObjectSpawns = ((BaseUnityPlugin)this).Config.Bind<int>("Gameplay", "MaxRandomLootObjectSpawns", 250, "The maximum amount of random loot objects that will spawn per level. -1 to disable");
DisabledModDrops = ((BaseUnityPlugin)this).Config.Bind<string>("Gameplay", "DisabledModDrops", "", "Plugin names that should count as not being loaded for loot tables. Seperate plugin names with a colon");
SosigSpawnDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Performance", "SosigSpawnDistance", 75f, "How far away you have to be for sausages to spawn in.");
SosigDeSpawnDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Performance", "SosigDeSpawnDistance", 150f, "TODO");
ProximitySpawnDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Performance", "ProximitySpawnDistance", 25f, "Distance until Proximity triggers activate, can be expensive if too far.\nNote: Some proximity triggers override this setting.");
CullingEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Experimental", "Culling", true, "If untouched items are to be disabled after player is set distance away from the loot spawn point.");
ItemCullingDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Experimental", "ItemCullingDistance", 50f, "The distance at which items are set to be inactive.");
}
}
public class LootTable
{
public string Name { get; private set; }
public string[] Meta { get; set; }
public List<TableEntry> Entries { get; private set; } = new List<TableEntry>();
public int TotalWeight { get; set; } = -1;
public LootTable(string name, TableEntry[] entries)
{
foreach (TableEntry entry in entries)
{
AddEntry(entry);
}
Name = name;
}
public void AddEntry(TableEntry entry)
{
Entries.Add(entry);
}
public List<string> RollObjectId()
{
if (TotalWeight == -1)
{
CalculateTotalWeight();
}
if (TotalWeight == 0)
{
Lootations.Logger.LogError((object)("Total weight calculated to be 0 in " + Name));
return new List<string>();
}
int num = Random.Range(1, TotalWeight + 1);
foreach (TableEntry entry in Entries)
{
if (num <= entry.Weight)
{
return entry.RollObjectId();
}
num -= entry.Weight;
}
Lootations.Logger.LogError((object)("Could not roll any ids in " + Name));
return new List<string>();
}
public void CalculateTotalWeight()
{
TotalWeight = 0;
foreach (TableEntry entry in Entries)
{
TotalWeight += entry.Weight;
}
}
}
public interface IValidator
{
bool IsValid();
}
public class MetaTags
{
public List<IValidator> Validators = new List<IValidator>();
}
public static class MetaTagsManager
{
public static Dictionary<string, Func<string, MetaTags, bool>> keyToMethod = new Dictionary<string, Func<string, MetaTags, bool>> {
{
"ModDependency",
delegate(string s, MetaTags tags)
{
tags.Validators.Add(new ModDependency(s));
return true;
}
} };
public static MetaTags ParseTableMetaTags(LootTable table)
{
string[] meta = table.Meta;
MetaTags metaTags = new MetaTags();
string[] array = meta;
for (int i = 0; i < array.Length; i++)
{
string[] array2 = array[i].Split(new char[1] { ':' });
if (array2.Length != 2)
{
Lootations.Logger.LogWarning((object)"Skipping meta tag with ambiguous key:value pair");
continue;
}
string key = array2[0].Trim();
if (!keyToMethod.ContainsKey(key))
{
Lootations.Logger.LogWarning((object)"Skipping meta tag with non-existing meta key");
continue;
}
string arg = array2[1].Trim();
keyToMethod[key](arg, metaTags);
}
return metaTags;
}
}
public class ModDependency : IValidator
{
private string _modDependency;
public ModDependency(string modDependency)
{
_modDependency = modDependency;
}
public bool IsValid()
{
if (Lootations.DisabledModDrops != null && Lootations.DisabledModDrops.Value.Split(new char[1] { ',' }).Contains(_modDependency))
{
return false;
}
return Chainloader.PluginInfos.ContainsKey(_modDependency);
}
}
public class TableEntry
{
public enum TableType
{
OBJECT_ID,
TABLE_REFERENCE,
TAGS
}
public TableType Type { get; set; }
public int Weight { get; set; }
public List<string> LootIds { get; set; }
public static TableEntry ObjectEntry(string objectId, int weight)
{
return new TableEntry
{
Weight = weight,
LootIds = new List<string>(1) { objectId },
Type = TableType.OBJECT_ID
};
}
public static TableEntry TableReference(string tableName, int weight)
{
return new TableEntry
{
Weight = weight,
LootIds = new List<string>(1) { tableName },
Type = TableType.TABLE_REFERENCE
};
}
public List<string> RollObjectId()
{
switch (Type)
{
case TableType.OBJECT_ID:
return LootIds;
case TableType.TABLE_REFERENCE:
return TableManager.GetTable(LootIds[0]).RollObjectId();
case TableType.TAGS:
return new List<string>();
default:
Lootations.Logger.LogError((object)"Invalid TableEntry Type. Returning None.");
return new List<string>();
}
}
private bool IsTagAndValueValid(string tag, string value)
{
PropertyInfo property = ((object)IM.OD["BulbBlue"]).GetType().GetProperty(tag.Insert(0, "Tag"));
if ((object)property == null)
{
Lootations.Logger.LogError((object)("Could not find tag with name " + property));
return false;
}
return true;
}
private void InitializeTagTable()
{
if (Type != TableType.TAGS || LootIds.Count == 0)
{
return;
}
string[] array = LootIds[0].Split(new char[1] { ':' });
if (array.Length != 2)
{
Lootations.Logger.LogError((object)"Error parsing tags in tag table entry, invalid argument length");
return;
}
string tag = array[0];
string value = array[1];
new List<string>();
IsTagAndValueValid(tag, value);
foreach (KeyValuePair<string, FVRObject> item in IM.OD)
{
_ = item;
}
}
}
public static class TableManager
{
private static Dictionary<string, LootTable> _lootTables;
private static readonly LootTable NullTable = new LootTable("NONE", new TableEntry[1] { TableEntry.ObjectEntry("NONE", 1) });
public static void Initialize()
{
_lootTables = new Dictionary<string, LootTable>();
Lootations.Logger.LogInfo((object)"Begun reading loot table files.");
string[] files = Directory.GetFiles(Paths.PluginPath, "*.lttbl", SearchOption.AllDirectories);
for (int i = 0; i < files.Length; i++)
{
ProcessFile(files[i]);
}
ValidateAllTables();
}
private static void ValidateAllTables()
{
foreach (KeyValuePair<string, LootTable> lootTable in _lootTables)
{
RemoveZeroWeightEntries(lootTable.Value);
ValidateObjectIds(lootTable.Value);
}
foreach (KeyValuePair<string, LootTable> lootTable2 in _lootTables)
{
lootTable2.Value.CalculateTotalWeight();
}
foreach (KeyValuePair<string, LootTable> lootTable3 in _lootTables)
{
ValidateReferences(lootTable3.Value);
}
}
private static void RemoveZeroWeightEntries(LootTable table)
{
for (int i = 0; i < table.Entries.Count; i++)
{
if (table.Entries[i].Weight == 0)
{
table.Entries.RemoveAt(i);
i--;
}
}
}
private static void ValidateObjectIds(LootTable table)
{
for (int i = 0; i < table.Entries.Count; i++)
{
if (table.Entries[i].Type == TableEntry.TableType.TABLE_REFERENCE)
{
continue;
}
List<string> lootIds = table.Entries[i].LootIds;
for (int j = 0; j < lootIds.Count; j++)
{
string text = lootIds[j];
if (!IM.OD.ContainsKey(text))
{
Lootations.Logger.LogDebug((object)("Unknown object id " + text + " in table " + table.Name));
}
}
if (lootIds.Count == 0)
{
table.Entries.RemoveAt(i);
table.CalculateTotalWeight();
i--;
}
}
}
private static void ValidateReferences(LootTable table)
{
for (int i = 0; i < table.Entries.Count; i++)
{
TableEntry tableEntry = table.Entries[i];
if (tableEntry.Type == TableEntry.TableType.TABLE_REFERENCE)
{
if (GetTable(tableEntry.LootIds[0]) == NullTable)
{
Lootations.Logger.LogWarning((object)("Reference to non-existant table " + tableEntry.LootIds[0] + " in " + table.Name));
table.Entries.RemoveAt(i);
table.CalculateTotalWeight();
i--;
}
else if (GetTable(tableEntry.LootIds[0]).TotalWeight == 0)
{
Lootations.Logger.LogDebug((object)("Deleting reference entry to empty table " + tableEntry.LootIds[0] + " in " + table.Name));
table.Entries.RemoveAt(i);
table.CalculateTotalWeight();
i--;
}
}
}
}
public static void AddLootTable(LootTable table)
{
foreach (IValidator validator in MetaTagsManager.ParseTableMetaTags(table).Validators)
{
if (!validator.IsValid())
{
Lootations.Logger.LogInfo((object)("Skipping loading table due to failed validator: " + table.Name));
return;
}
}
if (_lootTables.ContainsKey(table.Name))
{
Lootations.Logger.LogInfo((object)("Appending to table " + table.Name));
LootTable lootTable = _lootTables[table.Name];
{
foreach (TableEntry entry in table.Entries)
{
lootTable.Entries.Add(entry);
}
return;
}
}
for (int i = 0; i < table.Entries.Count; i++)
{
TableEntry tableEntry = table.Entries[i];
if (tableEntry.Weight == 0)
{
table.Entries.Remove(tableEntry);
i--;
}
}
_lootTables.Add(table.Name, table);
}
public static LootTable GetTable(string name)
{
if (!_lootTables.TryGetValue(name, out var value))
{
Lootations.Logger.LogWarning((object)("Attempt to access nonexistant table " + name));
return NullTable;
}
return value;
}
private static void ProcessFile(string fileName)
{
foreach (LootTable item in JsonConvert.DeserializeObject<List<LootTable>>(File.ReadAllText(fileName)))
{
AddLootTable(item);
}
}
}
public interface ILootTrigger
{
public delegate void OnTriggeredDelegate(ILootTrigger trigger);
event OnTriggeredDelegate OnTriggered;
void Trigger();
void LootReset();
}
public class LootCardScanTrigger : MonoBehaviour, ILootTrigger
{
public GameObject LootObjectOwner;
public int KeycardTier = 1;
public event ILootTrigger.OnTriggeredDelegate OnTriggered;
public void Awake()
{
LootObject.HookTrigger(LootObjectOwner, (MonoBehaviour)(object)this);
}
private void OnTriggerEnter(Collider other)
{
WW_Keycard component = ((Component)other).GetComponent<WW_Keycard>();
if ((Object)(object)component != (Object)null && component.TierType == KeycardTier)
{
Trigger();
}
}
public void Trigger()
{
this.OnTriggered?.Invoke(this);
}
private void OnDrawGizmos()
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
Gizmos.color = new Color(0f, 0.6f, 0f, 0.5f);
}
public void LootReset()
{
}
}
public class LootCoverTrigger : FVRInteractiveObject, ILootTrigger
{
public GameObject LootObjectOwner;
public Transform Root;
public Transform Hinge;
private float startAngle;
public float MinRot;
public float MaxRot = 45f;
private bool JustInteracted;
public event ILootTrigger.OnTriggeredDelegate OnTriggered;
public override void Awake()
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
((FVRInteractiveObject)this).Awake();
startAngle = ((Component)Hinge).transform.localEulerAngles.z;
if ((Object)(object)Root == (Object)null || (Object)(object)Hinge == (Object)null)
{
Lootations.Logger.LogError((object)"CoverTrigger doesn't have a root or hinge, this is misconfigured!");
((Component)this).gameObject.SetActive(false);
}
else
{
LootObject.HookTrigger(LootObjectOwner, (MonoBehaviour)(object)this);
}
}
public void Trigger()
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
if (!JustInteracted)
{
((Component)Hinge).transform.localEulerAngles = new Vector3(0f, 0f, MaxRot);
}
this.OnTriggered?.Invoke(this);
}
public override void BeginInteraction(FVRViveHand hand)
{
((FVRInteractiveObject)this).BeginInteraction(hand);
AudioSource component = ((Component)this).GetComponent<AudioSource>();
if (component != null)
{
component.Play();
}
JustInteracted = true;
Trigger();
JustInteracted = false;
}
public override void UpdateInteraction(FVRViveHand hand)
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
((FVRInteractiveObject)this).UpdateInteraction(hand);
Vector3 val = Root.InverseTransformPoint(((HandInput)(ref hand.Input)).Pos);
float num = Mathf.Atan2(val.y, val.x) * 57.29578f;
num = Mathf.Clamp(num, MinRot, MaxRot);
((Component)Hinge).transform.localEulerAngles = new Vector3(0f, 0f, num);
}
public void LootReset()
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
((Component)Hinge).transform.localEulerAngles = new Vector3(0f, 0f, startAngle);
}
private void OnDrawGizmos()
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_011e: Unknown result type (might be due to invalid IL or missing references)
//IL_0123: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)Root == (Object)null))
{
Gizmos.color = new Color(0f, 0.6f, 0f, 0.5f);
Gizmos.DrawLine(((Component)Root).transform.position, ((Component)Root).transform.position + new Vector3(0f, ((Component)Root).transform.forward.y * Mathf.Sin(MinRot), ((Component)Root).transform.forward.z * Mathf.Cos(MinRot)) * 0.25f);
Gizmos.DrawLine(((Component)Root).transform.position, ((Component)Root).transform.position + new Vector3(0f, ((Component)Root).transform.forward.y * Mathf.Sin(MaxRot), ((Component)Root).transform.forward.z * Mathf.Cos(MaxRot)) * 0.25f);
}
}
}
public class LootDamageTrigger : MonoBehaviour, IFVRDamageable, ILootTrigger
{
public GameObject LootObjectOwner;
public DamageClass triggerDamageType = (DamageClass)3;
public float triggerDamageSize = 10f;
public event ILootTrigger.OnTriggeredDelegate OnTriggered;
public void Awake()
{
LootObject.HookTrigger(LootObjectOwner, (MonoBehaviour)(object)this);
}
void IFVRDamageable.Damage(Damage dam)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
if (dam.Class == triggerDamageType)
{
AudioSource component = ((Component)this).GetComponent<AudioSource>();
if (component != null)
{
component.Play();
}
Trigger();
}
}
public void Trigger()
{
this.OnTriggered?.Invoke(this);
}
public void LootReset()
{
}
}
public class LootPhysicsTrigger : FVRPhysicalObject, ILootTrigger
{
[Header("Loot Trigger")]
public GameObject LootObjectOwner;
private Vector3 startingPosition;
private Quaternion startingRotation;
private Vector3 startingScale;
public event ILootTrigger.OnTriggeredDelegate OnTriggered;
public override void Awake()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
startingPosition = ((Component)this).transform.localPosition;
startingRotation = ((Component)this).transform.localRotation;
startingScale = ((Component)this).transform.localScale;
LootObject.HookTrigger(LootObjectOwner, (MonoBehaviour)(object)this);
}
public override void BeginInteraction(FVRViveHand hand)
{
((FVRPhysicalObject)this).BeginInteraction(hand);
Trigger();
}
public void Trigger()
{
this.OnTriggered?.Invoke(this);
}
public void LootReset()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
((Component)this).transform.position = startingPosition;
((Component)this).transform.rotation = startingRotation;
((Component)this).transform.localScale = startingScale;
}
}
public class LootProximityTrigger : MonoBehaviour, ILootTrigger
{
public GameObject LootObjectOwner;
[Header("Instance Settings")]
public bool UseInstanceSettings;
public float TriggerDistance = 250f;
private float triggerDistance;
public event ILootTrigger.OnTriggeredDelegate OnTriggered;
public void Awake()
{
LootObject.HookTrigger(LootObjectOwner, (MonoBehaviour)(object)this);
if (UseInstanceSettings)
{
triggerDistance = TriggerDistance;
}
else
{
triggerDistance = Lootations.ProximitySpawnDistance.Value;
}
}
public void Trigger()
{
this.OnTriggered?.Invoke(this);
}
public void LootReset()
{
}
public void Update()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
if (Utilities.PlayerWithinDistance(((Component)this).transform.position, triggerDistance))
{
Trigger();
}
}
}
public class LootSlideTrigger : FVRInteractiveObject, ILootTrigger
{
public GameObject LootObjectOwner;
public GameObject Root;
public GameObject Hinge;
public float MaxOffset = 0.25f;
public event ILootTrigger.OnTriggeredDelegate OnTriggered;
public override void Awake()
{
if ((Object)(object)Root == (Object)null || (Object)(object)Hinge == (Object)null)
{
Lootations.Logger.LogError((object)"SlideTrigger doesn't have a root or hinge, this is misconfigured!");
((Component)this).gameObject.SetActive(false);
}
else
{
LootObject.HookTrigger(LootObjectOwner, (MonoBehaviour)(object)this);
}
}
public override void BeginInteraction(FVRViveHand hand)
{
((FVRInteractiveObject)this).BeginInteraction(hand);
}
public void Trigger()
{
this.OnTriggered?.Invoke(this);
}
public override void UpdateInteraction(FVRViveHand hand)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
((FVRInteractiveObject)this).UpdateInteraction(hand);
float num = Mathf.Clamp(Root.transform.InverseTransformPoint(((HandInput)(ref hand.Input)).Pos).z, 0f, MaxOffset);
Hinge.transform.localPosition = new Vector3(0f, 0f, num);
}
public void LootReset()
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
Hinge.transform.localPosition = new Vector3(0f, 0f, 0f);
}
private void OnDrawGizmos()
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
Gizmos.color = new Color(0f, 0.6f, 0f, 0.5f);
Gizmos.DrawLine(Root.transform.position, Root.transform.position + Root.transform.forward * MaxOffset);
}
}
internal static class Utilities
{
private static readonly float NAVMESH_QUERY_RANGE = 30f;
public static LootSpawnPoint[] GameObjectsToPoints(GameObject[] gameObjects)
{
if (gameObjects.Length == 0)
{
return new LootSpawnPoint[0];
}
LootSpawnPoint[] array = new LootSpawnPoint[gameObjects.Length];
for (int i = 0; i < gameObjects.Length; i++)
{
LootSpawnPoint component = gameObjects[i].GetComponent<LootSpawnPoint>();
if ((Object)(object)component == (Object)null)
{
Lootations.Logger.LogError((object)"Object has loot spawn point set without its component");
}
else
{
array[i] = component;
}
}
return array;
}
public static bool FindPointOnNavmesh(Vector3 centre, out Vector3 result)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
NavMeshHit val = default(NavMeshHit);
if (NavMesh.SamplePosition(centre, ref val, NAVMESH_QUERY_RANGE, -1))
{
result = ((NavMeshHit)(ref val)).position;
return true;
}
result = Vector3.zero;
return false;
}
public static bool RandomPointOnNavmesh(Vector3 centre, float range, out Vector3 result)
{
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
NavMeshHit val = default(NavMeshHit);
for (int i = 0; i < 30; i++)
{
if (NavMesh.SamplePosition(centre + Random.insideUnitSphere * range, ref val, 0.5f, -1))
{
result = ((NavMeshHit)(ref val)).position;
return true;
}
}
result = Vector3.zero;
return false;
}
public static string GetRandomInStringArray(string[] arr)
{
if (arr.Length == 0)
{
return "";
}
return arr[Random.Range(0, arr.Length + 1)];
}
public static Vector3 GetPlayerPosition()
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
return ((Component)GM.CurrentPlayerBody.Head).transform.position;
}
public static bool PositionsWithinDistance(Vector3 a, Vector3 b, float distance)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
Vector3 val = b - a;
return ((Vector3)(ref val)).sqrMagnitude < distance * distance;
}
public static PlayerData GetPlayer(int i)
{
return PlayerData.GetPlayer(i);
}
public static bool PlayerWithinDistance(Vector3 a, float distance)
{
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
if (Lootations.h3mpEnabled && Networking.IsHost())
{
int[] playerIds = Networking.GetPlayerIds();
for (int i = 0; i < playerIds.Length; i++)
{
if (PositionsWithinDistance(Networking.GetPlayerPosition(playerIds[i]), a, distance))
{
return true;
}
}
}
return PositionsWithinDistance(GetPlayerPosition(), a, distance);
}
}
}